Skip to content

Releases: objectstack-ai/framework

objectstack-vscode@7.4.1

01 Jun 13:16
afaf858

Choose a tag to compare

objectstack-vscode@7.4.1

objectstack-vscode@7.4.0

01 Jun 10:49
aec0e8a

Choose a tag to compare

objectstack-vscode@7.4.0

create-objectstack@7.4.1

01 Jun 13:13
afaf858

Choose a tag to compare

create-objectstack@7.4.1

create-objectstack@7.4.0

01 Jun 10:47
aec0e8a

Choose a tag to compare

create-objectstack@7.4.0

@objectstack/types@7.4.1

01 Jun 13:16
afaf858

Choose a tag to compare

Patch Changes

  • @objectstack/spec@7.4.1

@objectstack/types@7.4.0

01 Jun 10:49
aec0e8a

Choose a tag to compare

Patch Changes

@objectstack/sveltekit@7.4.1

01 Jun 13:14
afaf858

Choose a tag to compare

@objectstack/sveltekit@7.4.1

@objectstack/sveltekit@7.4.0

01 Jun 10:46
aec0e8a

Choose a tag to compare

@objectstack/sveltekit@7.4.0

@objectstack/spec@7.4.1

01 Jun 13:16
afaf858

Choose a tag to compare

@objectstack/spec@7.4.1

@objectstack/spec@7.4.0

01 Jun 10:49
aec0e8a

Choose a tag to compare

Minor Changes

  • 23c7107: ADR-0020 — converge the three "state machine" declaration shapes to one
    enforced state_machine validation rule.

    Before this change a record state machine could be declared three ways (a
    workflow metadata type, an object.stateMachines map, or a state_machine
    validation rule) and none of them were enforced at runtime — a declarative
    guardrail that was pure decoration, and a hallucination trap for AI authors.

    Enforcement (@objectstack/objectql)

    • New validation/rule-validator.ts evaluates the object's validations union
      on the write path: evaluateValidationRules, needsPriorRecord, and the
      legalNextStates introspection helper (all exported from the package root).
    • state_machine rules reject illegal field transitions on update (with the
      rule's message); script / cross_field predicate rules now also fire
      (they were silently broken on PATCH updates because only the patch, not the
      prior record, was available). The engine plumbs the prior record into
      rule evaluation on single-row update; multi-row (updateMany) updates log a
      warning and skip rule evaluation rather than enforce on incomplete data.

    Convergence / retirement (@objectstack/spec) — breaking

    • Retires the workflow metadata type (removed from the metadata-type enum,
      the registry, the schema map, the workflows collection key, and the
      plural→singular mapping).
    • Removes the object.stateMachines map and the stack.workflows array. The
      state_machine validation rule is the single canonical home.
    • The XState-style StateMachineSchema file is kept (still used by the
      agent conversation lifecycle and the discovery protocol); only its role as
      the workflow metadata-type backing schema was removed. The optional
      workflow RPC service surface (CoreServiceName.workflow,
      /api/v1/workflow, IWorkflowService) is kept as a documented follow-up.

    Introspection (@objectstack/runtime)

    • Adds GET /metadata/objects/:name/state/:field?from=:state, returning the
      legal next states for a field (next: null when no FSM governs the field,
      [] for a declared dead-end) so UIs/agents read the transition table instead
      of re-deriving it.

    Surfaces (@objectstack/platform-objects, @objectstack/cli)

    • Studio drops the standalone "Workflow Rules" nav (state machines are edited
      alongside the object's other validation rules).
    • explain no longer lists workflow as a related metadata type.

    Migration: replace a workflow / StateMachineConfig declaration with a
    state_machine validation rule on the object (field + { from: [allowedTo] }
    transition table), and move any side-effecting actions (emails, task creation)
    into a record-triggered or scheduled Flow (ADR-0019). See the migrated
    examples/app-crm flows for the pattern.

  • c72daad: ADR-0029 D7 — Setup app navigation contributions.

    Adds the UI-layer analog of object own/extend: a package can contribute
    navigation items into an app it does not own, so a shared admin app can be a
    thin shell while each capability plugin ships the menu for the objects it owns.

    • @objectstack/spec — new NavigationContributionSchema ({ app, group?, priority, items }) and an optional navigationContributions field on the
      manifest.

    • @objectstack/objectqlSchemaRegistry.registerAppNavContribution()
      plus lazy merge in getApp / getAllApps (by target group id + priority,
      cloning so the stored app is never mutated); the engine wires
      manifest.navigationContributions during app registration.

    • @objectstack/platform-objects — the Setup app becomes a shell of
      empty group anchors; its entries for platform-objects-owned objects move to
      SETUP_NAV_CONTRIBUTIONS.

    • @objectstack/plugin-auth — registers SETUP_NAV_CONTRIBUTIONS alongside
      the Setup app it already registers.

    • @objectstack/plugin-webhooks — contributes its Webhooks /
      Webhook Deliveries entries into the Setup group_integrations slot (it owns
      sys_webhook / sys_webhook_delivery per K2.a), demonstrating end-to-end
      cross-plugin contribution.

      The rendered Setup nav is identical to the former static artifact — just
      assembled from its owners. A disabled/absent capability contributes nothing and
      its slot stays empty (in addition to the existing requiresObject gating).
      This unblocks moving each remaining K2 domain's menu out of the monolith with
      its objects.

  • f115182: ADR-0019 — App as the consumer-facing unit. The consumer Marketplace surfaces
    exactly one user-visible noun, the App.

    • Adds CONSUMER_INSTALLABLE_TYPES and isConsumerInstallable(type) (the single
      source of truth for "what a consumer can install").
    • Constrains MarketplaceListingSchema.packageType to CONSUMER_INSTALLABLE_TYPES
      (default app) so a non-App (driver/server/plugin/…) listing cannot be
      represented — the "consumers see only Apps" guarantee is enforced in the data
      contract, not a forgettable query filter.
    • defineStack() now enforces at most one App per package: a package with
      manifest.type === 'app' may not define more than one app — the banned "suite
      contains apps" shape throws with a clear fix (fold into one app with multiple
      tabs, or split into separate packages). Zero apps is allowed; non-app
      package types are unconstrained. Non-breaking for existing stacks.

    The package type enum is unchanged; the additions are non-breaking. No
    runtime/registry/execution changes.

  • 2faf9f2: External Datasource Federation (ADR-0015) — Phase 1.

    Adds the spec foundation and the DDL gate for federating mature external
    databases without ObjectStack ever mutating their schema:

    • Datasource.schemaMode (managed | external | validate-only) and
      Datasource.external settings, with a cross-field invariant.
    • Object.external binding (remote table/schema, writability, column map).
    • Shared error contract: ExternalSchemaMismatchError,
      ExternalWriteForbiddenError, ExternalSchemaModeViolationError
      (stable codes) + structured SchemaDiffEntry rendering.
    • driver-sql DDL gate: schema-mutating DDL (initObjects/syncSchema/
      dropTable) is rejected when schemaMode !== 'managed'.

    All changes are additive and backward-compatible (schemaMode defaults to
    'managed').

  • 2faf9f2: External Datasource Federation (ADR-0015) — Phase 2 (service core).

    Adds the federation service contract, the type-compatibility matrix, and a
    new service package that introspects, drafts, and validates federated
    objects:

    • @objectstack/spec:
      • data/type-compat.ts — dialect-aware SQL↔field-type matrix
        (canonicalizeSqlType, suggestFieldType, isCompatible) for
        postgres/mysql/sqlite/snowflake/bigquery/mongo.
      • contracts/external-datasource-service.tsIExternalDatasourceService
        plus RemoteTable, GenerateDraftOpts, ObjectDraft,
        SchemaValidationResult/Report.
    • @objectstack/service-external-datasource (new): implements the service —
      listRemoteTables, generateObjectDraft (renders a reviewable
      *.object.ts with // REVIEW: markers), validateObject/validateAll
      (structured SchemaDiffEntry diffs), and refreshCatalog. Decoupled from
      the kernel via injected I/O; kernel plugin registers it as the
      external-datasource service.

    REST routes and the os datasource CLI commands follow in a subsequent
    slice.

  • 2faf9f2: External Datasource Federation (ADR-0015) — Phase 3 spec: external_catalog
    metadata type.

    • Registers external_catalog in MetadataTypeSchema and
      DEFAULT_METADATA_TYPE_REGISTRY (system domain, allowRuntimeCreate: true,
      not org-overridable).
    • Adds data/external-catalog.zod.tsExternalCatalogSchema /
      ExternalTableSchema / ExternalColumnSchema for persisting a cached
      remote-schema snapshot of a federated datasource (consumed by
      refreshCatalog, the boot-validation gate, and Studio's schema browser).
  • ff3d006: Screen-flow runtime — interactive screen nodes (suspend → render → resume).

    A screen node that declares input fields now suspends the run on entry
    (reusing the ADR-0019 durable pause), surfaces a ScreenSpec describing the
    form, and resumes with the collected values applied as bare flow variables
    so downstream nodes read them via {var}. (waitForInput: false forces the
    old server pass-through.)

    • spec: AutomationResult.screen?: ScreenSpec, ResumeSignal.variables?
      (bare vars), IAutomationService.getSuspendedScreen?(runId).
    • service-automation: the screen executor builds the ScreenSpec and
      suspends when fields are present; the suspend/resume plumbing threads the
      screen through FlowSuspendSignalSuspendedRun → the paused result;
      resume() sets signal.variables as bare flow variables; getSuspendedScreen.
    • runtime: POST /api/v1/automation/:name/runs/:runId/resume (body
      { inputs }) and GET …/runs/:runId/screen, wired through both the
      dispatcher route table and handleAutomation.

    Verified end-to-end headlessly: the showcase Reassign Wizard launches → pauses
    at the "New Assignee" screen → resumes with the input → the task is reassigned.
    The obje...

Read more