From f4afd191c0814edad6fa3fe8e9ee6ac78b110194 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 1 Jun 2026 08:56:15 +0000 Subject: [PATCH] chore: version packages --- ...adr-0020-state-machine-converge-enforce.md | 55 ---- .../adr-0029-d7-setup-nav-contributions.md | 36 -- .../adr-0029-d8-i18n-plugin-ownership.md | 33 -- .changeset/adr-0029-k0-webhooks-ownership.md | 26 -- .changeset/adr-0029-k2-security-ownership.md | 32 -- .../adr-0029-k2b-approvals-ownership.md | 24 -- .../adr-0030-notification-convergence-p0.md | 57 ---- .changeset/adr-0030-notification-p2.md | 28 -- .changeset/adr-0030-notification-p3a-email.md | 33 -- .../adr-0030-notification-p3b1-quiet-hours.md | 28 -- .changeset/adr-0030-p1-reliable-delivery.md | 36 -- .changeset/cli-dev-sqlite-seed-admin.md | 18 - .changeset/connector-mcp.md | 26 -- .changeset/consumer-app-two-tier.md | 21 -- .../external-datasource-federation-p1.md | 21 -- .../external-datasource-federation-p2-cli.md | 11 - .../external-datasource-federation-p2-rest.md | 11 - .../external-datasource-federation-p2.md | 27 -- ...rnal-datasource-federation-p3-boot-gate.md | 12 - .../external-datasource-federation-p3-spec.md | 14 - .../external-datasource-federation-p4-ai.md | 12 - ...nal-datasource-federation-p6-write-gate.md | 15 - .changeset/fix-conditional-flows-skip.md | 28 -- .../fix-platform-admin-skip-system-user.md | 32 -- .changeset/locale-aware-metadata.md | 16 - .../messaging-triggers-capability-tokens.md | 24 -- .changeset/metadata-translation-audit.md | 33 -- .../notification-action-url-from-source.md | 22 -- ...notification-dedup-unique-and-retention.md | 37 --- .changeset/openapi-to-connector.md | 5 - .changeset/record-change-flow-trigger.md | 42 --- .changeset/schedule-flow-trigger.md | 28 -- .changeset/screen-flow-runtime.md | 27 -- .changeset/seed-identity-binding.md | 23 -- apps/account/CHANGELOG.md | 2 + apps/account/package.json | 2 +- examples/app-crm/CHANGELOG.md | 21 ++ examples/app-crm/package.json | 2 +- examples/app-showcase/CHANGELOG.md | 24 ++ examples/app-showcase/package.json | 2 +- examples/app-todo/CHANGELOG.md | 32 ++ examples/app-todo/package.json | 2 +- packages/adapters/express/CHANGELOG.md | 2 + packages/adapters/express/package.json | 2 +- packages/adapters/fastify/CHANGELOG.md | 2 + packages/adapters/fastify/package.json | 2 +- packages/adapters/hono/CHANGELOG.md | 7 + packages/adapters/hono/package.json | 2 +- packages/adapters/nestjs/CHANGELOG.md | 2 + packages/adapters/nestjs/package.json | 2 +- packages/adapters/nextjs/CHANGELOG.md | 2 + packages/adapters/nextjs/package.json | 2 +- packages/adapters/nuxt/CHANGELOG.md | 2 + packages/adapters/nuxt/package.json | 2 +- packages/adapters/sveltekit/CHANGELOG.md | 2 + packages/adapters/sveltekit/package.json | 2 +- packages/cli/CHANGELOG.md | 253 +++++++++++++++ packages/cli/package.json | 2 +- packages/client-react/CHANGELOG.md | 30 ++ packages/client-react/package.json | 2 +- packages/client/CHANGELOG.md | 29 ++ packages/client/package.json | 2 +- .../connectors/connector-mcp/CHANGELOG.md | 44 +++ .../connectors/connector-mcp/package.json | 2 +- .../connectors/connector-openapi/CHANGELOG.md | 23 ++ .../connectors/connector-openapi/package.json | 2 +- .../connectors/connector-rest/CHANGELOG.md | 19 ++ .../connectors/connector-rest/package.json | 2 +- .../connectors/connector-slack/CHANGELOG.md | 19 ++ .../connectors/connector-slack/package.json | 2 +- packages/console/CHANGELOG.md | 2 + packages/console/package.json | 2 +- packages/core/CHANGELOG.md | 17 + packages/core/package.json | 2 +- packages/create-objectstack/CHANGELOG.md | 2 + packages/create-objectstack/package.json | 2 +- packages/formula/CHANGELOG.md | 17 + packages/formula/package.json | 2 +- packages/metadata-core/CHANGELOG.md | 2 + packages/metadata-core/package.json | 2 +- packages/metadata-fs/CHANGELOG.md | 6 + packages/metadata-fs/package.json | 2 +- packages/metadata/CHANGELOG.md | 83 +++++ packages/metadata/package.json | 2 +- packages/objectql/CHANGELOG.md | 170 ++++++++++ packages/objectql/package.json | 2 +- packages/observability/CHANGELOG.md | 17 + packages/observability/package.json | 2 +- packages/platform-objects/CHANGELOG.md | 307 ++++++++++++++++++ packages/platform-objects/package.json | 2 +- packages/plugins/driver-memory/CHANGELOG.md | 18 + packages/plugins/driver-memory/package.json | 2 +- packages/plugins/driver-mongodb/CHANGELOG.md | 18 + packages/plugins/driver-mongodb/package.json | 2 +- packages/plugins/driver-sql/CHANGELOG.md | 37 +++ packages/plugins/driver-sql/package.json | 2 +- .../plugins/driver-sqlite-wasm/CHANGELOG.md | 19 ++ .../plugins/driver-sqlite-wasm/package.json | 2 +- packages/plugins/embedder-openai/CHANGELOG.md | 17 + packages/plugins/embedder-openai/package.json | 2 +- .../plugins/knowledge-memory/CHANGELOG.md | 19 ++ .../plugins/knowledge-memory/package.json | 2 +- .../plugins/knowledge-ragflow/CHANGELOG.md | 19 ++ .../plugins/knowledge-ragflow/package.json | 2 +- .../plugins/plugin-approvals/CHANGELOG.md | 75 +++++ .../plugins/plugin-approvals/package.json | 2 +- packages/plugins/plugin-audit/CHANGELOG.md | 80 +++++ packages/plugins/plugin-audit/package.json | 2 +- packages/plugins/plugin-auth/CHANGELOG.md | 57 ++++ packages/plugins/plugin-auth/package.json | 2 +- packages/plugins/plugin-dev/CHANGELOG.md | 19 ++ packages/plugins/plugin-dev/package.json | 2 +- packages/plugins/plugin-email/CHANGELOG.md | 25 ++ packages/plugins/plugin-email/package.json | 2 +- .../plugins/plugin-hono-server/CHANGELOG.md | 19 ++ .../plugins/plugin-hono-server/package.json | 2 +- .../plugins/plugin-mcp-server/CHANGELOG.md | 19 ++ .../plugins/plugin-mcp-server/package.json | 2 +- packages/plugins/plugin-msw/CHANGELOG.md | 23 ++ packages/plugins/plugin-msw/package.json | 2 +- .../plugins/plugin-org-scoping/CHANGELOG.md | 25 ++ .../plugins/plugin-org-scoping/package.json | 2 +- packages/plugins/plugin-reports/CHANGELOG.md | 25 ++ packages/plugins/plugin-reports/package.json | 2 +- packages/plugins/plugin-security/CHANGELOG.md | 108 ++++++ packages/plugins/plugin-security/package.json | 2 +- packages/plugins/plugin-sharing/CHANGELOG.md | 83 +++++ packages/plugins/plugin-sharing/package.json | 2 +- .../plugin-trigger-record-change/CHANGELOG.md | 61 ++++ .../plugin-trigger-record-change/package.json | 2 +- .../plugin-trigger-schedule/CHANGELOG.md | 46 +++ .../plugin-trigger-schedule/package.json | 2 +- packages/plugins/plugin-webhooks/CHANGELOG.md | 105 ++++++ packages/plugins/plugin-webhooks/package.json | 2 +- packages/rest/CHANGELOG.md | 65 ++++ packages/rest/package.json | 2 +- packages/runtime/CHANGELOG.md | 216 ++++++++++++ packages/runtime/package.json | 2 +- packages/services/service-ai/CHANGELOG.md | 31 ++ packages/services/service-ai/package.json | 2 +- .../services/service-analytics/CHANGELOG.md | 18 + .../services/service-analytics/package.json | 2 +- .../services/service-automation/CHANGELOG.md | 160 +++++++++ .../services/service-automation/package.json | 2 +- packages/services/service-cache/CHANGELOG.md | 19 ++ packages/services/service-cache/package.json | 2 +- .../service-cluster-redis/CHANGELOG.md | 18 + .../service-cluster-redis/package.json | 2 +- .../services/service-cluster/CHANGELOG.md | 18 + .../services/service-cluster/package.json | 2 +- .../service-external-datasource/CHANGELOG.md | 44 +++ .../service-external-datasource/package.json | 2 +- packages/services/service-feed/CHANGELOG.md | 18 + packages/services/service-feed/package.json | 2 +- packages/services/service-i18n/CHANGELOG.md | 18 + packages/services/service-i18n/package.json | 2 +- packages/services/service-job/CHANGELOG.md | 25 ++ packages/services/service-job/package.json | 2 +- .../services/service-knowledge/CHANGELOG.md | 18 + .../services/service-knowledge/package.json | 2 +- .../services/service-messaging/CHANGELOG.md | 260 +++++++++++++++ .../services/service-messaging/package.json | 2 +- .../services/service-package/CHANGELOG.md | 18 + .../services/service-package/package.json | 2 +- packages/services/service-queue/CHANGELOG.md | 25 ++ packages/services/service-queue/package.json | 2 +- .../services/service-realtime/CHANGELOG.md | 25 ++ .../services/service-realtime/package.json | 2 +- .../services/service-settings/CHANGELOG.md | 53 +++ .../services/service-settings/package.json | 2 +- .../services/service-storage/CHANGELOG.md | 19 ++ .../services/service-storage/package.json | 2 +- packages/spec/CHANGELOG.md | 273 ++++++++++++++++ packages/spec/package.json | 2 +- packages/types/CHANGELOG.md | 17 + packages/types/package.json | 2 +- packages/vscode-objectstack/CHANGELOG.md | 2 + packages/vscode-objectstack/package.json | 2 +- 178 files changed, 3487 insertions(+), 965 deletions(-) delete mode 100644 .changeset/adr-0020-state-machine-converge-enforce.md delete mode 100644 .changeset/adr-0029-d7-setup-nav-contributions.md delete mode 100644 .changeset/adr-0029-d8-i18n-plugin-ownership.md delete mode 100644 .changeset/adr-0029-k0-webhooks-ownership.md delete mode 100644 .changeset/adr-0029-k2-security-ownership.md delete mode 100644 .changeset/adr-0029-k2b-approvals-ownership.md delete mode 100644 .changeset/adr-0030-notification-convergence-p0.md delete mode 100644 .changeset/adr-0030-notification-p2.md delete mode 100644 .changeset/adr-0030-notification-p3a-email.md delete mode 100644 .changeset/adr-0030-notification-p3b1-quiet-hours.md delete mode 100644 .changeset/adr-0030-p1-reliable-delivery.md delete mode 100644 .changeset/cli-dev-sqlite-seed-admin.md delete mode 100644 .changeset/connector-mcp.md delete mode 100644 .changeset/consumer-app-two-tier.md delete mode 100644 .changeset/external-datasource-federation-p1.md delete mode 100644 .changeset/external-datasource-federation-p2-cli.md delete mode 100644 .changeset/external-datasource-federation-p2-rest.md delete mode 100644 .changeset/external-datasource-federation-p2.md delete mode 100644 .changeset/external-datasource-federation-p3-boot-gate.md delete mode 100644 .changeset/external-datasource-federation-p3-spec.md delete mode 100644 .changeset/external-datasource-federation-p4-ai.md delete mode 100644 .changeset/external-datasource-federation-p6-write-gate.md delete mode 100644 .changeset/fix-conditional-flows-skip.md delete mode 100644 .changeset/fix-platform-admin-skip-system-user.md delete mode 100644 .changeset/locale-aware-metadata.md delete mode 100644 .changeset/messaging-triggers-capability-tokens.md delete mode 100644 .changeset/metadata-translation-audit.md delete mode 100644 .changeset/notification-action-url-from-source.md delete mode 100644 .changeset/notification-dedup-unique-and-retention.md delete mode 100644 .changeset/openapi-to-connector.md delete mode 100644 .changeset/record-change-flow-trigger.md delete mode 100644 .changeset/schedule-flow-trigger.md delete mode 100644 .changeset/screen-flow-runtime.md delete mode 100644 .changeset/seed-identity-binding.md create mode 100644 examples/app-showcase/CHANGELOG.md create mode 100644 packages/connectors/connector-mcp/CHANGELOG.md create mode 100644 packages/connectors/connector-openapi/CHANGELOG.md create mode 100644 packages/connectors/connector-rest/CHANGELOG.md create mode 100644 packages/connectors/connector-slack/CHANGELOG.md create mode 100644 packages/plugins/plugin-trigger-record-change/CHANGELOG.md create mode 100644 packages/plugins/plugin-trigger-schedule/CHANGELOG.md create mode 100644 packages/services/service-external-datasource/CHANGELOG.md create mode 100644 packages/services/service-messaging/CHANGELOG.md diff --git a/.changeset/adr-0020-state-machine-converge-enforce.md b/.changeset/adr-0020-state-machine-converge-enforce.md deleted file mode 100644 index 750832fc7..000000000 --- a/.changeset/adr-0020-state-machine-converge-enforce.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -"@objectstack/spec": minor -"@objectstack/objectql": minor -"@objectstack/runtime": patch -"@objectstack/platform-objects": patch -"@objectstack/cli": patch ---- - -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. diff --git a/.changeset/adr-0029-d7-setup-nav-contributions.md b/.changeset/adr-0029-d7-setup-nav-contributions.md deleted file mode 100644 index f54683475..000000000 --- a/.changeset/adr-0029-d7-setup-nav-contributions.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -"@objectstack/spec": minor -"@objectstack/objectql": minor -"@objectstack/platform-objects": minor -"@objectstack/plugin-auth": minor -"@objectstack/plugin-webhooks": minor ---- - -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/objectql`** — `SchemaRegistry.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. diff --git a/.changeset/adr-0029-d8-i18n-plugin-ownership.md b/.changeset/adr-0029-d8-i18n-plugin-ownership.md deleted file mode 100644 index 6a4a040d3..000000000 --- a/.changeset/adr-0029-d8-i18n-plugin-ownership.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -"@objectstack/platform-objects": patch -"@objectstack/plugin-webhooks": patch -"@objectstack/plugin-approvals": patch -"@objectstack/plugin-security": patch -"@objectstack/plugin-sharing": patch ---- - -ADR-0029 D8 — migrate i18n ownership for the moved domains to their plugins. - -The object translations for the domains decomposed in K2.a/K2.b/K2 previously -lived in the `@objectstack/platform-objects` generated bundles even though the -objects now live in their capability plugins. This moves each domain's i18n -extraction + bundles to the owning plugin, preserving every hand-translated -string (zh-CN / ja-JP / es-ES): - -- Each plugin gains a build-time `scripts/i18n-extract.config.ts` and a - `src/translations/` bundle (`{locale}.objects.generated.ts` + an `index.ts` - barrel), generated with `os i18n extract` and self-baselined so re-runs - preserve translations. -- Each plugin loads its bundle at runtime on `kernel:ready` via - `i18n.loadTranslations` (the i18n service is optional — load is best-effort). - - `plugin-webhooks` ← `sys_webhook`, `sys_webhook_delivery` - - `plugin-approvals` ← `sys_approval_request`, `sys_approval_action` - - `plugin-security` ← `sys_role`, `sys_permission_set`, - `sys_user_permission_set`, `sys_role_permission_set` - - `plugin-sharing` ← `sys_record_share`, `sys_sharing_rule`, `sys_share_link` -- `@objectstack/platform-objects` translation bundles are regenerated to drop - those objects' keys (its extract config already excluded them); all other - objects' translations and the metadata-form bundles are preserved. - -Net runtime effect is unchanged (same translations load, now contributed by the -package that owns each object) — closing the D8 follow-up tracked since K2.a. diff --git a/.changeset/adr-0029-k0-webhooks-ownership.md b/.changeset/adr-0029-k0-webhooks-ownership.md deleted file mode 100644 index d45a6316e..000000000 --- a/.changeset/adr-0029-k0-webhooks-ownership.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -"@objectstack/objectql": minor -"@objectstack/platform-objects": minor -"@objectstack/plugin-webhooks": minor ---- - -ADR-0029 K0 + K2.a — single-owner invariant and webhooks ownership pilot. - -**K0 (`@objectstack/objectql`)** — add `SchemaRegistry.assertSingleOwnerPerObject()`, -the install-time backstop for the kernel-decomposition invariant: every -registered object must resolve to exactly one `own` contributor. A second -cross-package owner is already rejected at registration time; this additionally -catches "extend with no owner" (which would otherwise resolve to nothing). Call -after kernel bootstrap completes. - -**K2.a (`@objectstack/plugin-webhooks` ← `@objectstack/platform-objects`)** — move -the `sys_webhook` object definition out of the `platform-objects` monolith into -`@objectstack/plugin-webhooks`, where it joins its sibling `sys_webhook_delivery` -so the plugin owns both its data model and behavior as one unit. `sys_webhook` is -no longer exported from `@objectstack/platform-objects` (or its `/integration` -subpath, now an empty barrel); import it from `@objectstack/plugin-webhooks/schema` -instead. Runtime behavior is unchanged — the webhook plugin already registered -`sys_webhook` at runtime; only the definition's home moved. Setup-app navigation -(which references `sys_webhook` by name) and existing i18n bundles (object-name -keyed) continue to work. Per ADR-0029 D8, migrating the object's i18n extraction -into the plugin is a tracked follow-up before the next translation regeneration. diff --git a/.changeset/adr-0029-k2-security-ownership.md b/.changeset/adr-0029-k2-security-ownership.md deleted file mode 100644 index 3e5c5224a..000000000 --- a/.changeset/adr-0029-k2-security-ownership.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -"@objectstack/platform-objects": minor -"@objectstack/plugin-security": minor -"@objectstack/plugin-sharing": minor ---- - -ADR-0029 K2 — security domain ownership (RBAC + sharing) + Setup nav contributions. - -Moves the security objects out of the `@objectstack/platform-objects` monolith -into the two capability plugins that already register and operate them, split by -concern (the two are orthogonal — sharing objects never reference RBAC objects): - -- **`@objectstack/plugin-security`** (RBAC) gains `sys_role`, - `sys_permission_set`, `sys_user_permission_set`, `sys_role_permission_set`, - and the `defaultPermissionSets` seed (which its `bootstrap-platform-admin` - already consumes). The RBAC + default-permission-set tests move with them. -- **`@objectstack/plugin-sharing`** gains `sys_record_share`, - `sys_sharing_rule`, `sys_share_link`. -- `@objectstack/platform-objects` no longer defines/exports any security - objects; the `/security` subpath is now an empty barrel. Runtime is unchanged - (both plugins already registered these objects at runtime). - -**D7 navigation** — the Setup app's `group_access_control` is now assembled from -three sources: `plugin-security` contributes Roles / Permission Sets (priority -100), `plugin-sharing` contributes Sharing Rules / Record Shares (priority 200), -and `platform-objects` keeps only API Keys (`sys_api_key`, an identity object, -priority 300) — preserving the original menu order. - -**i18n (D8)** — the objects are removed from the `platform-objects` i18n extract -config; existing generated bundles keep working at runtime (object-name keyed). -Migrating the i18n extraction to the owning plugins remains the tracked -follow-up. diff --git a/.changeset/adr-0029-k2b-approvals-ownership.md b/.changeset/adr-0029-k2b-approvals-ownership.md deleted file mode 100644 index f94139e5c..000000000 --- a/.changeset/adr-0029-k2b-approvals-ownership.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -"@objectstack/platform-objects": minor -"@objectstack/plugin-approvals": minor ---- - -ADR-0029 K2.b — approvals domain ownership + Setup nav contribution. - -Moves `sys_approval_request` / `sys_approval_action` out of the -`@objectstack/platform-objects` monolith into `@objectstack/plugin-approvals`, -which already registers and operates them — so the plugin now owns its data -model, behavior, and admin menu as one unit. - -- The object definitions move to `plugin-approvals`; `platform-objects` no - longer exports them from `/audit`. Runtime is unchanged (the plugin already - registered them at runtime). -- **D7 navigation** — the Setup app's `group_approvals` entries (`Requests`, - `Action History`) move out of `platform-objects`' `SETUP_NAV_CONTRIBUTIONS` - into `plugin-approvals`' `navigationContributions`. The plugin fills the slot - it owns; when the plugin is absent the slot stays empty. -- **i18n (D8)** — the objects are removed from the `platform-objects` i18n - extract config; their existing generated translation bundles keep working at - runtime (object-name keyed). Migrating the i18n extraction/bundles to the - plugin remains the tracked cross-cutting follow-up (best done with the - `os i18n extract` tooling, not hand-edited generated files). diff --git a/.changeset/adr-0030-notification-convergence-p0.md b/.changeset/adr-0030-notification-convergence-p0.md deleted file mode 100644 index e8aee889d..000000000 --- a/.changeset/adr-0030-notification-convergence-p0.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -"@objectstack/service-messaging": minor -"@objectstack/platform-objects": minor -"@objectstack/plugin-audit": minor -"@objectstack/service-automation": minor -"@objectstack/metadata": minor -"@objectstack/cli": patch -"@objectstack/runtime": patch ---- - -ADR-0030 P0 (framework) — converge notifications onto a single ingress and the -layered model. Every producer now publishes through -`NotificationService.emit(EmitInput)`; the in-app inbox is a materialization of -delivery, not a row producers write. - -**Single ingress (`@objectstack/service-messaging`) — breaking** -- `MessagingService.emit` takes the new `EmitInput` contract (`topic` / - `audience` / `payload` / `severity` / `dedupKey` / `source` / `actorId` / - `organizationId` / `channels`) instead of the flat `Notification` shape. It - writes the L2 `sys_notification` event (idempotent on `dedupKey`), resolves the - audience, then fans out; it returns `{ notificationId, deduped, deliveries, - delivered, failed }`. -- New `sys_notification_receipt` object — the read-state spine - (`delivered|read|clicked|dismissed`), keyed `(notification_id, user_id, - channel)`. The inbox channel writes a `delivered` receipt on materialization. -- `sys_inbox_message`: adds `notification_id` / `delivery_id`, **drops `read`** - (read-state moved to the receipt), adds the user `mine` list view. - -**Event re-model (`@objectstack/platform-objects`) — breaking** -- `sys_notification` is re-modeled from a per-user inbox into the L2 **event** - (`topic`, `payload`, `severity`, `dedup_key`, `source_*`, `actor_id`). Removes - `recipient_id` / `is_read` / `read_at` / `type` / `title` / `body` / `url` / - `actor_name` and the inbox actions/views. App-nav: the account inbox points at - `sys_inbox_message`; Setup shows the notification event log. - -**Producers routed through `emit()`** -- `@objectstack/service-automation`: the `notify` node maps its config to - `EmitInput`. -- `@objectstack/plugin-audit`: collaboration `@mention` → `collab.mention` and - assignment → `collab.assignment` (both with a `dedupKey`); no more direct - `sys_notification` writes. Collaboration notifications now require - `MessagingServicePlugin` (they degrade to a warn otherwise). - -**Migration (`@objectstack/metadata`)** -- Idempotent `migrateSysNotificationToEvent` splits legacy `sys_notification` - inbox rows into `sys_inbox_message` + receipts and rewrites the event row. - -**Startup (`@objectstack/cli`, `@objectstack/runtime`)** -- `messaging` is now a foundational capability. On `objectstack serve` it is - added to `ALWAYS_ON_CAPABILITIES` (every non-`minimal` preset starts it); on - cloud per-project kernels the capability loader expands `requires` to add - `messaging` whenever `audit` is present. This keeps collaboration `@mention` / - assignment notifications (which now flow through the pipeline) working out of - the box on both paths. `--preset minimal` opts out. - -The Console bell repoint (objectui) and phases P1–P3 are tracked in -`docs/handoff/adr-0030-notification-convergence.md`. diff --git a/.changeset/adr-0030-notification-p2.md b/.changeset/adr-0030-notification-p2.md deleted file mode 100644 index 934070800..000000000 --- a/.changeset/adr-0030-notification-p2.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -"@objectstack/service-messaging": minor ---- - -ADR-0030 P2 — subscription + preference. Adds the Layer-3 preference filter so -users can mute notification topics/channels, with admin-global defaults and -mandatory-topic bypass. - -- **`sys_notification_preference`** — per `(user_id, topic, channel)` toggle - (`enabled`, plus `digest`/`quiet_hours` for P3). `user_id='*'` rows are the - admin-global default; a real-user row overrides it; `topic`/`channel` support - `*` wildcards. Unique `(user_id, topic, channel)`. -- **`sys_notification_subscription`** — standing subscription of a principal - (`role:`/`team:`/`user:`/id) to a topic (the opt-in counterpart to explicit - audience; object + schema land now, subscription-driven fan-out is a follow-up). -- **`PreferenceResolver`** — wired into `MessagingService.emit()` between - recipient resolution and fan-out/enqueue. Most-specific-wins resolution - (user→`*`, topic→`*`, channel→`*`; default ON). Two safety rules: **mandatory - topics bypass** (configurable via `mandatoryTopics`, exact or `prefix.`), and - **fail-open** (no data engine or a lookup error delivers all, never silently - drops). `emit()` now filters the `(recipient × channel)` matrix per user. -- Both objects are registered by `MessagingServicePlugin` and contributed to the - Setup app's Configuration nav slot (ADR-0029 D7), so they appear in - REST/Studio only when messaging is installed. - -Acceptance: a user muting a topic/channel stops receiving it on that channel; -mandatory topics still deliver. service-messaging suite: 66 passing -(adds `preference-resolver.test.ts` + an emit-level mute/bypass test). diff --git a/.changeset/adr-0030-notification-p3a-email.md b/.changeset/adr-0030-notification-p3a-email.md deleted file mode 100644 index a6043813d..000000000 --- a/.changeset/adr-0030-notification-p3a-email.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -"@objectstack/service-messaging": minor ---- - -ADR-0030 P3a — email channel + notification templates. The same `emit()` now -reaches inbox **and** email per the user's preferences, rendered from a -template. - -- **`email` channel** (`createEmailChannel`) — a thin `MessagingChannel` that - delegates transport to the existing `email` service (ADR-0022: channel adds - messaging semantics, the email sub-system stays the transport). It resolves the - recipient user id → address (`sys_user.email`, or an email-shaped recipient - verbatim), renders, and sends. Retry/backoff/dead-letter come free from the P1 - outbox dispatcher. Registered at `kernel:ready` only when an `email` service is - present; absent ⇒ no channel (an explicit `channels:['email']` then reports - "not registered" rather than silently no-opping). No-ops gracefully like the - inbox channel when the capability isn't installed. -- **`sys_notification_template`** (topic × channel × locale) + a renderer: - declarative `{{ payload.x }}` interpolation (no logic — auditable metadata), - HTML/markdown/text bodies, locale fallback (`en-US` → `en` → default), and a - **generic fallback to `payload.title`/`body`** when no template matches (so - templates are purely additive). Contributed to the Setup → Configuration nav. -- Channels are now keyed per recipient (from P2), so a notification reaches each - user on exactly the channels they accept, rendered by that channel's template. - -Scope note (ADR-0022): **Slack stays a connector** (`connector-slack` already -ships the raw API path); a Slack *notification channel* needs per-user identity -mapping + OAuth and is enterprise-tier — deferred. push/webhook channels and the -digest / quiet-hours middleware (P3b) are follow-ups on the same seam. - -Tests: service-messaging **85 passing** — adds `template-renderer.test.ts` and -`email-channel.test.ts` (address resolution, template vs fallback rendering, -no-service no-op, unresolved-address failure, transport-failure retry). diff --git a/.changeset/adr-0030-notification-p3b1-quiet-hours.md b/.changeset/adr-0030-notification-p3b1-quiet-hours.md deleted file mode 100644 index 2bf220045..000000000 --- a/.changeset/adr-0030-notification-p3b1-quiet-hours.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -"@objectstack/service-messaging": minor ---- - -ADR-0030 P3b-1 — quiet-hours. A notification that lands inside a recipient's -quiet-hours window is **deferred to the window's end** instead of disturbing -them; it then delivers normally. - -- Implemented as a **deferred dispatch** on the P1 outbox — no parallel - scheduler: `EnqueueDeliveryInput.notBefore` sets the delivery row's initial - `nextAttemptAt`, and the existing dispatcher already skips pending rows whose - `nextAttemptAt` is in the future. One delivery spine, reusing claim/retry/ - observability. -- `PreferenceResolver` reads `quiet_hours` (`{ tz, start, end }`, P2's field) off - a channel-wildcard preference row (quiet hours are a per-person, channel- - agnostic setting), computes the deferral with `quietHoursDeferral()` (HH:MM in - the row's `tz`, default UTC; supports overnight windows that wrap midnight), - and stamps `notBefore` on the target. `emit()` passes it through to the outbox. -- **critical** severity bypasses quiet hours (delivers immediately), like - mandatory topics bypass muting. Honored on the durable outbox path; inline - best-effort fan-out ignores it. - -Tests: service-messaging **92 passing** — adds `quietHoursDeferral` unit cases -(same-day / overnight / outside / degenerate) and resolver cases (notBefore -stamped, critical bypass, JSON-string `quiet_hours`). - -Follow-up: **P3b-2 — digest** (batch same-`(user, channel, window)` deliveries -into one) builds on this same deferral foundation, adding the window collapse. diff --git a/.changeset/adr-0030-p1-reliable-delivery.md b/.changeset/adr-0030-p1-reliable-delivery.md deleted file mode 100644 index e7de8edb0..000000000 --- a/.changeset/adr-0030-p1-reliable-delivery.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -"@objectstack/service-messaging": minor ---- - -ADR-0030 P1 — reliable delivery + RecipientResolver. - -**RecipientResolver** — the single home for audience → user-id expansion, wired -into `MessagingService.emit()`. Queries the same identity/membership model -`plugin-sharing` uses (directly via the data engine, no backward plugin -dependency): -- `role:` → `sys_member` rows (tenant-scoped) -- `team:` → `sys_team_member` rows -- `owner_of::` / `{ ownerOf }` → the record's owner/assignee field -- `` → `sys_user` (verbatim fallback on miss); `user:` / bare id → id - -Best-effort: a failed directory lookup yields 0 recipients for that spec rather -than throwing. The inbox channel's email→id fallback moved here — the channel -now keys rows by the already-resolved recipient. - -**Reliable delivery outbox + dispatcher** (mirrors `plugin-webhooks`): -- New `sys_notification_delivery` outbox object (L4) — one row per - `(event × recipient × channel)`; `pending|in_flight|success|failed|dead|suppressed` - state machine; unique `(notification_id, recipient_id, channel)` enqueue dedup. -- `INotificationOutbox` with `SqlNotificationOutbox` + `MemoryNotificationOutbox` - backends; atomic claim (`pending → in_flight`) + stale-in_flight reaping. -- `NotificationDispatcher` — interval loop over partitions, each guarded by a - per-partition cluster lock (single-node always-grant fallback when no cluster - service); sends via the channel and acks with exponential backoff + jitter; - dead-letters once the retry budget is exhausted. -- `emit()` enqueues `pending` deliveries when an outbox is attached; otherwise it - fans out inline (the P0 behavior). `MessagingServicePlugin` wires the outbox + - dispatcher at `kernel:ready` and registers the new object. - -A failed channel send now retries and is observable on the delivery row; -duplicate enqueue is idempotent. Backoff/classification and clocks are injectable -for deterministic tests. diff --git a/.changeset/cli-dev-sqlite-seed-admin.md b/.changeset/cli-dev-sqlite-seed-admin.md deleted file mode 100644 index 3ae75bf0d..000000000 --- a/.changeset/cli-dev-sqlite-seed-admin.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -"@objectstack/cli": minor ---- - -`objectstack dev` now defaults to SQLite and auto-seeds an admin. - -- **Default driver → SQLite.** With no `OS_DATABASE_URL`/`OS_DATABASE_DRIVER`, - dev now prefers `SqlDriver(sqlite, :memory:)` over the pure-JS `InMemoryDriver` - for production-like SQL semantics. It probes by opening a connection (knex - loads `better-sqlite3` lazily at first query) and falls back to - `InMemoryDriver` **with a warning** if the native binary is unavailable — - closing a hole where the surrounding silent catch could leave the kernel with - no driver. -- **`--seed-admin` defaults ON in dev.** Idempotent and non-destructive: POSTs - the public sign-up endpoint, creating `admin@objectos.ai` only on an empty DB - (then promoted to platform admin) and skipping when the email already exists - (422/400), so a custom password is never overwritten. Disable with - `--no-seed-admin`. diff --git a/.changeset/connector-mcp.md b/.changeset/connector-mcp.md deleted file mode 100644 index 0236d02aa..000000000 --- a/.changeset/connector-mcp.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -"@objectstack/connector-mcp": minor ---- - -MCP Connector (ADR-0024) — adopt any Model Context Protocol server as a connector. - -Adds `@objectstack/connector-mcp`, a single generic adapter that turns *any* -MCP server into an ordinary `type: 'api'` connector on the automation engine — -no per-server code: - -- `createMcpConnector({ transport, include?, … })` connects over **stdio** or - **streamable-HTTP**, calls `tools/list`, and maps each tool to a connector - action (`name → key`, `description → label/description`, - `inputSchema → inputSchema`). Handlers dispatch to `tools/call` and normalise - the result to the shared `{ ok, content, … }` envelope (logical tool errors - surface as `ok: false` rather than throwing). -- `ConnectorMcpPlugin` registers the connector via the existing - `engine.registerConnector()` path (no new engine surface, no `mcp_call` node) - and tears the MCP connection down on shutdown. Fail-soft: an unreachable - server or missing automation engine is logged and skipped. -- Credentials live with the MCP server (transport `env`/`headers`), never in - `ConnectorSchema` and never in the serialized, discovery-exposed `def`. - -Open-tier scope: client adapter + operator-supplied static credentials. A -curated server registry, managed secrets, per-tenant lifecycle, and sandboxed -stdio execution remain the enterprise tier. diff --git a/.changeset/consumer-app-two-tier.md b/.changeset/consumer-app-two-tier.md deleted file mode 100644 index 496c77f98..000000000 --- a/.changeset/consumer-app-two-tier.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -"@objectstack/spec": minor ---- - -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. diff --git a/.changeset/external-datasource-federation-p1.md b/.changeset/external-datasource-federation-p1.md deleted file mode 100644 index 2f094ae56..000000000 --- a/.changeset/external-datasource-federation-p1.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -"@objectstack/spec": minor -"@objectstack/driver-sql": minor ---- - -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 `code`s) + 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'`). diff --git a/.changeset/external-datasource-federation-p2-cli.md b/.changeset/external-datasource-federation-p2-cli.md deleted file mode 100644 index b4fc3a5a3..000000000 --- a/.changeset/external-datasource-federation-p2-cli.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -"@objectstack/cli": minor ---- - -External Datasource Federation (ADR-0015) — CLI surface. - -New `os datasource` command group: `list-tables` (list remote tables), -`introspect` (generate a reviewable `*.object.ts` draft from a remote table), -and `validate` (validate federated objects against the remote schema; exits -non-zero on mismatch). Backed by the `/api/v1/datasources/:name/external/*` -REST routes. diff --git a/.changeset/external-datasource-federation-p2-rest.md b/.changeset/external-datasource-federation-p2-rest.md deleted file mode 100644 index 68c8aa5a7..000000000 --- a/.changeset/external-datasource-federation-p2-rest.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -"@objectstack/rest": minor ---- - -External Datasource Federation (ADR-0015) — REST surface. - -Adds `registerExternalDatasourceRoutes`, mounting `/api/v1/datasources/:name/ -external/*` — `GET tables`, `POST tables/:remote/draft`, `POST refresh-catalog`, -`POST validate` — served by the `external-datasource` service and wired into the -REST API plugin. Routes return `503 external_service_unavailable` when the -service is not registered, so they are safe to mount unconditionally. diff --git a/.changeset/external-datasource-federation-p2.md b/.changeset/external-datasource-federation-p2.md deleted file mode 100644 index 88d4a5354..000000000 --- a/.changeset/external-datasource-federation-p2.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -"@objectstack/spec": minor -"@objectstack/service-external-datasource": minor ---- - -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.ts` — `IExternalDatasourceService` - 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. diff --git a/.changeset/external-datasource-federation-p3-boot-gate.md b/.changeset/external-datasource-federation-p3-boot-gate.md deleted file mode 100644 index f8df7564c..000000000 --- a/.changeset/external-datasource-federation-p3-boot-gate.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -"@objectstack/runtime": minor ---- - -External Datasource Federation (ADR-0015) — boot-validation gate (Gate 2). - -Adds `ExternalValidationPlugin` (`createExternalValidationPlugin`) which, on -`kernel:ready`, validates every federated object against its remote table via -the `external-datasource` service and applies the datasource's -`external.validation.onMismatch` policy: `fail` (throws -`ExternalSchemaMismatchError`, aborting boot — the default), `warn` (logs the -diff), or `ignore`. No-op when federation is unused. diff --git a/.changeset/external-datasource-federation-p3-spec.md b/.changeset/external-datasource-federation-p3-spec.md deleted file mode 100644 index 3a5120b8a..000000000 --- a/.changeset/external-datasource-federation-p3-spec.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -"@objectstack/spec": minor ---- - -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.ts` — `ExternalCatalogSchema` / - `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). diff --git a/.changeset/external-datasource-federation-p4-ai.md b/.changeset/external-datasource-federation-p4-ai.md deleted file mode 100644 index 178bc178f..000000000 --- a/.changeset/external-datasource-federation-p4-ai.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -"@objectstack/service-ai": minor ---- - -External Datasource Federation (ADR-0015) — Phase 4: AI awareness. - -`SchemaRetriever.renderSnippet` now annotates federated objects in the -auto-injected schema context, e.g. -`### wh_order — Warehouse Order [external, read-only, datasource=warehouse]`, -so the LLM knows an object comes from a customer's production database and must -not propose schema changes or unsafe writes. `ObjectShape` gains `datasource` -+ `external` (read from object metadata). Managed objects are unannotated. diff --git a/.changeset/external-datasource-federation-p6-write-gate.md b/.changeset/external-datasource-federation-p6-write-gate.md deleted file mode 100644 index ea4c7c9ce..000000000 --- a/.changeset/external-datasource-federation-p6-write-gate.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -"@objectstack/objectql": minor ---- - -External Datasource Federation (ADR-0015) — write gate (Gate 3) + introspection plumbing. - -- Write gate: ObjectQL `insert`/`update`/`delete` now block writes to a - federated datasource (`schemaMode !== 'managed'`) unless BOTH - `datasource.external.allowWrites` and `object.external.writable` are true, - throwing `ExternalWriteForbiddenError` (code `EXTERNAL_WRITE_FORBIDDEN`). - Managed datasources (and objects without a datasource definition) are - unaffected. New `registerDatasourceDef()` records declarative datasource - ownership; manifests carrying `datasources` are indexed during `registerApp`. -- `engine.introspectDatasource(name)` delegates to the named driver's - `introspectSchema()`, wiring the external-datasource service end-to-end. diff --git a/.changeset/fix-conditional-flows-skip.md b/.changeset/fix-conditional-flows-skip.md deleted file mode 100644 index 581e19ca3..000000000 --- a/.changeset/fix-conditional-flows-skip.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -"@objectstack/service-automation": patch -"@objectstack/objectql": patch ---- - -Fix conditional & record-change flows silently skipping. - -Two bugs together caused every flow with a start-node / edge **condition** to -silently skip (record-change triggers fired but the flow body never ran; -audit-style `previous.*` gates and `budget > 100000`-style gates all evaluated -to false): - -- **service-automation — CEL engine unreachable in ESM.** The condition - evaluator loaded the formula engine via a CommonJS `require('@objectstack/formula')`. - In the package's ESM build (`"type": "module"`) that resolves to tsup's - throwing `__require` stub, so **every** CEL evaluation threw and the - swallowing `catch` returned `false`. Replaced with a static top-level import, - which binds correctly in both the ESM and CJS builds. - -- **objectql — prior record not exposed to update hooks.** `HookContext` - documents a `previous` snapshot for update/delete, but `engine.update` never - populated it (the row it fetched for validation was a local var). Record-change - conditions like `status == "done" && previous.status != "done"` therefore had - no `previous` to read. The engine now attaches the pre-update record to - `hookContext.previous` for single-id updates whenever a validation rule needs - it or an `afterUpdate` hook is registered. - -Both paths are covered by new unit tests. diff --git a/.changeset/fix-platform-admin-skip-system-user.md b/.changeset/fix-platform-admin-skip-system-user.md deleted file mode 100644 index 0bb18f43d..000000000 --- a/.changeset/fix-platform-admin-skip-system-user.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -"@objectstack/plugin-security": patch -"@objectstack/cli": patch ---- - -Fix: the first-boot platform-admin promotion no longer gets stolen by the -`usr_system` seed identity, and the dev seed admin uses fixed, well-known -credentials. - -**`@objectstack/plugin-security` — `bootstrapPlatformAdmin` skips the system user** - -`5e831dea3` (#1392) added `ensureSeedIdentity` to the runtime SeedLoader, -which upserts a non-loginable system identity (`usr_system`, role `system`, -`system@objectstack.local`) to own seeded records — created *before* the first -human sign-up. Because `bootstrapPlatformAdmin` promoted the **earliest-created** -`sys_user`, on any app that ships seed data `usr_system` won the promotion and -the real admin login stayed at `role: user`. Login succeeded but Setup and -Studio (gated by `setup.access` / `studio.access` on `admin_full_access`) were -invisible — a silent, confusing regression. - -`bootstrap-platform-admin.ts` now filters out the system account -(`id === SystemUserId.SYSTEM || role === 'system'`) when picking the first user -to promote, and the "an admin already exists" short-circuit ignores any -`admin_full_access` grant held by `usr_system` — so a database where it was -wrongly promoted self-heals on the next boot. - -**`@objectstack/cli` — `os dev` seeds `admin@objectos.ai` / `admin123`** - -The `--admin-email` / `--admin-password` defaults changed from -`admin@dev.local` / `admin12345` to the fixed, well-known -`admin@objectos.ai` / `admin123`, so tooling and docs never have to guess the -seeded credentials. Override with `--admin-email` / `--admin-password`. diff --git a/.changeset/locale-aware-metadata.md b/.changeset/locale-aware-metadata.md deleted file mode 100644 index 6e1cf51f9..000000000 --- a/.changeset/locale-aware-metadata.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -"@objectstack/client": minor -"@objectstack/client-react": minor -"@objectstack/objectql": patch -"@objectstack/rest": patch -"@objectstack/spec": patch ---- - -Make metadata labels follow the active UI language without a page refresh (#1319). - -The client now carries the active locale on every request (`Accept-Language`, -`setLocale`/`getLocale`), the protocol ETag is locale-aware so cached metadata -no longer collides across languages, and the `client-react` metadata hooks -refetch when the locale changes. The `apps/account` console wires its router -locale through so a language switch relabels server-resolved object/field/view -labels in place instead of leaving the UI half-translated until reload. diff --git a/.changeset/messaging-triggers-capability-tokens.md b/.changeset/messaging-triggers-capability-tokens.md deleted file mode 100644 index c9125d8a9..000000000 --- a/.changeset/messaging-triggers-capability-tokens.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -"@objectstack/service-messaging": minor -"@objectstack/cli": minor -"@objectstack/runtime": minor ---- - -Messaging + triggers capability tokens, and notify-by-email recipient resolution. - -Make the `notify` flow node and auto-firing flows usable from a plain -`defineStack({ requires: [...] })` — no hand-wired plugin instances. - -- **CLI / runtime — new capability tokens.** `messaging` → - `MessagingServicePlugin` (the `notify` node delivers to the inbox channel - instead of degrading to a logged no-op); `triggers` → - `RecordChangeTriggerPlugin` + `ScheduleTriggerPlugin` (autolaunched / schedule - flows actually fire — pair `triggers` with `job` for cron/interval). Wired - identically in the CLI `CAPABILITY_PROVIDERS` table and the runtime - `capability-loader`. -- **Inbox channel — notify-by-email.** Flows commonly address recipients by - email (e.g. `{record.assignee}`), but `sys_inbox_message` is keyed by user id. - The inbox channel now resolves an email-shaped recipient to its `sys_user.id` - (configurable via `InboxChannelOptions.userObject`), with a verbatim fallback - when the recipient is not email-shaped, no user matches, or the lookup fails — - so a failed resolution can never drop the row. diff --git a/.changeset/metadata-translation-audit.md b/.changeset/metadata-translation-audit.md deleted file mode 100644 index 1a35989ab..000000000 --- a/.changeset/metadata-translation-audit.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -"@objectstack/spec": patch -"@objectstack/rest": patch -"@objectstack/platform-objects": patch -"@objectstack/service-settings": patch ---- - -Fix system-metadata translations: locale fallback, app/dashboard localization, and coverage gaps. - -Switching the UI language left many surfaces in English. Three root causes -are addressed: - -- **Locale fallback (server).** The metadata translation resolver - (`@objectstack/spec` `i18n-resolver`) now resolves a requested locale - against the locales actually present in the bundle (exact → - case-insensitive → base-language → variant), so a request for `zh` - correctly hits the `zh-CN` bundle instead of falling back to English. - This mirrors `resolveLocale` in `@objectstack/core` and benefits every - resolver (objects, views, actions, settings, metadata forms). - -- **App & dashboard localization (server).** Added `translateApp` and - `translateDashboard` resolvers and wired `app`/`dashboard` into the REST - `/meta` translation path. App labels, sidebar/navigation group labels, - and dashboard titles/widgets were previously never localized at the API - boundary even though the translation data existed. - -- **Coverage & quality (data).** Added translations for the previously - untranslated platform objects `sys_share_link`, `sys_view_definition`, - and `sys_metadata_audit` (and registered them in the i18n-extract config - so future extractions keep them). Replaced English placeholder strings - left in the `zh-CN` / `ja-JP` / `es-ES` object and metadata-form bundles - (notably action `confirmText` / `successMessage` prompts). Added the - missing `es-ES` built-in Settings bundle in `@objectstack/service-settings`. diff --git a/.changeset/notification-action-url-from-source.md b/.changeset/notification-action-url-from-source.md deleted file mode 100644 index 5e908f8c7..000000000 --- a/.changeset/notification-action-url-from-source.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -"@objectstack/service-messaging": minor ---- - -Synthesize the inbox `action_url` from the event `source` (ADR-0030 L5). - -The Console bell reads `sys_inbox_message` (the L5 in-app materialization), -which carries only `action_url` — not the L2 `sys_notification` event's -`source_object`/`source_id`. Producers that pass a `source` but no explicit -`payload.url` (collaboration `@mention`, record assignment) therefore -materialized inbox rows with no navigable link, so the bell entry couldn't -deep-link to the originating record. - -`emit()` now synthesizes an app-relative `/{object}/{id}` link from `source` -when no explicit `payload.url`/`payload.actionUrl` is supplied — in both the -inline fan-out and the durable-outbox enqueue paths (`actionUrlFor()`). -Precedence: explicit url → source-derived link → `undefined`. Keeps the L5 -materialization self-sufficient for navigation (the objectui bell consumes -`action_url`). - -Tests: 3 new `messaging-service.test.ts` cases (source→link, explicit-url -precedence, neither→undefined); all 95 service-messaging tests green. diff --git a/.changeset/notification-dedup-unique-and-retention.md b/.changeset/notification-dedup-unique-and-retention.md deleted file mode 100644 index 8da6b2a2b..000000000 --- a/.changeset/notification-dedup-unique-and-retention.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -"@objectstack/service-messaging": minor -"@objectstack/platform-objects": patch ---- - -Harden the notification pipeline: race-safe dedup + opt-in retention (ADR-0030). - -**Race-safe dedup.** `sys_notification.dedup_key` is now declared a **UNIQUE** -index (was a plain index), and `emit()` **converges on a unique-key conflict**: -the pre-insert `dedup_key` check is a fast-path, but if a concurrent `emit` -raced past it and inserted first, our insert hits the violation — we catch it -and converge to the winner's event (a dedup hit) instead of throwing or -double-emitting. This mirrors the delivery outbox's enqueue convergence and -stops a record-change storm from producing duplicate bell notifications. SQL -treats NULLs as distinct, so the common events with no `dedup_key` are -unconstrained. (Enforcement is per-driver: where declared indexes are -materialized the conflict path activates; drivers that don't materialize them -fall back to the best-effort fast-path — the catch is simply never taken. Note -the SQL driver currently doesn't sync declared object indexes, which already -affects the delivery/receipt unique indexes — tracked separately.) - -**Opt-in retention.** New `NotificationRetention` sweeper + plugin options -`retentionDays` / `retentionSweepMs`. Every `emit()` writes a `sys_notification` -event (plus delivery/materialization/receipt rows), so a high-frequency -periodic flow grows the tables unbounded. When `retentionDays > 0`, a -low-frequency sweep (default hourly, timer `unref`'d) bulk-deletes events, -deliveries, inbox messages and receipts older than the cutoff — a notification -ages out wholesale, keeping the model consistent (no dangling `notification_id`) -and the bell (recent-only) unaffected. The delivery row's epoch-ms `created_at` -vs the others' ISO `created_at` is handled per target. **Default off** — no -notification data is deleted without explicit operator policy. Each target is -isolated (one object's failure doesn't abort the sweep), and the sweep runs -under a system context (retention is a cross-tenant operator policy). - -Tests: +7 `service-messaging` cases (converge-on-conflict, non-conflict -rethrow, retention cutoff-formatting per target, no-engine / non-positive -no-ops, failure isolation, missing-count) — 102 passing. diff --git a/.changeset/openapi-to-connector.md b/.changeset/openapi-to-connector.md deleted file mode 100644 index b0e645dd5..000000000 --- a/.changeset/openapi-to-connector.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@objectstack/connector-openapi": minor ---- - -Add `@objectstack/connector-openapi` — generate an ObjectStack connector from a declarative OpenAPI 3.x document (ADR-0023). One operation becomes one connector action; a single generic handler drives a self-contained static-auth HTTP transport (mirroring `@objectstack/connector-rest`). The generated `type: 'api'` connector registers via `engine.registerConnector(def, handlers)` with no new engine surface, and supports an `include` allowlist for trimming large specs. diff --git a/.changeset/record-change-flow-trigger.md b/.changeset/record-change-flow-trigger.md deleted file mode 100644 index 59591267e..000000000 --- a/.changeset/record-change-flow-trigger.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -"@objectstack/plugin-trigger-record-change": minor -"@objectstack/service-automation": minor -"@objectstack/spec": patch ---- - -Record-change flow trigger — auto-launch flows on data mutations. - -Completes the automation engine's `FlowTrigger` extension point so flows whose -`start` node declares a record-change trigger (`config: { objectName, -triggerType: 'record-after-update', condition }`) actually fire on the matching -mutation. Previously the slot was dead — nothing called `trigger.start` — so -such flows could only run via a manual `engine.execute()`. - -**Engine baseline (`@objectstack/service-automation`)** -- Redefines `FlowTrigger` around a parsed `FlowTriggerBinding` (flowName, - object, event, condition, schedule, raw config). The engine parses the start - node and hands the trigger a normalized binding, keeping trigger plugins - decoupled from flow-definition internals (mirrors `connector_action` ↔ - `connector-rest`). -- Ordering-independent, bidirectional wiring: `registerFlow`/`toggleFlow` - activate bindings; `registerTrigger` retro-binds already-registered flows (a - trigger plugin wires up on `kernel:ready`, after flows are pulled in); - `unregisterFlow`/`unregisterTrigger`/disable tear them down. -- Centralized start-condition gate in `execute()`: the start node's `condition` - (e.g. `status == 'done' && previous.status != 'done'`) is evaluated once for - every trigger type and manual runs; false ⇒ `{ skipped: true }`. -- Seeds `record`, flattened record fields, and `previous` into flow variables. -- New `getActiveTriggerBindings()` getter + exports `FlowTriggerBinding`. - -**Spec (`@objectstack/spec`)** -- Adds `previous?` to `AutomationContext` — the pre-update "old" row, so flows - can gate on transitions. - -**New package (`@objectstack/plugin-trigger-record-change`)** -- The concrete trigger: subscribes to ObjectQL lifecycle hooks - (`record-after-update` → `afterUpdate`, etc.), builds an `AutomationContext` - from the new/old record, and runs the flow. Error-isolated (a flow failure - never breaks the CRUD write); graceful degrade when the automation service or - ObjectQL engine is absent (mirrors `plugin-audit`). - -The `schedule` trigger (ticker/cron + `sys_job` lifecycle) is a follow-up. diff --git a/.changeset/schedule-flow-trigger.md b/.changeset/schedule-flow-trigger.md deleted file mode 100644 index 6dd29c0a0..000000000 --- a/.changeset/schedule-flow-trigger.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -"@objectstack/plugin-trigger-schedule": minor ---- - -Schedule flow trigger — auto-launch flows on a cron/interval/once schedule. - -The sibling of `@objectstack/plugin-trigger-record-change`: it completes the -*time-based* arm of the automation engine's `FlowTrigger` extension point. The -engine already parses a flow's start node into a `schedule` binding -(`flow.type === 'schedule'` or a start-node `config.schedule` descriptor); this -plugin registers the concrete `schedule` trigger and delegates timing to the -platform `IJobService` (the `'job'` service), so it stays adapter-agnostic — the -job service selects a cron-capable adapter (durable `DbJobAdapter` / -`CronJobAdapter`) for cron schedules and the interval adapter otherwise. - -- `normalizeSchedule` accepts the canonical `JobSchedule` plus shorthands (a - bare cron string, `{ cron }` / `{ expression }`, `{ every }` / `{ intervalMs }`, - `{ at }`). -- When a job fires, the flow runs with `event: 'schedule'` and - `params: { jobId, flowName, schedule }`; the engine's start-condition gate - still applies. -- Error-isolated (a flow failure never crashes the job runner); per-flow job - name so `stop()` cancels exactly one flow; the job service is resolved lazily - per bind so adapter upgrades are picked up; graceful degrade when the - automation or job service is absent. - -No engine change required — the `schedule` binding shipped with the -record-change trigger PR. diff --git a/.changeset/screen-flow-runtime.md b/.changeset/screen-flow-runtime.md deleted file mode 100644 index ae936c32a..000000000 --- a/.changeset/screen-flow-runtime.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -"@objectstack/service-automation": minor -"@objectstack/runtime": minor -"@objectstack/spec": minor ---- - -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 `FlowSuspendSignal` → `SuspendedRun` → 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 objectui `FlowRunner` UI that renders these screens ships separately. diff --git a/.changeset/seed-identity-binding.md b/.changeset/seed-identity-binding.md deleted file mode 100644 index b8276983d..000000000 --- a/.changeset/seed-identity-binding.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -"@objectstack/spec": minor -"@objectstack/runtime": minor ---- - -Seed data: first-class identity binding + loud failures (fixes #1389) - -Records seeded via `defineDataset` / `defineStack({ data })` can now bind to a -platform user with `cel\`os.user.id\`` (and to the org with `cel\`os.org.id\``), -which previously never resolved at boot. - -- **`os.user` / `os.org` now actually resolve.** The runtime provisions a - deterministic, non-loginable system user (`usr_system`, role `system`) - *before* any seed runs and binds it to `os.user`, so identity-derived seed - values resolve even on a fresh boot — before the first human sign-up. The - human login admin remains a separate better-auth identity and need not own - seed data. Exposed as the canonical `SystemUserId.SYSTEM` constant. -- **New `SeedLoaderConfig.identity`** carries the `os.user` / `os.org` subject - into CEL evaluation (`@objectstack/spec`). -- **Failures are loud, not silent.** A record whose CEL value can't resolve - (e.g. a required `cel\`os.user.id\`` with no identity) — or that fails to - write — is now counted as an error, marks the load unsuccessful, and logs an - actionable message, instead of being silently dropped. diff --git a/apps/account/CHANGELOG.md b/apps/account/CHANGELOG.md index 7c9f1bb07..46be68d52 100644 --- a/apps/account/CHANGELOG.md +++ b/apps/account/CHANGELOG.md @@ -1,5 +1,7 @@ # @objectstack/account +## 7.4.0 + ## 7.3.0 ## 7.2.1 diff --git a/apps/account/package.json b/apps/account/package.json index aa1d43f3f..567c5cb96 100644 --- a/apps/account/package.json +++ b/apps/account/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/account", - "version": "7.3.0", + "version": "7.4.0", "description": "ObjectStack Account - End-user account & organization self-service portal", "license": "Apache-2.0", "type": "module", diff --git a/examples/app-crm/CHANGELOG.md b/examples/app-crm/CHANGELOG.md index 942a81b4f..48bf8ca20 100644 --- a/examples/app-crm/CHANGELOG.md +++ b/examples/app-crm/CHANGELOG.md @@ -1,5 +1,26 @@ # @objectstack/example-crm +## 4.0.31 + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [13632b1] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [394d34f] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/runtime@7.4.0 + ## 4.0.30 ### Patch Changes diff --git a/examples/app-crm/package.json b/examples/app-crm/package.json index f419ac7be..544e88f18 100644 --- a/examples/app-crm/package.json +++ b/examples/app-crm/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/example-crm", - "version": "4.0.30", + "version": "4.0.31", "description": "Minimal CRM example — a smoke-test workspace that exercises the metadata loading pipeline (objects → views → app → dashboard → hook → flow → seed). For a full-featured enterprise CRM see https://github.com/objectstack-ai/hotcrm.", "license": "Apache-2.0", "private": true, diff --git a/examples/app-showcase/CHANGELOG.md b/examples/app-showcase/CHANGELOG.md new file mode 100644 index 000000000..c49aa0b60 --- /dev/null +++ b/examples/app-showcase/CHANGELOG.md @@ -0,0 +1,24 @@ +# @objectstack/example-showcase + +## 0.1.1 + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [13632b1] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [394d34f] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/runtime@7.4.0 + - @objectstack/connector-rest@7.4.0 + - @objectstack/connector-slack@7.4.0 diff --git a/examples/app-showcase/package.json b/examples/app-showcase/package.json index 93115fa20..f2c76057b 100644 --- a/examples/app-showcase/package.json +++ b/examples/app-showcase/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/example-showcase", - "version": "0.1.0", + "version": "0.1.1", "description": "Kitchen-sink showcase workspace — exercises every metadata type, every view type, every chart type, and the major end-to-end capability chains (security, automation, AI). Built for demonstration, debugging, and coverage-driven verification.", "license": "Apache-2.0", "private": true, diff --git a/examples/app-todo/CHANGELOG.md b/examples/app-todo/CHANGELOG.md index 1fb7236e3..6123b134a 100644 --- a/examples/app-todo/CHANGELOG.md +++ b/examples/app-todo/CHANGELOG.md @@ -1,5 +1,37 @@ # @objectstack/example-todo +## 4.0.31 + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [eea3f1b] +- Updated dependencies [13632b1] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [a6d4cbb] +- Updated dependencies [58b450b] +- Updated dependencies [394d34f] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/objectql@7.4.0 + - @objectstack/runtime@7.4.0 + - @objectstack/metadata@7.4.0 + - @objectstack/service-ai@7.4.0 + - @objectstack/client@7.4.0 + - @objectstack/driver-sqlite-wasm@7.4.0 + - @objectstack/knowledge-memory@7.4.0 + - @objectstack/service-knowledge@7.4.0 + ## 4.0.30 ### Patch Changes diff --git a/examples/app-todo/package.json b/examples/app-todo/package.json index f1ff1ae2e..81f07aa5c 100644 --- a/examples/app-todo/package.json +++ b/examples/app-todo/package.json @@ -1,6 +1,6 @@ { "name": "@example/app-todo", - "version": "4.0.30", + "version": "4.0.31", "description": "Example Todo App using ObjectStack Protocol", "license": "Apache-2.0", "private": true, diff --git a/packages/adapters/express/CHANGELOG.md b/packages/adapters/express/CHANGELOG.md index fc1c7aed3..de3e734b2 100644 --- a/packages/adapters/express/CHANGELOG.md +++ b/packages/adapters/express/CHANGELOG.md @@ -1,5 +1,7 @@ # @objectstack/express +## 7.4.0 + ## 7.3.0 ## 7.2.1 diff --git a/packages/adapters/express/package.json b/packages/adapters/express/package.json index 3985a9afe..9ede8fc7e 100644 --- a/packages/adapters/express/package.json +++ b/packages/adapters/express/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/express", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/adapters/fastify/CHANGELOG.md b/packages/adapters/fastify/CHANGELOG.md index def39ddda..41abb8b64 100644 --- a/packages/adapters/fastify/CHANGELOG.md +++ b/packages/adapters/fastify/CHANGELOG.md @@ -1,5 +1,7 @@ # @objectstack/fastify +## 7.4.0 + ## 7.3.0 ## 7.2.1 diff --git a/packages/adapters/fastify/package.json b/packages/adapters/fastify/package.json index dc8b68834..dc8db3fc7 100644 --- a/packages/adapters/fastify/package.json +++ b/packages/adapters/fastify/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/fastify", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/adapters/hono/CHANGELOG.md b/packages/adapters/hono/CHANGELOG.md index 25ccd53ae..e2cbb01b3 100644 --- a/packages/adapters/hono/CHANGELOG.md +++ b/packages/adapters/hono/CHANGELOG.md @@ -1,5 +1,12 @@ # @objectstack/hono +## 7.4.0 + +### Patch Changes + +- @objectstack/plugin-hono-server@7.4.0 +- @objectstack/types@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/adapters/hono/package.json b/packages/adapters/hono/package.json index 380816258..c5c1f30f4 100644 --- a/packages/adapters/hono/package.json +++ b/packages/adapters/hono/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/hono", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/adapters/nestjs/CHANGELOG.md b/packages/adapters/nestjs/CHANGELOG.md index c67fbcf91..aa8b665f8 100644 --- a/packages/adapters/nestjs/CHANGELOG.md +++ b/packages/adapters/nestjs/CHANGELOG.md @@ -1,5 +1,7 @@ # @objectstack/nestjs +## 7.4.0 + ## 7.3.0 ## 7.2.1 diff --git a/packages/adapters/nestjs/package.json b/packages/adapters/nestjs/package.json index 72f7aacc3..fb0ba20d8 100644 --- a/packages/adapters/nestjs/package.json +++ b/packages/adapters/nestjs/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/nestjs", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/adapters/nextjs/CHANGELOG.md b/packages/adapters/nextjs/CHANGELOG.md index 708603044..11714df38 100644 --- a/packages/adapters/nextjs/CHANGELOG.md +++ b/packages/adapters/nextjs/CHANGELOG.md @@ -1,5 +1,7 @@ # @objectstack/nextjs +## 7.4.0 + ## 7.3.0 ## 7.2.1 diff --git a/packages/adapters/nextjs/package.json b/packages/adapters/nextjs/package.json index 861a6fc79..2a6e0e19e 100644 --- a/packages/adapters/nextjs/package.json +++ b/packages/adapters/nextjs/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/nextjs", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/adapters/nuxt/CHANGELOG.md b/packages/adapters/nuxt/CHANGELOG.md index 1c735d74c..1387d09c0 100644 --- a/packages/adapters/nuxt/CHANGELOG.md +++ b/packages/adapters/nuxt/CHANGELOG.md @@ -1,5 +1,7 @@ # @objectstack/nuxt +## 7.4.0 + ## 7.3.0 ## 7.2.1 diff --git a/packages/adapters/nuxt/package.json b/packages/adapters/nuxt/package.json index 577450281..157c4c8c8 100644 --- a/packages/adapters/nuxt/package.json +++ b/packages/adapters/nuxt/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/nuxt", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/adapters/sveltekit/CHANGELOG.md b/packages/adapters/sveltekit/CHANGELOG.md index af134e14e..9bf6f3032 100644 --- a/packages/adapters/sveltekit/CHANGELOG.md +++ b/packages/adapters/sveltekit/CHANGELOG.md @@ -1,5 +1,7 @@ # @objectstack/sveltekit +## 7.4.0 + ## 7.3.0 ## 7.2.1 diff --git a/packages/adapters/sveltekit/package.json b/packages/adapters/sveltekit/package.json index 16ddc8f47..146c7a80f 100644 --- a/packages/adapters/sveltekit/package.json +++ b/packages/adapters/sveltekit/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/sveltekit", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index 57418606e..73c59228d 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,258 @@ # @objectstack/cli +## 7.4.0 + +### Minor Changes + +- 70b63f2: `objectstack dev` now defaults to SQLite and auto-seeds an admin. + + - **Default driver → SQLite.** With no `OS_DATABASE_URL`/`OS_DATABASE_DRIVER`, + dev now prefers `SqlDriver(sqlite, :memory:)` over the pure-JS `InMemoryDriver` + for production-like SQL semantics. It probes by opening a connection (knex + loads `better-sqlite3` lazily at first query) and falls back to + `InMemoryDriver` **with a warning** if the native binary is unavailable — + closing a hole where the surrounding silent catch could leave the kernel with + no driver. + - **`--seed-admin` defaults ON in dev.** Idempotent and non-destructive: POSTs + the public sign-up endpoint, creating `admin@objectos.ai` only on an empty DB + (then promoted to platform admin) and skipping when the email already exists + (422/400), so a custom password is never overwritten. Disable with + `--no-seed-admin`. + +- 2faf9f2: External Datasource Federation (ADR-0015) — CLI surface. + + New `os datasource` command group: `list-tables` (list remote tables), + `introspect` (generate a reviewable `*.object.ts` draft from a remote table), + and `validate` (validate federated objects against the remote schema; exits + non-zero on mismatch). Backed by the `/api/v1/datasources/:name/external/*` + REST routes. + +- 394d34f: Messaging + triggers capability tokens, and notify-by-email recipient resolution. + + Make the `notify` flow node and auto-firing flows usable from a plain + `defineStack({ requires: [...] })` — no hand-wired plugin instances. + + - **CLI / runtime — new capability tokens.** `messaging` → + `MessagingServicePlugin` (the `notify` node delivers to the inbox channel + instead of degrading to a logged no-op); `triggers` → + `RecordChangeTriggerPlugin` + `ScheduleTriggerPlugin` (autolaunched / schedule + flows actually fire — pair `triggers` with `job` for cron/interval). Wired + identically in the CLI `CAPABILITY_PROVIDERS` table and the runtime + `capability-loader`. + - **Inbox channel — notify-by-email.** Flows commonly address recipients by + email (e.g. `{record.assignee}`), but `sys_inbox_message` is keyed by user id. + The inbox channel now resolves an email-shaped recipient to its `sys_user.id` + (configurable via `InboxChannelOptions.userObject`), with a verbatim fallback + when the recipient is not email-shaped, no user matches, or the lookup fails — + so a failed resolution can never drop the row. + +### Patch 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. + +- 13632b1: ADR-0030 P0 (framework) — converge notifications onto a single ingress and the + layered model. Every producer now publishes through + `NotificationService.emit(EmitInput)`; the in-app inbox is a materialization of + delivery, not a row producers write. + + **Single ingress (`@objectstack/service-messaging`) — breaking** + + - `MessagingService.emit` takes the new `EmitInput` contract (`topic` / + `audience` / `payload` / `severity` / `dedupKey` / `source` / `actorId` / + `organizationId` / `channels`) instead of the flat `Notification` shape. It + writes the L2 `sys_notification` event (idempotent on `dedupKey`), resolves the + audience, then fans out; it returns `{ notificationId, deduped, deliveries, +delivered, failed }`. + - New `sys_notification_receipt` object — the read-state spine + (`delivered|read|clicked|dismissed`), keyed `(notification_id, user_id, +channel)`. The inbox channel writes a `delivered` receipt on materialization. + - `sys_inbox_message`: adds `notification_id` / `delivery_id`, **drops `read`** + (read-state moved to the receipt), adds the user `mine` list view. + + **Event re-model (`@objectstack/platform-objects`) — breaking** + + - `sys_notification` is re-modeled from a per-user inbox into the L2 **event** + (`topic`, `payload`, `severity`, `dedup_key`, `source_*`, `actor_id`). Removes + `recipient_id` / `is_read` / `read_at` / `type` / `title` / `body` / `url` / + `actor_name` and the inbox actions/views. App-nav: the account inbox points at + `sys_inbox_message`; Setup shows the notification event log. + + **Producers routed through `emit()`** + + - `@objectstack/service-automation`: the `notify` node maps its config to + `EmitInput`. + - `@objectstack/plugin-audit`: collaboration `@mention` → `collab.mention` and + assignment → `collab.assignment` (both with a `dedupKey`); no more direct + `sys_notification` writes. Collaboration notifications now require + `MessagingServicePlugin` (they degrade to a warn otherwise). + + **Migration (`@objectstack/metadata`)** + + - Idempotent `migrateSysNotificationToEvent` splits legacy `sys_notification` + inbox rows into `sys_inbox_message` + receipts and rewrites the event row. + + **Startup (`@objectstack/cli`, `@objectstack/runtime`)** + + - `messaging` is now a foundational capability. On `objectstack serve` it is + added to `ALWAYS_ON_CAPABILITIES` (every non-`minimal` preset starts it); on + cloud per-project kernels the capability loader expands `requires` to add + `messaging` whenever `audit` is present. This keeps collaboration `@mention` / + assignment notifications (which now flow through the pipeline) working out of + the box on both paths. `--preset minimal` opts out. + + The Console bell repoint (objectui) and phases P1–P3 are tracked in + `docs/handoff/adr-0030-notification-convergence.md`. + +- 08fbbb4: Fix: the first-boot platform-admin promotion no longer gets stolen by the + `usr_system` seed identity, and the dev seed admin uses fixed, well-known + credentials. + + **`@objectstack/plugin-security` — `bootstrapPlatformAdmin` skips the system user** + + `5e831dea3` (#1392) added `ensureSeedIdentity` to the runtime SeedLoader, + which upserts a non-loginable system identity (`usr_system`, role `system`, + `system@objectstack.local`) to own seeded records — created _before_ the first + human sign-up. Because `bootstrapPlatformAdmin` promoted the **earliest-created** + `sys_user`, on any app that ships seed data `usr_system` won the promotion and + the real admin login stayed at `role: user`. Login succeeded but Setup and + Studio (gated by `setup.access` / `studio.access` on `admin_full_access`) were + invisible — a silent, confusing regression. + + `bootstrap-platform-admin.ts` now filters out the system account + (`id === SystemUserId.SYSTEM || role === 'system'`) when picking the first user + to promote, and the "an admin already exists" short-circuit ignores any + `admin_full_access` grant held by `usr_system` — so a database where it was + wrongly promoted self-heals on the next boot. + + **`@objectstack/cli` — `os dev` seeds `admin@objectos.ai` / `admin123`** + + The `--admin-email` / `--admin-password` defaults changed from + `admin@dev.local` / `admin12345` to the fixed, well-known + `admin@objectos.ai` / `admin123`, so tooling and docs never have to guess the + seeded credentials. Override with `--admin-email` / `--admin-password`. + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [4404572] +- Updated dependencies [eea3f1b] +- Updated dependencies [e478e0c] +- Updated dependencies [4cc2ced] +- Updated dependencies [13632b1] +- Updated dependencies [a40d010] +- Updated dependencies [f3424fc] +- Updated dependencies [c8753ef] +- Updated dependencies [406fda5] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [a6d4cbb] +- Updated dependencies [08fbbb4] +- Updated dependencies [58b450b] +- Updated dependencies [394d34f] +- Updated dependencies [82eb6cf] +- Updated dependencies [3a45780] +- Updated dependencies [c381977] +- Updated dependencies [13d8653] +- Updated dependencies [03fd7f0] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/objectql@7.4.0 + - @objectstack/runtime@7.4.0 + - @objectstack/platform-objects@7.4.0 + - @objectstack/plugin-auth@7.4.0 + - @objectstack/plugin-webhooks@7.4.0 + - @objectstack/plugin-approvals@7.4.0 + - @objectstack/plugin-security@7.4.0 + - @objectstack/plugin-sharing@7.4.0 + - @objectstack/service-messaging@7.4.0 + - @objectstack/plugin-audit@7.4.0 + - @objectstack/service-automation@7.4.0 + - @objectstack/driver-sql@7.4.0 + - @objectstack/rest@7.4.0 + - @objectstack/service-external-datasource@7.4.0 + - @objectstack/service-ai@7.4.0 + - @objectstack/client@7.4.0 + - @objectstack/service-settings@7.4.0 + - @objectstack/plugin-trigger-record-change@7.4.0 + - @objectstack/plugin-trigger-schedule@7.4.0 + - @objectstack/account@7.4.0 + - @objectstack/core@7.4.0 + - @objectstack/observability@7.4.0 + - @objectstack/driver-memory@7.4.0 + - @objectstack/driver-mongodb@7.4.0 + - @objectstack/driver-sqlite-wasm@7.4.0 + - @objectstack/plugin-email@7.4.0 + - @objectstack/plugin-hono-server@7.4.0 + - @objectstack/plugin-mcp-server@7.4.0 + - @objectstack/plugin-org-scoping@7.4.0 + - @objectstack/plugin-reports@7.4.0 + - @objectstack/service-analytics@7.4.0 + - @objectstack/service-cache@7.4.0 + - @objectstack/service-feed@7.4.0 + - @objectstack/service-job@7.4.0 + - @objectstack/service-package@7.4.0 + - @objectstack/service-queue@7.4.0 + - @objectstack/service-realtime@7.4.0 + - @objectstack/service-storage@7.4.0 + - @objectstack/types@7.4.0 + - @objectstack/console@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index 687b2640a..c8895b5e1 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/cli", - "version": "7.3.0", + "version": "7.4.0", "description": "Command Line Interface for ObjectStack Protocol", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/client-react/CHANGELOG.md b/packages/client-react/CHANGELOG.md index a07d95496..d2330cc4d 100644 --- a/packages/client-react/CHANGELOG.md +++ b/packages/client-react/CHANGELOG.md @@ -1,5 +1,35 @@ # @objectstack/client-react +## 7.4.0 + +### Minor Changes + +- 58b450b: Make metadata labels follow the active UI language without a page refresh (#1319). + + The client now carries the active locale on every request (`Accept-Language`, + `setLocale`/`getLocale`), the protocol ETag is locale-aware so cached metadata + no longer collides across languages, and the `client-react` metadata hooks + refetch when the locale changes. The `apps/account` console wires its router + locale through so a language switch relabels server-resolved object/field/view + labels in place instead of leaving the UI half-translated until reload. + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/client@7.4.0 + - @objectstack/core@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/client-react/package.json b/packages/client-react/package.json index cca7763ba..8c37cd6e2 100644 --- a/packages/client-react/package.json +++ b/packages/client-react/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/client-react", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "React hooks for ObjectStack Client SDK", "main": "dist/index.js", diff --git a/packages/client/CHANGELOG.md b/packages/client/CHANGELOG.md index c604c9aaf..e4203a222 100644 --- a/packages/client/CHANGELOG.md +++ b/packages/client/CHANGELOG.md @@ -1,5 +1,34 @@ # @objectstack/client +## 7.4.0 + +### Minor Changes + +- 58b450b: Make metadata labels follow the active UI language without a page refresh (#1319). + + The client now carries the active locale on every request (`Accept-Language`, + `setLocale`/`getLocale`), the protocol ETag is locale-aware so cached metadata + no longer collides across languages, and the `client-react` metadata hooks + refetch when the locale changes. The `apps/account` console wires its router + locale through so a language switch relabels server-resolved object/field/view + labels in place instead of leaving the UI half-translated until reload. + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/core@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/client/package.json b/packages/client/package.json index 42e79de9a..aa5b1dfa6 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/client", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "Official Client SDK for ObjectStack Protocol", "main": "dist/index.js", diff --git a/packages/connectors/connector-mcp/CHANGELOG.md b/packages/connectors/connector-mcp/CHANGELOG.md new file mode 100644 index 000000000..740201a47 --- /dev/null +++ b/packages/connectors/connector-mcp/CHANGELOG.md @@ -0,0 +1,44 @@ +# @objectstack/connector-mcp + +## 7.4.0 + +### Minor Changes + +- 6e4b3f2: MCP Connector (ADR-0024) — adopt any Model Context Protocol server as a connector. + + Adds `@objectstack/connector-mcp`, a single generic adapter that turns _any_ + MCP server into an ordinary `type: 'api'` connector on the automation engine — + no per-server code: + + - `createMcpConnector({ transport, include?, … })` connects over **stdio** or + **streamable-HTTP**, calls `tools/list`, and maps each tool to a connector + action (`name → key`, `description → label/description`, + `inputSchema → inputSchema`). Handlers dispatch to `tools/call` and normalise + the result to the shared `{ ok, content, … }` envelope (logical tool errors + surface as `ok: false` rather than throwing). + - `ConnectorMcpPlugin` registers the connector via the existing + `engine.registerConnector()` path (no new engine surface, no `mcp_call` node) + and tears the MCP connection down on shutdown. Fail-soft: an unreachable + server or missing automation engine is logged and skipped. + - Credentials live with the MCP server (transport `env`/`headers`), never in + `ConnectorSchema` and never in the serialized, discovery-exposed `def`. + + Open-tier scope: client adapter + operator-supplied static credentials. A + curated server registry, managed secrets, per-tenant lifecycle, and sandboxed + stdio execution remain the enterprise tier. + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/core@7.4.0 diff --git a/packages/connectors/connector-mcp/package.json b/packages/connectors/connector-mcp/package.json index f1e0c3732..922fbb2b6 100644 --- a/packages/connectors/connector-mcp/package.json +++ b/packages/connectors/connector-mcp/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/connector-mcp", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "Model Context Protocol (MCP) connector for ObjectStack — a generic adapter that turns any MCP server's tools into a connector's actions on the automation engine's connector registry (ADR-0024).", "main": "dist/index.js", diff --git a/packages/connectors/connector-openapi/CHANGELOG.md b/packages/connectors/connector-openapi/CHANGELOG.md new file mode 100644 index 000000000..334316d07 --- /dev/null +++ b/packages/connectors/connector-openapi/CHANGELOG.md @@ -0,0 +1,23 @@ +# @objectstack/connector-openapi + +## 7.4.0 + +### Minor Changes + +- 71d8ae1: Add `@objectstack/connector-openapi` — generate an ObjectStack connector from a declarative OpenAPI 3.x document (ADR-0023). One operation becomes one connector action; a single generic handler drives a self-contained static-auth HTTP transport (mirroring `@objectstack/connector-rest`). The generated `type: 'api'` connector registers via `engine.registerConnector(def, handlers)` with no new engine surface, and supports an `include` allowlist for trimming large specs. + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/core@7.4.0 diff --git a/packages/connectors/connector-openapi/package.json b/packages/connectors/connector-openapi/package.json index 88a9bd6f4..2c8767d03 100644 --- a/packages/connectors/connector-openapi/package.json +++ b/packages/connectors/connector-openapi/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/connector-openapi", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "OpenAPI 3.x connector generator for ObjectStack — turns a declarative OpenAPI document into connector actions on the automation engine's registry, with a self-contained static-auth HTTP transport (ADR-0023).", "main": "dist/index.js", diff --git a/packages/connectors/connector-rest/CHANGELOG.md b/packages/connectors/connector-rest/CHANGELOG.md new file mode 100644 index 000000000..033f11300 --- /dev/null +++ b/packages/connectors/connector-rest/CHANGELOG.md @@ -0,0 +1,19 @@ +# @objectstack/connector-rest + +## 7.4.0 + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/core@7.4.0 diff --git a/packages/connectors/connector-rest/package.json b/packages/connectors/connector-rest/package.json index c3c067e7b..4225afef3 100644 --- a/packages/connectors/connector-rest/package.json +++ b/packages/connectors/connector-rest/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/connector-rest", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "Generic REST connector for ObjectStack — the reference concrete connector that registers a `request` action on the automation engine's connector registry (ADR-0018 §Addendum).", "main": "dist/index.js", diff --git a/packages/connectors/connector-slack/CHANGELOG.md b/packages/connectors/connector-slack/CHANGELOG.md new file mode 100644 index 000000000..ca84dd4ae --- /dev/null +++ b/packages/connectors/connector-slack/CHANGELOG.md @@ -0,0 +1,19 @@ +# @objectstack/connector-slack + +## 7.4.0 + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/core@7.4.0 diff --git a/packages/connectors/connector-slack/package.json b/packages/connectors/connector-slack/package.json index 1cacbdc6a..b0eb47af8 100644 --- a/packages/connectors/connector-slack/package.json +++ b/packages/connectors/connector-slack/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/connector-slack", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "Slack Web API connector for ObjectStack — registers `chat.postMessage` / `chat.update` / `call` actions on the automation engine's connector registry (ADR-0018 §Addendum, ADR-0022).", "main": "dist/index.js", diff --git a/packages/console/CHANGELOG.md b/packages/console/CHANGELOG.md index ba157c27b..ccd1be9a4 100644 --- a/packages/console/CHANGELOG.md +++ b/packages/console/CHANGELOG.md @@ -1,5 +1,7 @@ # @objectstack/console +## 7.4.0 + ## 7.3.0 ## 7.2.1 diff --git a/packages/console/package.json b/packages/console/package.json index 2be97ef1c..1d8513e15 100644 --- a/packages/console/package.json +++ b/packages/console/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/console", - "version": "7.3.0", + "version": "7.4.0", "description": "Prebuilt Console SPA pinned to this @objectstack/framework release. Source of truth: @object-ui/console (https://github.com/objectstack-ai/objectui).", "license": "Apache-2.0", "homepage": "https://github.com/objectstack-ai/framework/tree/main/packages/console", diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index 3d2093ebb..f9585296a 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -1,5 +1,22 @@ # @objectstack/core +## 7.4.0 + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/core/package.json b/packages/core/package.json index 400dde34a..29702ba1f 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/core", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "Microkernel Core for ObjectStack", "type": "module", diff --git a/packages/create-objectstack/CHANGELOG.md b/packages/create-objectstack/CHANGELOG.md index c34aea456..4a10e22b7 100644 --- a/packages/create-objectstack/CHANGELOG.md +++ b/packages/create-objectstack/CHANGELOG.md @@ -1,5 +1,7 @@ # create-objectstack +## 7.4.0 + ## 7.3.0 ## 7.2.1 diff --git a/packages/create-objectstack/package.json b/packages/create-objectstack/package.json index ffaddc17f..e6ddca705 100644 --- a/packages/create-objectstack/package.json +++ b/packages/create-objectstack/package.json @@ -1,6 +1,6 @@ { "name": "create-objectstack", - "version": "7.3.0", + "version": "7.4.0", "description": "Create a new ObjectStack project — npx create-objectstack", "bin": { "create-objectstack": "./bin/create-objectstack.js" diff --git a/packages/formula/CHANGELOG.md b/packages/formula/CHANGELOG.md index 6f1cb435c..83a52169f 100644 --- a/packages/formula/CHANGELOG.md +++ b/packages/formula/CHANGELOG.md @@ -1,5 +1,22 @@ # @objectstack/formula +## 7.4.0 + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/formula/package.json b/packages/formula/package.json index 95d4cb850..969410eb6 100644 --- a/packages/formula/package.json +++ b/packages/formula/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/formula", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "ObjectStack canonical expression engine — CEL (cel-js) + ObjectStack stdlib + dialect registry", "main": "dist/index.js", diff --git a/packages/metadata-core/CHANGELOG.md b/packages/metadata-core/CHANGELOG.md index 354c2f235..1c0979640 100644 --- a/packages/metadata-core/CHANGELOG.md +++ b/packages/metadata-core/CHANGELOG.md @@ -1,5 +1,7 @@ # @objectstack/metadata-core +## 7.4.0 + ## 7.3.0 ## 7.2.1 diff --git a/packages/metadata-core/package.json b/packages/metadata-core/package.json index 6ef947e7d..198130954 100644 --- a/packages/metadata-core/package.json +++ b/packages/metadata-core/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/metadata-core", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "Metadata Repository contracts: types, canonicalization, errors, interface (ADR-0008).", "type": "module", diff --git a/packages/metadata-fs/CHANGELOG.md b/packages/metadata-fs/CHANGELOG.md index f4a9b1e9c..99829852b 100644 --- a/packages/metadata-fs/CHANGELOG.md +++ b/packages/metadata-fs/CHANGELOG.md @@ -1,5 +1,11 @@ # @objectstack/metadata-fs +## 7.4.0 + +### Patch Changes + +- @objectstack/metadata-core@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/metadata-fs/package.json b/packages/metadata-fs/package.json index 4ebc901ad..9a430a8d6 100644 --- a/packages/metadata-fs/package.json +++ b/packages/metadata-fs/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/metadata-fs", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "FileSystemRepository: Node-only Repository implementation backed by JSON files and a JSONL change log (ADR-0008).", "type": "module", diff --git a/packages/metadata/CHANGELOG.md b/packages/metadata/CHANGELOG.md index 6a3c021ff..094b4cfb1 100644 --- a/packages/metadata/CHANGELOG.md +++ b/packages/metadata/CHANGELOG.md @@ -1,5 +1,88 @@ # @objectstack/metadata +## 7.4.0 + +### Minor Changes + +- 13632b1: ADR-0030 P0 (framework) — converge notifications onto a single ingress and the + layered model. Every producer now publishes through + `NotificationService.emit(EmitInput)`; the in-app inbox is a materialization of + delivery, not a row producers write. + + **Single ingress (`@objectstack/service-messaging`) — breaking** + + - `MessagingService.emit` takes the new `EmitInput` contract (`topic` / + `audience` / `payload` / `severity` / `dedupKey` / `source` / `actorId` / + `organizationId` / `channels`) instead of the flat `Notification` shape. It + writes the L2 `sys_notification` event (idempotent on `dedupKey`), resolves the + audience, then fans out; it returns `{ notificationId, deduped, deliveries, +delivered, failed }`. + - New `sys_notification_receipt` object — the read-state spine + (`delivered|read|clicked|dismissed`), keyed `(notification_id, user_id, +channel)`. The inbox channel writes a `delivered` receipt on materialization. + - `sys_inbox_message`: adds `notification_id` / `delivery_id`, **drops `read`** + (read-state moved to the receipt), adds the user `mine` list view. + + **Event re-model (`@objectstack/platform-objects`) — breaking** + + - `sys_notification` is re-modeled from a per-user inbox into the L2 **event** + (`topic`, `payload`, `severity`, `dedup_key`, `source_*`, `actor_id`). Removes + `recipient_id` / `is_read` / `read_at` / `type` / `title` / `body` / `url` / + `actor_name` and the inbox actions/views. App-nav: the account inbox points at + `sys_inbox_message`; Setup shows the notification event log. + + **Producers routed through `emit()`** + + - `@objectstack/service-automation`: the `notify` node maps its config to + `EmitInput`. + - `@objectstack/plugin-audit`: collaboration `@mention` → `collab.mention` and + assignment → `collab.assignment` (both with a `dedupKey`); no more direct + `sys_notification` writes. Collaboration notifications now require + `MessagingServicePlugin` (they degrade to a warn otherwise). + + **Migration (`@objectstack/metadata`)** + + - Idempotent `migrateSysNotificationToEvent` splits legacy `sys_notification` + inbox rows into `sys_inbox_message` + receipts and rewrites the event row. + + **Startup (`@objectstack/cli`, `@objectstack/runtime`)** + + - `messaging` is now a foundational capability. On `objectstack serve` it is + added to `ALWAYS_ON_CAPABILITIES` (every non-`minimal` preset starts it); on + cloud per-project kernels the capability loader expands `requires` to add + `messaging` whenever `audit` is present. This keeps collaboration `@mention` / + assignment notifications (which now flow through the pipeline) working out of + the box on both paths. `--preset minimal` opts out. + + The Console bell repoint (objectui) and phases P1–P3 are tracked in + `docs/handoff/adr-0030-notification-convergence.md`. + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [4404572] +- Updated dependencies [eea3f1b] +- Updated dependencies [e478e0c] +- Updated dependencies [4cc2ced] +- Updated dependencies [13632b1] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [c381977] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/platform-objects@7.4.0 + - @objectstack/core@7.4.0 + - @objectstack/types@7.4.0 + - @objectstack/metadata-core@7.4.0 + - @objectstack/metadata-fs@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/metadata/package.json b/packages/metadata/package.json index abc0a6445..038ef77ef 100644 --- a/packages/metadata/package.json +++ b/packages/metadata/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/metadata", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "Metadata loading, saving, and persistence for ObjectStack", "type": "module", diff --git a/packages/objectql/CHANGELOG.md b/packages/objectql/CHANGELOG.md index 6007ef0c9..eca09a206 100644 --- a/packages/objectql/CHANGELOG.md +++ b/packages/objectql/CHANGELOG.md @@ -1,5 +1,175 @@ # @objectstack/objectql +## 7.4.0 + +### 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/objectql`** — `SchemaRegistry.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. + +- eea3f1b: ADR-0029 K0 + K2.a — single-owner invariant and webhooks ownership pilot. + + **K0 (`@objectstack/objectql`)** — add `SchemaRegistry.assertSingleOwnerPerObject()`, + the install-time backstop for the kernel-decomposition invariant: every + registered object must resolve to exactly one `own` contributor. A second + cross-package owner is already rejected at registration time; this additionally + catches "extend with no owner" (which would otherwise resolve to nothing). Call + after kernel bootstrap completes. + + **K2.a (`@objectstack/plugin-webhooks` ← `@objectstack/platform-objects`)** — move + the `sys_webhook` object definition out of the `platform-objects` monolith into + `@objectstack/plugin-webhooks`, where it joins its sibling `sys_webhook_delivery` + so the plugin owns both its data model and behavior as one unit. `sys_webhook` is + no longer exported from `@objectstack/platform-objects` (or its `/integration` + subpath, now an empty barrel); import it from `@objectstack/plugin-webhooks/schema` + instead. Runtime behavior is unchanged — the webhook plugin already registered + `sys_webhook` at runtime; only the definition's home moved. Setup-app navigation + (which references `sys_webhook` by name) and existing i18n bundles (object-name + keyed) continue to work. Per ADR-0029 D8, migrating the object's i18n extraction + into the plugin is a tracked follow-up before the next translation regeneration. + +- 2faf9f2: External Datasource Federation (ADR-0015) — write gate (Gate 3) + introspection plumbing. + + - Write gate: ObjectQL `insert`/`update`/`delete` now block writes to a + federated datasource (`schemaMode !== 'managed'`) unless BOTH + `datasource.external.allowWrites` and `object.external.writable` are true, + throwing `ExternalWriteForbiddenError` (code `EXTERNAL_WRITE_FORBIDDEN`). + Managed datasources (and objects without a datasource definition) are + unaffected. New `registerDatasourceDef()` records declarative datasource + ownership; manifests carrying `datasources` are indexed during `registerApp`. + - `engine.introspectDatasource(name)` delegates to the named driver's + `introspectSchema()`, wiring the external-datasource service end-to-end. + +### Patch Changes + +- a6d4cbb: Fix conditional & record-change flows silently skipping. + + Two bugs together caused every flow with a start-node / edge **condition** to + silently skip (record-change triggers fired but the flow body never ran; + audit-style `previous.*` gates and `budget > 100000`-style gates all evaluated + to false): + + - **service-automation — CEL engine unreachable in ESM.** The condition + evaluator loaded the formula engine via a CommonJS `require('@objectstack/formula')`. + In the package's ESM build (`"type": "module"`) that resolves to tsup's + throwing `__require` stub, so **every** CEL evaluation threw and the + swallowing `catch` returned `false`. Replaced with a static top-level import, + which binds correctly in both the ESM and CJS builds. + + - **objectql — prior record not exposed to update hooks.** `HookContext` + documents a `previous` snapshot for update/delete, but `engine.update` never + populated it (the row it fetched for validation was a local var). Record-change + conditions like `status == "done" && previous.status != "done"` therefore had + no `previous` to read. The engine now attaches the pre-update record to + `hookContext.previous` for single-id updates whenever a validation rule needs + it or an `afterUpdate` hook is registered. + + Both paths are covered by new unit tests. + +- 58b450b: Make metadata labels follow the active UI language without a page refresh (#1319). + + The client now carries the active locale on every request (`Accept-Language`, + `setLocale`/`getLocale`), the protocol ETag is locale-aware so cached metadata + no longer collides across languages, and the `client-react` metadata hooks + refetch when the locale changes. The `apps/account` console wires its router + locale through so a language switch relabels server-resolved object/field/view + labels in place instead of leaving the UI half-translated until reload. + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/core@7.4.0 + - @objectstack/formula@7.4.0 + - @objectstack/types@7.4.0 + - @objectstack/metadata-core@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/objectql/package.json b/packages/objectql/package.json index 35a9597db..a4e4b82f4 100644 --- a/packages/objectql/package.json +++ b/packages/objectql/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/objectql", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "Isomorphic ObjectQL Engine for ObjectStack", "main": "dist/index.js", diff --git a/packages/observability/CHANGELOG.md b/packages/observability/CHANGELOG.md index 93a233dcd..dd76dda89 100644 --- a/packages/observability/CHANGELOG.md +++ b/packages/observability/CHANGELOG.md @@ -1,5 +1,22 @@ # @objectstack/observability +## 7.4.0 + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/observability/package.json b/packages/observability/package.json index e39c2dc83..f87937fd8 100644 --- a/packages/observability/package.json +++ b/packages/observability/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/observability", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "Observability contracts and exporters for ObjectStack — MetricsRegistry, ErrorReporter, Logger plus noop/console/OTLP-HTTP exporters. Deployment-target neutral; runtime and services depend on this so the same instrumentation works on Cloudflare Workers, Node, and self-hosted Kubernetes.", "type": "module", diff --git a/packages/platform-objects/CHANGELOG.md b/packages/platform-objects/CHANGELOG.md index 09764c480..29de45cb5 100644 --- a/packages/platform-objects/CHANGELOG.md +++ b/packages/platform-objects/CHANGELOG.md @@ -1,5 +1,312 @@ # @objectstack/platform-objects +## 7.4.0 + +### Minor Changes + +- 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/objectql`** — `SchemaRegistry.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. + +- eea3f1b: ADR-0029 K0 + K2.a — single-owner invariant and webhooks ownership pilot. + + **K0 (`@objectstack/objectql`)** — add `SchemaRegistry.assertSingleOwnerPerObject()`, + the install-time backstop for the kernel-decomposition invariant: every + registered object must resolve to exactly one `own` contributor. A second + cross-package owner is already rejected at registration time; this additionally + catches "extend with no owner" (which would otherwise resolve to nothing). Call + after kernel bootstrap completes. + + **K2.a (`@objectstack/plugin-webhooks` ← `@objectstack/platform-objects`)** — move + the `sys_webhook` object definition out of the `platform-objects` monolith into + `@objectstack/plugin-webhooks`, where it joins its sibling `sys_webhook_delivery` + so the plugin owns both its data model and behavior as one unit. `sys_webhook` is + no longer exported from `@objectstack/platform-objects` (or its `/integration` + subpath, now an empty barrel); import it from `@objectstack/plugin-webhooks/schema` + instead. Runtime behavior is unchanged — the webhook plugin already registered + `sys_webhook` at runtime; only the definition's home moved. Setup-app navigation + (which references `sys_webhook` by name) and existing i18n bundles (object-name + keyed) continue to work. Per ADR-0029 D8, migrating the object's i18n extraction + into the plugin is a tracked follow-up before the next translation regeneration. + +- e478e0c: ADR-0029 K2 — security domain ownership (RBAC + sharing) + Setup nav contributions. + + Moves the security objects out of the `@objectstack/platform-objects` monolith + into the two capability plugins that already register and operate them, split by + concern (the two are orthogonal — sharing objects never reference RBAC objects): + + - **`@objectstack/plugin-security`** (RBAC) gains `sys_role`, + `sys_permission_set`, `sys_user_permission_set`, `sys_role_permission_set`, + and the `defaultPermissionSets` seed (which its `bootstrap-platform-admin` + already consumes). The RBAC + default-permission-set tests move with them. + - **`@objectstack/plugin-sharing`** gains `sys_record_share`, + `sys_sharing_rule`, `sys_share_link`. + - `@objectstack/platform-objects` no longer defines/exports any security + objects; the `/security` subpath is now an empty barrel. Runtime is unchanged + (both plugins already registered these objects at runtime). + + **D7 navigation** — the Setup app's `group_access_control` is now assembled from + three sources: `plugin-security` contributes Roles / Permission Sets (priority + 100), `plugin-sharing` contributes Sharing Rules / Record Shares (priority 200), + and `platform-objects` keeps only API Keys (`sys_api_key`, an identity object, + priority 300) — preserving the original menu order. + + **i18n (D8)** — the objects are removed from the `platform-objects` i18n extract + config; existing generated bundles keep working at runtime (object-name keyed). + Migrating the i18n extraction to the owning plugins remains the tracked + follow-up. + +- 4cc2ced: ADR-0029 K2.b — approvals domain ownership + Setup nav contribution. + + Moves `sys_approval_request` / `sys_approval_action` out of the + `@objectstack/platform-objects` monolith into `@objectstack/plugin-approvals`, + which already registers and operates them — so the plugin now owns its data + model, behavior, and admin menu as one unit. + + - The object definitions move to `plugin-approvals`; `platform-objects` no + longer exports them from `/audit`. Runtime is unchanged (the plugin already + registered them at runtime). + - **D7 navigation** — the Setup app's `group_approvals` entries (`Requests`, + `Action History`) move out of `platform-objects`' `SETUP_NAV_CONTRIBUTIONS` + into `plugin-approvals`' `navigationContributions`. The plugin fills the slot + it owns; when the plugin is absent the slot stays empty. + - **i18n (D8)** — the objects are removed from the `platform-objects` i18n + extract config; their existing generated translation bundles keep working at + runtime (object-name keyed). Migrating the i18n extraction/bundles to the + plugin remains the tracked cross-cutting follow-up (best done with the + `os i18n extract` tooling, not hand-edited generated files). + +- 13632b1: ADR-0030 P0 (framework) — converge notifications onto a single ingress and the + layered model. Every producer now publishes through + `NotificationService.emit(EmitInput)`; the in-app inbox is a materialization of + delivery, not a row producers write. + + **Single ingress (`@objectstack/service-messaging`) — breaking** + + - `MessagingService.emit` takes the new `EmitInput` contract (`topic` / + `audience` / `payload` / `severity` / `dedupKey` / `source` / `actorId` / + `organizationId` / `channels`) instead of the flat `Notification` shape. It + writes the L2 `sys_notification` event (idempotent on `dedupKey`), resolves the + audience, then fans out; it returns `{ notificationId, deduped, deliveries, +delivered, failed }`. + - New `sys_notification_receipt` object — the read-state spine + (`delivered|read|clicked|dismissed`), keyed `(notification_id, user_id, +channel)`. The inbox channel writes a `delivered` receipt on materialization. + - `sys_inbox_message`: adds `notification_id` / `delivery_id`, **drops `read`** + (read-state moved to the receipt), adds the user `mine` list view. + + **Event re-model (`@objectstack/platform-objects`) — breaking** + + - `sys_notification` is re-modeled from a per-user inbox into the L2 **event** + (`topic`, `payload`, `severity`, `dedup_key`, `source_*`, `actor_id`). Removes + `recipient_id` / `is_read` / `read_at` / `type` / `title` / `body` / `url` / + `actor_name` and the inbox actions/views. App-nav: the account inbox points at + `sys_inbox_message`; Setup shows the notification event log. + + **Producers routed through `emit()`** + + - `@objectstack/service-automation`: the `notify` node maps its config to + `EmitInput`. + - `@objectstack/plugin-audit`: collaboration `@mention` → `collab.mention` and + assignment → `collab.assignment` (both with a `dedupKey`); no more direct + `sys_notification` writes. Collaboration notifications now require + `MessagingServicePlugin` (they degrade to a warn otherwise). + + **Migration (`@objectstack/metadata`)** + + - Idempotent `migrateSysNotificationToEvent` splits legacy `sys_notification` + inbox rows into `sys_inbox_message` + receipts and rewrites the event row. + + **Startup (`@objectstack/cli`, `@objectstack/runtime`)** + + - `messaging` is now a foundational capability. On `objectstack serve` it is + added to `ALWAYS_ON_CAPABILITIES` (every non-`minimal` preset starts it); on + cloud per-project kernels the capability loader expands `requires` to add + `messaging` whenever `audit` is present. This keeps collaboration `@mention` / + assignment notifications (which now flow through the pipeline) working out of + the box on both paths. `--preset minimal` opts out. + + The Console bell repoint (objectui) and phases P1–P3 are tracked in + `docs/handoff/adr-0030-notification-convergence.md`. + +### Patch 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. + +- 4404572: ADR-0029 D8 — migrate i18n ownership for the moved domains to their plugins. + + The object translations for the domains decomposed in K2.a/K2.b/K2 previously + lived in the `@objectstack/platform-objects` generated bundles even though the + objects now live in their capability plugins. This moves each domain's i18n + extraction + bundles to the owning plugin, preserving every hand-translated + string (zh-CN / ja-JP / es-ES): + + - Each plugin gains a build-time `scripts/i18n-extract.config.ts` and a + `src/translations/` bundle (`{locale}.objects.generated.ts` + an `index.ts` + barrel), generated with `os i18n extract` and self-baselined so re-runs + preserve translations. + - Each plugin loads its bundle at runtime on `kernel:ready` via + `i18n.loadTranslations` (the i18n service is optional — load is best-effort). + - `plugin-webhooks` ← `sys_webhook`, `sys_webhook_delivery` + - `plugin-approvals` ← `sys_approval_request`, `sys_approval_action` + - `plugin-security` ← `sys_role`, `sys_permission_set`, + `sys_user_permission_set`, `sys_role_permission_set` + - `plugin-sharing` ← `sys_record_share`, `sys_sharing_rule`, `sys_share_link` + - `@objectstack/platform-objects` translation bundles are regenerated to drop + those objects' keys (its extract config already excluded them); all other + objects' translations and the metadata-form bundles are preserved. + + Net runtime effect is unchanged (same translations load, now contributed by the + package that owns each object) — closing the D8 follow-up tracked since K2.a. + +- 82eb6cf: Fix system-metadata translations: locale fallback, app/dashboard localization, and coverage gaps. + + Switching the UI language left many surfaces in English. Three root causes + are addressed: + + - **Locale fallback (server).** The metadata translation resolver + (`@objectstack/spec` `i18n-resolver`) now resolves a requested locale + against the locales actually present in the bundle (exact → + case-insensitive → base-language → variant), so a request for `zh` + correctly hits the `zh-CN` bundle instead of falling back to English. + This mirrors `resolveLocale` in `@objectstack/core` and benefits every + resolver (objects, views, actions, settings, metadata forms). + + - **App & dashboard localization (server).** Added `translateApp` and + `translateDashboard` resolvers and wired `app`/`dashboard` into the REST + `/meta` translation path. App labels, sidebar/navigation group labels, + and dashboard titles/widgets were previously never localized at the API + boundary even though the translation data existed. + + - **Coverage & quality (data).** Added translations for the previously + untranslated platform objects `sys_share_link`, `sys_view_definition`, + and `sys_metadata_audit` (and registered them in the i18n-extract config + so future extractions keep them). Replaced English placeholder strings + left in the `zh-CN` / `ja-JP` / `es-ES` object and metadata-form bundles + (notably action `confirmText` / `successMessage` prompts). Added the + missing `es-ES` built-in Settings bundle in `@objectstack/service-settings`. + +- c381977: Harden the notification pipeline: race-safe dedup + opt-in retention (ADR-0030). + + **Race-safe dedup.** `sys_notification.dedup_key` is now declared a **UNIQUE** + index (was a plain index), and `emit()` **converges on a unique-key conflict**: + the pre-insert `dedup_key` check is a fast-path, but if a concurrent `emit` + raced past it and inserted first, our insert hits the violation — we catch it + and converge to the winner's event (a dedup hit) instead of throwing or + double-emitting. This mirrors the delivery outbox's enqueue convergence and + stops a record-change storm from producing duplicate bell notifications. SQL + treats NULLs as distinct, so the common events with no `dedup_key` are + unconstrained. (Enforcement is per-driver: where declared indexes are + materialized the conflict path activates; drivers that don't materialize them + fall back to the best-effort fast-path — the catch is simply never taken. Note + the SQL driver currently doesn't sync declared object indexes, which already + affects the delivery/receipt unique indexes — tracked separately.) + + **Opt-in retention.** New `NotificationRetention` sweeper + plugin options + `retentionDays` / `retentionSweepMs`. Every `emit()` writes a `sys_notification` + event (plus delivery/materialization/receipt rows), so a high-frequency + periodic flow grows the tables unbounded. When `retentionDays > 0`, a + low-frequency sweep (default hourly, timer `unref`'d) bulk-deletes events, + deliveries, inbox messages and receipts older than the cutoff — a notification + ages out wholesale, keeping the model consistent (no dangling `notification_id`) + and the bell (recent-only) unaffected. The delivery row's epoch-ms `created_at` + vs the others' ISO `created_at` is handled per target. **Default off** — no + notification data is deleted without explicit operator policy. Each target is + isolated (one object's failure doesn't abort the sweep), and the sweep runs + under a system context (retention is a cross-tenant operator policy). + + Tests: +7 `service-messaging` cases (converge-on-conflict, non-conflict + rethrow, retention cutoff-formatting per target, no-engine / non-positive + no-ops, failure isolation, missing-count) — 102 passing. + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/platform-objects/package.json b/packages/platform-objects/package.json index 42659bffc..049a9732d 100644 --- a/packages/platform-objects/package.json +++ b/packages/platform-objects/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/platform-objects", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "Core platform object schemas for ObjectStack — identity, security, audit, tenant, and metadata objects", "main": "dist/index.js", diff --git a/packages/plugins/driver-memory/CHANGELOG.md b/packages/plugins/driver-memory/CHANGELOG.md index 9d9d01d65..3a10da7a0 100644 --- a/packages/plugins/driver-memory/CHANGELOG.md +++ b/packages/plugins/driver-memory/CHANGELOG.md @@ -1,5 +1,23 @@ # @objectstack/driver-memory +## 7.4.0 + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/core@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/plugins/driver-memory/package.json b/packages/plugins/driver-memory/package.json index cab46c7f9..93d877499 100644 --- a/packages/plugins/driver-memory/package.json +++ b/packages/plugins/driver-memory/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/driver-memory", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "In-Memory Driver for ObjectStack (Reference Implementation)", "main": "dist/index.js", diff --git a/packages/plugins/driver-mongodb/CHANGELOG.md b/packages/plugins/driver-mongodb/CHANGELOG.md index 77495a90c..ed9e767bf 100644 --- a/packages/plugins/driver-mongodb/CHANGELOG.md +++ b/packages/plugins/driver-mongodb/CHANGELOG.md @@ -1,5 +1,23 @@ # @objectstack/driver-mongodb +## 7.4.0 + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/core@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/plugins/driver-mongodb/package.json b/packages/plugins/driver-mongodb/package.json index d3117ddf5..265f0b580 100644 --- a/packages/plugins/driver-mongodb/package.json +++ b/packages/plugins/driver-mongodb/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/driver-mongodb", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "MongoDB Driver for ObjectStack - Native document database driver via official mongodb client", "main": "dist/index.js", diff --git a/packages/plugins/driver-sql/CHANGELOG.md b/packages/plugins/driver-sql/CHANGELOG.md index 75b54002c..d871211a3 100644 --- a/packages/plugins/driver-sql/CHANGELOG.md +++ b/packages/plugins/driver-sql/CHANGELOG.md @@ -1,5 +1,42 @@ # @objectstack/driver-sql +## 7.4.0 + +### Minor 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 `code`s) + 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'`). + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/core@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/plugins/driver-sql/package.json b/packages/plugins/driver-sql/package.json index c1b8e5735..adced25f3 100644 --- a/packages/plugins/driver-sql/package.json +++ b/packages/plugins/driver-sql/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/driver-sql", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "SQL Driver for ObjectStack - Supports PostgreSQL, MySQL, SQLite via Knex", "main": "dist/index.js", diff --git a/packages/plugins/driver-sqlite-wasm/CHANGELOG.md b/packages/plugins/driver-sqlite-wasm/CHANGELOG.md index 440c9d607..9933af25a 100644 --- a/packages/plugins/driver-sqlite-wasm/CHANGELOG.md +++ b/packages/plugins/driver-sqlite-wasm/CHANGELOG.md @@ -1,5 +1,24 @@ # @objectstack/driver-sqlite-wasm +## 7.4.0 + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/driver-sql@7.4.0 + - @objectstack/core@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/plugins/driver-sqlite-wasm/package.json b/packages/plugins/driver-sqlite-wasm/package.json index c822a43d1..01162b795 100644 --- a/packages/plugins/driver-sqlite-wasm/package.json +++ b/packages/plugins/driver-sqlite-wasm/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/driver-sqlite-wasm", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "WASM SQLite Driver for ObjectStack — runs in browser/WebContainer (StackBlitz) without native bindings", "keywords": [ diff --git a/packages/plugins/embedder-openai/CHANGELOG.md b/packages/plugins/embedder-openai/CHANGELOG.md index 34876b874..ad04643bd 100644 --- a/packages/plugins/embedder-openai/CHANGELOG.md +++ b/packages/plugins/embedder-openai/CHANGELOG.md @@ -1,5 +1,22 @@ # @objectstack/embedder-openai +## 7.4.0 + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/plugins/embedder-openai/package.json b/packages/plugins/embedder-openai/package.json index 631c67d81..f4c769a7f 100644 --- a/packages/plugins/embedder-openai/package.json +++ b/packages/plugins/embedder-openai/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/embedder-openai", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "OpenAI-compatible embedder for ObjectStack — works against OpenAI, 阿里通义 DashScope, 智谱 BigModel, 硅基流动 SiliconFlow, 火山引擎 Doubao, MiniMax, Ollama, and any drop-in OpenAI-shape endpoint.", "main": "dist/index.js", diff --git a/packages/plugins/knowledge-memory/CHANGELOG.md b/packages/plugins/knowledge-memory/CHANGELOG.md index 3aca54784..d86676d0a 100644 --- a/packages/plugins/knowledge-memory/CHANGELOG.md +++ b/packages/plugins/knowledge-memory/CHANGELOG.md @@ -1,5 +1,24 @@ # @objectstack/knowledge-memory +## 7.4.0 + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/core@7.4.0 + - @objectstack/service-knowledge@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/plugins/knowledge-memory/package.json b/packages/plugins/knowledge-memory/package.json index ca2213e47..4253af42f 100644 --- a/packages/plugins/knowledge-memory/package.json +++ b/packages/plugins/knowledge-memory/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/knowledge-memory", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "In-memory knowledge adapter for ObjectStack (dev / test reference implementation).", "main": "dist/index.js", diff --git a/packages/plugins/knowledge-ragflow/CHANGELOG.md b/packages/plugins/knowledge-ragflow/CHANGELOG.md index c254fe2cb..736f263b5 100644 --- a/packages/plugins/knowledge-ragflow/CHANGELOG.md +++ b/packages/plugins/knowledge-ragflow/CHANGELOG.md @@ -1,5 +1,24 @@ # @objectstack/knowledge-ragflow +## 7.4.0 + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/core@7.4.0 + - @objectstack/service-knowledge@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/plugins/knowledge-ragflow/package.json b/packages/plugins/knowledge-ragflow/package.json index e748270c7..dfa52e8ce 100644 --- a/packages/plugins/knowledge-ragflow/package.json +++ b/packages/plugins/knowledge-ragflow/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/knowledge-ragflow", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "RAGFlow knowledge adapter for ObjectStack — production-grade RAG via the Apache 2.0 RAGFlow REST API.", "main": "dist/index.js", diff --git a/packages/plugins/plugin-approvals/CHANGELOG.md b/packages/plugins/plugin-approvals/CHANGELOG.md index c221ff1a7..b4eb332ac 100644 --- a/packages/plugins/plugin-approvals/CHANGELOG.md +++ b/packages/plugins/plugin-approvals/CHANGELOG.md @@ -1,5 +1,80 @@ # @objectstack/plugin-approvals +## 7.4.0 + +### Minor Changes + +- 4cc2ced: ADR-0029 K2.b — approvals domain ownership + Setup nav contribution. + + Moves `sys_approval_request` / `sys_approval_action` out of the + `@objectstack/platform-objects` monolith into `@objectstack/plugin-approvals`, + which already registers and operates them — so the plugin now owns its data + model, behavior, and admin menu as one unit. + + - The object definitions move to `plugin-approvals`; `platform-objects` no + longer exports them from `/audit`. Runtime is unchanged (the plugin already + registered them at runtime). + - **D7 navigation** — the Setup app's `group_approvals` entries (`Requests`, + `Action History`) move out of `platform-objects`' `SETUP_NAV_CONTRIBUTIONS` + into `plugin-approvals`' `navigationContributions`. The plugin fills the slot + it owns; when the plugin is absent the slot stays empty. + - **i18n (D8)** — the objects are removed from the `platform-objects` i18n + extract config; their existing generated translation bundles keep working at + runtime (object-name keyed). Migrating the i18n extraction/bundles to the + plugin remains the tracked cross-cutting follow-up (best done with the + `os i18n extract` tooling, not hand-edited generated files). + +### Patch Changes + +- 4404572: ADR-0029 D8 — migrate i18n ownership for the moved domains to their plugins. + + The object translations for the domains decomposed in K2.a/K2.b/K2 previously + lived in the `@objectstack/platform-objects` generated bundles even though the + objects now live in their capability plugins. This moves each domain's i18n + extraction + bundles to the owning plugin, preserving every hand-translated + string (zh-CN / ja-JP / es-ES): + + - Each plugin gains a build-time `scripts/i18n-extract.config.ts` and a + `src/translations/` bundle (`{locale}.objects.generated.ts` + an `index.ts` + barrel), generated with `os i18n extract` and self-baselined so re-runs + preserve translations. + - Each plugin loads its bundle at runtime on `kernel:ready` via + `i18n.loadTranslations` (the i18n service is optional — load is best-effort). + - `plugin-webhooks` ← `sys_webhook`, `sys_webhook_delivery` + - `plugin-approvals` ← `sys_approval_request`, `sys_approval_action` + - `plugin-security` ← `sys_role`, `sys_permission_set`, + `sys_user_permission_set`, `sys_role_permission_set` + - `plugin-sharing` ← `sys_record_share`, `sys_sharing_rule`, `sys_share_link` + - `@objectstack/platform-objects` translation bundles are regenerated to drop + those objects' keys (its extract config already excluded them); all other + objects' translations and the metadata-form bundles are preserved. + + Net runtime effect is unchanged (same translations load, now contributed by the + package that owns each object) — closing the D8 follow-up tracked since K2.a. + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [4404572] +- Updated dependencies [eea3f1b] +- Updated dependencies [e478e0c] +- Updated dependencies [4cc2ced] +- Updated dependencies [13632b1] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [c381977] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/platform-objects@7.4.0 + - @objectstack/core@7.4.0 + - @objectstack/formula@7.4.0 + - @objectstack/metadata-core@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/plugins/plugin-approvals/package.json b/packages/plugins/plugin-approvals/package.json index a5db51092..abfe28dd8 100644 --- a/packages/plugins/plugin-approvals/package.json +++ b/packages/plugins/plugin-approvals/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/plugin-approvals", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "Multi-step approval engine for ObjectStack — sys_approval_process + sys_approval_request + sys_approval_action + IApprovalService.", "main": "dist/index.js", diff --git a/packages/plugins/plugin-audit/CHANGELOG.md b/packages/plugins/plugin-audit/CHANGELOG.md index e65767b91..487ada6a0 100644 --- a/packages/plugins/plugin-audit/CHANGELOG.md +++ b/packages/plugins/plugin-audit/CHANGELOG.md @@ -1,5 +1,85 @@ # @objectstack/plugin-audit +## 7.4.0 + +### Minor Changes + +- 13632b1: ADR-0030 P0 (framework) — converge notifications onto a single ingress and the + layered model. Every producer now publishes through + `NotificationService.emit(EmitInput)`; the in-app inbox is a materialization of + delivery, not a row producers write. + + **Single ingress (`@objectstack/service-messaging`) — breaking** + + - `MessagingService.emit` takes the new `EmitInput` contract (`topic` / + `audience` / `payload` / `severity` / `dedupKey` / `source` / `actorId` / + `organizationId` / `channels`) instead of the flat `Notification` shape. It + writes the L2 `sys_notification` event (idempotent on `dedupKey`), resolves the + audience, then fans out; it returns `{ notificationId, deduped, deliveries, +delivered, failed }`. + - New `sys_notification_receipt` object — the read-state spine + (`delivered|read|clicked|dismissed`), keyed `(notification_id, user_id, +channel)`. The inbox channel writes a `delivered` receipt on materialization. + - `sys_inbox_message`: adds `notification_id` / `delivery_id`, **drops `read`** + (read-state moved to the receipt), adds the user `mine` list view. + + **Event re-model (`@objectstack/platform-objects`) — breaking** + + - `sys_notification` is re-modeled from a per-user inbox into the L2 **event** + (`topic`, `payload`, `severity`, `dedup_key`, `source_*`, `actor_id`). Removes + `recipient_id` / `is_read` / `read_at` / `type` / `title` / `body` / `url` / + `actor_name` and the inbox actions/views. App-nav: the account inbox points at + `sys_inbox_message`; Setup shows the notification event log. + + **Producers routed through `emit()`** + + - `@objectstack/service-automation`: the `notify` node maps its config to + `EmitInput`. + - `@objectstack/plugin-audit`: collaboration `@mention` → `collab.mention` and + assignment → `collab.assignment` (both with a `dedupKey`); no more direct + `sys_notification` writes. Collaboration notifications now require + `MessagingServicePlugin` (they degrade to a warn otherwise). + + **Migration (`@objectstack/metadata`)** + + - Idempotent `migrateSysNotificationToEvent` splits legacy `sys_notification` + inbox rows into `sys_inbox_message` + receipts and rewrites the event row. + + **Startup (`@objectstack/cli`, `@objectstack/runtime`)** + + - `messaging` is now a foundational capability. On `objectstack serve` it is + added to `ALWAYS_ON_CAPABILITIES` (every non-`minimal` preset starts it); on + cloud per-project kernels the capability loader expands `requires` to add + `messaging` whenever `audit` is present. This keeps collaboration `@mention` / + assignment notifications (which now flow through the pipeline) working out of + the box on both paths. `--preset minimal` opts out. + + The Console bell repoint (objectui) and phases P1–P3 are tracked in + `docs/handoff/adr-0030-notification-convergence.md`. + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [4404572] +- Updated dependencies [eea3f1b] +- Updated dependencies [e478e0c] +- Updated dependencies [4cc2ced] +- Updated dependencies [13632b1] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [c381977] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/platform-objects@7.4.0 + - @objectstack/core@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/plugins/plugin-audit/package.json b/packages/plugins/plugin-audit/package.json index 4863955de..c746030a4 100644 --- a/packages/plugins/plugin-audit/package.json +++ b/packages/plugins/plugin-audit/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/plugin-audit", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "Audit Plugin for ObjectStack — System audit log object and audit trail", "main": "dist/index.js", diff --git a/packages/plugins/plugin-auth/CHANGELOG.md b/packages/plugins/plugin-auth/CHANGELOG.md index 49cb492f2..1416fcfef 100644 --- a/packages/plugins/plugin-auth/CHANGELOG.md +++ b/packages/plugins/plugin-auth/CHANGELOG.md @@ -1,5 +1,62 @@ # Changelog +## 7.4.0 + +### Minor Changes + +- 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/objectql`** — `SchemaRegistry.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. + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [4404572] +- Updated dependencies [eea3f1b] +- Updated dependencies [e478e0c] +- Updated dependencies [4cc2ced] +- Updated dependencies [13632b1] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [c381977] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/platform-objects@7.4.0 + - @objectstack/core@7.4.0 + - @objectstack/types@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/plugins/plugin-auth/package.json b/packages/plugins/plugin-auth/package.json index d2c024f74..56e4d5c34 100644 --- a/packages/plugins/plugin-auth/package.json +++ b/packages/plugins/plugin-auth/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/plugin-auth", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "Authentication & Identity Plugin for ObjectStack", "main": "dist/index.js", diff --git a/packages/plugins/plugin-dev/CHANGELOG.md b/packages/plugins/plugin-dev/CHANGELOG.md index 8763cc84c..c2ae0ef25 100644 --- a/packages/plugins/plugin-dev/CHANGELOG.md +++ b/packages/plugins/plugin-dev/CHANGELOG.md @@ -1,5 +1,24 @@ # @objectstack/plugin-dev +## 7.4.0 + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/core@7.4.0 + - @objectstack/types@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/plugins/plugin-dev/package.json b/packages/plugins/plugin-dev/package.json index f64120c1b..38a29bad8 100644 --- a/packages/plugins/plugin-dev/package.json +++ b/packages/plugins/plugin-dev/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/plugin-dev", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "Development Mode Plugin for ObjectStack — auto-enables all services with in-memory implementations", "main": "dist/index.js", diff --git a/packages/plugins/plugin-email/CHANGELOG.md b/packages/plugins/plugin-email/CHANGELOG.md index f7778bcd2..3d5751938 100644 --- a/packages/plugins/plugin-email/CHANGELOG.md +++ b/packages/plugins/plugin-email/CHANGELOG.md @@ -1,5 +1,30 @@ # @objectstack/plugin-email +## 7.4.0 + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [4404572] +- Updated dependencies [eea3f1b] +- Updated dependencies [e478e0c] +- Updated dependencies [4cc2ced] +- Updated dependencies [13632b1] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [c381977] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/platform-objects@7.4.0 + - @objectstack/core@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/plugins/plugin-email/package.json b/packages/plugins/plugin-email/package.json index bab050658..052fecb74 100644 --- a/packages/plugins/plugin-email/package.json +++ b/packages/plugins/plugin-email/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/plugin-email", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "Email service plugin for ObjectStack — IEmailService + transport-pluggable outbound delivery with sys_email persistence.", "main": "dist/index.js", diff --git a/packages/plugins/plugin-hono-server/CHANGELOG.md b/packages/plugins/plugin-hono-server/CHANGELOG.md index 606186070..7f204eefd 100644 --- a/packages/plugins/plugin-hono-server/CHANGELOG.md +++ b/packages/plugins/plugin-hono-server/CHANGELOG.md @@ -1,5 +1,24 @@ # @objectstack/plugin-hono-server +## 7.4.0 + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/core@7.4.0 + - @objectstack/types@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/plugins/plugin-hono-server/package.json b/packages/plugins/plugin-hono-server/package.json index e5ddc8560..f60f07083 100644 --- a/packages/plugins/plugin-hono-server/package.json +++ b/packages/plugins/plugin-hono-server/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/plugin-hono-server", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "Standard Hono Server Adapter for ObjectStack Runtime", "main": "dist/index.js", diff --git a/packages/plugins/plugin-mcp-server/CHANGELOG.md b/packages/plugins/plugin-mcp-server/CHANGELOG.md index 8da8e4e0c..0e8b57db4 100644 --- a/packages/plugins/plugin-mcp-server/CHANGELOG.md +++ b/packages/plugins/plugin-mcp-server/CHANGELOG.md @@ -1,5 +1,24 @@ # @objectstack/plugin-mcp-server +## 7.4.0 + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/core@7.4.0 + - @objectstack/types@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/plugins/plugin-mcp-server/package.json b/packages/plugins/plugin-mcp-server/package.json index 665906475..9e16964f5 100644 --- a/packages/plugins/plugin-mcp-server/package.json +++ b/packages/plugins/plugin-mcp-server/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/plugin-mcp-server", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "MCP Runtime Server Plugin for ObjectStack — exposes AI tools, data resources, and agent prompts via the Model Context Protocol", "type": "module", diff --git a/packages/plugins/plugin-msw/CHANGELOG.md b/packages/plugins/plugin-msw/CHANGELOG.md index 30ed41e52..35ff6e020 100644 --- a/packages/plugins/plugin-msw/CHANGELOG.md +++ b/packages/plugins/plugin-msw/CHANGELOG.md @@ -1,5 +1,28 @@ # @objectstack/plugin-msw +## 7.4.0 + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [eea3f1b] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [a6d4cbb] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/objectql@7.4.0 + - @objectstack/core@7.4.0 + - @objectstack/types@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/plugins/plugin-msw/package.json b/packages/plugins/plugin-msw/package.json index 6f3d8948a..aa31de293 100644 --- a/packages/plugins/plugin-msw/package.json +++ b/packages/plugins/plugin-msw/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/plugin-msw", - "version": "7.3.0", + "version": "7.4.0", "description": "MSW (Mock Service Worker) Plugin for ObjectStack Runtime", "license": "Apache-2.0", "main": "dist/index.js", diff --git a/packages/plugins/plugin-org-scoping/CHANGELOG.md b/packages/plugins/plugin-org-scoping/CHANGELOG.md index c893491ad..1f18e5df8 100644 --- a/packages/plugins/plugin-org-scoping/CHANGELOG.md +++ b/packages/plugins/plugin-org-scoping/CHANGELOG.md @@ -1,5 +1,30 @@ # @objectstack/plugin-org-scoping +## 7.4.0 + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [4404572] +- Updated dependencies [eea3f1b] +- Updated dependencies [e478e0c] +- Updated dependencies [4cc2ced] +- Updated dependencies [13632b1] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [c381977] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/platform-objects@7.4.0 + - @objectstack/core@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/plugins/plugin-org-scoping/package.json b/packages/plugins/plugin-org-scoping/package.json index 5628a475d..8a64f7b35 100644 --- a/packages/plugins/plugin-org-scoping/package.json +++ b/packages/plugins/plugin-org-scoping/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/plugin-org-scoping", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "Organization-Scoping Plugin for ObjectStack — row-level Organization isolation, per-org seed replay, default-org bootstrap", "main": "dist/index.js", diff --git a/packages/plugins/plugin-reports/CHANGELOG.md b/packages/plugins/plugin-reports/CHANGELOG.md index 21ebafd07..e8c44e4a6 100644 --- a/packages/plugins/plugin-reports/CHANGELOG.md +++ b/packages/plugins/plugin-reports/CHANGELOG.md @@ -1,5 +1,30 @@ # @objectstack/plugin-reports +## 7.4.0 + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [4404572] +- Updated dependencies [eea3f1b] +- Updated dependencies [e478e0c] +- Updated dependencies [4cc2ced] +- Updated dependencies [13632b1] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [c381977] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/platform-objects@7.4.0 + - @objectstack/core@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/plugins/plugin-reports/package.json b/packages/plugins/plugin-reports/package.json index abbcee5d7..6b521ac0d 100644 --- a/packages/plugins/plugin-reports/package.json +++ b/packages/plugins/plugin-reports/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/plugin-reports", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "Saved reports + scheduled email digests for ObjectStack — sys_saved_report + sys_report_schedule + IReportService.", "main": "dist/index.js", diff --git a/packages/plugins/plugin-security/CHANGELOG.md b/packages/plugins/plugin-security/CHANGELOG.md index ce0c542f4..74c11363f 100644 --- a/packages/plugins/plugin-security/CHANGELOG.md +++ b/packages/plugins/plugin-security/CHANGELOG.md @@ -1,5 +1,113 @@ # @objectstack/plugin-security +## 7.4.0 + +### Minor Changes + +- e478e0c: ADR-0029 K2 — security domain ownership (RBAC + sharing) + Setup nav contributions. + + Moves the security objects out of the `@objectstack/platform-objects` monolith + into the two capability plugins that already register and operate them, split by + concern (the two are orthogonal — sharing objects never reference RBAC objects): + + - **`@objectstack/plugin-security`** (RBAC) gains `sys_role`, + `sys_permission_set`, `sys_user_permission_set`, `sys_role_permission_set`, + and the `defaultPermissionSets` seed (which its `bootstrap-platform-admin` + already consumes). The RBAC + default-permission-set tests move with them. + - **`@objectstack/plugin-sharing`** gains `sys_record_share`, + `sys_sharing_rule`, `sys_share_link`. + - `@objectstack/platform-objects` no longer defines/exports any security + objects; the `/security` subpath is now an empty barrel. Runtime is unchanged + (both plugins already registered these objects at runtime). + + **D7 navigation** — the Setup app's `group_access_control` is now assembled from + three sources: `plugin-security` contributes Roles / Permission Sets (priority + 100), `plugin-sharing` contributes Sharing Rules / Record Shares (priority 200), + and `platform-objects` keeps only API Keys (`sys_api_key`, an identity object, + priority 300) — preserving the original menu order. + + **i18n (D8)** — the objects are removed from the `platform-objects` i18n extract + config; existing generated bundles keep working at runtime (object-name keyed). + Migrating the i18n extraction to the owning plugins remains the tracked + follow-up. + +### Patch Changes + +- 4404572: ADR-0029 D8 — migrate i18n ownership for the moved domains to their plugins. + + The object translations for the domains decomposed in K2.a/K2.b/K2 previously + lived in the `@objectstack/platform-objects` generated bundles even though the + objects now live in their capability plugins. This moves each domain's i18n + extraction + bundles to the owning plugin, preserving every hand-translated + string (zh-CN / ja-JP / es-ES): + + - Each plugin gains a build-time `scripts/i18n-extract.config.ts` and a + `src/translations/` bundle (`{locale}.objects.generated.ts` + an `index.ts` + barrel), generated with `os i18n extract` and self-baselined so re-runs + preserve translations. + - Each plugin loads its bundle at runtime on `kernel:ready` via + `i18n.loadTranslations` (the i18n service is optional — load is best-effort). + - `plugin-webhooks` ← `sys_webhook`, `sys_webhook_delivery` + - `plugin-approvals` ← `sys_approval_request`, `sys_approval_action` + - `plugin-security` ← `sys_role`, `sys_permission_set`, + `sys_user_permission_set`, `sys_role_permission_set` + - `plugin-sharing` ← `sys_record_share`, `sys_sharing_rule`, `sys_share_link` + - `@objectstack/platform-objects` translation bundles are regenerated to drop + those objects' keys (its extract config already excluded them); all other + objects' translations and the metadata-form bundles are preserved. + + Net runtime effect is unchanged (same translations load, now contributed by the + package that owns each object) — closing the D8 follow-up tracked since K2.a. + +- 08fbbb4: Fix: the first-boot platform-admin promotion no longer gets stolen by the + `usr_system` seed identity, and the dev seed admin uses fixed, well-known + credentials. + + **`@objectstack/plugin-security` — `bootstrapPlatformAdmin` skips the system user** + + `5e831dea3` (#1392) added `ensureSeedIdentity` to the runtime SeedLoader, + which upserts a non-loginable system identity (`usr_system`, role `system`, + `system@objectstack.local`) to own seeded records — created _before_ the first + human sign-up. Because `bootstrapPlatformAdmin` promoted the **earliest-created** + `sys_user`, on any app that ships seed data `usr_system` won the promotion and + the real admin login stayed at `role: user`. Login succeeded but Setup and + Studio (gated by `setup.access` / `studio.access` on `admin_full_access`) were + invisible — a silent, confusing regression. + + `bootstrap-platform-admin.ts` now filters out the system account + (`id === SystemUserId.SYSTEM || role === 'system'`) when picking the first user + to promote, and the "an admin already exists" short-circuit ignores any + `admin_full_access` grant held by `usr_system` — so a database where it was + wrongly promoted self-heals on the next boot. + + **`@objectstack/cli` — `os dev` seeds `admin@objectos.ai` / `admin123`** + + The `--admin-email` / `--admin-password` defaults changed from + `admin@dev.local` / `admin12345` to the fixed, well-known + `admin@objectos.ai` / `admin123`, so tooling and docs never have to guess the + seeded credentials. Override with `--admin-email` / `--admin-password`. + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [4404572] +- Updated dependencies [eea3f1b] +- Updated dependencies [e478e0c] +- Updated dependencies [4cc2ced] +- Updated dependencies [13632b1] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [c381977] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/platform-objects@7.4.0 + - @objectstack/core@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/plugins/plugin-security/package.json b/packages/plugins/plugin-security/package.json index 64950ce1a..313ce495f 100644 --- a/packages/plugins/plugin-security/package.json +++ b/packages/plugins/plugin-security/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/plugin-security", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "Security Plugin for ObjectStack — RBAC, RLS, and Field-Level Security Runtime", "main": "dist/index.js", diff --git a/packages/plugins/plugin-sharing/CHANGELOG.md b/packages/plugins/plugin-sharing/CHANGELOG.md index b050b6b7e..c0081db5b 100644 --- a/packages/plugins/plugin-sharing/CHANGELOG.md +++ b/packages/plugins/plugin-sharing/CHANGELOG.md @@ -1,5 +1,88 @@ # @objectstack/plugin-sharing +## 7.4.0 + +### Minor Changes + +- e478e0c: ADR-0029 K2 — security domain ownership (RBAC + sharing) + Setup nav contributions. + + Moves the security objects out of the `@objectstack/platform-objects` monolith + into the two capability plugins that already register and operate them, split by + concern (the two are orthogonal — sharing objects never reference RBAC objects): + + - **`@objectstack/plugin-security`** (RBAC) gains `sys_role`, + `sys_permission_set`, `sys_user_permission_set`, `sys_role_permission_set`, + and the `defaultPermissionSets` seed (which its `bootstrap-platform-admin` + already consumes). The RBAC + default-permission-set tests move with them. + - **`@objectstack/plugin-sharing`** gains `sys_record_share`, + `sys_sharing_rule`, `sys_share_link`. + - `@objectstack/platform-objects` no longer defines/exports any security + objects; the `/security` subpath is now an empty barrel. Runtime is unchanged + (both plugins already registered these objects at runtime). + + **D7 navigation** — the Setup app's `group_access_control` is now assembled from + three sources: `plugin-security` contributes Roles / Permission Sets (priority + 100), `plugin-sharing` contributes Sharing Rules / Record Shares (priority 200), + and `platform-objects` keeps only API Keys (`sys_api_key`, an identity object, + priority 300) — preserving the original menu order. + + **i18n (D8)** — the objects are removed from the `platform-objects` i18n extract + config; existing generated bundles keep working at runtime (object-name keyed). + Migrating the i18n extraction to the owning plugins remains the tracked + follow-up. + +### Patch Changes + +- 4404572: ADR-0029 D8 — migrate i18n ownership for the moved domains to their plugins. + + The object translations for the domains decomposed in K2.a/K2.b/K2 previously + lived in the `@objectstack/platform-objects` generated bundles even though the + objects now live in their capability plugins. This moves each domain's i18n + extraction + bundles to the owning plugin, preserving every hand-translated + string (zh-CN / ja-JP / es-ES): + + - Each plugin gains a build-time `scripts/i18n-extract.config.ts` and a + `src/translations/` bundle (`{locale}.objects.generated.ts` + an `index.ts` + barrel), generated with `os i18n extract` and self-baselined so re-runs + preserve translations. + - Each plugin loads its bundle at runtime on `kernel:ready` via + `i18n.loadTranslations` (the i18n service is optional — load is best-effort). + - `plugin-webhooks` ← `sys_webhook`, `sys_webhook_delivery` + - `plugin-approvals` ← `sys_approval_request`, `sys_approval_action` + - `plugin-security` ← `sys_role`, `sys_permission_set`, + `sys_user_permission_set`, `sys_role_permission_set` + - `plugin-sharing` ← `sys_record_share`, `sys_sharing_rule`, `sys_share_link` + - `@objectstack/platform-objects` translation bundles are regenerated to drop + those objects' keys (its extract config already excluded them); all other + objects' translations and the metadata-form bundles are preserved. + + Net runtime effect is unchanged (same translations load, now contributed by the + package that owns each object) — closing the D8 follow-up tracked since K2.a. + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [4404572] +- Updated dependencies [eea3f1b] +- Updated dependencies [e478e0c] +- Updated dependencies [4cc2ced] +- Updated dependencies [13632b1] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [a6d4cbb] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [c381977] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/objectql@7.4.0 + - @objectstack/platform-objects@7.4.0 + - @objectstack/core@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/plugins/plugin-sharing/package.json b/packages/plugins/plugin-sharing/package.json index ddaf94003..7953bd187 100644 --- a/packages/plugins/plugin-sharing/package.json +++ b/packages/plugins/plugin-sharing/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/plugin-sharing", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "Record-level sharing for ObjectStack — sys_record_share + middleware that enforces sharingModel + ISharingService.", "main": "dist/index.js", diff --git a/packages/plugins/plugin-trigger-record-change/CHANGELOG.md b/packages/plugins/plugin-trigger-record-change/CHANGELOG.md new file mode 100644 index 000000000..b83da1071 --- /dev/null +++ b/packages/plugins/plugin-trigger-record-change/CHANGELOG.md @@ -0,0 +1,61 @@ +# @objectstack/plugin-trigger-record-change + +## 7.4.0 + +### Minor Changes + +- 13d8653: Record-change flow trigger — auto-launch flows on data mutations. + + Completes the automation engine's `FlowTrigger` extension point so flows whose + `start` node declares a record-change trigger (`config: { objectName, +triggerType: 'record-after-update', condition }`) actually fire on the matching + mutation. Previously the slot was dead — nothing called `trigger.start` — so + such flows could only run via a manual `engine.execute()`. + + **Engine baseline (`@objectstack/service-automation`)** + + - Redefines `FlowTrigger` around a parsed `FlowTriggerBinding` (flowName, + object, event, condition, schedule, raw config). The engine parses the start + node and hands the trigger a normalized binding, keeping trigger plugins + decoupled from flow-definition internals (mirrors `connector_action` ↔ + `connector-rest`). + - Ordering-independent, bidirectional wiring: `registerFlow`/`toggleFlow` + activate bindings; `registerTrigger` retro-binds already-registered flows (a + trigger plugin wires up on `kernel:ready`, after flows are pulled in); + `unregisterFlow`/`unregisterTrigger`/disable tear them down. + - Centralized start-condition gate in `execute()`: the start node's `condition` + (e.g. `status == 'done' && previous.status != 'done'`) is evaluated once for + every trigger type and manual runs; false ⇒ `{ skipped: true }`. + - Seeds `record`, flattened record fields, and `previous` into flow variables. + - New `getActiveTriggerBindings()` getter + exports `FlowTriggerBinding`. + + **Spec (`@objectstack/spec`)** + + - Adds `previous?` to `AutomationContext` — the pre-update "old" row, so flows + can gate on transitions. + + **New package (`@objectstack/plugin-trigger-record-change`)** + + - The concrete trigger: subscribes to ObjectQL lifecycle hooks + (`record-after-update` → `afterUpdate`, etc.), builds an `AutomationContext` + from the new/old record, and runs the flow. Error-isolated (a flow failure + never breaks the CRUD write); graceful degrade when the automation service or + ObjectQL engine is absent (mirrors `plugin-audit`). + + The `schedule` trigger (ticker/cron + `sys_job` lifecycle) is a follow-up. + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/core@7.4.0 diff --git a/packages/plugins/plugin-trigger-record-change/package.json b/packages/plugins/plugin-trigger-record-change/package.json index 0167007ed..4a8effdf7 100644 --- a/packages/plugins/plugin-trigger-record-change/package.json +++ b/packages/plugins/plugin-trigger-record-change/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/plugin-trigger-record-change", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "Record-change flow trigger for ObjectStack — auto-launches flows on object insert/update/delete via ObjectQL lifecycle hooks (ADR-0018)", "main": "dist/index.js", diff --git a/packages/plugins/plugin-trigger-schedule/CHANGELOG.md b/packages/plugins/plugin-trigger-schedule/CHANGELOG.md new file mode 100644 index 000000000..86464648f --- /dev/null +++ b/packages/plugins/plugin-trigger-schedule/CHANGELOG.md @@ -0,0 +1,46 @@ +# @objectstack/plugin-trigger-schedule + +## 7.4.0 + +### Minor Changes + +- 03fd7f0: Schedule flow trigger — auto-launch flows on a cron/interval/once schedule. + + The sibling of `@objectstack/plugin-trigger-record-change`: it completes the + _time-based_ arm of the automation engine's `FlowTrigger` extension point. The + engine already parses a flow's start node into a `schedule` binding + (`flow.type === 'schedule'` or a start-node `config.schedule` descriptor); this + plugin registers the concrete `schedule` trigger and delegates timing to the + platform `IJobService` (the `'job'` service), so it stays adapter-agnostic — the + job service selects a cron-capable adapter (durable `DbJobAdapter` / + `CronJobAdapter`) for cron schedules and the interval adapter otherwise. + + - `normalizeSchedule` accepts the canonical `JobSchedule` plus shorthands (a + bare cron string, `{ cron }` / `{ expression }`, `{ every }` / `{ intervalMs }`, + `{ at }`). + - When a job fires, the flow runs with `event: 'schedule'` and + `params: { jobId, flowName, schedule }`; the engine's start-condition gate + still applies. + - Error-isolated (a flow failure never crashes the job runner); per-flow job + name so `stop()` cancels exactly one flow; the job service is resolved lazily + per bind so adapter upgrades are picked up; graceful degrade when the + automation or job service is absent. + + No engine change required — the `schedule` binding shipped with the + record-change trigger PR. + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/core@7.4.0 diff --git a/packages/plugins/plugin-trigger-schedule/package.json b/packages/plugins/plugin-trigger-schedule/package.json index 73893ccee..f38567011 100644 --- a/packages/plugins/plugin-trigger-schedule/package.json +++ b/packages/plugins/plugin-trigger-schedule/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/plugin-trigger-schedule", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "Schedule flow trigger for ObjectStack — auto-launches flows on a cron/interval/once schedule via the IJobService (ADR-0018)", "main": "dist/index.js", diff --git a/packages/plugins/plugin-webhooks/CHANGELOG.md b/packages/plugins/plugin-webhooks/CHANGELOG.md index 9d1baaf0e..bae8fe9b4 100644 --- a/packages/plugins/plugin-webhooks/CHANGELOG.md +++ b/packages/plugins/plugin-webhooks/CHANGELOG.md @@ -1,5 +1,110 @@ # @objectstack/plugin-webhooks +## 7.4.0 + +### Minor Changes + +- 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/objectql`** — `SchemaRegistry.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. + +- eea3f1b: ADR-0029 K0 + K2.a — single-owner invariant and webhooks ownership pilot. + + **K0 (`@objectstack/objectql`)** — add `SchemaRegistry.assertSingleOwnerPerObject()`, + the install-time backstop for the kernel-decomposition invariant: every + registered object must resolve to exactly one `own` contributor. A second + cross-package owner is already rejected at registration time; this additionally + catches "extend with no owner" (which would otherwise resolve to nothing). Call + after kernel bootstrap completes. + + **K2.a (`@objectstack/plugin-webhooks` ← `@objectstack/platform-objects`)** — move + the `sys_webhook` object definition out of the `platform-objects` monolith into + `@objectstack/plugin-webhooks`, where it joins its sibling `sys_webhook_delivery` + so the plugin owns both its data model and behavior as one unit. `sys_webhook` is + no longer exported from `@objectstack/platform-objects` (or its `/integration` + subpath, now an empty barrel); import it from `@objectstack/plugin-webhooks/schema` + instead. Runtime behavior is unchanged — the webhook plugin already registered + `sys_webhook` at runtime; only the definition's home moved. Setup-app navigation + (which references `sys_webhook` by name) and existing i18n bundles (object-name + keyed) continue to work. Per ADR-0029 D8, migrating the object's i18n extraction + into the plugin is a tracked follow-up before the next translation regeneration. + +### Patch Changes + +- 4404572: ADR-0029 D8 — migrate i18n ownership for the moved domains to their plugins. + + The object translations for the domains decomposed in K2.a/K2.b/K2 previously + lived in the `@objectstack/platform-objects` generated bundles even though the + objects now live in their capability plugins. This moves each domain's i18n + extraction + bundles to the owning plugin, preserving every hand-translated + string (zh-CN / ja-JP / es-ES): + + - Each plugin gains a build-time `scripts/i18n-extract.config.ts` and a + `src/translations/` bundle (`{locale}.objects.generated.ts` + an `index.ts` + barrel), generated with `os i18n extract` and self-baselined so re-runs + preserve translations. + - Each plugin loads its bundle at runtime on `kernel:ready` via + `i18n.loadTranslations` (the i18n service is optional — load is best-effort). + - `plugin-webhooks` ← `sys_webhook`, `sys_webhook_delivery` + - `plugin-approvals` ← `sys_approval_request`, `sys_approval_action` + - `plugin-security` ← `sys_role`, `sys_permission_set`, + `sys_user_permission_set`, `sys_role_permission_set` + - `plugin-sharing` ← `sys_record_share`, `sys_sharing_rule`, `sys_share_link` + - `@objectstack/platform-objects` translation bundles are regenerated to drop + those objects' keys (its extract config already excluded them); all other + objects' translations and the metadata-form bundles are preserved. + + Net runtime effect is unchanged (same translations load, now contributed by the + package that owns each object) — closing the D8 follow-up tracked since K2.a. + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [4404572] +- Updated dependencies [eea3f1b] +- Updated dependencies [e478e0c] +- Updated dependencies [4cc2ced] +- Updated dependencies [13632b1] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [c381977] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/platform-objects@7.4.0 + - @objectstack/core@7.4.0 + - @objectstack/service-cluster@7.4.0 + - @objectstack/types@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/plugins/plugin-webhooks/package.json b/packages/plugins/plugin-webhooks/package.json index 56c67ac73..d813e6601 100644 --- a/packages/plugins/plugin-webhooks/package.json +++ b/packages/plugins/plugin-webhooks/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/plugin-webhooks", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "Persistent, cluster-aware webhook dispatcher. Durable outbox + per-partition cluster.lock for exactly-once-ish delivery across nodes. See content/docs/concepts/webhook-delivery.mdx.", "type": "module", diff --git a/packages/rest/CHANGELOG.md b/packages/rest/CHANGELOG.md index 3b1df4212..ca530b6b9 100644 --- a/packages/rest/CHANGELOG.md +++ b/packages/rest/CHANGELOG.md @@ -1,5 +1,70 @@ # @objectstack/rest +## 7.4.0 + +### Minor Changes + +- 2faf9f2: External Datasource Federation (ADR-0015) — REST surface. + + Adds `registerExternalDatasourceRoutes`, mounting `/api/v1/datasources/:name/ +external/*` — `GET tables`, `POST tables/:remote/draft`, `POST refresh-catalog`, + `POST validate` — served by the `external-datasource` service and wired into the + REST API plugin. Routes return `503 external_service_unavailable` when the + service is not registered, so they are safe to mount unconditionally. + +### Patch Changes + +- 58b450b: Make metadata labels follow the active UI language without a page refresh (#1319). + + The client now carries the active locale on every request (`Accept-Language`, + `setLocale`/`getLocale`), the protocol ETag is locale-aware so cached metadata + no longer collides across languages, and the `client-react` metadata hooks + refetch when the locale changes. The `apps/account` console wires its router + locale through so a language switch relabels server-resolved object/field/view + labels in place instead of leaving the UI half-translated until reload. + +- 82eb6cf: Fix system-metadata translations: locale fallback, app/dashboard localization, and coverage gaps. + + Switching the UI language left many surfaces in English. Three root causes + are addressed: + + - **Locale fallback (server).** The metadata translation resolver + (`@objectstack/spec` `i18n-resolver`) now resolves a requested locale + against the locales actually present in the bundle (exact → + case-insensitive → base-language → variant), so a request for `zh` + correctly hits the `zh-CN` bundle instead of falling back to English. + This mirrors `resolveLocale` in `@objectstack/core` and benefits every + resolver (objects, views, actions, settings, metadata forms). + + - **App & dashboard localization (server).** Added `translateApp` and + `translateDashboard` resolvers and wired `app`/`dashboard` into the REST + `/meta` translation path. App labels, sidebar/navigation group labels, + and dashboard titles/widgets were previously never localized at the API + boundary even though the translation data existed. + + - **Coverage & quality (data).** Added translations for the previously + untranslated platform objects `sys_share_link`, `sys_view_definition`, + and `sys_metadata_audit` (and registered them in the i18n-extract config + so future extractions keep them). Replaced English placeholder strings + left in the `zh-CN` / `ja-JP` / `es-ES` object and metadata-form bundles + (notably action `confirmText` / `successMessage` prompts). Added the + missing `es-ES` built-in Settings bundle in `@objectstack/service-settings`. + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/core@7.4.0 + - @objectstack/service-package@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/rest/package.json b/packages/rest/package.json index 217f7a10f..179668742 100644 --- a/packages/rest/package.json +++ b/packages/rest/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/rest", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "ObjectStack REST API Server - automatic REST endpoint generation from protocol", "type": "module", diff --git a/packages/runtime/CHANGELOG.md b/packages/runtime/CHANGELOG.md index e8bb0adc8..05601ffd8 100644 --- a/packages/runtime/CHANGELOG.md +++ b/packages/runtime/CHANGELOG.md @@ -1,5 +1,221 @@ # @objectstack/runtime +## 7.4.0 + +### Minor Changes + +- 2faf9f2: External Datasource Federation (ADR-0015) — boot-validation gate (Gate 2). + + Adds `ExternalValidationPlugin` (`createExternalValidationPlugin`) which, on + `kernel:ready`, validates every federated object against its remote table via + the `external-datasource` service and applies the datasource's + `external.validation.onMismatch` policy: `fail` (throws + `ExternalSchemaMismatchError`, aborting boot — the default), `warn` (logs the + diff), or `ignore`. No-op when federation is unused. + +- 394d34f: Messaging + triggers capability tokens, and notify-by-email recipient resolution. + + Make the `notify` flow node and auto-firing flows usable from a plain + `defineStack({ requires: [...] })` — no hand-wired plugin instances. + + - **CLI / runtime — new capability tokens.** `messaging` → + `MessagingServicePlugin` (the `notify` node delivers to the inbox channel + instead of degrading to a logged no-op); `triggers` → + `RecordChangeTriggerPlugin` + `ScheduleTriggerPlugin` (autolaunched / schedule + flows actually fire — pair `triggers` with `job` for cron/interval). Wired + identically in the CLI `CAPABILITY_PROVIDERS` table and the runtime + `capability-loader`. + - **Inbox channel — notify-by-email.** Flows commonly address recipients by + email (e.g. `{record.assignee}`), but `sys_inbox_message` is keyed by user id. + The inbox channel now resolves an email-shaped recipient to its `sys_user.id` + (configurable via `InboxChannelOptions.userObject`), with a verbatim fallback + when the recipient is not email-shaped, no user matches, or the lookup fails — + so a failed resolution can never drop the row. + +- 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 `FlowSuspendSignal` → `SuspendedRun` → 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 objectui `FlowRunner` UI that renders these screens ships separately. + +- 5e831de: Seed data: first-class identity binding + loud failures (fixes #1389) + + Records seeded via `defineDataset` / `defineStack({ data })` can now bind to a + platform user with `cel\`os.user.id\``(and to the org with`cel\`os.org.id\``), + which previously never resolved at boot. + + - **`os.user` / `os.org` now actually resolve.** The runtime provisions a + deterministic, non-loginable system user (`usr_system`, role `system`) + _before_ any seed runs and binds it to `os.user`, so identity-derived seed + values resolve even on a fresh boot — before the first human sign-up. The + human login admin remains a separate better-auth identity and need not own + seed data. Exposed as the canonical `SystemUserId.SYSTEM` constant. + - **New `SeedLoaderConfig.identity`** carries the `os.user` / `os.org` subject + into CEL evaluation (`@objectstack/spec`). + - **Failures are loud, not silent.** A record whose CEL value can't resolve + (e.g. a required `cel\`os.user.id\`` with no identity) — or that fails to + write — is now counted as an error, marks the load unsuccessful, and logs an + actionable message, instead of being silently dropped. + +### Patch 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. + +- 13632b1: ADR-0030 P0 (framework) — converge notifications onto a single ingress and the + layered model. Every producer now publishes through + `NotificationService.emit(EmitInput)`; the in-app inbox is a materialization of + delivery, not a row producers write. + + **Single ingress (`@objectstack/service-messaging`) — breaking** + + - `MessagingService.emit` takes the new `EmitInput` contract (`topic` / + `audience` / `payload` / `severity` / `dedupKey` / `source` / `actorId` / + `organizationId` / `channels`) instead of the flat `Notification` shape. It + writes the L2 `sys_notification` event (idempotent on `dedupKey`), resolves the + audience, then fans out; it returns `{ notificationId, deduped, deliveries, +delivered, failed }`. + - New `sys_notification_receipt` object — the read-state spine + (`delivered|read|clicked|dismissed`), keyed `(notification_id, user_id, +channel)`. The inbox channel writes a `delivered` receipt on materialization. + - `sys_inbox_message`: adds `notification_id` / `delivery_id`, **drops `read`** + (read-state moved to the receipt), adds the user `mine` list view. + + **Event re-model (`@objectstack/platform-objects`) — breaking** + + - `sys_notification` is re-modeled from a per-user inbox into the L2 **event** + (`topic`, `payload`, `severity`, `dedup_key`, `source_*`, `actor_id`). Removes + `recipient_id` / `is_read` / `read_at` / `type` / `title` / `body` / `url` / + `actor_name` and the inbox actions/views. App-nav: the account inbox points at + `sys_inbox_message`; Setup shows the notification event log. + + **Producers routed through `emit()`** + + - `@objectstack/service-automation`: the `notify` node maps its config to + `EmitInput`. + - `@objectstack/plugin-audit`: collaboration `@mention` → `collab.mention` and + assignment → `collab.assignment` (both with a `dedupKey`); no more direct + `sys_notification` writes. Collaboration notifications now require + `MessagingServicePlugin` (they degrade to a warn otherwise). + + **Migration (`@objectstack/metadata`)** + + - Idempotent `migrateSysNotificationToEvent` splits legacy `sys_notification` + inbox rows into `sys_inbox_message` + receipts and rewrites the event row. + + **Startup (`@objectstack/cli`, `@objectstack/runtime`)** + + - `messaging` is now a foundational capability. On `objectstack serve` it is + added to `ALWAYS_ON_CAPABILITIES` (every non-`minimal` preset starts it); on + cloud per-project kernels the capability loader expands `requires` to add + `messaging` whenever `audit` is present. This keeps collaboration `@mention` / + assignment notifications (which now flow through the pipeline) working out of + the box on both paths. `--preset minimal` opts out. + + The Console bell repoint (objectui) and phases P1–P3 are tracked in + `docs/handoff/adr-0030-notification-convergence.md`. + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [4404572] +- Updated dependencies [eea3f1b] +- Updated dependencies [e478e0c] +- Updated dependencies [13632b1] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [a6d4cbb] +- Updated dependencies [08fbbb4] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/objectql@7.4.0 + - @objectstack/plugin-auth@7.4.0 + - @objectstack/plugin-security@7.4.0 + - @objectstack/metadata@7.4.0 + - @objectstack/driver-sql@7.4.0 + - @objectstack/rest@7.4.0 + - @objectstack/core@7.4.0 + - @objectstack/formula@7.4.0 + - @objectstack/observability@7.4.0 + - @objectstack/driver-memory@7.4.0 + - @objectstack/driver-sqlite-wasm@7.4.0 + - @objectstack/plugin-org-scoping@7.4.0 + - @objectstack/service-cluster@7.4.0 + - @objectstack/service-i18n@7.4.0 + - @objectstack/types@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/runtime/package.json b/packages/runtime/package.json index 76b2d60e7..3705beb6b 100644 --- a/packages/runtime/package.json +++ b/packages/runtime/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/runtime", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "ObjectStack Core Runtime & Query Engine", "type": "module", diff --git a/packages/services/service-ai/CHANGELOG.md b/packages/services/service-ai/CHANGELOG.md index c4b8caaf1..7078d5530 100644 --- a/packages/services/service-ai/CHANGELOG.md +++ b/packages/services/service-ai/CHANGELOG.md @@ -1,5 +1,36 @@ # @objectstack/service-ai +## 7.4.0 + +### Minor Changes + +- 2faf9f2: External Datasource Federation (ADR-0015) — Phase 4: AI awareness. + + `SchemaRetriever.renderSnippet` now annotates federated objects in the + auto-injected schema context, e.g. + `### wh_order — Warehouse Order [external, read-only, datasource=warehouse]`, + so the LLM knows an object comes from a customer's production database and must + not propose schema changes or unsafe writes. `ObjectShape` gains `datasource` + + - `external` (read from object metadata). Managed objects are unannotated. + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/core@7.4.0 + - @objectstack/types@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/services/service-ai/package.json b/packages/services/service-ai/package.json index c40f3ef36..b611ddd85 100644 --- a/packages/services/service-ai/package.json +++ b/packages/services/service-ai/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/service-ai", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "AI Service for ObjectStack — implements IAIService with LLM adapter layer, conversation management, tool registry, and REST/SSE routes", "type": "module", diff --git a/packages/services/service-analytics/CHANGELOG.md b/packages/services/service-analytics/CHANGELOG.md index 2e1b0bb83..9188797f8 100644 --- a/packages/services/service-analytics/CHANGELOG.md +++ b/packages/services/service-analytics/CHANGELOG.md @@ -1,5 +1,23 @@ # Changelog — @objectstack/service-analytics +## 7.4.0 + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/core@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/services/service-analytics/package.json b/packages/services/service-analytics/package.json index 84a7f266e..e3e052291 100644 --- a/packages/services/service-analytics/package.json +++ b/packages/services/service-analytics/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/service-analytics", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "Analytics Service for ObjectStack — implements IAnalyticsService with multi-driver strategy pattern (NativeSQL, ObjectQL, InMemory)", "type": "module", diff --git a/packages/services/service-automation/CHANGELOG.md b/packages/services/service-automation/CHANGELOG.md index d084a155e..0c2f1a202 100644 --- a/packages/services/service-automation/CHANGELOG.md +++ b/packages/services/service-automation/CHANGELOG.md @@ -1,5 +1,165 @@ # @objectstack/service-automation +## 7.4.0 + +### Minor Changes + +- 13632b1: ADR-0030 P0 (framework) — converge notifications onto a single ingress and the + layered model. Every producer now publishes through + `NotificationService.emit(EmitInput)`; the in-app inbox is a materialization of + delivery, not a row producers write. + + **Single ingress (`@objectstack/service-messaging`) — breaking** + + - `MessagingService.emit` takes the new `EmitInput` contract (`topic` / + `audience` / `payload` / `severity` / `dedupKey` / `source` / `actorId` / + `organizationId` / `channels`) instead of the flat `Notification` shape. It + writes the L2 `sys_notification` event (idempotent on `dedupKey`), resolves the + audience, then fans out; it returns `{ notificationId, deduped, deliveries, +delivered, failed }`. + - New `sys_notification_receipt` object — the read-state spine + (`delivered|read|clicked|dismissed`), keyed `(notification_id, user_id, +channel)`. The inbox channel writes a `delivered` receipt on materialization. + - `sys_inbox_message`: adds `notification_id` / `delivery_id`, **drops `read`** + (read-state moved to the receipt), adds the user `mine` list view. + + **Event re-model (`@objectstack/platform-objects`) — breaking** + + - `sys_notification` is re-modeled from a per-user inbox into the L2 **event** + (`topic`, `payload`, `severity`, `dedup_key`, `source_*`, `actor_id`). Removes + `recipient_id` / `is_read` / `read_at` / `type` / `title` / `body` / `url` / + `actor_name` and the inbox actions/views. App-nav: the account inbox points at + `sys_inbox_message`; Setup shows the notification event log. + + **Producers routed through `emit()`** + + - `@objectstack/service-automation`: the `notify` node maps its config to + `EmitInput`. + - `@objectstack/plugin-audit`: collaboration `@mention` → `collab.mention` and + assignment → `collab.assignment` (both with a `dedupKey`); no more direct + `sys_notification` writes. Collaboration notifications now require + `MessagingServicePlugin` (they degrade to a warn otherwise). + + **Migration (`@objectstack/metadata`)** + + - Idempotent `migrateSysNotificationToEvent` splits legacy `sys_notification` + inbox rows into `sys_inbox_message` + receipts and rewrites the event row. + + **Startup (`@objectstack/cli`, `@objectstack/runtime`)** + + - `messaging` is now a foundational capability. On `objectstack serve` it is + added to `ALWAYS_ON_CAPABILITIES` (every non-`minimal` preset starts it); on + cloud per-project kernels the capability loader expands `requires` to add + `messaging` whenever `audit` is present. This keeps collaboration `@mention` / + assignment notifications (which now flow through the pipeline) working out of + the box on both paths. `--preset minimal` opts out. + + The Console bell repoint (objectui) and phases P1–P3 are tracked in + `docs/handoff/adr-0030-notification-convergence.md`. + +- 13d8653: Record-change flow trigger — auto-launch flows on data mutations. + + Completes the automation engine's `FlowTrigger` extension point so flows whose + `start` node declares a record-change trigger (`config: { objectName, +triggerType: 'record-after-update', condition }`) actually fire on the matching + mutation. Previously the slot was dead — nothing called `trigger.start` — so + such flows could only run via a manual `engine.execute()`. + + **Engine baseline (`@objectstack/service-automation`)** + + - Redefines `FlowTrigger` around a parsed `FlowTriggerBinding` (flowName, + object, event, condition, schedule, raw config). The engine parses the start + node and hands the trigger a normalized binding, keeping trigger plugins + decoupled from flow-definition internals (mirrors `connector_action` ↔ + `connector-rest`). + - Ordering-independent, bidirectional wiring: `registerFlow`/`toggleFlow` + activate bindings; `registerTrigger` retro-binds already-registered flows (a + trigger plugin wires up on `kernel:ready`, after flows are pulled in); + `unregisterFlow`/`unregisterTrigger`/disable tear them down. + - Centralized start-condition gate in `execute()`: the start node's `condition` + (e.g. `status == 'done' && previous.status != 'done'`) is evaluated once for + every trigger type and manual runs; false ⇒ `{ skipped: true }`. + - Seeds `record`, flattened record fields, and `previous` into flow variables. + - New `getActiveTriggerBindings()` getter + exports `FlowTriggerBinding`. + + **Spec (`@objectstack/spec`)** + + - Adds `previous?` to `AutomationContext` — the pre-update "old" row, so flows + can gate on transitions. + + **New package (`@objectstack/plugin-trigger-record-change`)** + + - The concrete trigger: subscribes to ObjectQL lifecycle hooks + (`record-after-update` → `afterUpdate`, etc.), builds an `AutomationContext` + from the new/old record, and runs the flow. Error-isolated (a flow failure + never breaks the CRUD write); graceful degrade when the automation service or + ObjectQL engine is absent (mirrors `plugin-audit`). + + The `schedule` trigger (ticker/cron + `sys_job` lifecycle) is a follow-up. + +- 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 `FlowSuspendSignal` → `SuspendedRun` → 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 objectui `FlowRunner` UI that renders these screens ships separately. + +### Patch Changes + +- a6d4cbb: Fix conditional & record-change flows silently skipping. + + Two bugs together caused every flow with a start-node / edge **condition** to + silently skip (record-change triggers fired but the flow body never ran; + audit-style `previous.*` gates and `budget > 100000`-style gates all evaluated + to false): + + - **service-automation — CEL engine unreachable in ESM.** The condition + evaluator loaded the formula engine via a CommonJS `require('@objectstack/formula')`. + In the package's ESM build (`"type": "module"`) that resolves to tsup's + throwing `__require` stub, so **every** CEL evaluation threw and the + swallowing `catch` returned `false`. Replaced with a static top-level import, + which binds correctly in both the ESM and CJS builds. + + - **objectql — prior record not exposed to update hooks.** `HookContext` + documents a `previous` snapshot for update/delete, but `engine.update` never + populated it (the row it fetched for validation was a local var). Record-change + conditions like `status == "done" && previous.status != "done"` therefore had + no `previous` to read. The engine now attaches the pre-update record to + `hookContext.previous` for single-id updates whenever a validation rule needs + it or an `afterUpdate` hook is registered. + + Both paths are covered by new unit tests. + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/core@7.4.0 + - @objectstack/formula@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/services/service-automation/package.json b/packages/services/service-automation/package.json index 148c67ed0..195743615 100644 --- a/packages/services/service-automation/package.json +++ b/packages/services/service-automation/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/service-automation", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "Automation Service for ObjectStack — implements IAutomationService with plugin-based DAG flow execution engine", "type": "module", diff --git a/packages/services/service-cache/CHANGELOG.md b/packages/services/service-cache/CHANGELOG.md index 99762e60a..a0c6be265 100644 --- a/packages/services/service-cache/CHANGELOG.md +++ b/packages/services/service-cache/CHANGELOG.md @@ -1,5 +1,24 @@ # @objectstack/service-cache +## 7.4.0 + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/core@7.4.0 + - @objectstack/observability@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/services/service-cache/package.json b/packages/services/service-cache/package.json index d5321faca..8b76ea86b 100644 --- a/packages/services/service-cache/package.json +++ b/packages/services/service-cache/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/service-cache", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "Cache Service for ObjectStack — implements ICacheService with in-memory and Redis adapters", "type": "module", diff --git a/packages/services/service-cluster-redis/CHANGELOG.md b/packages/services/service-cluster-redis/CHANGELOG.md index 964f08f26..c53833d0d 100644 --- a/packages/services/service-cluster-redis/CHANGELOG.md +++ b/packages/services/service-cluster-redis/CHANGELOG.md @@ -1,5 +1,23 @@ # @objectstack/service-cluster-redis +## 7.4.0 + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/service-cluster@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/services/service-cluster-redis/package.json b/packages/services/service-cluster-redis/package.json index 5b97663f8..d304bb18e 100644 --- a/packages/services/service-cluster-redis/package.json +++ b/packages/services/service-cluster-redis/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/service-cluster-redis", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "Redis cluster driver for ObjectStack — implements IPubSub/ILock/IKV/ICounter against Redis using ioredis.", "type": "module", diff --git a/packages/services/service-cluster/CHANGELOG.md b/packages/services/service-cluster/CHANGELOG.md index ea87886a3..83011c8e9 100644 --- a/packages/services/service-cluster/CHANGELOG.md +++ b/packages/services/service-cluster/CHANGELOG.md @@ -1,5 +1,23 @@ # @objectstack/service-cluster +## 7.4.0 + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/core@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/services/service-cluster/package.json b/packages/services/service-cluster/package.json index 258372111..a3755a4cd 100644 --- a/packages/services/service-cluster/package.json +++ b/packages/services/service-cluster/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/service-cluster", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "Cluster Service for ObjectStack — pluggable PubSub/Lock/KV/Counter primitives. Memory driver included; postgres/redis drivers ship separately.", "type": "module", diff --git a/packages/services/service-external-datasource/CHANGELOG.md b/packages/services/service-external-datasource/CHANGELOG.md new file mode 100644 index 000000000..bea98c043 --- /dev/null +++ b/packages/services/service-external-datasource/CHANGELOG.md @@ -0,0 +1,44 @@ +# @objectstack/service-external-datasource + +## 7.4.0 + +### Minor Changes + +- 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.ts` — `IExternalDatasourceService` + 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. + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/core@7.4.0 diff --git a/packages/services/service-external-datasource/package.json b/packages/services/service-external-datasource/package.json index cd75d69cb..4dfc94b2d 100644 --- a/packages/services/service-external-datasource/package.json +++ b/packages/services/service-external-datasource/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/service-external-datasource", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "External Datasource Federation service for ObjectStack — implements IExternalDatasourceService (introspect, draft, validate) per ADR-0015", "type": "module", diff --git a/packages/services/service-feed/CHANGELOG.md b/packages/services/service-feed/CHANGELOG.md index aa2d26dfe..5ae2d503f 100644 --- a/packages/services/service-feed/CHANGELOG.md +++ b/packages/services/service-feed/CHANGELOG.md @@ -1,5 +1,23 @@ # @objectstack/service-feed +## 7.4.0 + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/core@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/services/service-feed/package.json b/packages/services/service-feed/package.json index 88c58922b..5ac755941 100644 --- a/packages/services/service-feed/package.json +++ b/packages/services/service-feed/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/service-feed", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "Feed/Chatter Service for ObjectStack — implements IFeedService with in-memory adapter for comments, reactions, field changes, and record subscriptions", "type": "module", diff --git a/packages/services/service-i18n/CHANGELOG.md b/packages/services/service-i18n/CHANGELOG.md index d5c029e6e..0e946cd5e 100644 --- a/packages/services/service-i18n/CHANGELOG.md +++ b/packages/services/service-i18n/CHANGELOG.md @@ -1,5 +1,23 @@ # @objectstack/service-i18n +## 7.4.0 + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/core@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/services/service-i18n/package.json b/packages/services/service-i18n/package.json index 3a0c62679..75952da13 100644 --- a/packages/services/service-i18n/package.json +++ b/packages/services/service-i18n/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/service-i18n", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "I18n Service for ObjectStack — implements II18nService with file-based locale loading", "type": "module", diff --git a/packages/services/service-job/CHANGELOG.md b/packages/services/service-job/CHANGELOG.md index efd78a401..f38082c35 100644 --- a/packages/services/service-job/CHANGELOG.md +++ b/packages/services/service-job/CHANGELOG.md @@ -1,5 +1,30 @@ # @objectstack/service-job +## 7.4.0 + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [4404572] +- Updated dependencies [eea3f1b] +- Updated dependencies [e478e0c] +- Updated dependencies [4cc2ced] +- Updated dependencies [13632b1] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [c381977] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/platform-objects@7.4.0 + - @objectstack/core@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/services/service-job/package.json b/packages/services/service-job/package.json index 84339eb49..1f368f28b 100644 --- a/packages/services/service-job/package.json +++ b/packages/services/service-job/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/service-job", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "Job Service for ObjectStack — implements IJobService with setInterval and cron scheduling", "type": "module", diff --git a/packages/services/service-knowledge/CHANGELOG.md b/packages/services/service-knowledge/CHANGELOG.md index ba4df17eb..4f3ba3c25 100644 --- a/packages/services/service-knowledge/CHANGELOG.md +++ b/packages/services/service-knowledge/CHANGELOG.md @@ -1,5 +1,23 @@ # @objectstack/service-knowledge +## 7.4.0 + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/core@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/services/service-knowledge/package.json b/packages/services/service-knowledge/package.json index 0fbb2aa63..f47eb023a 100644 --- a/packages/services/service-knowledge/package.json +++ b/packages/services/service-knowledge/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/service-knowledge", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "Knowledge Service for ObjectStack — orchestrator implementing IKnowledgeService over pluggable IKnowledgeAdapter backends (RAGFlow, LlamaIndex, Dify, in-memory).", "type": "module", diff --git a/packages/services/service-messaging/CHANGELOG.md b/packages/services/service-messaging/CHANGELOG.md new file mode 100644 index 000000000..f833ed966 --- /dev/null +++ b/packages/services/service-messaging/CHANGELOG.md @@ -0,0 +1,260 @@ +# @objectstack/service-messaging + +## 7.4.0 + +### Minor Changes + +- 13632b1: ADR-0030 P0 (framework) — converge notifications onto a single ingress and the + layered model. Every producer now publishes through + `NotificationService.emit(EmitInput)`; the in-app inbox is a materialization of + delivery, not a row producers write. + + **Single ingress (`@objectstack/service-messaging`) — breaking** + + - `MessagingService.emit` takes the new `EmitInput` contract (`topic` / + `audience` / `payload` / `severity` / `dedupKey` / `source` / `actorId` / + `organizationId` / `channels`) instead of the flat `Notification` shape. It + writes the L2 `sys_notification` event (idempotent on `dedupKey`), resolves the + audience, then fans out; it returns `{ notificationId, deduped, deliveries, +delivered, failed }`. + - New `sys_notification_receipt` object — the read-state spine + (`delivered|read|clicked|dismissed`), keyed `(notification_id, user_id, +channel)`. The inbox channel writes a `delivered` receipt on materialization. + - `sys_inbox_message`: adds `notification_id` / `delivery_id`, **drops `read`** + (read-state moved to the receipt), adds the user `mine` list view. + + **Event re-model (`@objectstack/platform-objects`) — breaking** + + - `sys_notification` is re-modeled from a per-user inbox into the L2 **event** + (`topic`, `payload`, `severity`, `dedup_key`, `source_*`, `actor_id`). Removes + `recipient_id` / `is_read` / `read_at` / `type` / `title` / `body` / `url` / + `actor_name` and the inbox actions/views. App-nav: the account inbox points at + `sys_inbox_message`; Setup shows the notification event log. + + **Producers routed through `emit()`** + + - `@objectstack/service-automation`: the `notify` node maps its config to + `EmitInput`. + - `@objectstack/plugin-audit`: collaboration `@mention` → `collab.mention` and + assignment → `collab.assignment` (both with a `dedupKey`); no more direct + `sys_notification` writes. Collaboration notifications now require + `MessagingServicePlugin` (they degrade to a warn otherwise). + + **Migration (`@objectstack/metadata`)** + + - Idempotent `migrateSysNotificationToEvent` splits legacy `sys_notification` + inbox rows into `sys_inbox_message` + receipts and rewrites the event row. + + **Startup (`@objectstack/cli`, `@objectstack/runtime`)** + + - `messaging` is now a foundational capability. On `objectstack serve` it is + added to `ALWAYS_ON_CAPABILITIES` (every non-`minimal` preset starts it); on + cloud per-project kernels the capability loader expands `requires` to add + `messaging` whenever `audit` is present. This keeps collaboration `@mention` / + assignment notifications (which now flow through the pipeline) working out of + the box on both paths. `--preset minimal` opts out. + + The Console bell repoint (objectui) and phases P1–P3 are tracked in + `docs/handoff/adr-0030-notification-convergence.md`. + +- a40d010: ADR-0030 P2 — subscription + preference. Adds the Layer-3 preference filter so + users can mute notification topics/channels, with admin-global defaults and + mandatory-topic bypass. + + - **`sys_notification_preference`** — per `(user_id, topic, channel)` toggle + (`enabled`, plus `digest`/`quiet_hours` for P3). `user_id='*'` rows are the + admin-global default; a real-user row overrides it; `topic`/`channel` support + `*` wildcards. Unique `(user_id, topic, channel)`. + - **`sys_notification_subscription`** — standing subscription of a principal + (`role:`/`team:`/`user:`/id) to a topic (the opt-in counterpart to explicit + audience; object + schema land now, subscription-driven fan-out is a follow-up). + - **`PreferenceResolver`** — wired into `MessagingService.emit()` between + recipient resolution and fan-out/enqueue. Most-specific-wins resolution + (user→`*`, topic→`*`, channel→`*`; default ON). Two safety rules: **mandatory + topics bypass** (configurable via `mandatoryTopics`, exact or `prefix.`), and + **fail-open** (no data engine or a lookup error delivers all, never silently + drops). `emit()` now filters the `(recipient × channel)` matrix per user. + - Both objects are registered by `MessagingServicePlugin` and contributed to the + Setup app's Configuration nav slot (ADR-0029 D7), so they appear in + REST/Studio only when messaging is installed. + + Acceptance: a user muting a topic/channel stops receiving it on that channel; + mandatory topics still deliver. service-messaging suite: 66 passing + (adds `preference-resolver.test.ts` + an emit-level mute/bypass test). + +- f3424fc: ADR-0030 P3a — email channel + notification templates. The same `emit()` now + reaches inbox **and** email per the user's preferences, rendered from a + template. + + - **`email` channel** (`createEmailChannel`) — a thin `MessagingChannel` that + delegates transport to the existing `email` service (ADR-0022: channel adds + messaging semantics, the email sub-system stays the transport). It resolves the + recipient user id → address (`sys_user.email`, or an email-shaped recipient + verbatim), renders, and sends. Retry/backoff/dead-letter come free from the P1 + outbox dispatcher. Registered at `kernel:ready` only when an `email` service is + present; absent ⇒ no channel (an explicit `channels:['email']` then reports + "not registered" rather than silently no-opping). No-ops gracefully like the + inbox channel when the capability isn't installed. + - **`sys_notification_template`** (topic × channel × locale) + a renderer: + declarative `{{ payload.x }}` interpolation (no logic — auditable metadata), + HTML/markdown/text bodies, locale fallback (`en-US` → `en` → default), and a + **generic fallback to `payload.title`/`body`** when no template matches (so + templates are purely additive). Contributed to the Setup → Configuration nav. + - Channels are now keyed per recipient (from P2), so a notification reaches each + user on exactly the channels they accept, rendered by that channel's template. + + Scope note (ADR-0022): **Slack stays a connector** (`connector-slack` already + ships the raw API path); a Slack _notification channel_ needs per-user identity + mapping + OAuth and is enterprise-tier — deferred. push/webhook channels and the + digest / quiet-hours middleware (P3b) are follow-ups on the same seam. + + Tests: service-messaging **85 passing** — adds `template-renderer.test.ts` and + `email-channel.test.ts` (address resolution, template vs fallback rendering, + no-service no-op, unresolved-address failure, transport-failure retry). + +- c8753ef: ADR-0030 P3b-1 — quiet-hours. A notification that lands inside a recipient's + quiet-hours window is **deferred to the window's end** instead of disturbing + them; it then delivers normally. + + - Implemented as a **deferred dispatch** on the P1 outbox — no parallel + scheduler: `EnqueueDeliveryInput.notBefore` sets the delivery row's initial + `nextAttemptAt`, and the existing dispatcher already skips pending rows whose + `nextAttemptAt` is in the future. One delivery spine, reusing claim/retry/ + observability. + - `PreferenceResolver` reads `quiet_hours` (`{ tz, start, end }`, P2's field) off + a channel-wildcard preference row (quiet hours are a per-person, channel- + agnostic setting), computes the deferral with `quietHoursDeferral()` (HH:MM in + the row's `tz`, default UTC; supports overnight windows that wrap midnight), + and stamps `notBefore` on the target. `emit()` passes it through to the outbox. + - **critical** severity bypasses quiet hours (delivers immediately), like + mandatory topics bypass muting. Honored on the durable outbox path; inline + best-effort fan-out ignores it. + + Tests: service-messaging **92 passing** — adds `quietHoursDeferral` unit cases + (same-day / overnight / outside / degenerate) and resolver cases (notBefore + stamped, critical bypass, JSON-string `quiet_hours`). + + Follow-up: **P3b-2 — digest** (batch same-`(user, channel, window)` deliveries + into one) builds on this same deferral foundation, adding the window collapse. + +- 406fda5: ADR-0030 P1 — reliable delivery + RecipientResolver. + + **RecipientResolver** — the single home for audience → user-id expansion, wired + into `MessagingService.emit()`. Queries the same identity/membership model + `plugin-sharing` uses (directly via the data engine, no backward plugin + dependency): + + - `role:` → `sys_member` rows (tenant-scoped) + - `team:` → `sys_team_member` rows + - `owner_of::` / `{ ownerOf }` → the record's owner/assignee field + - `` → `sys_user` (verbatim fallback on miss); `user:` / bare id → id + + Best-effort: a failed directory lookup yields 0 recipients for that spec rather + than throwing. The inbox channel's email→id fallback moved here — the channel + now keys rows by the already-resolved recipient. + + **Reliable delivery outbox + dispatcher** (mirrors `plugin-webhooks`): + + - New `sys_notification_delivery` outbox object (L4) — one row per + `(event × recipient × channel)`; `pending|in_flight|success|failed|dead|suppressed` + state machine; unique `(notification_id, recipient_id, channel)` enqueue dedup. + - `INotificationOutbox` with `SqlNotificationOutbox` + `MemoryNotificationOutbox` + backends; atomic claim (`pending → in_flight`) + stale-in_flight reaping. + - `NotificationDispatcher` — interval loop over partitions, each guarded by a + per-partition cluster lock (single-node always-grant fallback when no cluster + service); sends via the channel and acks with exponential backoff + jitter; + dead-letters once the retry budget is exhausted. + - `emit()` enqueues `pending` deliveries when an outbox is attached; otherwise it + fans out inline (the P0 behavior). `MessagingServicePlugin` wires the outbox + + dispatcher at `kernel:ready` and registers the new object. + + A failed channel send now retries and is observable on the delivery row; + duplicate enqueue is idempotent. Backoff/classification and clocks are injectable + for deterministic tests. + +- 394d34f: Messaging + triggers capability tokens, and notify-by-email recipient resolution. + + Make the `notify` flow node and auto-firing flows usable from a plain + `defineStack({ requires: [...] })` — no hand-wired plugin instances. + + - **CLI / runtime — new capability tokens.** `messaging` → + `MessagingServicePlugin` (the `notify` node delivers to the inbox channel + instead of degrading to a logged no-op); `triggers` → + `RecordChangeTriggerPlugin` + `ScheduleTriggerPlugin` (autolaunched / schedule + flows actually fire — pair `triggers` with `job` for cron/interval). Wired + identically in the CLI `CAPABILITY_PROVIDERS` table and the runtime + `capability-loader`. + - **Inbox channel — notify-by-email.** Flows commonly address recipients by + email (e.g. `{record.assignee}`), but `sys_inbox_message` is keyed by user id. + The inbox channel now resolves an email-shaped recipient to its `sys_user.id` + (configurable via `InboxChannelOptions.userObject`), with a verbatim fallback + when the recipient is not email-shaped, no user matches, or the lookup fails — + so a failed resolution can never drop the row. + +- 3a45780: Synthesize the inbox `action_url` from the event `source` (ADR-0030 L5). + + The Console bell reads `sys_inbox_message` (the L5 in-app materialization), + which carries only `action_url` — not the L2 `sys_notification` event's + `source_object`/`source_id`. Producers that pass a `source` but no explicit + `payload.url` (collaboration `@mention`, record assignment) therefore + materialized inbox rows with no navigable link, so the bell entry couldn't + deep-link to the originating record. + + `emit()` now synthesizes an app-relative `/{object}/{id}` link from `source` + when no explicit `payload.url`/`payload.actionUrl` is supplied — in both the + inline fan-out and the durable-outbox enqueue paths (`actionUrlFor()`). + Precedence: explicit url → source-derived link → `undefined`. Keeps the L5 + materialization self-sufficient for navigation (the objectui bell consumes + `action_url`). + + Tests: 3 new `messaging-service.test.ts` cases (source→link, explicit-url + precedence, neither→undefined); all 95 service-messaging tests green. + +- c381977: Harden the notification pipeline: race-safe dedup + opt-in retention (ADR-0030). + + **Race-safe dedup.** `sys_notification.dedup_key` is now declared a **UNIQUE** + index (was a plain index), and `emit()` **converges on a unique-key conflict**: + the pre-insert `dedup_key` check is a fast-path, but if a concurrent `emit` + raced past it and inserted first, our insert hits the violation — we catch it + and converge to the winner's event (a dedup hit) instead of throwing or + double-emitting. This mirrors the delivery outbox's enqueue convergence and + stops a record-change storm from producing duplicate bell notifications. SQL + treats NULLs as distinct, so the common events with no `dedup_key` are + unconstrained. (Enforcement is per-driver: where declared indexes are + materialized the conflict path activates; drivers that don't materialize them + fall back to the best-effort fast-path — the catch is simply never taken. Note + the SQL driver currently doesn't sync declared object indexes, which already + affects the delivery/receipt unique indexes — tracked separately.) + + **Opt-in retention.** New `NotificationRetention` sweeper + plugin options + `retentionDays` / `retentionSweepMs`. Every `emit()` writes a `sys_notification` + event (plus delivery/materialization/receipt rows), so a high-frequency + periodic flow grows the tables unbounded. When `retentionDays > 0`, a + low-frequency sweep (default hourly, timer `unref`'d) bulk-deletes events, + deliveries, inbox messages and receipts older than the cutoff — a notification + ages out wholesale, keeping the model consistent (no dangling `notification_id`) + and the bell (recent-only) unaffected. The delivery row's epoch-ms `created_at` + vs the others' ISO `created_at` is handled per target. **Default off** — no + notification data is deleted without explicit operator policy. Each target is + isolated (one object's failure doesn't abort the sweep), and the sweep runs + under a system context (retention is a cross-tenant operator policy). + + Tests: +7 `service-messaging` cases (converge-on-conflict, non-conflict + rethrow, retention cutoff-formatting per target, no-engine / non-positive + no-ops, failure isolation, missing-count) — 102 passing. + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/core@7.4.0 diff --git a/packages/services/service-messaging/package.json b/packages/services/service-messaging/package.json index 3726d1b62..706a1754d 100644 --- a/packages/services/service-messaging/package.json +++ b/packages/services/service-messaging/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/service-messaging", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "Messaging Service for ObjectStack — outbound notification dispatch (ADR-0012). Ships the MessagingChannel registry, emit() fan-out, and the always-on inbox channel; other channels (email/webhook/push/IM) plug in.", "type": "module", diff --git a/packages/services/service-package/CHANGELOG.md b/packages/services/service-package/CHANGELOG.md index af0974a59..283475b8f 100644 --- a/packages/services/service-package/CHANGELOG.md +++ b/packages/services/service-package/CHANGELOG.md @@ -1,5 +1,23 @@ # @objectstack/service-package +## 7.4.0 + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/core@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/services/service-package/package.json b/packages/services/service-package/package.json index 90781a256..696633408 100644 --- a/packages/services/service-package/package.json +++ b/packages/services/service-package/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/service-package", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "Package management service for ObjectStack — publish, install, and manage packages", "type": "module", diff --git a/packages/services/service-queue/CHANGELOG.md b/packages/services/service-queue/CHANGELOG.md index f45559155..8abc078b2 100644 --- a/packages/services/service-queue/CHANGELOG.md +++ b/packages/services/service-queue/CHANGELOG.md @@ -1,5 +1,30 @@ # @objectstack/service-queue +## 7.4.0 + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [4404572] +- Updated dependencies [eea3f1b] +- Updated dependencies [e478e0c] +- Updated dependencies [4cc2ced] +- Updated dependencies [13632b1] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [c381977] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/platform-objects@7.4.0 + - @objectstack/core@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/services/service-queue/package.json b/packages/services/service-queue/package.json index 37082eae8..715d4c226 100644 --- a/packages/services/service-queue/package.json +++ b/packages/services/service-queue/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/service-queue", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "Queue Service for ObjectStack — implements IQueueService with in-memory and BullMQ adapters", "type": "module", diff --git a/packages/services/service-realtime/CHANGELOG.md b/packages/services/service-realtime/CHANGELOG.md index ea69fa266..a9ca6cddc 100644 --- a/packages/services/service-realtime/CHANGELOG.md +++ b/packages/services/service-realtime/CHANGELOG.md @@ -1,5 +1,30 @@ # @objectstack/service-realtime +## 7.4.0 + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [4404572] +- Updated dependencies [eea3f1b] +- Updated dependencies [e478e0c] +- Updated dependencies [4cc2ced] +- Updated dependencies [13632b1] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [c381977] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/platform-objects@7.4.0 + - @objectstack/core@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/services/service-realtime/package.json b/packages/services/service-realtime/package.json index 899775501..f1e2f1681 100644 --- a/packages/services/service-realtime/package.json +++ b/packages/services/service-realtime/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/service-realtime", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "Realtime Service for ObjectStack — implements IRealtimeService with WebSocket and in-memory pub/sub", "type": "module", diff --git a/packages/services/service-settings/CHANGELOG.md b/packages/services/service-settings/CHANGELOG.md index 0e18f54c9..60c7ed88e 100644 --- a/packages/services/service-settings/CHANGELOG.md +++ b/packages/services/service-settings/CHANGELOG.md @@ -1,5 +1,58 @@ # @objectstack/service-settings +## 7.4.0 + +### Patch Changes + +- 82eb6cf: Fix system-metadata translations: locale fallback, app/dashboard localization, and coverage gaps. + + Switching the UI language left many surfaces in English. Three root causes + are addressed: + + - **Locale fallback (server).** The metadata translation resolver + (`@objectstack/spec` `i18n-resolver`) now resolves a requested locale + against the locales actually present in the bundle (exact → + case-insensitive → base-language → variant), so a request for `zh` + correctly hits the `zh-CN` bundle instead of falling back to English. + This mirrors `resolveLocale` in `@objectstack/core` and benefits every + resolver (objects, views, actions, settings, metadata forms). + + - **App & dashboard localization (server).** Added `translateApp` and + `translateDashboard` resolvers and wired `app`/`dashboard` into the REST + `/meta` translation path. App labels, sidebar/navigation group labels, + and dashboard titles/widgets were previously never localized at the API + boundary even though the translation data existed. + + - **Coverage & quality (data).** Added translations for the previously + untranslated platform objects `sys_share_link`, `sys_view_definition`, + and `sys_metadata_audit` (and registered them in the i18n-extract config + so future extractions keep them). Replaced English placeholder strings + left in the `zh-CN` / `ja-JP` / `es-ES` object and metadata-form bundles + (notably action `confirmText` / `successMessage` prompts). Added the + missing `es-ES` built-in Settings bundle in `@objectstack/service-settings`. + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [4404572] +- Updated dependencies [eea3f1b] +- Updated dependencies [e478e0c] +- Updated dependencies [4cc2ced] +- Updated dependencies [13632b1] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [c381977] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/platform-objects@7.4.0 + - @objectstack/core@7.4.0 + - @objectstack/types@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/services/service-settings/package.json b/packages/services/service-settings/package.json index 14dfa5089..58ecfa05b 100644 --- a/packages/services/service-settings/package.json +++ b/packages/services/service-settings/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/service-settings", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "Settings service for ObjectStack — manifest registry + K/V resolver (Env > Tenant > User > Default) + REST routes. See ADR-0007.", "type": "module", diff --git a/packages/services/service-storage/CHANGELOG.md b/packages/services/service-storage/CHANGELOG.md index c44dc61c0..5d34dccb4 100644 --- a/packages/services/service-storage/CHANGELOG.md +++ b/packages/services/service-storage/CHANGELOG.md @@ -1,5 +1,24 @@ # @objectstack/service-storage +## 7.4.0 + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + - @objectstack/core@7.4.0 + - @objectstack/observability@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/services/service-storage/package.json b/packages/services/service-storage/package.json index e938981e7..254f13d99 100644 --- a/packages/services/service-storage/package.json +++ b/packages/services/service-storage/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/service-storage", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "Storage Service for ObjectStack — implements IStorageService with local filesystem and S3 adapter skeleton", "type": "module", diff --git a/packages/spec/CHANGELOG.md b/packages/spec/CHANGELOG.md index dd8a4c001..6697482aa 100644 --- a/packages/spec/CHANGELOG.md +++ b/packages/spec/CHANGELOG.md @@ -1,5 +1,278 @@ # @objectstack/spec +## 7.4.0 + +### 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/objectql`** — `SchemaRegistry.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 `code`s) + 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.ts` — `IExternalDatasourceService` + 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.ts` — `ExternalCatalogSchema` / + `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 `FlowSuspendSignal` → `SuspendedRun` → 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 objectui `FlowRunner` UI that renders these screens ships separately. + +- 5e831de: Seed data: first-class identity binding + loud failures (fixes #1389) + + Records seeded via `defineDataset` / `defineStack({ data })` can now bind to a + platform user with `cel\`os.user.id\``(and to the org with`cel\`os.org.id\``), + which previously never resolved at boot. + + - **`os.user` / `os.org` now actually resolve.** The runtime provisions a + deterministic, non-loginable system user (`usr_system`, role `system`) + _before_ any seed runs and binds it to `os.user`, so identity-derived seed + values resolve even on a fresh boot — before the first human sign-up. The + human login admin remains a separate better-auth identity and need not own + seed data. Exposed as the canonical `SystemUserId.SYSTEM` constant. + - **New `SeedLoaderConfig.identity`** carries the `os.user` / `os.org` subject + into CEL evaluation (`@objectstack/spec`). + - **Failures are loud, not silent.** A record whose CEL value can't resolve + (e.g. a required `cel\`os.user.id\`` with no identity) — or that fails to + write — is now counted as an error, marks the load unsuccessful, and logs an + actionable message, instead of being silently dropped. + +### Patch Changes + +- 58b450b: Make metadata labels follow the active UI language without a page refresh (#1319). + + The client now carries the active locale on every request (`Accept-Language`, + `setLocale`/`getLocale`), the protocol ETag is locale-aware so cached metadata + no longer collides across languages, and the `client-react` metadata hooks + refetch when the locale changes. The `apps/account` console wires its router + locale through so a language switch relabels server-resolved object/field/view + labels in place instead of leaving the UI half-translated until reload. + +- 82eb6cf: Fix system-metadata translations: locale fallback, app/dashboard localization, and coverage gaps. + + Switching the UI language left many surfaces in English. Three root causes + are addressed: + + - **Locale fallback (server).** The metadata translation resolver + (`@objectstack/spec` `i18n-resolver`) now resolves a requested locale + against the locales actually present in the bundle (exact → + case-insensitive → base-language → variant), so a request for `zh` + correctly hits the `zh-CN` bundle instead of falling back to English. + This mirrors `resolveLocale` in `@objectstack/core` and benefits every + resolver (objects, views, actions, settings, metadata forms). + + - **App & dashboard localization (server).** Added `translateApp` and + `translateDashboard` resolvers and wired `app`/`dashboard` into the REST + `/meta` translation path. App labels, sidebar/navigation group labels, + and dashboard titles/widgets were previously never localized at the API + boundary even though the translation data existed. + + - **Coverage & quality (data).** Added translations for the previously + untranslated platform objects `sys_share_link`, `sys_view_definition`, + and `sys_metadata_audit` (and registered them in the i18n-extract config + so future extractions keep them). Replaced English placeholder strings + left in the `zh-CN` / `ja-JP` / `es-ES` object and metadata-form bundles + (notably action `confirmText` / `successMessage` prompts). Added the + missing `es-ES` built-in Settings bundle in `@objectstack/service-settings`. + +- 13d8653: Record-change flow trigger — auto-launch flows on data mutations. + + Completes the automation engine's `FlowTrigger` extension point so flows whose + `start` node declares a record-change trigger (`config: { objectName, +triggerType: 'record-after-update', condition }`) actually fire on the matching + mutation. Previously the slot was dead — nothing called `trigger.start` — so + such flows could only run via a manual `engine.execute()`. + + **Engine baseline (`@objectstack/service-automation`)** + + - Redefines `FlowTrigger` around a parsed `FlowTriggerBinding` (flowName, + object, event, condition, schedule, raw config). The engine parses the start + node and hands the trigger a normalized binding, keeping trigger plugins + decoupled from flow-definition internals (mirrors `connector_action` ↔ + `connector-rest`). + - Ordering-independent, bidirectional wiring: `registerFlow`/`toggleFlow` + activate bindings; `registerTrigger` retro-binds already-registered flows (a + trigger plugin wires up on `kernel:ready`, after flows are pulled in); + `unregisterFlow`/`unregisterTrigger`/disable tear them down. + - Centralized start-condition gate in `execute()`: the start node's `condition` + (e.g. `status == 'done' && previous.status != 'done'`) is evaluated once for + every trigger type and manual runs; false ⇒ `{ skipped: true }`. + - Seeds `record`, flattened record fields, and `previous` into flow variables. + - New `getActiveTriggerBindings()` getter + exports `FlowTriggerBinding`. + + **Spec (`@objectstack/spec`)** + + - Adds `previous?` to `AutomationContext` — the pre-update "old" row, so flows + can gate on transitions. + + **New package (`@objectstack/plugin-trigger-record-change`)** + + - The concrete trigger: subscribes to ObjectQL lifecycle hooks + (`record-after-update` → `afterUpdate`, etc.), builds an `AutomationContext` + from the new/old record, and runs the flow. Error-isolated (a flow failure + never breaks the CRUD write); graceful degrade when the automation service or + ObjectQL engine is absent (mirrors `plugin-audit`). + + The `schedule` trigger (ticker/cron + `sys_job` lifecycle) is a follow-up. + ## 7.3.0 ### Minor Changes diff --git a/packages/spec/package.json b/packages/spec/package.json index b361865c6..e518e2512 100644 --- a/packages/spec/package.json +++ b/packages/spec/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/spec", - "version": "7.3.0", + "version": "7.4.0", "description": "ObjectStack Protocol & Specification - TypeScript Interfaces, JSON Schemas, and Convention Configurations", "license": "Apache-2.0", "main": "dist/index.js", diff --git a/packages/types/CHANGELOG.md b/packages/types/CHANGELOG.md index 4305f5eae..5f65ddbe6 100644 --- a/packages/types/CHANGELOG.md +++ b/packages/types/CHANGELOG.md @@ -1,5 +1,22 @@ # @objectstack/types +## 7.4.0 + +### Patch Changes + +- Updated dependencies [23c7107] +- Updated dependencies [c72daad] +- Updated dependencies [f115182] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [2faf9f2] +- Updated dependencies [58b450b] +- Updated dependencies [82eb6cf] +- Updated dependencies [13d8653] +- Updated dependencies [ff3d006] +- Updated dependencies [5e831de] + - @objectstack/spec@7.4.0 + ## 7.3.0 ### Patch Changes diff --git a/packages/types/package.json b/packages/types/package.json index 92ccc5b3c..fb735198c 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/types", - "version": "7.3.0", + "version": "7.4.0", "license": "Apache-2.0", "description": "Shared interfaces describing the ObjectStack Runtime environment", "main": "dist/index.js", diff --git a/packages/vscode-objectstack/CHANGELOG.md b/packages/vscode-objectstack/CHANGELOG.md index adcc56f98..1c764b787 100644 --- a/packages/vscode-objectstack/CHANGELOG.md +++ b/packages/vscode-objectstack/CHANGELOG.md @@ -1,5 +1,7 @@ # objectstack-vscode +## 7.4.0 + ## 7.3.0 ## 7.2.1 diff --git a/packages/vscode-objectstack/package.json b/packages/vscode-objectstack/package.json index 964650fd7..10719b4e6 100644 --- a/packages/vscode-objectstack/package.json +++ b/packages/vscode-objectstack/package.json @@ -2,7 +2,7 @@ "name": "objectstack-vscode", "displayName": "ObjectStack", "description": "ObjectStack Protocol — Autocomplete, validation, and inline diagnostics for .object.ts, .view.ts, and objectstack.config.ts files", - "version": "7.3.0", + "version": "7.4.0", "publisher": "objectstack", "license": "Apache-2.0", "repository": {