diff --git a/.changeset/actions-as-ai-tools.md b/.changeset/actions-as-ai-tools.md deleted file mode 100644 index de27d0c6c..000000000 --- a/.changeset/actions-as-ai-tools.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -'@objectstack/spec': patch -'@objectstack/service-ai': patch ---- - -feat(ai): actions opt in to being AI tools via an `ai:` block (ADR-0011) - -Realigns ADR-0011 with its original opt-in design. An Action becomes an -AI-callable tool only when its metadata sets `ai.exposed: true`, which requires -an explicit, LLM-facing `ai.description` (≥40 chars, distinct from the UI -`label`). There is no heuristic auto-exposure and no description derived from -the label — a clean break from the first implementation's opt-out `aiExposed` -flag, which is removed (no compatibility shim; the platform has not shipped). - -The `ai:` block also carries `category`, `paramHints` (per-parameter JSON-Schema -refinement), `outputSchema` (summarised into the tool description for chaining), -and `requiresConfirmation` (overrides the destructive-action HITL default). -`AIToolDefinition` is extended to carry `category` / `outputSchema` / `objectName` -/ `requiresConfirmation`. The `@objectstack/service-ai` bridge -(`action-tools.ts`) now gates on opt-in, merges `paramHints`, and emits a lint -warning when an exposed destructive-looking action asserts itself safe via -`ai.requiresConfirmation: false`. diff --git a/.changeset/api-key-generation-endpoint.md b/.changeset/api-key-generation-endpoint.md deleted file mode 100644 index 32f12b247..000000000 --- a/.changeset/api-key-generation-endpoint.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -'@objectstack/runtime': minor ---- - -feat(runtime): API-key generation endpoint — show-once `sys_api_key` (ADR-0036, closes framework#1629) - -Adds `POST /api/v1/keys` — the only path that mints a `sys_api_key`. Phase 1a -shipped key *verification* and the `generateApiKey()` primitive; this is the -missing *generation* half that unblocks the self-serve connect flow. - -- Requires an authenticated principal; returns the **raw secret exactly once** - (`{ id, name, prefix, key }`). Only the sha256 **hash** is persisted — the raw - key is never stored, logged, or re-displayable. -- **Security (zero-tolerance):** `user_id` is pinned to the caller and never read - from the body (no impersonation); the body is whitelisted to `name` (+ optional - validated future `expires_at`) — any `key`/`id`/`user_id`/`revoked` in the body - is ignored, so a caller cannot forge a known-secret or escalate. The row is - written with an elevated `{ isSystem: true }` context (sys_api_key is - protection-locked) with server-controlled contents. Anonymous → 401; - non-POST → 405; past/unparseable `expires_at` → 400. -- `scopes` are intentionally NOT accepted from the body in v1 (the verify path - adds scopes to permissions, so honouring arbitrary body scopes would be an - escalation vector); a generated key acts exactly AS the caller via `user_id` - resolution. Scoped/narrowing keys need subset-enforcement — deferred. - -11 security tests (show-once, hash-not-raw persisted, round-trip auth via the -verify path, impersonation blocked, forgery blocked, 401/405/400, expiry -end-to-end). Full runtime suite green (376). diff --git a/.changeset/autonumber-driver-consolidation.md b/.changeset/autonumber-driver-consolidation.md deleted file mode 100644 index 2b12e1f2a..000000000 --- a/.changeset/autonumber-driver-consolidation.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -'@objectstack/spec': minor -'@objectstack/objectql': minor -'@objectstack/driver-sql': minor ---- - -fix(autonumber): one owner for autonumber generation — the persistent driver sequence (#1603) - -Autonumber values were generated in TWO places: the SQL driver's persistent, -atomic `_objectstack_sequences` table AND a non-persistent in-memory counter in -the ObjectQL engine. Because the engine pre-filled the field BEFORE calling the -driver, the driver always saw a value already set and skipped — so the -persistent sequence was effectively dead code, and a multi-instance / post-restart -deployment could mint duplicate numbers from the in-memory counter. - -This makes generation single-owner: - -- **`@objectstack/spec`** — `DriverCapabilities` gains an optional `autonumber` - flag: "driver natively generates persistent autonumber/sequence values". - -- **`@objectstack/driver-sql`** — advertises `supports.autonumber = true`. - `bulkCreate()` now fills autonumber fields too (previously only `create()` / - `upsert()` did), so bulk inserts also draw from the persistent sequence. - Field parsing now honors either the spec-canonical `autonumberFormat` key OR - the `format` shorthand (both appear in metadata). - -- **`@objectstack/objectql`** — when the driver advertises native autonumber - support, the engine NO LONGER pre-fills (it defers entirely to the persistent - driver sequence as the single source of truth). For drivers without native - support (memory, mongodb) the in-memory fallback is unchanged. The fallback - also now reads either `autonumberFormat` or `format`. Record-validation - exempts `autonumber` fields from the `required` check — the value is - runtime-owned and assigned after validation, so a required record number is - never rejected as "missing". - -No metadata changes required. Existing data is respected: the driver bootstraps -each sequence from the current max numeric tail on first use. diff --git a/.changeset/b2-conditional-field-rules.md b/.changeset/b2-conditional-field-rules.md deleted file mode 100644 index e944c5934..000000000 --- a/.changeset/b2-conditional-field-rules.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -"@objectstack/spec": minor -"@objectstack/objectql": minor ---- - -Field-level conditional rules (CEL): `visibleWhen` / `readonlyWhen` / `requiredWhen`, enforced server-side. - -Add three CEL-predicate field props (over `record`) evaluated on both sides. **Spec**: `visibleWhen` / `readonlyWhen` / `requiredWhen` (`requiredWhen` canonical; `conditionalRequired` kept as a back-compat alias). **Server (objectql)**: the validator now enforces `requiredWhen`/`conditionalRequired` over the merged record (so the rule can't be bypassed by a direct API write), and the update path ignores writes to a field whose `readonlyWhen` is TRUE (keeps the persisted value). `needsPriorRecord` accounts for conditional fields so the prior record is fetched on update. diff --git a/.changeset/external-call-resilience.md b/.changeset/external-call-resilience.md deleted file mode 100644 index e7037c562..000000000 --- a/.changeset/external-call-resilience.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -'@objectstack/spec': minor -'@objectstack/connector-rest': patch -'@objectstack/connector-slack': patch -'@objectstack/embedder-openai': patch -'@objectstack/connector-mcp': patch ---- - -feat(spec): resilientFetch — timeout + backoff for outbound HTTP (P1-1) - -Outbound calls in the connectors/embedder were naked `fetch` with no timeout or -retry, so a slow or rate-limited external API could hang an agent turn with no -recovery. - -New shared `resilientFetch` (`@objectstack/spec/shared`): -- per-attempt timeout via `AbortController` (default 30s); -- exponential backoff with jitter, up to 3 attempts, on network errors / 429 / 5xx; -- honours a `Retry-After` header on 429; -- never retries a caller-initiated abort (intentional cancellation). - -Wired into `connector-rest`, `connector-slack`, and `embedder-openai`. -`connector-mcp` talks through the MCP SDK transport, so it gets a 30s per-request -`timeout` on `callTool` / `listTools` instead. - -A stateful per-host **circuit breaker** is deliberately left as a follow-up: -timeout + backoff already removes the hang/no-recovery risk. diff --git a/.changeset/field-inline-edit.md b/.changeset/field-inline-edit.md deleted file mode 100644 index f29521a21..000000000 --- a/.changeset/field-inline-edit.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -'@objectstack/spec': minor ---- - -feat(spec): `inlineEdit` on relationship fields for declarative master-detail - -A `master_detail`/`lookup` field can now declare `inlineEdit: true` (plus -optional `inlineTitle` / `inlineColumns` / `inlineAmountField`) to mean "these -child records are entered/edited inline within the parent's form". The intent -lives in the data model: the parent's standard create/edit form then renders an -atomic master-detail form (object fields + an editable child grid) with no form -view config and no bespoke page. Use for line-item/composition children; leave -off for associations (comments, attachments). Renderer support is in objectui. diff --git a/.changeset/formview-subforms.md b/.changeset/formview-subforms.md deleted file mode 100644 index b6347e1c9..000000000 --- a/.changeset/formview-subforms.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -'@objectstack/spec': minor ---- - -feat(spec): `FormViewSchema.subforms` for config-driven master-detail - -A form view can now declare inline child collections via `subforms`, so the -standard create/edit form for an object can render as a master-detail form -(object fields on top, an editable child grid below, persisted atomically) -without a bespoke page. Each entry needs only `childObject`; the relationship -FK and grid columns are derived from the child object's metadata (override via -`relationshipField` / `columns`). Renderer support: ObjectForm already renders -`subforms` (objectui), and the ObjectView form path passes them through. diff --git a/.changeset/graceful-http-drain.md b/.changeset/graceful-http-drain.md deleted file mode 100644 index fa26ee795..000000000 --- a/.changeset/graceful-http-drain.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -'@objectstack/plugin-hono-server': patch ---- - -fix(hono-server): drain in-flight requests on shutdown instead of force-closing (P1-3) - -`HonoHttpServer.close()` called `closeAllConnections()`, which terminated active -connections mid-response — so a SIGTERM during a rolling deploy dropped in-flight -requests. It now drains gracefully: `server.close()` stops accepting new -connections and lets active requests finish, `closeIdleConnections()` releases -idle keep-alive sockets so the process exits promptly, and a bounded drain window -(default 10s, configurable, well under the kernel's 60s `shutdownTimeout`) -force-closes only the stragglers so shutdown can't hang. - -Note: the kernel already handles SIGINT/SIGTERM/SIGQUIT with an ordered, -timeout-bounded shutdown — this fixes the one place that wasn't draining. diff --git a/.changeset/hono-type-reexport.md b/.changeset/hono-type-reexport.md deleted file mode 100644 index e72116f31..000000000 --- a/.changeset/hono-type-reexport.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -'@objectstack/hono': patch ---- - -feat(hono): re-export the `Hono` type from `@objectstack/hono` - -Downstream apps that consume `createHonoApp()` only need the `Hono` type to -annotate the returned app. They can now `import type { Hono } from '@objectstack/hono'` -instead of adding their own `hono` dependency, which guarantees a single -`hono` across a `link:`/cross-package boundary (no duplicate-package -type-identity errors, no version-pin alignment). `hono` remains a normal -runtime dependency of this package, so standalone usage is unaffected. diff --git a/.changeset/mcp-objectstack-skill.md b/.changeset/mcp-objectstack-skill.md deleted file mode 100644 index 52cfcfe5f..000000000 --- a/.changeset/mcp-objectstack-skill.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -'@objectstack/mcp': minor ---- - -feat(mcp): generic ObjectStack Agent Skill generator (ADR-0036 Phase 2b) - -Adds `renderSkillMarkdown({ mcpUrl, envName })` — produces a portable -`SKILL.md` (open Agent Skills standard: Claude Code, OpenAI Codex, Gemini CLI, -Copilot, Cursor, …) that teaches any skills-capable agent how to drive an -ObjectStack environment over MCP. - -Per ADR-0036 Amendment C, this is ONE generic skill, not a per-app artifact: -- the content never enumerates a tenant's schema — it instructs the agent to - discover live via `list_objects` / `describe_object`, so one install works for - every app the caller's key can reach and a new app needs no reinstall; -- only the connection URL is environment-specific, slotted in by the caller; -- it documents the object-CRUD tools, auth via `x-api-key` (Bearer is session - auth), and the governance model (every call runs under the caller's - permissions + RLS — fewer rows / write rejections are expected, not bugs). - -Exported: `renderSkillMarkdown`, `OBJECTSTACK_SKILL_NAME`, -`OBJECTSTACK_SKILL_DESCRIPTION`, `RenderSkillOptions`. The objectui/cloud -surfacing layer calls this to offer a one-click skill download alongside the -env's remote-MCP URL and a show-once key. diff --git a/.changeset/mcp-streamable-http-transport.md b/.changeset/mcp-streamable-http-transport.md deleted file mode 100644 index 4f1468fe0..000000000 --- a/.changeset/mcp-streamable-http-transport.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -'@objectstack/mcp': minor -'@objectstack/runtime': minor ---- - -feat(mcp): Streamable HTTP transport — every app is a network-reachable MCP server (ADR-0036 Phase 2) - -The MCP server plugin spoke **stdio only**, so a remote agent (Claude Desktop / -Cursor) could not connect to a hosted env. This adds the **Streamable HTTP** -transport and wires it into the runtime's request path, building on the Phase 1a -`sys_api_key` auth foundation. - -- **`@objectstack/mcp`** (renamed from `@objectstack/plugin-mcp-server` — see the rename changeset) - - `MCPServerRuntime.handleHttpRequest(request, { bridge, parsedBody })` — - serves one MCP request over the Web-standard `WebStandardStreamableHTTPServerTransport` - (runs on Node 18+, Workers, Deno, Bun). **Stateless**: a fresh, isolated - `McpServer` + transport is built per request (the SDK-recommended pattern), - in JSON-response mode so the response is fully buffered — no streaming - pass-through concerns over the Worker→container hop. - - New `registerObjectTools` + `McpDataBridge` (`mcp-http-tools.ts`): the - object-CRUD tool set (`list_objects`, `describe_object`, `query_records`, - `get_record`, `create_record`, `update_record`, `delete_record`). All - execution is delegated to an injected, **principal-bound** bridge — the tool - layer never touches the data engine directly. System (`sys_*`) objects are - **not exposed** by default (fail-closed guard on every object-scoped tool). - The internal AI/authoring toolRegistry is deliberately NOT bridged onto the - external surface. - -- **`@objectstack/runtime`** - - `HttpDispatcher` serves `/mcp`: **opt-in** via `OS_MCP_SERVER_ENABLED=true` - (404 when off, so the surface isn't advertised); **fail-closed auth** - (anonymous → 401 — requires the principal resolved by Phase 1a's API-key - path or a session). It builds an `McpDataBridge` that runs every operation - through the existing `callData` path bound to the request's - `ExecutionContext`, so external agents run under the key's permissions + RLS, - never a parallel or escalated path. The discovery endpoint advertises `mcp` - only when enabled. - -Security: every external MCP entry runs as the scoped `sys_api_key` principal -under existing object permissions + RLS; MCP is opt-in per env; no raw keys or -secrets cross the wire. Fully unit-tested (transport handshake/tools, gate, -auth, principal binding). diff --git a/.changeset/mcp-web-request-adapter.md b/.changeset/mcp-web-request-adapter.md deleted file mode 100644 index adb5d9d0a..000000000 --- a/.changeset/mcp-web-request-adapter.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -'@objectstack/runtime': patch ---- - -fix(runtime): adapt node/Hono req → Web Request for the MCP transport (ADR-0036) - -The MCP Streamable HTTP transport needs a Web-standard `Request`, but the -runtime HTTP adapter hands the dispatcher a node/Hono-style req (plain `headers` -object, path-only `url`). `handleMcp` rejected it with 400 ("MCP transport -requires a standard HTTP request") — so the live endpoint was unusable even -once routed + registered. Unit tests passed a real `Request`, hiding it; caught -in staging e2e on `initialize`. - -`handleMcp` now reconstructs a Web `Request` (method, absolute URL from -host+path, normalised headers, JSON body from the parsed body) when the inbound -req isn't already Web-standard. Regression tests cover a POST and a GET -node-style req. diff --git a/.changeset/mount-mcp-keys-routes.md b/.changeset/mount-mcp-keys-routes.md deleted file mode 100644 index 754db13df..000000000 --- a/.changeset/mount-mcp-keys-routes.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -'@objectstack/runtime': patch ---- - -fix(runtime): mount /mcp and /keys HTTP routes (ADR-0036) — were unreachable - -The dispatcher mounts routes EXPLICITLY on the HTTP server (no catch-all). The -MCP transport (#1626) and key-generation (#1630) added branches inside -`dispatch()` but never registered the corresponding `server.()` routes, so -`/api/v1/mcp` and `/api/v1/keys` 404'd at the HTTP layer before ever reaching -the dispatcher. Unit tests called the handlers directly, hiding the gap; it only -showed up in live staging e2e. - -- Register `/mcp` (GET/POST/DELETE → dispatch, transport reads the method) and - `/keys` (POST) in the dispatcher plugin, routed through `dispatch()` so the - host's project-aware kernel swap + executionContext resolution run first. -- Add `dispatcher-plugin.routes.test.ts` asserting the routes are registered - (the regression that would have caught this). diff --git a/.changeset/notification-digest.md b/.changeset/notification-digest.md deleted file mode 100644 index f9bf58b84..000000000 --- a/.changeset/notification-digest.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -'@objectstack/service-messaging': minor ---- - -feat(messaging): digest batching for notifications (ADR-0030 P3b-2) - -Recipients can now batch a topic into a `daily` / `weekly` **digest** instead of -receiving every notification immediately. Builds on P3b-1's deferral seam: - -- `PreferenceResolver` consumes the `digest` preference field and `digestDeferral()` - defers a batched recipient to the next window (local midnight / Monday 00:00), - tagging the target with a stable `window`. Digest takes precedence over - quiet-hours; `critical` and mandatory topics bypass it. -- `sys_notification_delivery` gains a `digest_key` (`recipient|channel|window`). - Batched rows partition by that key so a window's rows co-locate, and the normal - outbox `claim()` skips them while the new `claimDigest()` drains a window whole. -- The dispatcher's digest pass collapses each `(recipient, channel, window)` group - into one `renderDigest()` message under the existing per-partition cluster lock, - then acks every row in the group with that single outcome. - -Additive: non-digest notifications are unchanged. Timezone-from-`sys_user`, -configurable send-hour, and MJML digest emails are deferred follow-ups. diff --git a/.changeset/notification-receipt-unique-race.md b/.changeset/notification-receipt-unique-race.md deleted file mode 100644 index dba1cb50d..000000000 --- a/.changeset/notification-receipt-unique-race.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -'@objectstack/service-messaging': patch ---- - -fix(messaging): converge mark-read receipt on unique-index race - -`markRead`'s `upsertReadReceipt` did `findOne`-then-`insert` (check-then-act), so -a concurrent mark-read — or the best-effort `delivered` receipt write still in -flight — could win the `UNIQUE(notification_id, user_id, channel)` index between -the read and the write. Clicking a notification then threw -`UNIQUE constraint failed: sys_notification_receipt...`. The insert now catches a -unique violation and falls back to flipping the now-present row to `read`, with a -cross-driver `isUniqueViolation` helper (SQLite / Postgres `23505` / -MySQL `ER_DUP_ENTRY`). diff --git a/.changeset/objectql-cascade-autonumber.md b/.changeset/objectql-cascade-autonumber.md deleted file mode 100644 index d1a91ec1d..000000000 --- a/.changeset/objectql-cascade-autonumber.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -"@objectstack/objectql": patch ---- - -fix(objectql): master_detail cascade delete + autonumber generation - -- `delete` now applies referential delete behavior for incoming relations: `master_detail` cascades to children (the parent owns the child lifecycle; only an explicit `restrict` deviates), `lookup` honors its `deleteBehavior` (default `set_null`). Recurses for grandchildren, depth-guarded, single-id deletes. Previously deleting a parent left its children orphaned. -- `insert` now generates values for empty `autonumber` fields before required-validation (`max+1`, seeded per `object.field`, honors `autonumberFormat`). Previously a required autonumber was rejected as "missing" and autonumber fields were never populated. diff --git a/.changeset/p0-security-hardening.md b/.changeset/p0-security-hardening.md deleted file mode 100644 index 911f66433..000000000 --- a/.changeset/p0-security-hardening.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -'@objectstack/plugin-auth': patch -'@objectstack/plugin-security': patch -'@objectstack/driver-sql': patch -'@objectstack/driver-mongodb': patch ---- - -fix(security): close four P0 launch-readiness findings - -- **plugin-auth (P0-1):** `generateSecret()` now throws (fails boot) when no - `OS_AUTH_SECRET` is set and `NODE_ENV==='production'`, instead of silently - falling back to a predictable `dev-secret-` (session forgery). The - dev/test fallback is unchanged. -- **plugin-security (P0-2):** the permission-resolution `catch` now **fails - closed** — it logs at ERROR and throws `PermissionDeniedError` rather than - `return next()`. A degraded metadata service can no longer let every - authenticated request bypass RBAC/RLS. System operations still bypass as before. -- **driver-sql (P0-3):** the `contains` / `$contains` operator now escapes LIKE - metacharacters (`%` / `_` / `\`) in the user value and binds an explicit - `ESCAPE '\'`, so a value of `%` matches literally instead of every row - (filter bypass). Correct across SQLite/MySQL/Postgres. -- **driver-mongodb (P0-4):** the field-operator translator now rejects unknown - `$`-operators instead of passing them through, blocking `$where` / `$function` - / `$expr` (server-side JS execution / query-intent bypass). All legitimate - ObjectQL operators remain allowlisted. - -+12 regression tests across the four packages. diff --git a/.changeset/p1-control-plane.md b/.changeset/p1-control-plane.md deleted file mode 100644 index 6a3a8624d..000000000 --- a/.changeset/p1-control-plane.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -'@objectstack/rest': patch -'@objectstack/service-cluster-redis': patch ---- - -perf(rest): cache hostname→environment resolution; document cluster pub/sub durability (P1-4, P1-5) - -- **rest (P1-4):** `resolveByHostname()` ran on every unscoped request — a - control-plane lookup (typically a DB query) in the hot path. `RestServer` now - caches `hostname → environmentId` in-memory with a 30s TTL across all three - resolution sites, caching negative results too so unknown hosts don't hammer the - registry. Registry errors are not cached, so a transient blip self-heals. -- **service-cluster-redis (P1-5):** recorded the durability contract for - `metadata.changed` in `pubsub.ts`. Redis pub/sub is at-most-once **by design**; - the event is a cache-invalidation hint only — the durable source of truth is the - transactional `sys_metadata` (+ `sys_metadata_history`) write, so a missed event - causes a stale cache until the next reload, never data loss. No code change to - the delivery semantics; risk accepted and documented. diff --git a/.changeset/region-step-logs.md b/.changeset/region-step-logs.md deleted file mode 100644 index bcc85b7c7..000000000 --- a/.changeset/region-step-logs.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -'@objectstack/spec': patch -'@objectstack/service-automation': patch ---- - -feat(automation): surface structured-region body steps in run observability (#1505) - -`loop` / `parallel` / `try_catch` previously ran their body, branch, and handler -regions against a region-local step log that was **discarded** — run logs -(`listRuns` / `getRun`) showed the container as a single opaque step, hiding the -per-iteration / per-branch steps that actually executed. - -`AutomationEngine.runRegion()` now **returns** its body steps, and the container -node folds them into the parent run log via a new `NodeExecutionResult.childSteps` -field. Each surfaced step is tagged with its **immediate** container via three new -optional fields on `ExecutionStepLogSchema` (and the engine's `StepLogEntry`): - -- `parentNodeId` — the enclosing `loop` / `parallel` / `try_catch` node -- `iteration` — zero-based loop iteration or parallel branch index -- `regionKind` — `loop-body` | `parallel-branch` | `try` | `catch` - -Tagging fills only fields left undefined, so nested regions keep each step's -innermost container. A failed try-region attempt's partial steps are still not -surfaced (preserving `try_catch` retry semantics). Fully additive — existing run -logs and consumers are unaffected. diff --git a/.changeset/rename-mcp-package.md b/.changeset/rename-mcp-package.md deleted file mode 100644 index 35542d928..000000000 --- a/.changeset/rename-mcp-package.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -'@objectstack/mcp': major -'@objectstack/cli': patch ---- - -refactor(mcp)!: rename `@objectstack/plugin-mcp-server` → `@objectstack/mcp` (ADR-0036) - -The outbound MCP-server package drops the legacy `plugin-` prefix and moves to -the top level (`packages/mcp`), parallel to `@objectstack/rest` — both are "your -app exposed over a protocol". Inbound MCP (consuming external servers) stays -`@objectstack/connector-mcp`. - -**Breaking:** the package name changed. Update imports -`@objectstack/plugin-mcp-server` → `@objectstack/mcp`. The exported API -(`MCPServerPlugin`, `MCPServerRuntime`, `registerObjectTools`, `McpDataBridge`, -…) is unchanged. The internal plugin id is now `com.objectstack.mcp`. Pre-launch -clean break — no compatibility shim (only `@objectstack/cli` depended on it -internally). diff --git a/.changeset/rest-discovery-mcp.md b/.changeset/rest-discovery-mcp.md deleted file mode 100644 index e6dbe1b1a..000000000 --- a/.changeset/rest-discovery-mcp.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -'@objectstack/rest': patch ---- - -fix(rest): advertise `routes.mcp` in /discovery when MCP is enabled (cloud#152) - -The objectui Integrations page reads `discovery.routes.mcp` to show the "Connect -an AI agent" card, but it stayed absent on live envs even with MCP enabled. Root -cause (NOT a cache, as first suspected): `@objectstack/rest` serves its OWN -`/discovery` (`protocol.getDiscovery()`), separate from the dispatcher's -`getDiscoveryInfo` where the `mcp` field was added — so the REST-served discovery -never advertised it. - -The REST discovery handler now adds `routes.mcp` (pointing at the unscoped -`/api/v1/mcp`, since the MCP route is mounted bare) when -`OS_MCP_SERVER_ENABLED=true`, and omits it otherwise — mirroring the dispatcher -discovery and the opt-in gate. 2 tests (enabled → advertised, disabled → absent). diff --git a/.changeset/rest-honors-api-key.md b/.changeset/rest-honors-api-key.md deleted file mode 100644 index 5da8cb10f..000000000 --- a/.changeset/rest-honors-api-key.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -'@objectstack/core': minor -'@objectstack/rest': patch -'@objectstack/runtime': patch ---- - -fix(rest): REST data API honors sys_api_key — one shared verifier with MCP (closes #1633) - -Staging e2e found the MCP surface authenticated a `sys_api_key` but the REST data -API (`@objectstack/rest`) returned 401 for the same key — its `resolveExecCtx` -only checked the better-auth session, never the API key. - -Converged both surfaces onto ONE verifier so they can't drift: - -- **`@objectstack/core/security`** now owns the shared `sys_api_key` primitives - (`hashApiKey`, `generateApiKey`, `extractApiKey`, `parseScopes`, `isExpired`) - plus a new `resolveApiKeyPrincipal(ql, headers, nowMs?)` that hashes the - inbound key, looks it up by the indexed at-rest hash, and rejects unknown / - revoked / expired / owner-less keys (fail-closed). `core` is the natural home: - both `rest` and `runtime` depend on it, it depends on neither (no cycle), and - it's server-side (already uses `node:crypto`). -- **`@objectstack/runtime`** — `security/api-key.ts` re-exports the primitives - from core (stable import surface) and `resolveExecutionContext` now delegates - its API-key branch to `resolveApiKeyPrincipal`. -- **`@objectstack/rest`** — `resolveExecCtx` resolves the data engine once and - tries `resolveApiKeyPrincipal` (x-api-key / `Authorization: ApiKey`) BEFORE the - session, so `/api/v1/data` + `/api/v1/meta` now authenticate an API key under - the key's permissions + RLS, exactly like the dispatcher/MCP path. - -Tests: core `api-key.test.ts` (primitives + verifier: valid / revoked / expired / -unknown / owner-less / plaintext-not-matched / fail-closed-ql). runtime + rest -suites green. diff --git a/.changeset/rest-map-schema-errors.md b/.changeset/rest-map-schema-errors.md deleted file mode 100644 index a94e6a8bc..000000000 --- a/.changeset/rest-map-schema-errors.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -'@objectstack/rest': patch ---- - -fix(rest): map schema-mismatch & not-null driver errors to structured 4xx - -`mapDataError` collapsed any SQL-looking driver error into a generic -`500 DATABASE_ERROR`, so a bad write payload to the data API leaked a 500 -instead of a fixable 4xx (e.g. `POST /data/sys_team` with an unknown field, -or omitting a required column). It now maps unknown-column errors to -`400 INVALID_FIELD { field }` and not-null violations to -`400 VALIDATION_FAILED { fields:[{required}] }` across SQLite/Postgres/MySQL -phrasings, placed before the unknown-object branch so Postgres -`column … of relation … does not exist` is not mis-mapped to 404. Genuine -driver faults still return 500; unique violations still return 409. diff --git a/.changeset/retire-workflow-rule-paradigm.md b/.changeset/retire-workflow-rule-paradigm.md deleted file mode 100644 index 47d9505d9..000000000 --- a/.changeset/retire-workflow-rule-paradigm.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -'@objectstack/spec': patch -'@objectstack/service-automation': patch ---- - -chore(automation): retire the `workflow_rule` authoring paradigm (ADR-0018 M5 dropped) - -ADR-0019 already removed the Workflow-Rule → Flow compiler (Workflow Rules were -removed in #1398 and `workflow` was reclaimed for state machines), but the -`workflow_rule` paradigm tag survived in `ActionParadigmSchema` and on every -built-in node descriptor. There is no declarative Workflow-Rule authoring view -to feed, so the tag is now retired: `ActionParadigmSchema` keeps `['flow', -'approval']`, and the `http` / `notify` / `connector_action` descriptors (plus -the deprecated-alias fallback) advertise `['flow', 'approval']`. Approval -execution convergence is delivered by the ADR-0019 approval Flow node, not a -compiler. ADR-0018's status and migration table are updated to mark M3 shipped, -M4 framework-complete, and M5 dropped. diff --git a/.changeset/showcase-project-detail.md b/.changeset/showcase-project-detail.md deleted file mode 100644 index fe8a3a135..000000000 --- a/.changeset/showcase-project-detail.md +++ /dev/null @@ -1,4 +0,0 @@ ---- ---- - -docs(app-showcase): slotted project detail page with an inline-editable `record:line_items` Tasks grid (example only). diff --git a/.changeset/summary-rollup-fields.md b/.changeset/summary-rollup-fields.md deleted file mode 100644 index dc3d1f8bc..000000000 --- a/.changeset/summary-rollup-fields.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -'@objectstack/spec': minor -'@objectstack/objectql': minor ---- - -feat(objectql): compute roll-up `summary` fields server-side - -The `summary` field type was declared in the spec but never computed — its value -stayed empty. ObjectQL now recomputes roll-up summaries automatically: a parent -field whose `summaryOperations` aggregates (`count`/`sum`/`min`/`max`/`avg`) a -field across child records is recalculated whenever a child is inserted, -updated, or deleted. - -- **`@objectstack/spec`** — `summaryOperations` gains an optional - `relationshipField` (the child→parent FK). When omitted the engine - auto-detects it from the child's `lookup`/`master_detail` field whose - `reference` points back at the parent; set it explicitly only when the child - has more than one such reference. - -- **`@objectstack/objectql`** — after `afterInsert` / `afterUpdate` / - `afterDelete` on a child object, the engine finds the affected parent (from - the child's FK, plus the prior FK on update/delete so a re-parented child - updates both), re-aggregates the child collection, and writes the result onto - the parent's summary field. It runs in the caller's execution context, so when - a transaction is open (e.g. the cross-object `/api/v1/batch`) the rollup - commits atomically with the child writes. A small index of child→summary - descriptors is built lazily from the registry and invalidated on package - registration. - -Empty collections roll up to `0` for `count`/`sum` and `null` for -`min`/`max`/`avg`. This lets master-detail forms stop computing parent totals on -the client — the server is now the single source of truth. diff --git a/.changeset/tx-ambient-fix.md b/.changeset/tx-ambient-fix.md deleted file mode 100644 index 83754d71d..000000000 --- a/.changeset/tx-ambient-fix.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@objectstack/objectql": minor -"@objectstack/rest": minor ---- - -Robust multi-write transactions (ADR-0034). `engine.transaction()` now establishes an ambient transaction (AsyncLocalStorage) so every data operation during the callback — including internal reads performed while a write runs — binds to the active transaction's connection instead of asking the pool for another one and deadlocking on SQLite's single-connection pool. Adds a cross-object transactional batch endpoint (`POST /api/v1/data/batch`) with intra-batch `{ $ref: }` parent references, so a parent and its children can be created atomically in one transaction. diff --git a/apps/account/CHANGELOG.md b/apps/account/CHANGELOG.md index 8e57baf4f..1dad4923e 100644 --- a/apps/account/CHANGELOG.md +++ b/apps/account/CHANGELOG.md @@ -1,5 +1,7 @@ # @objectstack/account +## 8.0.0 + ## 7.9.0 ## 7.8.0 diff --git a/apps/account/package.json b/apps/account/package.json index 7149d7224..0bedb0f14 100644 --- a/apps/account/package.json +++ b/apps/account/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/account", - "version": "7.9.0", + "version": "8.0.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 6ba28eea1..9f7a836dc 100644 --- a/examples/app-crm/CHANGELOG.md +++ b/examples/app-crm/CHANGELOG.md @@ -1,5 +1,26 @@ # @objectstack/example-crm +## 4.0.38 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [f68be58] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [bc0d85b] +- Updated dependencies [2537e28] +- Updated dependencies [0ec7717] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/runtime@8.0.0 + ## 4.0.37 ### Patch Changes diff --git a/examples/app-crm/package.json b/examples/app-crm/package.json index 27bd2031b..cad6647b3 100644 --- a/examples/app-crm/package.json +++ b/examples/app-crm/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/example-crm", - "version": "4.0.37", + "version": "4.0.38", "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 index 6fa6d823f..1cb08d368 100644 --- a/examples/app-showcase/CHANGELOG.md +++ b/examples/app-showcase/CHANGELOG.md @@ -1,5 +1,28 @@ # @objectstack/example-showcase +## 0.1.8 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [f68be58] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [bc0d85b] +- Updated dependencies [2537e28] +- Updated dependencies [0ec7717] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/runtime@8.0.0 + - @objectstack/connector-rest@8.0.0 + - @objectstack/connector-slack@8.0.0 + ## 0.1.7 ### Patch Changes diff --git a/examples/app-showcase/package.json b/examples/app-showcase/package.json index 11c2e1440..1e553d270 100644 --- a/examples/app-showcase/package.json +++ b/examples/app-showcase/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/example-showcase", - "version": "0.1.7", + "version": "0.1.8", "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 cf84119f8..adee40cf3 100644 --- a/examples/app-todo/CHANGELOG.md +++ b/examples/app-todo/CHANGELOG.md @@ -1,5 +1,35 @@ # @objectstack/example-todo +## 4.0.38 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [f68be58] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [bc0d85b] +- Updated dependencies [2537e28] +- Updated dependencies [0ec7717] +- Updated dependencies [e6374b5] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] +- Updated dependencies [345e189] + - @objectstack/spec@8.0.0 + - @objectstack/service-ai@8.0.0 + - @objectstack/runtime@8.0.0 + - @objectstack/objectql@8.0.0 + - @objectstack/client@8.0.0 + - @objectstack/metadata@8.0.0 + - @objectstack/driver-sqlite-wasm@8.0.0 + - @objectstack/knowledge-memory@8.0.0 + - @objectstack/service-knowledge@8.0.0 + ## 4.0.37 ### Patch Changes diff --git a/examples/app-todo/package.json b/examples/app-todo/package.json index ddbc8cea7..e1104e2b7 100644 --- a/examples/app-todo/package.json +++ b/examples/app-todo/package.json @@ -1,6 +1,6 @@ { "name": "@example/app-todo", - "version": "4.0.37", + "version": "4.0.38", "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 9d93932aa..4ef53a94a 100644 --- a/packages/adapters/express/CHANGELOG.md +++ b/packages/adapters/express/CHANGELOG.md @@ -1,5 +1,16 @@ # @objectstack/express +## 8.0.0 + +### Patch Changes + +- Updated dependencies [f68be58] +- Updated dependencies [bc0d85b] +- Updated dependencies [2537e28] +- Updated dependencies [0ec7717] +- Updated dependencies [c262301] + - @objectstack/runtime@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/adapters/express/package.json b/packages/adapters/express/package.json index ea45aed94..f5b6ca2c2 100644 --- a/packages/adapters/express/package.json +++ b/packages/adapters/express/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/express", - "version": "7.9.0", + "version": "8.0.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 556583977..9750b78c5 100644 --- a/packages/adapters/fastify/CHANGELOG.md +++ b/packages/adapters/fastify/CHANGELOG.md @@ -1,5 +1,16 @@ # @objectstack/fastify +## 8.0.0 + +### Patch Changes + +- Updated dependencies [f68be58] +- Updated dependencies [bc0d85b] +- Updated dependencies [2537e28] +- Updated dependencies [0ec7717] +- Updated dependencies [c262301] + - @objectstack/runtime@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/adapters/fastify/package.json b/packages/adapters/fastify/package.json index 0490d3623..2418ec488 100644 --- a/packages/adapters/fastify/package.json +++ b/packages/adapters/fastify/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/fastify", - "version": "7.9.0", + "version": "8.0.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 314df9018..772d8673b 100644 --- a/packages/adapters/hono/CHANGELOG.md +++ b/packages/adapters/hono/CHANGELOG.md @@ -1,5 +1,28 @@ # @objectstack/hono +## 8.0.0 + +### Patch Changes + +- e15c845: feat(hono): re-export the `Hono` type from `@objectstack/hono` + + Downstream apps that consume `createHonoApp()` only need the `Hono` type to + annotate the returned app. They can now `import type { Hono } from '@objectstack/hono'` + instead of adding their own `hono` dependency, which guarantees a single + `hono` across a `link:`/cross-package boundary (no duplicate-package + type-identity errors, no version-pin alignment). `hono` remains a normal + runtime dependency of this package, so standalone usage is unaffected. + +- Updated dependencies [f68be58] +- Updated dependencies [93f97b2] +- Updated dependencies [bc0d85b] +- Updated dependencies [2537e28] +- Updated dependencies [0ec7717] +- Updated dependencies [c262301] + - @objectstack/runtime@8.0.0 + - @objectstack/plugin-hono-server@8.0.0 + - @objectstack/types@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/adapters/hono/package.json b/packages/adapters/hono/package.json index d0cc63a20..7b3762b36 100644 --- a/packages/adapters/hono/package.json +++ b/packages/adapters/hono/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/hono", - "version": "7.9.0", + "version": "8.0.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 996160108..35f2cf1a2 100644 --- a/packages/adapters/nestjs/CHANGELOG.md +++ b/packages/adapters/nestjs/CHANGELOG.md @@ -1,5 +1,16 @@ # @objectstack/nestjs +## 8.0.0 + +### Patch Changes + +- Updated dependencies [f68be58] +- Updated dependencies [bc0d85b] +- Updated dependencies [2537e28] +- Updated dependencies [0ec7717] +- Updated dependencies [c262301] + - @objectstack/runtime@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/adapters/nestjs/package.json b/packages/adapters/nestjs/package.json index a3bc86f19..8ed9d2b31 100644 --- a/packages/adapters/nestjs/package.json +++ b/packages/adapters/nestjs/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/nestjs", - "version": "7.9.0", + "version": "8.0.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 d1a1eeab9..28060afc9 100644 --- a/packages/adapters/nextjs/CHANGELOG.md +++ b/packages/adapters/nextjs/CHANGELOG.md @@ -1,5 +1,16 @@ # @objectstack/nextjs +## 8.0.0 + +### Patch Changes + +- Updated dependencies [f68be58] +- Updated dependencies [bc0d85b] +- Updated dependencies [2537e28] +- Updated dependencies [0ec7717] +- Updated dependencies [c262301] + - @objectstack/runtime@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/adapters/nextjs/package.json b/packages/adapters/nextjs/package.json index d0aecc952..340421916 100644 --- a/packages/adapters/nextjs/package.json +++ b/packages/adapters/nextjs/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/nextjs", - "version": "7.9.0", + "version": "8.0.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 005e61707..49c2bd9a1 100644 --- a/packages/adapters/nuxt/CHANGELOG.md +++ b/packages/adapters/nuxt/CHANGELOG.md @@ -1,5 +1,16 @@ # @objectstack/nuxt +## 8.0.0 + +### Patch Changes + +- Updated dependencies [f68be58] +- Updated dependencies [bc0d85b] +- Updated dependencies [2537e28] +- Updated dependencies [0ec7717] +- Updated dependencies [c262301] + - @objectstack/runtime@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/adapters/nuxt/package.json b/packages/adapters/nuxt/package.json index 53422eb19..61e22a78c 100644 --- a/packages/adapters/nuxt/package.json +++ b/packages/adapters/nuxt/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/nuxt", - "version": "7.9.0", + "version": "8.0.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 7f1c5fdcf..c1f4f37a2 100644 --- a/packages/adapters/sveltekit/CHANGELOG.md +++ b/packages/adapters/sveltekit/CHANGELOG.md @@ -1,5 +1,16 @@ # @objectstack/sveltekit +## 8.0.0 + +### Patch Changes + +- Updated dependencies [f68be58] +- Updated dependencies [bc0d85b] +- Updated dependencies [2537e28] +- Updated dependencies [0ec7717] +- Updated dependencies [c262301] + - @objectstack/runtime@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/adapters/sveltekit/package.json b/packages/adapters/sveltekit/package.json index cfcbbe54a..9347e29c3 100644 --- a/packages/adapters/sveltekit/package.json +++ b/packages/adapters/sveltekit/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/sveltekit", - "version": "7.9.0", + "version": "8.0.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 b48426ecb..d9d856554 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,91 @@ # @objectstack/cli +## 8.0.0 + +### Patch Changes + +- d9f72fe: refactor(mcp)!: rename `@objectstack/plugin-mcp-server` → `@objectstack/mcp` (ADR-0036) + + The outbound MCP-server package drops the legacy `plugin-` prefix and moves to + the top level (`packages/mcp`), parallel to `@objectstack/rest` — both are "your + app exposed over a protocol". Inbound MCP (consuming external servers) stays + `@objectstack/connector-mcp`. + + **Breaking:** the package name changed. Update imports + `@objectstack/plugin-mcp-server` → `@objectstack/mcp`. The exported API + (`MCPServerPlugin`, `MCPServerRuntime`, `registerObjectTools`, `McpDataBridge`, + …) is unchanged. The internal plugin id is now `com.objectstack.mcp`. Pre-launch + clean break — no compatibility shim (only `@objectstack/cli` depended on it + internally). + +- Updated dependencies [a46c017] +- Updated dependencies [f68be58] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [93f97b2] +- Updated dependencies [87cb13c] +- Updated dependencies [bc0d85b] +- Updated dependencies [2537e28] +- Updated dependencies [0ec7717] +- Updated dependencies [9f311f8] +- Updated dependencies [c70eec1] +- Updated dependencies [e6374b5] +- Updated dependencies [1e8b680] +- Updated dependencies [0a6438e] +- Updated dependencies [3306d2f] +- Updated dependencies [d9f72fe] +- Updated dependencies [ae7fb3f] +- Updated dependencies [c262301] +- Updated dependencies [e1478fe] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] +- Updated dependencies [345e189] + - @objectstack/spec@8.0.0 + - @objectstack/service-ai@8.0.0 + - @objectstack/runtime@8.0.0 + - @objectstack/objectql@8.0.0 + - @objectstack/driver-sql@8.0.0 + - @objectstack/plugin-hono-server@8.0.0 + - @objectstack/mcp@8.0.0 + - @objectstack/service-messaging@8.0.0 + - @objectstack/plugin-auth@8.0.0 + - @objectstack/plugin-security@8.0.0 + - @objectstack/driver-mongodb@8.0.0 + - @objectstack/rest@8.0.0 + - @objectstack/service-automation@8.0.0 + - @objectstack/core@8.0.0 + - @objectstack/account@8.0.0 + - @objectstack/client@8.0.0 + - @objectstack/formula@8.0.0 + - @objectstack/observability@8.0.0 + - @objectstack/platform-objects@8.0.0 + - @objectstack/driver-memory@8.0.0 + - @objectstack/driver-sqlite-wasm@8.0.0 + - @objectstack/plugin-approvals@8.0.0 + - @objectstack/plugin-audit@8.0.0 + - @objectstack/plugin-email@8.0.0 + - @objectstack/plugin-org-scoping@8.0.0 + - @objectstack/plugin-reports@8.0.0 + - @objectstack/plugin-sharing@8.0.0 + - @objectstack/plugin-trigger-record-change@8.0.0 + - @objectstack/plugin-trigger-schedule@8.0.0 + - @objectstack/plugin-webhooks@8.0.0 + - @objectstack/service-analytics@8.0.0 + - @objectstack/service-cache@8.0.0 + - @objectstack/service-datasource@8.0.0 + - @objectstack/service-feed@8.0.0 + - @objectstack/service-job@8.0.0 + - @objectstack/service-package@8.0.0 + - @objectstack/service-queue@8.0.0 + - @objectstack/service-realtime@8.0.0 + - @objectstack/service-settings@8.0.0 + - @objectstack/service-storage@8.0.0 + - @objectstack/types@8.0.0 + - @objectstack/console@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index 6fd03dcb9..dd58b04fd 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/cli", - "version": "7.9.0", + "version": "8.0.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 ba43719fa..e5d4450a7 100644 --- a/packages/client-react/CHANGELOG.md +++ b/packages/client-react/CHANGELOG.md @@ -1,5 +1,23 @@ # @objectstack/client-react +## 8.0.0 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + - @objectstack/client@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/client-react/package.json b/packages/client-react/package.json index 01963b021..a32b85b2f 100644 --- a/packages/client-react/package.json +++ b/packages/client-react/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/client-react", - "version": "7.9.0", + "version": "8.0.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 4875b4c15..e381fb32c 100644 --- a/packages/client/CHANGELOG.md +++ b/packages/client/CHANGELOG.md @@ -1,5 +1,22 @@ # @objectstack/client +## 8.0.0 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/client/package.json b/packages/client/package.json index 291ed07c1..235820187 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/client", - "version": "7.9.0", + "version": "8.0.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 index c7a675bcc..a77de6513 100644 --- a/packages/connectors/connector-mcp/CHANGELOG.md +++ b/packages/connectors/connector-mcp/CHANGELOG.md @@ -1,5 +1,42 @@ # @objectstack/connector-mcp +## 8.0.0 + +### Patch Changes + +- d5a8161: feat(spec): resilientFetch — timeout + backoff for outbound HTTP (P1-1) + + Outbound calls in the connectors/embedder were naked `fetch` with no timeout or + retry, so a slow or rate-limited external API could hang an agent turn with no + recovery. + + New shared `resilientFetch` (`@objectstack/spec/shared`): + + - per-attempt timeout via `AbortController` (default 30s); + - exponential backoff with jitter, up to 3 attempts, on network errors / 429 / 5xx; + - honours a `Retry-After` header on 429; + - never retries a caller-initiated abort (intentional cancellation). + + Wired into `connector-rest`, `connector-slack`, and `embedder-openai`. + `connector-mcp` talks through the MCP SDK transport, so it gets a 30s per-request + `timeout` on `callTool` / `listTools` instead. + + A stateful per-host **circuit breaker** is deliberately left as a follow-up: + timeout + backoff already removes the hang/no-recovery risk. + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/connectors/connector-mcp/package.json b/packages/connectors/connector-mcp/package.json index b682c0cf2..805dff543 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.9.0", + "version": "8.0.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 index a459e1a75..8612046e5 100644 --- a/packages/connectors/connector-openapi/CHANGELOG.md +++ b/packages/connectors/connector-openapi/CHANGELOG.md @@ -1,5 +1,22 @@ # @objectstack/connector-openapi +## 8.0.0 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/connectors/connector-openapi/package.json b/packages/connectors/connector-openapi/package.json index 9867ea32d..e9f93d1e7 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.9.0", + "version": "8.0.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 index 83740dc55..dc199f865 100644 --- a/packages/connectors/connector-rest/CHANGELOG.md +++ b/packages/connectors/connector-rest/CHANGELOG.md @@ -1,5 +1,42 @@ # @objectstack/connector-rest +## 8.0.0 + +### Patch Changes + +- d5a8161: feat(spec): resilientFetch — timeout + backoff for outbound HTTP (P1-1) + + Outbound calls in the connectors/embedder were naked `fetch` with no timeout or + retry, so a slow or rate-limited external API could hang an agent turn with no + recovery. + + New shared `resilientFetch` (`@objectstack/spec/shared`): + + - per-attempt timeout via `AbortController` (default 30s); + - exponential backoff with jitter, up to 3 attempts, on network errors / 429 / 5xx; + - honours a `Retry-After` header on 429; + - never retries a caller-initiated abort (intentional cancellation). + + Wired into `connector-rest`, `connector-slack`, and `embedder-openai`. + `connector-mcp` talks through the MCP SDK transport, so it gets a 30s per-request + `timeout` on `callTool` / `listTools` instead. + + A stateful per-host **circuit breaker** is deliberately left as a follow-up: + timeout + backoff already removes the hang/no-recovery risk. + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/connectors/connector-rest/package.json b/packages/connectors/connector-rest/package.json index 57ad0dec6..d8849730e 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.9.0", + "version": "8.0.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 index 9fdb7b1b1..9b41c15e1 100644 --- a/packages/connectors/connector-slack/CHANGELOG.md +++ b/packages/connectors/connector-slack/CHANGELOG.md @@ -1,5 +1,42 @@ # @objectstack/connector-slack +## 8.0.0 + +### Patch Changes + +- d5a8161: feat(spec): resilientFetch — timeout + backoff for outbound HTTP (P1-1) + + Outbound calls in the connectors/embedder were naked `fetch` with no timeout or + retry, so a slow or rate-limited external API could hang an agent turn with no + recovery. + + New shared `resilientFetch` (`@objectstack/spec/shared`): + + - per-attempt timeout via `AbortController` (default 30s); + - exponential backoff with jitter, up to 3 attempts, on network errors / 429 / 5xx; + - honours a `Retry-After` header on 429; + - never retries a caller-initiated abort (intentional cancellation). + + Wired into `connector-rest`, `connector-slack`, and `embedder-openai`. + `connector-mcp` talks through the MCP SDK transport, so it gets a 30s per-request + `timeout` on `callTool` / `listTools` instead. + + A stateful per-host **circuit breaker** is deliberately left as a follow-up: + timeout + backoff already removes the hang/no-recovery risk. + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/connectors/connector-slack/package.json b/packages/connectors/connector-slack/package.json index 8890187ac..5d6da5526 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.9.0", + "version": "8.0.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 2465b139f..8415280c4 100644 --- a/packages/console/CHANGELOG.md +++ b/packages/console/CHANGELOG.md @@ -1,5 +1,7 @@ # @objectstack/console +## 8.0.0 + ## 7.9.0 ## 7.8.0 diff --git a/packages/console/package.json b/packages/console/package.json index c59554842..82d0752ce 100644 --- a/packages/console/package.json +++ b/packages/console/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/console", - "version": "7.9.0", + "version": "8.0.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 ad8c89f0e..0b32ea7b0 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -1,5 +1,49 @@ # @objectstack/core +## 8.0.0 + +### Minor Changes + +- c262301: fix(rest): REST data API honors sys_api_key — one shared verifier with MCP (closes #1633) + + Staging e2e found the MCP surface authenticated a `sys_api_key` but the REST data + API (`@objectstack/rest`) returned 401 for the same key — its `resolveExecCtx` + only checked the better-auth session, never the API key. + + Converged both surfaces onto ONE verifier so they can't drift: + + - **`@objectstack/core/security`** now owns the shared `sys_api_key` primitives + (`hashApiKey`, `generateApiKey`, `extractApiKey`, `parseScopes`, `isExpired`) + plus a new `resolveApiKeyPrincipal(ql, headers, nowMs?)` that hashes the + inbound key, looks it up by the indexed at-rest hash, and rejects unknown / + revoked / expired / owner-less keys (fail-closed). `core` is the natural home: + both `rest` and `runtime` depend on it, it depends on neither (no cycle), and + it's server-side (already uses `node:crypto`). + - **`@objectstack/runtime`** — `security/api-key.ts` re-exports the primitives + from core (stable import surface) and `resolveExecutionContext` now delegates + its API-key branch to `resolveApiKeyPrincipal`. + - **`@objectstack/rest`** — `resolveExecCtx` resolves the data engine once and + tries `resolveApiKeyPrincipal` (x-api-key / `Authorization: ApiKey`) BEFORE the + session, so `/api/v1/data` + `/api/v1/meta` now authenticate an API key under + the key's permissions + RLS, exactly like the dispatcher/MCP path. + + Tests: core `api-key.test.ts` (primitives + verifier: valid / revoked / expired / + unknown / owner-less / plaintext-not-matched / fail-closed-ql). runtime + rest + suites green. + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/core/package.json b/packages/core/package.json index 672e7e315..d2603104d 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/core", - "version": "7.9.0", + "version": "8.0.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 c43031dd7..08df1d3a7 100644 --- a/packages/create-objectstack/CHANGELOG.md +++ b/packages/create-objectstack/CHANGELOG.md @@ -1,5 +1,7 @@ # create-objectstack +## 8.0.0 + ## 7.9.0 ## 7.8.0 diff --git a/packages/create-objectstack/package.json b/packages/create-objectstack/package.json index b1ffc090c..5d8665f86 100644 --- a/packages/create-objectstack/package.json +++ b/packages/create-objectstack/package.json @@ -1,6 +1,6 @@ { "name": "create-objectstack", - "version": "7.9.0", + "version": "8.0.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 ba75dc515..72fd42597 100644 --- a/packages/formula/CHANGELOG.md +++ b/packages/formula/CHANGELOG.md @@ -1,5 +1,20 @@ # @objectstack/formula +## 8.0.0 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/formula/package.json b/packages/formula/package.json index 87d51c7a5..12fda58e0 100644 --- a/packages/formula/package.json +++ b/packages/formula/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/formula", - "version": "7.9.0", + "version": "8.0.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/mcp/CHANGELOG.md b/packages/mcp/CHANGELOG.md index 2192fa6df..0762b25f3 100644 --- a/packages/mcp/CHANGELOG.md +++ b/packages/mcp/CHANGELOG.md @@ -1,5 +1,102 @@ # @objectstack/plugin-mcp-server +## 8.0.0 + +### Major Changes + +- d9f72fe: refactor(mcp)!: rename `@objectstack/plugin-mcp-server` → `@objectstack/mcp` (ADR-0036) + + The outbound MCP-server package drops the legacy `plugin-` prefix and moves to + the top level (`packages/mcp`), parallel to `@objectstack/rest` — both are "your + app exposed over a protocol". Inbound MCP (consuming external servers) stays + `@objectstack/connector-mcp`. + + **Breaking:** the package name changed. Update imports + `@objectstack/plugin-mcp-server` → `@objectstack/mcp`. The exported API + (`MCPServerPlugin`, `MCPServerRuntime`, `registerObjectTools`, `McpDataBridge`, + …) is unchanged. The internal plugin id is now `com.objectstack.mcp`. Pre-launch + clean break — no compatibility shim (only `@objectstack/cli` depended on it + internally). + +### Minor Changes + +- 87cb13c: feat(mcp): generic ObjectStack Agent Skill generator (ADR-0036 Phase 2b) + + Adds `renderSkillMarkdown({ mcpUrl, envName })` — produces a portable + `SKILL.md` (open Agent Skills standard: Claude Code, OpenAI Codex, Gemini CLI, + Copilot, Cursor, …) that teaches any skills-capable agent how to drive an + ObjectStack environment over MCP. + + Per ADR-0036 Amendment C, this is ONE generic skill, not a per-app artifact: + + - the content never enumerates a tenant's schema — it instructs the agent to + discover live via `list_objects` / `describe_object`, so one install works for + every app the caller's key can reach and a new app needs no reinstall; + - only the connection URL is environment-specific, slotted in by the caller; + - it documents the object-CRUD tools, auth via `x-api-key` (Bearer is session + auth), and the governance model (every call runs under the caller's + permissions + RLS — fewer rows / write rejections are expected, not bugs). + + Exported: `renderSkillMarkdown`, `OBJECTSTACK_SKILL_NAME`, + `OBJECTSTACK_SKILL_DESCRIPTION`, `RenderSkillOptions`. The objectui/cloud + surfacing layer calls this to offer a one-click skill download alongside the + env's remote-MCP URL and a show-once key. + +- bc0d85b: feat(mcp): Streamable HTTP transport — every app is a network-reachable MCP server (ADR-0036 Phase 2) + + The MCP server plugin spoke **stdio only**, so a remote agent (Claude Desktop / + Cursor) could not connect to a hosted env. This adds the **Streamable HTTP** + transport and wires it into the runtime's request path, building on the Phase 1a + `sys_api_key` auth foundation. + + - **`@objectstack/mcp`** (renamed from `@objectstack/plugin-mcp-server` — see the rename changeset) + + - `MCPServerRuntime.handleHttpRequest(request, { bridge, parsedBody })` — + serves one MCP request over the Web-standard `WebStandardStreamableHTTPServerTransport` + (runs on Node 18+, Workers, Deno, Bun). **Stateless**: a fresh, isolated + `McpServer` + transport is built per request (the SDK-recommended pattern), + in JSON-response mode so the response is fully buffered — no streaming + pass-through concerns over the Worker→container hop. + - New `registerObjectTools` + `McpDataBridge` (`mcp-http-tools.ts`): the + object-CRUD tool set (`list_objects`, `describe_object`, `query_records`, + `get_record`, `create_record`, `update_record`, `delete_record`). All + execution is delegated to an injected, **principal-bound** bridge — the tool + layer never touches the data engine directly. System (`sys_*`) objects are + **not exposed** by default (fail-closed guard on every object-scoped tool). + The internal AI/authoring toolRegistry is deliberately NOT bridged onto the + external surface. + + - **`@objectstack/runtime`** + - `HttpDispatcher` serves `/mcp`: **opt-in** via `OS_MCP_SERVER_ENABLED=true` + (404 when off, so the surface isn't advertised); **fail-closed auth** + (anonymous → 401 — requires the principal resolved by Phase 1a's API-key + path or a session). It builds an `McpDataBridge` that runs every operation + through the existing `callData` path bound to the request's + `ExecutionContext`, so external agents run under the key's permissions + RLS, + never a parallel or escalated path. The discovery endpoint advertises `mcp` + only when enabled. + + Security: every external MCP entry runs as the scoped `sys_api_key` principal + under existing object permissions + RLS; MCP is opt-in per env; no raw keys or + secrets cross the wire. Fully unit-tested (transport handshake/tools, gate, + auth, principal binding). + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + - @objectstack/types@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/mcp/package.json b/packages/mcp/package.json index a5fd6dd7a..803019d11 100644 --- a/packages/mcp/package.json +++ b/packages/mcp/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/mcp", - "version": "7.9.0", + "version": "8.0.0", "license": "Apache-2.0", "description": "ObjectStack as an MCP server — exposes your app's objects (and AI tools) over the Model Context Protocol (stdio + Streamable HTTP)", "type": "module", diff --git a/packages/metadata-core/CHANGELOG.md b/packages/metadata-core/CHANGELOG.md index 0555bf087..757518fa6 100644 --- a/packages/metadata-core/CHANGELOG.md +++ b/packages/metadata-core/CHANGELOG.md @@ -1,5 +1,20 @@ # @objectstack/metadata-core +## 8.0.0 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/metadata-core/package.json b/packages/metadata-core/package.json index 7175c7d34..8f1a16e22 100644 --- a/packages/metadata-core/package.json +++ b/packages/metadata-core/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/metadata-core", - "version": "7.9.0", + "version": "8.0.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 5926f1bba..90405879f 100644 --- a/packages/metadata-fs/CHANGELOG.md +++ b/packages/metadata-fs/CHANGELOG.md @@ -1,5 +1,11 @@ # @objectstack/metadata-fs +## 8.0.0 + +### Patch Changes + +- @objectstack/metadata-core@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/metadata-fs/package.json b/packages/metadata-fs/package.json index f88040ae2..33402615e 100644 --- a/packages/metadata-fs/package.json +++ b/packages/metadata-fs/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/metadata-fs", - "version": "7.9.0", + "version": "8.0.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 6a90331bd..59ef089c3 100644 --- a/packages/metadata/CHANGELOG.md +++ b/packages/metadata/CHANGELOG.md @@ -1,5 +1,26 @@ # @objectstack/metadata +## 8.0.0 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + - @objectstack/metadata-core@8.0.0 + - @objectstack/platform-objects@8.0.0 + - @objectstack/types@8.0.0 + - @objectstack/metadata-fs@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/metadata/package.json b/packages/metadata/package.json index c562b40fa..8b76bbd49 100644 --- a/packages/metadata/package.json +++ b/packages/metadata/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/metadata", - "version": "7.9.0", + "version": "8.0.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 218d7ff1f..afff6797d 100644 --- a/packages/objectql/CHANGELOG.md +++ b/packages/objectql/CHANGELOG.md @@ -1,5 +1,98 @@ # @objectstack/objectql +## 8.0.0 + +### Minor Changes + +- b990b89: fix(autonumber): one owner for autonumber generation — the persistent driver sequence (#1603) + + Autonumber values were generated in TWO places: the SQL driver's persistent, + atomic `_objectstack_sequences` table AND a non-persistent in-memory counter in + the ObjectQL engine. Because the engine pre-filled the field BEFORE calling the + driver, the driver always saw a value already set and skipped — so the + persistent sequence was effectively dead code, and a multi-instance / post-restart + deployment could mint duplicate numbers from the in-memory counter. + + This makes generation single-owner: + + - **`@objectstack/spec`** — `DriverCapabilities` gains an optional `autonumber` + flag: "driver natively generates persistent autonumber/sequence values". + + - **`@objectstack/driver-sql`** — advertises `supports.autonumber = true`. + `bulkCreate()` now fills autonumber fields too (previously only `create()` / + `upsert()` did), so bulk inserts also draw from the persistent sequence. + Field parsing now honors either the spec-canonical `autonumberFormat` key OR + the `format` shorthand (both appear in metadata). + + - **`@objectstack/objectql`** — when the driver advertises native autonumber + support, the engine NO LONGER pre-fills (it defers entirely to the persistent + driver sequence as the single source of truth). For drivers without native + support (memory, mongodb) the in-memory fallback is unchanged. The fallback + also now reads either `autonumberFormat` or `format`. Record-validation + exempts `autonumber` fields from the `required` check — the value is + runtime-owned and assigned after validation, so a required record number is + never rejected as "missing". + + No metadata changes required. Existing data is respected: the driver bootstraps + each sequence from the current max numeric tail on first use. + +- 99111ec: Field-level conditional rules (CEL): `visibleWhen` / `readonlyWhen` / `requiredWhen`, enforced server-side. + + Add three CEL-predicate field props (over `record`) evaluated on both sides. **Spec**: `visibleWhen` / `readonlyWhen` / `requiredWhen` (`requiredWhen` canonical; `conditionalRequired` kept as a back-compat alias). **Server (objectql)**: the validator now enforces `requiredWhen`/`conditionalRequired` over the merged record (so the rule can't be bypassed by a direct API write), and the update path ignores writes to a field whose `readonlyWhen` is TRUE (keeps the persisted value). `needsPriorRecord` accounts for conditional fields so the prior record is fetched on update. + +- 9e2e229: feat(objectql): compute roll-up `summary` fields server-side + + The `summary` field type was declared in the spec but never computed — its value + stayed empty. ObjectQL now recomputes roll-up summaries automatically: a parent + field whose `summaryOperations` aggregates (`count`/`sum`/`min`/`max`/`avg`) a + field across child records is recalculated whenever a child is inserted, + updated, or deleted. + + - **`@objectstack/spec`** — `summaryOperations` gains an optional + `relationshipField` (the child→parent FK). When omitted the engine + auto-detects it from the child's `lookup`/`master_detail` field whose + `reference` points back at the parent; set it explicitly only when the child + has more than one such reference. + + - **`@objectstack/objectql`** — after `afterInsert` / `afterUpdate` / + `afterDelete` on a child object, the engine finds the affected parent (from + the child's FK, plus the prior FK on update/delete so a re-parented child + updates both), re-aggregates the child collection, and writes the result onto + the parent's summary field. It runs in the caller's execution context, so when + a transaction is open (e.g. the cross-object `/api/v1/batch`) the rollup + commits atomically with the child writes. A small index of child→summary + descriptors is built lazily from the registry and invalidated on package + registration. + + Empty collections roll up to `0` for `count`/`sum` and `null` for + `min`/`max`/`avg`. This lets master-detail forms stop computing parent totals on + the client — the server is now the single source of truth. + +- 345e189: Robust multi-write transactions (ADR-0034). `engine.transaction()` now establishes an ambient transaction (AsyncLocalStorage) so every data operation during the callback — including internal reads performed while a write runs — binds to the active transaction's connection instead of asking the pool for another one and deadlocking on SQLite's single-connection pool. Adds a cross-object transactional batch endpoint (`POST /api/v1/data/batch`) with intra-batch `{ $ref: }` parent references, so a parent and its children can be created atomically in one transaction. + +### Patch Changes + +- e6374b5: fix(objectql): master_detail cascade delete + autonumber generation + + - `delete` now applies referential delete behavior for incoming relations: `master_detail` cascades to children (the parent owns the child lifecycle; only an explicit `restrict` deviates), `lookup` honors its `deleteBehavior` (default `set_null`). Recurses for grandchildren, depth-guarded, single-id deletes. Previously deleting a parent left its children orphaned. + - `insert` now generates values for empty `autonumber` fields before required-validation (`max+1`, seeded per `object.field`, honors `autonumberFormat`). Previously a required autonumber was rejected as "missing" and autonumber fields were never populated. + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + - @objectstack/formula@8.0.0 + - @objectstack/metadata-core@8.0.0 + - @objectstack/types@8.0.0 + ## 7.9.0 ### Minor Changes diff --git a/packages/objectql/package.json b/packages/objectql/package.json index 2241312c6..59146c69a 100644 --- a/packages/objectql/package.json +++ b/packages/objectql/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/objectql", - "version": "7.9.0", + "version": "8.0.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 de485c761..c9c847823 100644 --- a/packages/observability/CHANGELOG.md +++ b/packages/observability/CHANGELOG.md @@ -1,5 +1,20 @@ # @objectstack/observability +## 8.0.0 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/observability/package.json b/packages/observability/package.json index bee010788..58ef9c8d5 100644 --- a/packages/observability/package.json +++ b/packages/observability/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/observability", - "version": "7.9.0", + "version": "8.0.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 18cea1707..578c20df5 100644 --- a/packages/platform-objects/CHANGELOG.md +++ b/packages/platform-objects/CHANGELOG.md @@ -1,5 +1,21 @@ # @objectstack/platform-objects +## 8.0.0 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/metadata-core@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/platform-objects/package.json b/packages/platform-objects/package.json index 1ec57c36a..554266340 100644 --- a/packages/platform-objects/package.json +++ b/packages/platform-objects/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/platform-objects", - "version": "7.9.0", + "version": "8.0.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 3ab491ac9..3bc08c40c 100644 --- a/packages/plugins/driver-memory/CHANGELOG.md +++ b/packages/plugins/driver-memory/CHANGELOG.md @@ -1,5 +1,22 @@ # @objectstack/driver-memory +## 8.0.0 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/plugins/driver-memory/package.json b/packages/plugins/driver-memory/package.json index 8db67b27f..cf655d7cd 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.9.0", + "version": "8.0.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 b928430d9..6048b06dd 100644 --- a/packages/plugins/driver-mongodb/CHANGELOG.md +++ b/packages/plugins/driver-mongodb/CHANGELOG.md @@ -1,5 +1,43 @@ # @objectstack/driver-mongodb +## 8.0.0 + +### Patch Changes + +- 1e8b680: fix(security): close four P0 launch-readiness findings + + - **plugin-auth (P0-1):** `generateSecret()` now throws (fails boot) when no + `OS_AUTH_SECRET` is set and `NODE_ENV==='production'`, instead of silently + falling back to a predictable `dev-secret-` (session forgery). The + dev/test fallback is unchanged. + - **plugin-security (P0-2):** the permission-resolution `catch` now **fails + closed** — it logs at ERROR and throws `PermissionDeniedError` rather than + `return next()`. A degraded metadata service can no longer let every + authenticated request bypass RBAC/RLS. System operations still bypass as before. + - **driver-sql (P0-3):** the `contains` / `$contains` operator now escapes LIKE + metacharacters (`%` / `_` / `\`) in the user value and binds an explicit + `ESCAPE '\'`, so a value of `%` matches literally instead of every row + (filter bypass). Correct across SQLite/MySQL/Postgres. + - **driver-mongodb (P0-4):** the field-operator translator now rejects unknown + `$`-operators instead of passing them through, blocking `$where` / `$function` + / `$expr` (server-side JS execution / query-intent bypass). All legitimate + ObjectQL operators remain allowlisted. + + +12 regression tests across the four packages. + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/plugins/driver-mongodb/package.json b/packages/plugins/driver-mongodb/package.json index 245a65507..07eeee68d 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.9.0", + "version": "8.0.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 bbf5e78ae..881003890 100644 --- a/packages/plugins/driver-sql/CHANGELOG.md +++ b/packages/plugins/driver-sql/CHANGELOG.md @@ -1,5 +1,77 @@ # @objectstack/driver-sql +## 8.0.0 + +### Minor Changes + +- b990b89: fix(autonumber): one owner for autonumber generation — the persistent driver sequence (#1603) + + Autonumber values were generated in TWO places: the SQL driver's persistent, + atomic `_objectstack_sequences` table AND a non-persistent in-memory counter in + the ObjectQL engine. Because the engine pre-filled the field BEFORE calling the + driver, the driver always saw a value already set and skipped — so the + persistent sequence was effectively dead code, and a multi-instance / post-restart + deployment could mint duplicate numbers from the in-memory counter. + + This makes generation single-owner: + + - **`@objectstack/spec`** — `DriverCapabilities` gains an optional `autonumber` + flag: "driver natively generates persistent autonumber/sequence values". + + - **`@objectstack/driver-sql`** — advertises `supports.autonumber = true`. + `bulkCreate()` now fills autonumber fields too (previously only `create()` / + `upsert()` did), so bulk inserts also draw from the persistent sequence. + Field parsing now honors either the spec-canonical `autonumberFormat` key OR + the `format` shorthand (both appear in metadata). + + - **`@objectstack/objectql`** — when the driver advertises native autonumber + support, the engine NO LONGER pre-fills (it defers entirely to the persistent + driver sequence as the single source of truth). For drivers without native + support (memory, mongodb) the in-memory fallback is unchanged. The fallback + also now reads either `autonumberFormat` or `format`. Record-validation + exempts `autonumber` fields from the `required` check — the value is + runtime-owned and assigned after validation, so a required record number is + never rejected as "missing". + + No metadata changes required. Existing data is respected: the driver bootstraps + each sequence from the current max numeric tail on first use. + +### Patch Changes + +- 1e8b680: fix(security): close four P0 launch-readiness findings + + - **plugin-auth (P0-1):** `generateSecret()` now throws (fails boot) when no + `OS_AUTH_SECRET` is set and `NODE_ENV==='production'`, instead of silently + falling back to a predictable `dev-secret-` (session forgery). The + dev/test fallback is unchanged. + - **plugin-security (P0-2):** the permission-resolution `catch` now **fails + closed** — it logs at ERROR and throws `PermissionDeniedError` rather than + `return next()`. A degraded metadata service can no longer let every + authenticated request bypass RBAC/RLS. System operations still bypass as before. + - **driver-sql (P0-3):** the `contains` / `$contains` operator now escapes LIKE + metacharacters (`%` / `_` / `\`) in the user value and binds an explicit + `ESCAPE '\'`, so a value of `%` matches literally instead of every row + (filter bypass). Correct across SQLite/MySQL/Postgres. + - **driver-mongodb (P0-4):** the field-operator translator now rejects unknown + `$`-operators instead of passing them through, blocking `$where` / `$function` + / `$expr` (server-side JS execution / query-intent bypass). All legitimate + ObjectQL operators remain allowlisted. + + +12 regression tests across the four packages. + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/plugins/driver-sql/package.json b/packages/plugins/driver-sql/package.json index 5d407049f..134b1bc86 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.9.0", + "version": "8.0.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 11d09be22..5373930a5 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 +## 8.0.0 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [1e8b680] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/driver-sql@8.0.0 + - @objectstack/core@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/plugins/driver-sqlite-wasm/package.json b/packages/plugins/driver-sqlite-wasm/package.json index 931eb0dd2..2eb66a649 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.9.0", + "version": "8.0.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 6cfd9464a..bba61da5b 100644 --- a/packages/plugins/embedder-openai/CHANGELOG.md +++ b/packages/plugins/embedder-openai/CHANGELOG.md @@ -1,5 +1,40 @@ # @objectstack/embedder-openai +## 8.0.0 + +### Patch Changes + +- d5a8161: feat(spec): resilientFetch — timeout + backoff for outbound HTTP (P1-1) + + Outbound calls in the connectors/embedder were naked `fetch` with no timeout or + retry, so a slow or rate-limited external API could hang an agent turn with no + recovery. + + New shared `resilientFetch` (`@objectstack/spec/shared`): + + - per-attempt timeout via `AbortController` (default 30s); + - exponential backoff with jitter, up to 3 attempts, on network errors / 429 / 5xx; + - honours a `Retry-After` header on 429; + - never retries a caller-initiated abort (intentional cancellation). + + Wired into `connector-rest`, `connector-slack`, and `embedder-openai`. + `connector-mcp` talks through the MCP SDK transport, so it gets a 30s per-request + `timeout` on `callTool` / `listTools` instead. + + A stateful per-host **circuit breaker** is deliberately left as a follow-up: + timeout + backoff already removes the hang/no-recovery risk. + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/plugins/embedder-openai/package.json b/packages/plugins/embedder-openai/package.json index 17659f273..00f9c0f04 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.9.0", + "version": "8.0.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 cf3e1e561..977a15b0d 100644 --- a/packages/plugins/knowledge-memory/CHANGELOG.md +++ b/packages/plugins/knowledge-memory/CHANGELOG.md @@ -1,5 +1,23 @@ # @objectstack/knowledge-memory +## 8.0.0 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + - @objectstack/service-knowledge@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/plugins/knowledge-memory/package.json b/packages/plugins/knowledge-memory/package.json index 10caaddb3..5f3d6023c 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.9.0", + "version": "8.0.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 a35837194..48ddd098d 100644 --- a/packages/plugins/knowledge-ragflow/CHANGELOG.md +++ b/packages/plugins/knowledge-ragflow/CHANGELOG.md @@ -1,5 +1,23 @@ # @objectstack/knowledge-ragflow +## 8.0.0 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + - @objectstack/service-knowledge@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/plugins/knowledge-ragflow/package.json b/packages/plugins/knowledge-ragflow/package.json index 0b7111d73..a89a1e766 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.9.0", + "version": "8.0.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 86eac7f0f..067affb0a 100644 --- a/packages/plugins/plugin-approvals/CHANGELOG.md +++ b/packages/plugins/plugin-approvals/CHANGELOG.md @@ -1,5 +1,25 @@ # @objectstack/plugin-approvals +## 8.0.0 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + - @objectstack/formula@8.0.0 + - @objectstack/metadata-core@8.0.0 + - @objectstack/platform-objects@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/plugins/plugin-approvals/package.json b/packages/plugins/plugin-approvals/package.json index 01ec474fd..7112ef827 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.9.0", + "version": "8.0.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 65b203ab5..fb44ded5a 100644 --- a/packages/plugins/plugin-audit/CHANGELOG.md +++ b/packages/plugins/plugin-audit/CHANGELOG.md @@ -1,5 +1,23 @@ # @objectstack/plugin-audit +## 8.0.0 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + - @objectstack/platform-objects@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/plugins/plugin-audit/package.json b/packages/plugins/plugin-audit/package.json index e10922fb8..6421011ba 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.9.0", + "version": "8.0.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 fb081abe4..604905b0f 100644 --- a/packages/plugins/plugin-auth/CHANGELOG.md +++ b/packages/plugins/plugin-auth/CHANGELOG.md @@ -1,5 +1,45 @@ # Changelog +## 8.0.0 + +### Patch Changes + +- 1e8b680: fix(security): close four P0 launch-readiness findings + + - **plugin-auth (P0-1):** `generateSecret()` now throws (fails boot) when no + `OS_AUTH_SECRET` is set and `NODE_ENV==='production'`, instead of silently + falling back to a predictable `dev-secret-` (session forgery). The + dev/test fallback is unchanged. + - **plugin-security (P0-2):** the permission-resolution `catch` now **fails + closed** — it logs at ERROR and throws `PermissionDeniedError` rather than + `return next()`. A degraded metadata service can no longer let every + authenticated request bypass RBAC/RLS. System operations still bypass as before. + - **driver-sql (P0-3):** the `contains` / `$contains` operator now escapes LIKE + metacharacters (`%` / `_` / `\`) in the user value and binds an explicit + `ESCAPE '\'`, so a value of `%` matches literally instead of every row + (filter bypass). Correct across SQLite/MySQL/Postgres. + - **driver-mongodb (P0-4):** the field-operator translator now rejects unknown + `$`-operators instead of passing them through, blocking `$where` / `$function` + / `$expr` (server-side JS execution / query-intent bypass). All legitimate + ObjectQL operators remain allowlisted. + + +12 regression tests across the four packages. + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + - @objectstack/platform-objects@8.0.0 + - @objectstack/types@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/plugins/plugin-auth/package.json b/packages/plugins/plugin-auth/package.json index f46c3ced8..3bd24e9a8 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.9.0", + "version": "8.0.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 314684349..eb8d3d6a5 100644 --- a/packages/plugins/plugin-dev/CHANGELOG.md +++ b/packages/plugins/plugin-dev/CHANGELOG.md @@ -1,5 +1,43 @@ # @objectstack/plugin-dev +## 8.0.0 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [f68be58] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [93f97b2] +- Updated dependencies [bc0d85b] +- Updated dependencies [2537e28] +- Updated dependencies [0ec7717] +- Updated dependencies [e6374b5] +- Updated dependencies [1e8b680] +- Updated dependencies [0a6438e] +- Updated dependencies [3306d2f] +- Updated dependencies [ae7fb3f] +- Updated dependencies [c262301] +- Updated dependencies [e1478fe] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] +- Updated dependencies [345e189] + - @objectstack/spec@8.0.0 + - @objectstack/runtime@8.0.0 + - @objectstack/objectql@8.0.0 + - @objectstack/plugin-hono-server@8.0.0 + - @objectstack/plugin-auth@8.0.0 + - @objectstack/plugin-security@8.0.0 + - @objectstack/rest@8.0.0 + - @objectstack/core@8.0.0 + - @objectstack/driver-memory@8.0.0 + - @objectstack/plugin-org-scoping@8.0.0 + - @objectstack/service-i18n@8.0.0 + - @objectstack/types@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/plugins/plugin-dev/package.json b/packages/plugins/plugin-dev/package.json index 263ad6892..62e36c98b 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.9.0", + "version": "8.0.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 b7dced7c6..e622765bf 100644 --- a/packages/plugins/plugin-email/CHANGELOG.md +++ b/packages/plugins/plugin-email/CHANGELOG.md @@ -1,5 +1,23 @@ # @objectstack/plugin-email +## 8.0.0 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + - @objectstack/platform-objects@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/plugins/plugin-email/package.json b/packages/plugins/plugin-email/package.json index afe2fd570..bfba62f43 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.9.0", + "version": "8.0.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 cef0bc186..4dcf744fb 100644 --- a/packages/plugins/plugin-hono-server/CHANGELOG.md +++ b/packages/plugins/plugin-hono-server/CHANGELOG.md @@ -1,5 +1,36 @@ # @objectstack/plugin-hono-server +## 8.0.0 + +### Patch Changes + +- 93f97b2: fix(hono-server): drain in-flight requests on shutdown instead of force-closing (P1-3) + + `HonoHttpServer.close()` called `closeAllConnections()`, which terminated active + connections mid-response — so a SIGTERM during a rolling deploy dropped in-flight + requests. It now drains gracefully: `server.close()` stops accepting new + connections and lets active requests finish, `closeIdleConnections()` releases + idle keep-alive sockets so the process exits promptly, and a bounded drain window + (default 10s, configurable, well under the kernel's 60s `shutdownTimeout`) + force-closes only the stragglers so shutdown can't hang. + + Note: the kernel already handles SIGINT/SIGTERM/SIGQUIT with an ordered, + timeout-bounded shutdown — this fixes the one place that wasn't draining. + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + - @objectstack/types@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/plugins/plugin-hono-server/package.json b/packages/plugins/plugin-hono-server/package.json index 7b90a97c1..7af332f93 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.9.0", + "version": "8.0.0", "license": "Apache-2.0", "description": "Standard Hono Server Adapter for ObjectStack Runtime", "main": "dist/index.js", diff --git a/packages/plugins/plugin-msw/CHANGELOG.md b/packages/plugins/plugin-msw/CHANGELOG.md index 477cacd1a..355a5ccdc 100644 --- a/packages/plugins/plugin-msw/CHANGELOG.md +++ b/packages/plugins/plugin-msw/CHANGELOG.md @@ -1,5 +1,31 @@ # @objectstack/plugin-msw +## 8.0.0 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [f68be58] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [bc0d85b] +- Updated dependencies [2537e28] +- Updated dependencies [0ec7717] +- Updated dependencies [e6374b5] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] +- Updated dependencies [345e189] + - @objectstack/spec@8.0.0 + - @objectstack/runtime@8.0.0 + - @objectstack/objectql@8.0.0 + - @objectstack/core@8.0.0 + - @objectstack/types@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/plugins/plugin-msw/package.json b/packages/plugins/plugin-msw/package.json index 12e53bdde..636910320 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.9.0", + "version": "8.0.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 ba2201413..ca7145139 100644 --- a/packages/plugins/plugin-org-scoping/CHANGELOG.md +++ b/packages/plugins/plugin-org-scoping/CHANGELOG.md @@ -1,5 +1,23 @@ # @objectstack/plugin-org-scoping +## 8.0.0 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + - @objectstack/platform-objects@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/plugins/plugin-org-scoping/package.json b/packages/plugins/plugin-org-scoping/package.json index 7572b7403..b99d98bdb 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.9.0", + "version": "8.0.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 4f898405c..1881c9525 100644 --- a/packages/plugins/plugin-reports/CHANGELOG.md +++ b/packages/plugins/plugin-reports/CHANGELOG.md @@ -1,5 +1,23 @@ # @objectstack/plugin-reports +## 8.0.0 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + - @objectstack/platform-objects@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/plugins/plugin-reports/package.json b/packages/plugins/plugin-reports/package.json index 63fe44986..872bf3052 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.9.0", + "version": "8.0.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 1462cec5e..ed9243618 100644 --- a/packages/plugins/plugin-security/CHANGELOG.md +++ b/packages/plugins/plugin-security/CHANGELOG.md @@ -1,5 +1,44 @@ # @objectstack/plugin-security +## 8.0.0 + +### Patch Changes + +- 1e8b680: fix(security): close four P0 launch-readiness findings + + - **plugin-auth (P0-1):** `generateSecret()` now throws (fails boot) when no + `OS_AUTH_SECRET` is set and `NODE_ENV==='production'`, instead of silently + falling back to a predictable `dev-secret-` (session forgery). The + dev/test fallback is unchanged. + - **plugin-security (P0-2):** the permission-resolution `catch` now **fails + closed** — it logs at ERROR and throws `PermissionDeniedError` rather than + `return next()`. A degraded metadata service can no longer let every + authenticated request bypass RBAC/RLS. System operations still bypass as before. + - **driver-sql (P0-3):** the `contains` / `$contains` operator now escapes LIKE + metacharacters (`%` / `_` / `\`) in the user value and binds an explicit + `ESCAPE '\'`, so a value of `%` matches literally instead of every row + (filter bypass). Correct across SQLite/MySQL/Postgres. + - **driver-mongodb (P0-4):** the field-operator translator now rejects unknown + `$`-operators instead of passing them through, blocking `$where` / `$function` + / `$expr` (server-side JS execution / query-intent bypass). All legitimate + ObjectQL operators remain allowlisted. + + +12 regression tests across the four packages. + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + - @objectstack/platform-objects@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/plugins/plugin-security/package.json b/packages/plugins/plugin-security/package.json index b32c3021b..e6495aeed 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.9.0", + "version": "8.0.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 4de04280e..77b29147b 100644 --- a/packages/plugins/plugin-sharing/CHANGELOG.md +++ b/packages/plugins/plugin-sharing/CHANGELOG.md @@ -1,5 +1,26 @@ # @objectstack/plugin-sharing +## 8.0.0 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [e6374b5] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] +- Updated dependencies [345e189] + - @objectstack/spec@8.0.0 + - @objectstack/objectql@8.0.0 + - @objectstack/core@8.0.0 + - @objectstack/platform-objects@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/plugins/plugin-sharing/package.json b/packages/plugins/plugin-sharing/package.json index 1ada96c8b..6023f780d 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.9.0", + "version": "8.0.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 index 0a5c24a4e..06a2a0bcb 100644 --- a/packages/plugins/plugin-trigger-record-change/CHANGELOG.md +++ b/packages/plugins/plugin-trigger-record-change/CHANGELOG.md @@ -1,5 +1,22 @@ # @objectstack/plugin-trigger-record-change +## 8.0.0 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/plugins/plugin-trigger-record-change/package.json b/packages/plugins/plugin-trigger-record-change/package.json index 684a36a0f..b4a92d435 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.9.0", + "version": "8.0.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 index 0c70bb377..8a27751d8 100644 --- a/packages/plugins/plugin-trigger-schedule/CHANGELOG.md +++ b/packages/plugins/plugin-trigger-schedule/CHANGELOG.md @@ -1,5 +1,22 @@ # @objectstack/plugin-trigger-schedule +## 8.0.0 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/plugins/plugin-trigger-schedule/package.json b/packages/plugins/plugin-trigger-schedule/package.json index f7cbfce33..1d47d3753 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.9.0", + "version": "8.0.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 b164ee9eb..8b26eb855 100644 --- a/packages/plugins/plugin-webhooks/CHANGELOG.md +++ b/packages/plugins/plugin-webhooks/CHANGELOG.md @@ -1,5 +1,25 @@ # @objectstack/plugin-webhooks +## 8.0.0 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [9f311f8] +- Updated dependencies [c70eec1] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/service-messaging@8.0.0 + - @objectstack/core@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/plugins/plugin-webhooks/package.json b/packages/plugins/plugin-webhooks/package.json index 7ece51f56..516298c57 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.9.0", + "version": "8.0.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 3dde7607a..b2399f6a9 100644 --- a/packages/rest/CHANGELOG.md +++ b/packages/rest/CHANGELOG.md @@ -1,5 +1,94 @@ # @objectstack/rest +## 8.0.0 + +### Minor Changes + +- 345e189: Robust multi-write transactions (ADR-0034). `engine.transaction()` now establishes an ambient transaction (AsyncLocalStorage) so every data operation during the callback — including internal reads performed while a write runs — binds to the active transaction's connection instead of asking the pool for another one and deadlocking on SQLite's single-connection pool. Adds a cross-object transactional batch endpoint (`POST /api/v1/data/batch`) with intra-batch `{ $ref: }` parent references, so a parent and its children can be created atomically in one transaction. + +### Patch Changes + +- 0a6438e: perf(rest): cache hostname→environment resolution; document cluster pub/sub durability (P1-4, P1-5) + + - **rest (P1-4):** `resolveByHostname()` ran on every unscoped request — a + control-plane lookup (typically a DB query) in the hot path. `RestServer` now + caches `hostname → environmentId` in-memory with a 30s TTL across all three + resolution sites, caching negative results too so unknown hosts don't hammer the + registry. Registry errors are not cached, so a transient blip self-heals. + - **service-cluster-redis (P1-5):** recorded the durability contract for + `metadata.changed` in `pubsub.ts`. Redis pub/sub is at-most-once **by design**; + the event is a cache-invalidation hint only — the durable source of truth is the + transactional `sys_metadata` (+ `sys_metadata_history`) write, so a missed event + causes a stale cache until the next reload, never data loss. No code change to + the delivery semantics; risk accepted and documented. + +- ae7fb3f: fix(rest): advertise `routes.mcp` in /discovery when MCP is enabled (cloud#152) + + The objectui Integrations page reads `discovery.routes.mcp` to show the "Connect + an AI agent" card, but it stayed absent on live envs even with MCP enabled. Root + cause (NOT a cache, as first suspected): `@objectstack/rest` serves its OWN + `/discovery` (`protocol.getDiscovery()`), separate from the dispatcher's + `getDiscoveryInfo` where the `mcp` field was added — so the REST-served discovery + never advertised it. + + The REST discovery handler now adds `routes.mcp` (pointing at the unscoped + `/api/v1/mcp`, since the MCP route is mounted bare) when + `OS_MCP_SERVER_ENABLED=true`, and omits it otherwise — mirroring the dispatcher + discovery and the opt-in gate. 2 tests (enabled → advertised, disabled → absent). + +- c262301: fix(rest): REST data API honors sys_api_key — one shared verifier with MCP (closes #1633) + + Staging e2e found the MCP surface authenticated a `sys_api_key` but the REST data + API (`@objectstack/rest`) returned 401 for the same key — its `resolveExecCtx` + only checked the better-auth session, never the API key. + + Converged both surfaces onto ONE verifier so they can't drift: + + - **`@objectstack/core/security`** now owns the shared `sys_api_key` primitives + (`hashApiKey`, `generateApiKey`, `extractApiKey`, `parseScopes`, `isExpired`) + plus a new `resolveApiKeyPrincipal(ql, headers, nowMs?)` that hashes the + inbound key, looks it up by the indexed at-rest hash, and rejects unknown / + revoked / expired / owner-less keys (fail-closed). `core` is the natural home: + both `rest` and `runtime` depend on it, it depends on neither (no cycle), and + it's server-side (already uses `node:crypto`). + - **`@objectstack/runtime`** — `security/api-key.ts` re-exports the primitives + from core (stable import surface) and `resolveExecutionContext` now delegates + its API-key branch to `resolveApiKeyPrincipal`. + - **`@objectstack/rest`** — `resolveExecCtx` resolves the data engine once and + tries `resolveApiKeyPrincipal` (x-api-key / `Authorization: ApiKey`) BEFORE the + session, so `/api/v1/data` + `/api/v1/meta` now authenticate an API key under + the key's permissions + RLS, exactly like the dispatcher/MCP path. + + Tests: core `api-key.test.ts` (primitives + verifier: valid / revoked / expired / + unknown / owner-less / plaintext-not-matched / fail-closed-ql). runtime + rest + suites green. + +- e1478fe: fix(rest): map schema-mismatch & not-null driver errors to structured 4xx + + `mapDataError` collapsed any SQL-looking driver error into a generic + `500 DATABASE_ERROR`, so a bad write payload to the data API leaked a 500 + instead of a fixable 4xx (e.g. `POST /data/sys_team` with an unknown field, + or omitting a required column). It now maps unknown-column errors to + `400 INVALID_FIELD { field }` and not-null violations to + `400 VALIDATION_FAILED { fields:[{required}] }` across SQLite/Postgres/MySQL + phrasings, placed before the unknown-object branch so Postgres + `column … of relation … does not exist` is not mis-mapped to 404. Genuine + driver faults still return 500; unique violations still return 409. + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + - @objectstack/service-package@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/rest/package.json b/packages/rest/package.json index 5ead8860d..b051f022c 100644 --- a/packages/rest/package.json +++ b/packages/rest/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/rest", - "version": "7.9.0", + "version": "8.0.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 f5445636a..1895f65ce 100644 --- a/packages/runtime/CHANGELOG.md +++ b/packages/runtime/CHANGELOG.md @@ -1,5 +1,164 @@ # @objectstack/runtime +## 8.0.0 + +### Minor Changes + +- f68be58: feat(runtime): API-key generation endpoint — show-once `sys_api_key` (ADR-0036, closes framework#1629) + + Adds `POST /api/v1/keys` — the only path that mints a `sys_api_key`. Phase 1a + shipped key _verification_ and the `generateApiKey()` primitive; this is the + missing _generation_ half that unblocks the self-serve connect flow. + + - Requires an authenticated principal; returns the **raw secret exactly once** + (`{ id, name, prefix, key }`). Only the sha256 **hash** is persisted — the raw + key is never stored, logged, or re-displayable. + - **Security (zero-tolerance):** `user_id` is pinned to the caller and never read + from the body (no impersonation); the body is whitelisted to `name` (+ optional + validated future `expires_at`) — any `key`/`id`/`user_id`/`revoked` in the body + is ignored, so a caller cannot forge a known-secret or escalate. The row is + written with an elevated `{ isSystem: true }` context (sys_api_key is + protection-locked) with server-controlled contents. Anonymous → 401; + non-POST → 405; past/unparseable `expires_at` → 400. + - `scopes` are intentionally NOT accepted from the body in v1 (the verify path + adds scopes to permissions, so honouring arbitrary body scopes would be an + escalation vector); a generated key acts exactly AS the caller via `user_id` + resolution. Scoped/narrowing keys need subset-enforcement — deferred. + + 11 security tests (show-once, hash-not-raw persisted, round-trip auth via the + verify path, impersonation blocked, forgery blocked, 401/405/400, expiry + end-to-end). Full runtime suite green (376). + +- bc0d85b: feat(mcp): Streamable HTTP transport — every app is a network-reachable MCP server (ADR-0036 Phase 2) + + The MCP server plugin spoke **stdio only**, so a remote agent (Claude Desktop / + Cursor) could not connect to a hosted env. This adds the **Streamable HTTP** + transport and wires it into the runtime's request path, building on the Phase 1a + `sys_api_key` auth foundation. + + - **`@objectstack/mcp`** (renamed from `@objectstack/plugin-mcp-server` — see the rename changeset) + + - `MCPServerRuntime.handleHttpRequest(request, { bridge, parsedBody })` — + serves one MCP request over the Web-standard `WebStandardStreamableHTTPServerTransport` + (runs on Node 18+, Workers, Deno, Bun). **Stateless**: a fresh, isolated + `McpServer` + transport is built per request (the SDK-recommended pattern), + in JSON-response mode so the response is fully buffered — no streaming + pass-through concerns over the Worker→container hop. + - New `registerObjectTools` + `McpDataBridge` (`mcp-http-tools.ts`): the + object-CRUD tool set (`list_objects`, `describe_object`, `query_records`, + `get_record`, `create_record`, `update_record`, `delete_record`). All + execution is delegated to an injected, **principal-bound** bridge — the tool + layer never touches the data engine directly. System (`sys_*`) objects are + **not exposed** by default (fail-closed guard on every object-scoped tool). + The internal AI/authoring toolRegistry is deliberately NOT bridged onto the + external surface. + + - **`@objectstack/runtime`** + - `HttpDispatcher` serves `/mcp`: **opt-in** via `OS_MCP_SERVER_ENABLED=true` + (404 when off, so the surface isn't advertised); **fail-closed auth** + (anonymous → 401 — requires the principal resolved by Phase 1a's API-key + path or a session). It builds an `McpDataBridge` that runs every operation + through the existing `callData` path bound to the request's + `ExecutionContext`, so external agents run under the key's permissions + RLS, + never a parallel or escalated path. The discovery endpoint advertises `mcp` + only when enabled. + + Security: every external MCP entry runs as the scoped `sys_api_key` principal + under existing object permissions + RLS; MCP is opt-in per env; no raw keys or + secrets cross the wire. Fully unit-tested (transport handshake/tools, gate, + auth, principal binding). + +### Patch Changes + +- 2537e28: fix(runtime): adapt node/Hono req → Web Request for the MCP transport (ADR-0036) + + The MCP Streamable HTTP transport needs a Web-standard `Request`, but the + runtime HTTP adapter hands the dispatcher a node/Hono-style req (plain `headers` + object, path-only `url`). `handleMcp` rejected it with 400 ("MCP transport + requires a standard HTTP request") — so the live endpoint was unusable even + once routed + registered. Unit tests passed a real `Request`, hiding it; caught + in staging e2e on `initialize`. + + `handleMcp` now reconstructs a Web `Request` (method, absolute URL from + host+path, normalised headers, JSON body from the parsed body) when the inbound + req isn't already Web-standard. Regression tests cover a POST and a GET + node-style req. + +- 0ec7717: fix(runtime): mount /mcp and /keys HTTP routes (ADR-0036) — were unreachable + + The dispatcher mounts routes EXPLICITLY on the HTTP server (no catch-all). The + MCP transport (#1626) and key-generation (#1630) added branches inside + `dispatch()` but never registered the corresponding `server.()` routes, so + `/api/v1/mcp` and `/api/v1/keys` 404'd at the HTTP layer before ever reaching + the dispatcher. Unit tests called the handlers directly, hiding the gap; it only + showed up in live staging e2e. + + - Register `/mcp` (GET/POST/DELETE → dispatch, transport reads the method) and + `/keys` (POST) in the dispatcher plugin, routed through `dispatch()` so the + host's project-aware kernel swap + executionContext resolution run first. + - Add `dispatcher-plugin.routes.test.ts` asserting the routes are registered + (the regression that would have caught this). + +- c262301: fix(rest): REST data API honors sys_api_key — one shared verifier with MCP (closes #1633) + + Staging e2e found the MCP surface authenticated a `sys_api_key` but the REST data + API (`@objectstack/rest`) returned 401 for the same key — its `resolveExecCtx` + only checked the better-auth session, never the API key. + + Converged both surfaces onto ONE verifier so they can't drift: + + - **`@objectstack/core/security`** now owns the shared `sys_api_key` primitives + (`hashApiKey`, `generateApiKey`, `extractApiKey`, `parseScopes`, `isExpired`) + plus a new `resolveApiKeyPrincipal(ql, headers, nowMs?)` that hashes the + inbound key, looks it up by the indexed at-rest hash, and rejects unknown / + revoked / expired / owner-less keys (fail-closed). `core` is the natural home: + both `rest` and `runtime` depend on it, it depends on neither (no cycle), and + it's server-side (already uses `node:crypto`). + - **`@objectstack/runtime`** — `security/api-key.ts` re-exports the primitives + from core (stable import surface) and `resolveExecutionContext` now delegates + its API-key branch to `resolveApiKeyPrincipal`. + - **`@objectstack/rest`** — `resolveExecCtx` resolves the data engine once and + tries `resolveApiKeyPrincipal` (x-api-key / `Authorization: ApiKey`) BEFORE the + session, so `/api/v1/data` + `/api/v1/meta` now authenticate an API key under + the key's permissions + RLS, exactly like the dispatcher/MCP path. + + Tests: core `api-key.test.ts` (primitives + verifier: valid / revoked / expired / + unknown / owner-less / plaintext-not-matched / fail-closed-ql). runtime + rest + suites green. + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [e6374b5] +- Updated dependencies [1e8b680] +- Updated dependencies [0a6438e] +- Updated dependencies [3306d2f] +- Updated dependencies [ae7fb3f] +- Updated dependencies [c262301] +- Updated dependencies [e1478fe] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] +- Updated dependencies [345e189] + - @objectstack/spec@8.0.0 + - @objectstack/objectql@8.0.0 + - @objectstack/driver-sql@8.0.0 + - @objectstack/plugin-auth@8.0.0 + - @objectstack/plugin-security@8.0.0 + - @objectstack/rest@8.0.0 + - @objectstack/core@8.0.0 + - @objectstack/formula@8.0.0 + - @objectstack/metadata@8.0.0 + - @objectstack/observability@8.0.0 + - @objectstack/driver-memory@8.0.0 + - @objectstack/driver-sqlite-wasm@8.0.0 + - @objectstack/plugin-org-scoping@8.0.0 + - @objectstack/service-cluster@8.0.0 + - @objectstack/service-i18n@8.0.0 + - @objectstack/types@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/runtime/package.json b/packages/runtime/package.json index 95527f1c4..ff065985c 100644 --- a/packages/runtime/package.json +++ b/packages/runtime/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/runtime", - "version": "7.9.0", + "version": "8.0.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 6f32a4d50..0847ad7ec 100644 --- a/packages/services/service-ai/CHANGELOG.md +++ b/packages/services/service-ai/CHANGELOG.md @@ -1,5 +1,42 @@ # @objectstack/service-ai +## 8.0.0 + +### Patch Changes + +- a46c017: feat(ai): actions opt in to being AI tools via an `ai:` block (ADR-0011) + + Realigns ADR-0011 with its original opt-in design. An Action becomes an + AI-callable tool only when its metadata sets `ai.exposed: true`, which requires + an explicit, LLM-facing `ai.description` (≥40 chars, distinct from the UI + `label`). There is no heuristic auto-exposure and no description derived from + the label — a clean break from the first implementation's opt-out `aiExposed` + flag, which is removed (no compatibility shim; the platform has not shipped). + + The `ai:` block also carries `category`, `paramHints` (per-parameter JSON-Schema + refinement), `outputSchema` (summarised into the tool description for chaining), + and `requiresConfirmation` (overrides the destructive-action HITL default). + `AIToolDefinition` is extended to carry `category` / `outputSchema` / `objectName` + / `requiresConfirmation`. The `@objectstack/service-ai` bridge + (`action-tools.ts`) now gates on opt-in, merges `paramHints`, and emits a lint + warning when an exposed destructive-looking action asserts itself safe via + `ai.requiresConfirmation: false`. + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + - @objectstack/formula@8.0.0 + - @objectstack/types@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/services/service-ai/package.json b/packages/services/service-ai/package.json index bd5734961..292921851 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.9.0", + "version": "8.0.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 eced331ae..b6273ff65 100644 --- a/packages/services/service-analytics/CHANGELOG.md +++ b/packages/services/service-analytics/CHANGELOG.md @@ -1,5 +1,22 @@ # Changelog — @objectstack/service-analytics +## 8.0.0 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/services/service-analytics/package.json b/packages/services/service-analytics/package.json index 7b8f80bed..2c6fe3277 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.9.0", + "version": "8.0.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 322e4911b..ede711d0c 100644 --- a/packages/services/service-automation/CHANGELOG.md +++ b/packages/services/service-automation/CHANGELOG.md @@ -1,5 +1,57 @@ # @objectstack/service-automation +## 8.0.0 + +### Patch Changes + +- 3306d2f: feat(automation): surface structured-region body steps in run observability (#1505) + + `loop` / `parallel` / `try_catch` previously ran their body, branch, and handler + regions against a region-local step log that was **discarded** — run logs + (`listRuns` / `getRun`) showed the container as a single opaque step, hiding the + per-iteration / per-branch steps that actually executed. + + `AutomationEngine.runRegion()` now **returns** its body steps, and the container + node folds them into the parent run log via a new `NodeExecutionResult.childSteps` + field. Each surfaced step is tagged with its **immediate** container via three new + optional fields on `ExecutionStepLogSchema` (and the engine's `StepLogEntry`): + + - `parentNodeId` — the enclosing `loop` / `parallel` / `try_catch` node + - `iteration` — zero-based loop iteration or parallel branch index + - `regionKind` — `loop-body` | `parallel-branch` | `try` | `catch` + + Tagging fills only fields left undefined, so nested regions keep each step's + innermost container. A failed try-region attempt's partial steps are still not + surfaced (preserving `try_catch` retry semantics). Fully additive — existing run + logs and consumers are unaffected. + +- bc44195: chore(automation): retire the `workflow_rule` authoring paradigm (ADR-0018 M5 dropped) + + ADR-0019 already removed the Workflow-Rule → Flow compiler (Workflow Rules were + removed in #1398 and `workflow` was reclaimed for state machines), but the + `workflow_rule` paradigm tag survived in `ActionParadigmSchema` and on every + built-in node descriptor. There is no declarative Workflow-Rule authoring view + to feed, so the tag is now retired: `ActionParadigmSchema` keeps `['flow', +'approval']`, and the `http` / `notify` / `connector_action` descriptors (plus + the deprecated-alias fallback) advertise `['flow', 'approval']`. Approval + execution convergence is delivered by the ADR-0019 approval Flow node, not a + compiler. ADR-0018's status and migration table are updated to mark M3 shipped, + M4 framework-complete, and M5 dropped. + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + - @objectstack/formula@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/services/service-automation/package.json b/packages/services/service-automation/package.json index 7bb42d821..001390c47 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.9.0", + "version": "8.0.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 b46119835..7e9a85f20 100644 --- a/packages/services/service-cache/CHANGELOG.md +++ b/packages/services/service-cache/CHANGELOG.md @@ -1,5 +1,23 @@ # @objectstack/service-cache +## 8.0.0 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + - @objectstack/observability@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/services/service-cache/package.json b/packages/services/service-cache/package.json index ca64f165a..6ee4e18db 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.9.0", + "version": "8.0.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 73c3dfb72..85e4877fc 100644 --- a/packages/services/service-cluster-redis/CHANGELOG.md +++ b/packages/services/service-cluster-redis/CHANGELOG.md @@ -1,5 +1,35 @@ # @objectstack/service-cluster-redis +## 8.0.0 + +### Patch Changes + +- 0a6438e: perf(rest): cache hostname→environment resolution; document cluster pub/sub durability (P1-4, P1-5) + + - **rest (P1-4):** `resolveByHostname()` ran on every unscoped request — a + control-plane lookup (typically a DB query) in the hot path. `RestServer` now + caches `hostname → environmentId` in-memory with a 30s TTL across all three + resolution sites, caching negative results too so unknown hosts don't hammer the + registry. Registry errors are not cached, so a transient blip self-heals. + - **service-cluster-redis (P1-5):** recorded the durability contract for + `metadata.changed` in `pubsub.ts`. Redis pub/sub is at-most-once **by design**; + the event is a cache-invalidation hint only — the durable source of truth is the + transactional `sys_metadata` (+ `sys_metadata_history`) write, so a missed event + causes a stale cache until the next reload, never data loss. No code change to + the delivery semantics; risk accepted and documented. + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/service-cluster@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/services/service-cluster-redis/package.json b/packages/services/service-cluster-redis/package.json index d0e142ee5..8230e675d 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.9.0", + "version": "8.0.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 162c96343..12bc97658 100644 --- a/packages/services/service-cluster/CHANGELOG.md +++ b/packages/services/service-cluster/CHANGELOG.md @@ -1,5 +1,22 @@ # @objectstack/service-cluster +## 8.0.0 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/services/service-cluster/package.json b/packages/services/service-cluster/package.json index ea65f8ed5..ce6e47ded 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.9.0", + "version": "8.0.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-datasource/CHANGELOG.md b/packages/services/service-datasource/CHANGELOG.md index b10f1cfd8..3c0b4fb43 100644 --- a/packages/services/service-datasource/CHANGELOG.md +++ b/packages/services/service-datasource/CHANGELOG.md @@ -1,5 +1,22 @@ # @objectstack/service-external-datasource +## 8.0.0 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/services/service-datasource/package.json b/packages/services/service-datasource/package.json index f3e28247a..b75c46e99 100644 --- a/packages/services/service-datasource/package.json +++ b/packages/services/service-datasource/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/service-datasource", - "version": "7.9.0", + "version": "8.0.0", "license": "Apache-2.0", "description": "The datasource service (ADR-0015): external-table federation (introspect/draft/import/validate) + runtime UI datasource lifecycle (list/test/create/update/remove + REST routes). Open-source mechanism; the tier line falls on which ICryptoProvider / driver factory a host injects.", "type": "module", diff --git a/packages/services/service-feed/CHANGELOG.md b/packages/services/service-feed/CHANGELOG.md index d257ab7db..523fde7c4 100644 --- a/packages/services/service-feed/CHANGELOG.md +++ b/packages/services/service-feed/CHANGELOG.md @@ -1,5 +1,22 @@ # @objectstack/service-feed +## 8.0.0 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/services/service-feed/package.json b/packages/services/service-feed/package.json index 44deaf719..881cc7804 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.9.0", + "version": "8.0.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 8f3a17cb6..03b2c765f 100644 --- a/packages/services/service-i18n/CHANGELOG.md +++ b/packages/services/service-i18n/CHANGELOG.md @@ -1,5 +1,22 @@ # @objectstack/service-i18n +## 8.0.0 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/services/service-i18n/package.json b/packages/services/service-i18n/package.json index d9f9a1201..d4d6e0603 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.9.0", + "version": "8.0.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 3ca5f72c6..3a1ddb7c8 100644 --- a/packages/services/service-job/CHANGELOG.md +++ b/packages/services/service-job/CHANGELOG.md @@ -1,5 +1,23 @@ # @objectstack/service-job +## 8.0.0 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + - @objectstack/platform-objects@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/services/service-job/package.json b/packages/services/service-job/package.json index 100635ee6..d65a59030 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.9.0", + "version": "8.0.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 1cbfdf222..43d74dc6e 100644 --- a/packages/services/service-knowledge/CHANGELOG.md +++ b/packages/services/service-knowledge/CHANGELOG.md @@ -1,5 +1,22 @@ # @objectstack/service-knowledge +## 8.0.0 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/services/service-knowledge/package.json b/packages/services/service-knowledge/package.json index 9e4d2363c..c4fd671d7 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.9.0", + "version": "8.0.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 index f35bb1b7c..5c0f09d83 100644 --- a/packages/services/service-messaging/CHANGELOG.md +++ b/packages/services/service-messaging/CHANGELOG.md @@ -1,5 +1,54 @@ # @objectstack/service-messaging +## 8.0.0 + +### Minor Changes + +- 9f311f8: feat(messaging): digest batching for notifications (ADR-0030 P3b-2) + + Recipients can now batch a topic into a `daily` / `weekly` **digest** instead of + receiving every notification immediately. Builds on P3b-1's deferral seam: + + - `PreferenceResolver` consumes the `digest` preference field and `digestDeferral()` + defers a batched recipient to the next window (local midnight / Monday 00:00), + tagging the target with a stable `window`. Digest takes precedence over + quiet-hours; `critical` and mandatory topics bypass it. + - `sys_notification_delivery` gains a `digest_key` (`recipient|channel|window`). + Batched rows partition by that key so a window's rows co-locate, and the normal + outbox `claim()` skips them while the new `claimDigest()` drains a window whole. + - The dispatcher's digest pass collapses each `(recipient, channel, window)` group + into one `renderDigest()` message under the existing per-partition cluster lock, + then acks every row in the group with that single outcome. + + Additive: non-digest notifications are unchanged. Timezone-from-`sys_user`, + configurable send-hour, and MJML digest emails are deferred follow-ups. + +### Patch Changes + +- c70eec1: fix(messaging): converge mark-read receipt on unique-index race + + `markRead`'s `upsertReadReceipt` did `findOne`-then-`insert` (check-then-act), so + a concurrent mark-read — or the best-effort `delivered` receipt write still in + flight — could win the `UNIQUE(notification_id, user_id, channel)` index between + the read and the write. Clicking a notification then threw + `UNIQUE constraint failed: sys_notification_receipt...`. The insert now catches a + unique violation and falls back to flipping the now-present row to `read`, with a + cross-driver `isUniqueViolation` helper (SQLite / Postgres `23505` / + MySQL `ER_DUP_ENTRY`). + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/services/service-messaging/package.json b/packages/services/service-messaging/package.json index bbfd6812e..1a0cad997 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.9.0", + "version": "8.0.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 5ed29d047..61a3044ce 100644 --- a/packages/services/service-package/CHANGELOG.md +++ b/packages/services/service-package/CHANGELOG.md @@ -1,5 +1,22 @@ # @objectstack/service-package +## 8.0.0 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/services/service-package/package.json b/packages/services/service-package/package.json index abc87b3ed..3c3589620 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.9.0", + "version": "8.0.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 9aed9b390..47d66045f 100644 --- a/packages/services/service-queue/CHANGELOG.md +++ b/packages/services/service-queue/CHANGELOG.md @@ -1,5 +1,23 @@ # @objectstack/service-queue +## 8.0.0 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + - @objectstack/platform-objects@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/services/service-queue/package.json b/packages/services/service-queue/package.json index 956132cfa..312f54fb0 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.9.0", + "version": "8.0.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 882cd7b5b..81be82b1b 100644 --- a/packages/services/service-realtime/CHANGELOG.md +++ b/packages/services/service-realtime/CHANGELOG.md @@ -1,5 +1,23 @@ # @objectstack/service-realtime +## 8.0.0 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + - @objectstack/platform-objects@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/services/service-realtime/package.json b/packages/services/service-realtime/package.json index 754f99791..70fda9e30 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.9.0", + "version": "8.0.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 2b2a59de6..d302f318f 100644 --- a/packages/services/service-settings/CHANGELOG.md +++ b/packages/services/service-settings/CHANGELOG.md @@ -1,5 +1,24 @@ # @objectstack/service-settings +## 8.0.0 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + - @objectstack/platform-objects@8.0.0 + - @objectstack/types@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/services/service-settings/package.json b/packages/services/service-settings/package.json index 9ba2f4a25..47952581a 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.9.0", + "version": "8.0.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 df9d2962d..cb4748f01 100644 --- a/packages/services/service-storage/CHANGELOG.md +++ b/packages/services/service-storage/CHANGELOG.md @@ -1,5 +1,23 @@ # @objectstack/service-storage +## 8.0.0 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [c262301] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + - @objectstack/core@8.0.0 + - @objectstack/observability@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/services/service-storage/package.json b/packages/services/service-storage/package.json index aea216ca5..52374f9d0 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.9.0", + "version": "8.0.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 7414cbbe1..3ee608968 100644 --- a/packages/spec/CHANGELOG.md +++ b/packages/spec/CHANGELOG.md @@ -1,5 +1,167 @@ # @objectstack/spec +## 8.0.0 + +### Minor Changes + +- b990b89: fix(autonumber): one owner for autonumber generation — the persistent driver sequence (#1603) + + Autonumber values were generated in TWO places: the SQL driver's persistent, + atomic `_objectstack_sequences` table AND a non-persistent in-memory counter in + the ObjectQL engine. Because the engine pre-filled the field BEFORE calling the + driver, the driver always saw a value already set and skipped — so the + persistent sequence was effectively dead code, and a multi-instance / post-restart + deployment could mint duplicate numbers from the in-memory counter. + + This makes generation single-owner: + + - **`@objectstack/spec`** — `DriverCapabilities` gains an optional `autonumber` + flag: "driver natively generates persistent autonumber/sequence values". + + - **`@objectstack/driver-sql`** — advertises `supports.autonumber = true`. + `bulkCreate()` now fills autonumber fields too (previously only `create()` / + `upsert()` did), so bulk inserts also draw from the persistent sequence. + Field parsing now honors either the spec-canonical `autonumberFormat` key OR + the `format` shorthand (both appear in metadata). + + - **`@objectstack/objectql`** — when the driver advertises native autonumber + support, the engine NO LONGER pre-fills (it defers entirely to the persistent + driver sequence as the single source of truth). For drivers without native + support (memory, mongodb) the in-memory fallback is unchanged. The fallback + also now reads either `autonumberFormat` or `format`. Record-validation + exempts `autonumber` fields from the `required` check — the value is + runtime-owned and assigned after validation, so a required record number is + never rejected as "missing". + + No metadata changes required. Existing data is respected: the driver bootstraps + each sequence from the current max numeric tail on first use. + +- 99111ec: Field-level conditional rules (CEL): `visibleWhen` / `readonlyWhen` / `requiredWhen`, enforced server-side. + + Add three CEL-predicate field props (over `record`) evaluated on both sides. **Spec**: `visibleWhen` / `readonlyWhen` / `requiredWhen` (`requiredWhen` canonical; `conditionalRequired` kept as a back-compat alias). **Server (objectql)**: the validator now enforces `requiredWhen`/`conditionalRequired` over the merged record (so the rule can't be bypassed by a direct API write), and the update path ignores writes to a field whose `readonlyWhen` is TRUE (keeps the persisted value). `needsPriorRecord` accounts for conditional fields so the prior record is fetched on update. + +- d5a8161: feat(spec): resilientFetch — timeout + backoff for outbound HTTP (P1-1) + + Outbound calls in the connectors/embedder were naked `fetch` with no timeout or + retry, so a slow or rate-limited external API could hang an agent turn with no + recovery. + + New shared `resilientFetch` (`@objectstack/spec/shared`): + + - per-attempt timeout via `AbortController` (default 30s); + - exponential backoff with jitter, up to 3 attempts, on network errors / 429 / 5xx; + - honours a `Retry-After` header on 429; + - never retries a caller-initiated abort (intentional cancellation). + + Wired into `connector-rest`, `connector-slack`, and `embedder-openai`. + `connector-mcp` talks through the MCP SDK transport, so it gets a 30s per-request + `timeout` on `callTool` / `listTools` instead. + + A stateful per-host **circuit breaker** is deliberately left as a follow-up: + timeout + backoff already removes the hang/no-recovery risk. + +- 5cf1f1b: feat(spec): `inlineEdit` on relationship fields for declarative master-detail + + A `master_detail`/`lookup` field can now declare `inlineEdit: true` (plus + optional `inlineTitle` / `inlineColumns` / `inlineAmountField`) to mean "these + child records are entered/edited inline within the parent's form". The intent + lives in the data model: the parent's standard create/edit form then renders an + atomic master-detail form (object fields + an editable child grid) with no form + view config and no bespoke page. Use for line-item/composition children; leave + off for associations (comments, attachments). Renderer support is in objectui. + +- 9ef89d4: feat(spec): `FormViewSchema.subforms` for config-driven master-detail + + A form view can now declare inline child collections via `subforms`, so the + standard create/edit form for an object can render as a master-detail form + (object fields on top, an editable child grid below, persisted atomically) + without a bespoke page. Each entry needs only `childObject`; the relationship + FK and grid columns are derived from the child object's metadata (override via + `relationshipField` / `columns`). Renderer support: ObjectForm already renders + `subforms` (objectui), and the ObjectView form path passes them through. + +- 9e2e229: feat(objectql): compute roll-up `summary` fields server-side + + The `summary` field type was declared in the spec but never computed — its value + stayed empty. ObjectQL now recomputes roll-up summaries automatically: a parent + field whose `summaryOperations` aggregates (`count`/`sum`/`min`/`max`/`avg`) a + field across child records is recalculated whenever a child is inserted, + updated, or deleted. + + - **`@objectstack/spec`** — `summaryOperations` gains an optional + `relationshipField` (the child→parent FK). When omitted the engine + auto-detects it from the child's `lookup`/`master_detail` field whose + `reference` points back at the parent; set it explicitly only when the child + has more than one such reference. + + - **`@objectstack/objectql`** — after `afterInsert` / `afterUpdate` / + `afterDelete` on a child object, the engine finds the affected parent (from + the child's FK, plus the prior FK on update/delete so a re-parented child + updates both), re-aggregates the child collection, and writes the result onto + the parent's summary field. It runs in the caller's execution context, so when + a transaction is open (e.g. the cross-object `/api/v1/batch`) the rollup + commits atomically with the child writes. A small index of child→summary + descriptors is built lazily from the registry and invalidated on package + registration. + + Empty collections roll up to `0` for `count`/`sum` and `null` for + `min`/`max`/`avg`. This lets master-detail forms stop computing parent totals on + the client — the server is now the single source of truth. + +### Patch Changes + +- a46c017: feat(ai): actions opt in to being AI tools via an `ai:` block (ADR-0011) + + Realigns ADR-0011 with its original opt-in design. An Action becomes an + AI-callable tool only when its metadata sets `ai.exposed: true`, which requires + an explicit, LLM-facing `ai.description` (≥40 chars, distinct from the UI + `label`). There is no heuristic auto-exposure and no description derived from + the label — a clean break from the first implementation's opt-out `aiExposed` + flag, which is removed (no compatibility shim; the platform has not shipped). + + The `ai:` block also carries `category`, `paramHints` (per-parameter JSON-Schema + refinement), `outputSchema` (summarised into the tool description for chaining), + and `requiresConfirmation` (overrides the destructive-action HITL default). + `AIToolDefinition` is extended to carry `category` / `outputSchema` / `objectName` + / `requiresConfirmation`. The `@objectstack/service-ai` bridge + (`action-tools.ts`) now gates on opt-in, merges `paramHints`, and emits a lint + warning when an exposed destructive-looking action asserts itself safe via + `ai.requiresConfirmation: false`. + +- 3306d2f: feat(automation): surface structured-region body steps in run observability (#1505) + + `loop` / `parallel` / `try_catch` previously ran their body, branch, and handler + regions against a region-local step log that was **discarded** — run logs + (`listRuns` / `getRun`) showed the container as a single opaque step, hiding the + per-iteration / per-branch steps that actually executed. + + `AutomationEngine.runRegion()` now **returns** its body steps, and the container + node folds them into the parent run log via a new `NodeExecutionResult.childSteps` + field. Each surfaced step is tagged with its **immediate** container via three new + optional fields on `ExecutionStepLogSchema` (and the engine's `StepLogEntry`): + + - `parentNodeId` — the enclosing `loop` / `parallel` / `try_catch` node + - `iteration` — zero-based loop iteration or parallel branch index + - `regionKind` — `loop-body` | `parallel-branch` | `try` | `catch` + + Tagging fills only fields left undefined, so nested regions keep each step's + innermost container. A failed try-region attempt's partial steps are still not + surfaced (preserving `try_catch` retry semantics). Fully additive — existing run + logs and consumers are unaffected. + +- bc44195: chore(automation): retire the `workflow_rule` authoring paradigm (ADR-0018 M5 dropped) + + ADR-0019 already removed the Workflow-Rule → Flow compiler (Workflow Rules were + removed in #1398 and `workflow` was reclaimed for state machines), but the + `workflow_rule` paradigm tag survived in `ActionParadigmSchema` and on every + built-in node descriptor. There is no declarative Workflow-Rule authoring view + to feed, so the tag is now retired: `ActionParadigmSchema` keeps `['flow', +'approval']`, and the `http` / `notify` / `connector_action` descriptors (plus + the deprecated-alias fallback) advertise `['flow', 'approval']`. Approval + execution convergence is delivered by the ADR-0019 approval Flow node, not a + compiler. ADR-0018's status and migration table are updated to mark M3 shipped, + M4 framework-complete, and M5 dropped. + ## 7.9.0 ## 7.8.0 diff --git a/packages/spec/package.json b/packages/spec/package.json index f91d69a5e..eff8dd9a9 100644 --- a/packages/spec/package.json +++ b/packages/spec/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/spec", - "version": "7.9.0", + "version": "8.0.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 ec330dc21..6123e3194 100644 --- a/packages/types/CHANGELOG.md +++ b/packages/types/CHANGELOG.md @@ -1,5 +1,20 @@ # @objectstack/types +## 8.0.0 + +### Patch Changes + +- Updated dependencies [a46c017] +- Updated dependencies [b990b89] +- Updated dependencies [99111ec] +- Updated dependencies [d5a8161] +- Updated dependencies [5cf1f1b] +- Updated dependencies [9ef89d4] +- Updated dependencies [3306d2f] +- Updated dependencies [bc44195] +- Updated dependencies [9e2e229] + - @objectstack/spec@8.0.0 + ## 7.9.0 ### Patch Changes diff --git a/packages/types/package.json b/packages/types/package.json index 225eca580..47e0922f5 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@objectstack/types", - "version": "7.9.0", + "version": "8.0.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 6af1b46d0..e49d84a29 100644 --- a/packages/vscode-objectstack/CHANGELOG.md +++ b/packages/vscode-objectstack/CHANGELOG.md @@ -1,5 +1,7 @@ # objectstack-vscode +## 8.0.0 + ## 7.9.0 ## 7.8.0 diff --git a/packages/vscode-objectstack/package.json b/packages/vscode-objectstack/package.json index ae8ec2c97..8228babad 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.9.0", + "version": "8.0.0", "publisher": "objectstack", "license": "Apache-2.0", "repository": {