stitchkit 0.68.0 → 0.68.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. package/dist/agent-runtime/admission-lanes.d.ts +1 -1
  2. package/dist/agent-runtime/compaction.d.ts +2 -2
  3. package/dist/agent-runtime/events.d.ts +1 -1
  4. package/dist/agent-runtime/history.d.ts +1 -1
  5. package/dist/agent-runtime/history.d.ts.map +1 -1
  6. package/dist/agent-runtime/injection.d.ts +1 -1
  7. package/dist/agent-runtime/managed-tools.d.ts +3 -3
  8. package/dist/agent-runtime/models.d.ts +1 -1
  9. package/dist/agent-runtime/observability.d.ts +1 -1
  10. package/dist/agent-runtime/prompt.d.ts +1 -1
  11. package/dist/agent-runtime/prompt.d.ts.map +1 -1
  12. package/dist/agent-runtime/protocol.d.ts +19 -1
  13. package/dist/agent-runtime/protocol.d.ts.map +1 -1
  14. package/dist/agent-runtime/run-execution.d.ts +5 -5
  15. package/dist/agent-runtime/run-execution.d.ts.map +1 -1
  16. package/dist/agent-runtime/runtime-internals.d.ts +1 -1
  17. package/dist/agent-runtime/runtime-result.d.ts +1 -1
  18. package/dist/agent-runtime/runtime.d.ts +14 -12
  19. package/dist/agent-runtime/runtime.d.ts.map +1 -1
  20. package/dist/agent-runtime/store-driver.d.ts +2 -2
  21. package/dist/agent-runtime/store.d.ts +2 -2
  22. package/dist/agent-runtime/terminal-commit.d.ts +2 -2
  23. package/dist/agent-runtime/terminal-status.d.ts +1 -1
  24. package/dist/agent-runtime-openrouter.d.ts +1 -1
  25. package/dist/agent-runtime.d.ts +15 -15
  26. package/dist/agent-runtime.d.ts.map +1 -1
  27. package/dist/agent-runtime.js +87 -26
  28. package/dist/application/admission.d.ts +1 -1
  29. package/dist/application/events.d.ts +2 -2
  30. package/dist/application/grammy.d.ts +2 -2
  31. package/dist/application/graph.d.ts +1 -1
  32. package/dist/application/health.d.ts +1 -1
  33. package/dist/application/kernel.d.ts +3 -3
  34. package/dist/application/opentelemetry.d.ts +3 -3
  35. package/dist/application/resource.d.ts +1 -1
  36. package/dist/application/schedule.d.ts +1 -1
  37. package/dist/application/server-resource.d.ts +7 -9
  38. package/dist/application/server-resource.d.ts.map +1 -1
  39. package/dist/application-grammy.d.ts +1 -1
  40. package/dist/application-opentelemetry.d.ts +1 -1
  41. package/dist/application.d.ts +11 -11
  42. package/dist/application.js +7 -7
  43. package/dist/browser/client-multipart.d.ts +1 -1
  44. package/dist/browser/client-url.d.ts +2 -2
  45. package/dist/browser/client.d.ts +4 -4
  46. package/dist/browser/client.d.ts.map +1 -1
  47. package/dist/browser/contract-stream.d.ts +1 -1
  48. package/dist/browser/http.d.ts +7 -7
  49. package/dist/browser/http.d.ts.map +1 -1
  50. package/dist/browser/socket-io.d.ts +12 -31
  51. package/dist/browser/socket-io.d.ts.map +1 -1
  52. package/dist/browser/stream.d.ts +2 -2
  53. package/dist/cli.d.ts +6 -6
  54. package/dist/cli.js +4 -3
  55. package/dist/contract/errors-factory.d.ts +1 -1
  56. package/dist/contract/factory.d.ts +1 -1
  57. package/dist/contract/index.d.ts +7 -7
  58. package/dist/files/boundary.d.ts +1 -1
  59. package/dist/files.d.ts +2 -2
  60. package/dist/{index-zd4v31v2.js → index-2ve29dzn.js} +3 -3
  61. package/dist/index-7etq650s.js +75 -0
  62. package/dist/{index-7pn02bgv.js → index-cszjsxy5.js} +22 -83
  63. package/dist/index-g2j2m6vv.js +63 -0
  64. package/dist/{index-nymn7wbg.js → index-nck3yx3y.js} +15 -8
  65. package/dist/index.d.ts +10 -10
  66. package/dist/index.js +4 -4
  67. package/dist/internal/errors.d.ts +1 -1
  68. package/dist/internal/observability-sink.d.ts +1 -1
  69. package/dist/node.d.ts +11 -11
  70. package/dist/node.js +2 -2
  71. package/dist/observability/audit.d.ts +5 -5
  72. package/dist/observability/context.d.ts +2 -2
  73. package/dist/observability/event.d.ts +2 -2
  74. package/dist/observability/index.d.ts +6 -6
  75. package/dist/react/entity-cache.d.ts +26 -1
  76. package/dist/react/entity-cache.d.ts.map +1 -1
  77. package/dist/react.d.ts +3 -3
  78. package/dist/react.d.ts.map +1 -1
  79. package/dist/react.js +136 -38
  80. package/dist/realtime/contract.d.ts +1 -1
  81. package/dist/realtime/index.d.ts +4 -4
  82. package/dist/realtime/rejection.d.ts +1 -1
  83. package/dist/realtime/request.d.ts +1 -1
  84. package/dist/realtime/socket.d.ts +2 -2
  85. package/dist/remote.d.ts +1 -1
  86. package/dist/remote.js +1 -1
  87. package/dist/server/bun.d.ts +3 -3
  88. package/dist/server/context-contribution.d.ts +1 -1
  89. package/dist/server/context.d.ts +4 -4
  90. package/dist/server/contract-stream.d.ts +2 -2
  91. package/dist/server/create.d.ts +1 -1
  92. package/dist/server/error-hook.d.ts +3 -3
  93. package/dist/server/file.d.ts +1 -1
  94. package/dist/server/implement.d.ts +2 -2
  95. package/dist/server/index.d.ts +31 -31
  96. package/dist/server/index.js +9 -9
  97. package/dist/server/lifecycle.d.ts +1 -1
  98. package/dist/server/logging.d.ts +1 -1
  99. package/dist/server/middleware/auth.d.ts +2 -2
  100. package/dist/server/multipart.d.ts +2 -2
  101. package/dist/server/node.d.ts +2 -2
  102. package/dist/server/openapi.d.ts +1 -1
  103. package/dist/server/process-signal-common.d.ts +1 -1
  104. package/dist/server/process-signals.d.ts +1 -1
  105. package/dist/server/realtime.d.ts +4 -4
  106. package/dist/server/response-metadata.d.ts +1 -1
  107. package/dist/server/router.d.ts +1 -1
  108. package/dist/server/shutdown.d.ts +1 -1
  109. package/dist/server/socket-io-node.d.ts +3 -3
  110. package/dist/server/socket-io.d.ts +6 -6
  111. package/dist/server/streaming-route.d.ts +2 -2
  112. package/dist/server/types.d.ts +6 -6
  113. package/dist/server/unix-client-bun.d.ts.map +1 -1
  114. package/dist/server/unix-client.d.ts +2 -2
  115. package/dist/server/unix-client.d.ts.map +1 -1
  116. package/dist/testing/agent-store-conformance.d.ts +1 -1
  117. package/dist/testing/managed-resource-conformance-contract.d.ts +1 -1
  118. package/dist/testing/managed-resource-conformance-driver.d.ts +2 -2
  119. package/dist/testing/managed-resource-conformance-scenarios.d.ts +2 -2
  120. package/dist/testing/managed-resource-conformance.d.ts +2 -2
  121. package/dist/testing/surface-conformance.d.ts +3 -3
  122. package/dist/testing/surface-manifest.d.ts +5 -5
  123. package/dist/testing.d.ts +8 -8
  124. package/dist/testing.js +1 -1
  125. package/dist/tool-invoker.d.ts +9 -0
  126. package/dist/tool-invoker.d.ts.map +1 -0
  127. package/dist/tool-invoker.js +16 -0
  128. package/dist/tools/agent.d.ts +4 -4
  129. package/dist/tools/async-operation.d.ts +3 -3
  130. package/dist/tools/cli-command.d.ts +3 -3
  131. package/dist/tools/cli-format.d.ts +1 -1
  132. package/dist/tools/cli-policy.d.ts +1 -1
  133. package/dist/tools/cli-wait.d.ts +1 -1
  134. package/dist/tools/cli.d.ts +7 -7
  135. package/dist/tools/define-download-tool.d.ts +4 -4
  136. package/dist/tools/define-upload-tool.d.ts +3 -3
  137. package/dist/tools/define-view-file-tool.d.ts +3 -3
  138. package/dist/tools/define-wait-tool.d.ts +2 -2
  139. package/dist/tools/download-core.d.ts +2 -2
  140. package/dist/tools/execute.d.ts +2 -2
  141. package/dist/tools/flatten-join.d.ts +1 -1
  142. package/dist/tools/internal/surface-projector.d.ts +3 -3
  143. package/dist/tools/invoker.d.ts +4 -4
  144. package/dist/tools/lifecycle.d.ts +1 -1
  145. package/dist/tools/list-names.d.ts +2 -2
  146. package/dist/tools/managed-file-error.d.ts +1 -1
  147. package/dist/tools/manifest.d.ts +3 -3
  148. package/dist/tools/mcp-handler.d.ts +4 -4
  149. package/dist/tools/mcp-prepare.d.ts +8 -8
  150. package/dist/tools/mcp-round-policy.d.ts +1 -1
  151. package/dist/tools/mcp-round.d.ts +3 -3
  152. package/dist/tools/mcp-stdio-signals.d.ts +2 -2
  153. package/dist/tools/mcp-stdio.d.ts +3 -3
  154. package/dist/tools/mcp.d.ts +7 -7
  155. package/dist/tools/mount-download.d.ts +1 -1
  156. package/dist/tools/mount-upload.d.ts +1 -1
  157. package/dist/tools/mount.d.ts +5 -5
  158. package/dist/tools/native-definition.d.ts +2 -2
  159. package/dist/tools/native-mcp.d.ts +3 -3
  160. package/dist/tools/oauth-metadata.d.ts +1 -1
  161. package/dist/tools/oauth-provider.d.ts +1 -1
  162. package/dist/tools/presentation.d.ts +1 -1
  163. package/dist/tools/remote.d.ts +3 -3
  164. package/dist/tools/runtime-tool.d.ts +2 -2
  165. package/dist/tools/surface.d.ts +5 -5
  166. package/dist/tools/tool-logger.d.ts +1 -1
  167. package/dist/tools/toolkit.d.ts +7 -7
  168. package/dist/tools/transports.d.ts +2 -2
  169. package/dist/tools/upload-core.d.ts +1 -1
  170. package/dist/tools/view-file.d.ts +1 -1
  171. package/dist/tools.d.ts +42 -42
  172. package/dist/tools.js +18 -61
  173. package/llms-full.txt +169 -18
  174. package/package.json +8 -4
  175. package/dist/{index-avjd67h6.js → index-cz32amcb.js} +3 -3
package/llms-full.txt CHANGED
@@ -51,6 +51,7 @@ own, recorded as an ADR.
51
51
  | `stitchkit/server` | server (Bun) | stable | `createServer`, `implement`, hooks, auth, Socket.IO server, server primitives |
52
52
  | `stitchkit/node` | server (Node ≥ 22) | stable | `serveNode` + the runtime-agnostic core — the Node mirror of `/server` |
53
53
  | `stitchkit/tools` | server | stable | `createMcpHandler`, `mountMcp`, `mountAgent`, the OAuth provider, native tools |
54
+ | `stitchkit/tools/invoker` | server | stable | peer-free `createToolInvoker` over the canonical contract tool runner |
54
55
  | `stitchkit/cli` | server | stable | `createCli` — the CLI transport, light (no MCP SDK / `ai`) |
55
56
  | `stitchkit/remote` | browser **and** server | stable | peer-free `implementRemote` for thin HTTP proxy processes |
56
57
  | `stitchkit/files` | server (Bun or Node) | stable | peer-free managed local-file boundary |
@@ -159,7 +160,8 @@ map — feature → packages:
159
160
  | anything (validation) | `zod` |
160
161
  | `createServer` (Bun) | — (uses `Bun.serve`) |
161
162
  | `serveNode` (Node ≥ 22) | `srvx` (+ `@types/bun` dev) |
162
- | MCP / agent tools (`stitchkit/tools`) | `@modelcontextprotocol/server` `ai` |
163
+ | In-process contract tools (`stitchkit/tools/invoker`) | |
164
+ | MCP / agent adapters (`stitchkit/tools`) | `@modelcontextprotocol/server` `ai` |
163
165
  | Agent application runtime (`stitchkit/agent-runtime`) | `ai` |
164
166
  | OpenRouter runtime adapter (`stitchkit/agent-runtime/openrouter`) | `ai` `@openrouter/ai-sdk-provider` |
165
167
  | MCP host/client tests | `@modelcontextprotocol/client` |
@@ -167,7 +169,7 @@ map — feature → packages:
167
169
  | React data layer (`stitchkit/react`) | `@tanstack/react-query` `react-query-kit` |
168
170
  | **Socket.IO server on Bun** | `socket.io` `@socket.io/bun-engine` |
169
171
  | **Socket.IO server on Node** | `socket.io` |
170
- | Socket.IO client | `socket.io-client` (brings `@socket.io/component-emitter`, which the browser declarations reference for types only) |
172
+ | Socket.IO client | `socket.io-client` (runtime peer; unrelated root declarations remain peer-free) |
171
173
  | grammY lifecycle adapters (`stitchkit/application/grammy`) | `grammy` |
172
174
  | OpenTelemetry gauges (`stitchkit/application/opentelemetry`) | `@opentelemetry/api` |
173
175
 
@@ -1914,6 +1916,14 @@ socket, and a missing socket cannot fall through to that host over TCP. Defaults
1914
1916
  are 16 MiB request/response bodies, 64 KiB headers, 30 s to response headers,
1915
1917
  eight connections and five redirects.
1916
1918
 
1919
+ `maxHeaderBytes` is enforced before exposing a response. Bun's owned parser
1920
+ counts the complete response head in wire bytes, including the status line and
1921
+ terminating blank line. Node passes the same configured integer unchanged to
1922
+ `http.request({ maxHeaderSize })`, so its native parser's documented header-size
1923
+ accounting is authoritative there. Exceeding either ceiling yields
1924
+ `UNIX_HEADERS_TOO_LARGE` with `delivery: 'response-received'`. A stalled body
1925
+ pauses its socket, and resuming preserves the exact chunked body.
1926
+
1917
1927
  `UnixClientTransportError` carries a stable `code` and `delivery`:
1918
1928
  `not-dispatched`, `possibly-dispatched` or `response-received`. Only the first
1919
1929
  proves that the remote operation did not begin; Stitchkit never silently retries
@@ -2028,12 +2038,58 @@ Abort and timeout do not emit `network_error` and are not retried. The same
2028
2038
  options work for query, JSON, multipart and raw-response calls. Stitchkit does
2029
2039
  not expose upload progress: Fetch has no portable upload-progress primitive.
2030
2040
 
2041
+ An injected transport failure is normalized to `UNKNOWN_ERROR` while its exact
2042
+ object remains available as `ApiError.cause`. This is how a bounded adapter can
2043
+ preserve facts the generic client cannot invent — for example a Unix transport's
2044
+ `not-dispatched`, `possibly-dispatched` or `response-received` state. Never replay
2045
+ an effect from `UNKNOWN_ERROR` alone; inspect the owned adapter's cause and retry
2046
+ only when it proves that dispatch did not happen.
2047
+
2031
2048
  For an endpoint without contract arguments, pass only the options object:
2032
2049
 
2033
2050
  ```ts
2034
2051
  await api.health.withOptions({ signal: controller.signal })
2035
2052
  ```
2036
2053
 
2054
+ ### Injected delivery adapters
2055
+
2056
+ `ClientFetch` is the narrow composition seam for application-owned delivery.
2057
+ The contract still owns operation identity, request serialization and response
2058
+ validation; the adapter owns I/O, bounds and dispatch certainty:
2059
+
2060
+ ```ts
2061
+ import { type ClientFetch, createClient } from 'stitchkit'
2062
+
2063
+ const delivery: ClientFetch = async (input, init) => {
2064
+ // Fixed deployment destination and policy are chosen here, not by caller data.
2065
+ return boundedFetch(input, { ...init, signal: init?.signal })
2066
+ }
2067
+
2068
+ const query = createClient(queryContract, {
2069
+ baseUrl: 'https://service.internal',
2070
+ fetch: delivery,
2071
+ })
2072
+ const work = createClient(requestWorkContract, {
2073
+ baseUrl: 'https://service.internal',
2074
+ fetch: delivery,
2075
+ })
2076
+ ```
2077
+
2078
+ The same adapter accepts unrelated contract shapes without learning their DTOs
2079
+ or operation inventory. `createClient` chooses method/path from the contract,
2080
+ serializes only the declared arguments, forwards `.withOptions(..., { signal })`
2081
+ and validates the response through the endpoint's output schema. A caller payload
2082
+ cannot replace the configured base URL or reserved operation path.
2083
+
2084
+ Contract metadata describes an effect; it does not authorize one. Authentication,
2085
+ scope and destination policy remain in the application/server boundary. A schema
2086
+ mismatch is an explicit validation failure and is not retried automatically. A
2087
+ timeout means the caller stopped waiting, not that the remote effect did not run.
2088
+
2089
+ Published declarations are checked from a clean tarball under both bundler and
2090
+ NodeNext resolution. The HTTP-only NodeNext proof uses `skipLibCheck: false` and
2091
+ installs no Socket.IO peer. → ADR 0120.
2092
+
2037
2093
  ### Many contracts at once
2038
2094
 
2039
2095
  ```ts
@@ -2170,6 +2226,7 @@ try {
2170
2226
  err.details // structured details, if any
2171
2227
  err.hint // optional hint
2172
2228
  err.traceId // x-request-id — correlate this failure with backend logs
2229
+ err.cause // concrete injected transport failure, when delivery failed
2173
2230
  }
2174
2231
  }
2175
2232
  ```
@@ -2468,7 +2525,7 @@ AI SDK `ToolSet` and call its transport adapter manually. Compile an in-process
2468
2525
  invoker once and call the shared framework runner directly:
2469
2526
 
2470
2527
  ```ts
2471
- import { createToolInvoker } from 'stitchkit/tools'
2528
+ import { createToolInvoker } from 'stitchkit/tools/invoker'
2472
2529
 
2473
2530
  const invoker = createToolInvoker(services, {
2474
2531
  transport: 'AGENT', // required exposure policy
@@ -2497,6 +2554,11 @@ recursive calls without retaining request state. Every invocation gets a fresh
2497
2554
  tool-call context and runs the same extension resolution, input/output
2498
2555
  validation, lifecycle, hooks and output-strip reporter as mounted tools.
2499
2556
 
2557
+ The dedicated entrypoint needs only the normal `stitchkit`/`zod` install. Use
2558
+ the broader `stitchkit/tools` barrel when the same program also mounts MCP or AI
2559
+ adapters and has installed their optional peers. Both imports reach the same
2560
+ runner; this is dependency isolation, not a second execution implementation.
2561
+
2500
2562
  `invoke` returns the canonical discriminated `ToolResult`, not an AI SDK or MCP
2501
2563
  presentation envelope. `invokeOrThrow` returns validated data and throws the
2502
2564
  runner's normalized `AppError` on failure, preserving an application error's
@@ -3772,6 +3834,14 @@ const store = createAgentRuntimeStore({
3772
3834
  })
3773
3835
  ```
3774
3836
 
3837
+ Prompt budgeting keeps reservation deficits signed. If instructions,
3838
+ `reservedOutput`, tool schemas, attachments and provider overhead already exceed
3839
+ `contextWindow`, `composeAgentPrompt` returns `contextDecision: 'oversized'`
3840
+ and a negative `availableHistoryTokens` even when history is empty. A `compact`
3841
+ policy is returned only when removing history could actually make the prompt
3842
+ fit. Exact equality (including a zero window with zero reservations/history)
3843
+ fits; any unavailable component keeps the decision `unavailable`.
3844
+
3775
3845
  The same opaque `tx` reaches head, run, admission and history callbacks. The adapter maps rows
3776
3846
  and supplies atomicity; Stitchkit owns transition validation and revision
3777
3847
  arithmetic. The executable reference is
@@ -4099,6 +4169,24 @@ is the reserved built-in policy name. `loop.prepareStep` is the controlled AI
4099
4169
  SDK step boundary for changing active tools, model, instructions or messages.
4100
4170
  It cannot replace the managed tool set or bypass its lifecycle fence.
4101
4171
 
4172
+ Completion validity belongs to the protocol and is checked before the terminal
4173
+ CAS. Protocols that require a visible answer opt in explicitly:
4174
+
4175
+ ```ts
4176
+ const protocol = defineAgentProtocol({
4177
+ context: ContextSchema,
4178
+ inputMetadata: InputMetadataSchema,
4179
+ terminalAcceptance: 'require-output',
4180
+ })
4181
+ ```
4182
+
4183
+ The built-in rule accepts non-blank text, generated files, structured provider
4184
+ parts, and a named tool-only `policy_stop`. The default is `allow-empty` for
4185
+ protocols where an empty acknowledgement is meaningful. Pass a callback when
4186
+ the product has a narrower definition; it receives the candidate message,
4187
+ terminal reason and optional policy name, and runs before persistence. A false
4188
+ result fails the candidate instead of rewriting an already committed success.
4189
+
4102
4190
  `loop.idleTimeoutMs` is inactivity, not total duration: the deadline resets on
4103
4191
  every model stream event. A stalled call aborts with durable reason `timeout`;
4104
4192
  user interruption and shutdown remain distinct.
@@ -4121,7 +4209,10 @@ effect must be replay-safe.
4121
4209
  ## History, provider metadata and files
4122
4210
 
4123
4211
  `projectAgentHistory` converts canonical engine records into provider-valid AI
4124
- SDK messages and pairs tool calls/results. Provider-required metadata is kept
4212
+ SDK messages and pairs tool calls/results in persisted causal order. Adjacent
4213
+ parallel calls stay in one assistant round and their adjacent results stay in
4214
+ one tool round; a dependent call after those results starts a new assistant
4215
+ round, and trailing final text remains after the last tool result. Provider-required metadata is kept
4125
4216
  in a versioned opaque envelope and omitted from product delivery by default.
4126
4217
  `projectAgentHistoryDetailed` additionally returns one inspectable decision per canonical record;
4127
4218
  leading assistant records, crash drafts and unmatched tool chronology are never silently passed to
@@ -4358,10 +4449,12 @@ const cleanup = createManagedSchedule({
4358
4449
  const http = managedServerResource({
4359
4450
  id: 'http',
4360
4451
  dependsOn: [database],
4361
- // Called during `start`, after `database` is ready which is how "bind the
4362
- // port once the database is up" is expressed. Pass an already-running server
4363
- // instead when the application created it itself.
4364
- server: () => createServer({ port: env.PORT, services }),
4452
+ // Called during `start`, after `database` is ready. The factory receives the
4453
+ // same declared-dependency and startup-signal context as any resource.
4454
+ server: (context) => {
4455
+ const db = context.use(database)
4456
+ return createServer({ port: env.PORT, services: createServices(db) })
4457
+ },
4365
4458
  })
4366
4459
 
4367
4460
  const app = createApplication({
@@ -4449,6 +4542,12 @@ Declare the dependency with the **resource**, not its id, whenever you intend to
4449
4542
  read from it: that is the form `use` can type, and it keeps the declaration and
4450
4543
  the read from drifting apart. A string still works when all you need is order.
4451
4544
 
4545
+ `managedServerResource` follows the same rule. Its factory receives this context
4546
+ during `start`, so constructing routes from a database/service/socket value does
4547
+ not need an outer mutable handoff or a custom `start` override. A zero-argument
4548
+ factory remains valid when it needs only ordering, and an already-running handle
4549
+ can still be passed directly. → ADR 0121.
4550
+
4452
4551
  The value is published when `start` resolves and stays readable for the rest of
4453
4552
  the application's life — from `activate` and from the shutdown phases too, where
4454
4553
  a dependant may still need the handle it was given.
@@ -5071,7 +5170,10 @@ already-listening server and it adopts that one instead.
5071
5170
  const http = managedServerResource({
5072
5171
  id: 'http',
5073
5172
  dependsOn: [database],
5074
- server: () => createServer({ port: env.PORT, services }),
5173
+ server: (context) => {
5174
+ const db = context.use(database)
5175
+ return createServer({ port: env.PORT, services: createServices(db) })
5176
+ },
5075
5177
  })
5076
5178
 
5077
5179
  const app = createApplication({ id: 'service', resources: [database, http] })
@@ -5082,6 +5184,11 @@ The server resource publishes its `ManagedServerHandle`, so anything that needs
5082
5184
  the running server — a Socket.IO attachment, a URL to log, a probe — reads it
5083
5185
  with `context.use(http)` rather than through a module-local.
5084
5186
 
5187
+ The factory itself receives `ManagedResourceContext` too. It can read only the
5188
+ dependencies declared on the server resource and shares the graph's startup
5189
+ signal. A dependency failure prevents the factory from binding; a factory
5190
+ rejection is rolled back without invoking the factory a second time.
5191
+
5085
5192
  Do not spread this resource over your own `start` to control creation order:
5086
5193
  that shape exists only as a workaround for the version whose `start` was empty,
5087
5194
  and `dependsOn` now expresses the order directly. The executable recipe binds a
@@ -5995,6 +6102,36 @@ page metadata and `pageParams`; an infinite create changes only the selected
5995
6102
  edge page (`createAt: 'start' | 'end'`). Creates are deduplicated across every
5996
6103
  cached page. `updateMissing` makes an absent update explicitly skip or insert.
5997
6104
 
6105
+ Filtered query families can additionally declare membership per exact key and
6106
+ evidence-aware total reconciliation:
6107
+
6108
+ ```ts
6109
+ list: {
6110
+ key: ['tickets'],
6111
+ shape: 'infinite-paginated',
6112
+ createAt: 'start',
6113
+ updateMissing: 'skip',
6114
+ membership: {
6115
+ evaluate: (event, queryKey) => membershipFor(event, queryKey),
6116
+ unknown: 'invalidate',
6117
+ },
6118
+ total: {
6119
+ mode: 'reconcile',
6120
+ unknown: 'invalidate',
6121
+ delta: ({ event, present, membership }) => provenDelta(event, present, membership),
6122
+ },
6123
+ }
6124
+ ```
6125
+
6126
+ Membership is `include | exclude | unknown`. An excluded update removes an
6127
+ existing row; an included one follows `updateMissing`. Unknown evidence never
6128
+ guesses and either preserves or invalidates the exact query. The conservative
6129
+ total policy increments only a non-duplicate create and decrements only a
6130
+ delete/update whose membership is observed; unseen IDs are `unknown`. Supply
6131
+ `delta` only when the event itself proves a stronger transition. Every page's
6132
+ numeric `total` changes together while cursor metadata and `pageParams` remain
6133
+ unchanged.
6134
+
5998
6135
  The event entity may be richer than a list row. Keep the full value in detail
5999
6136
  cache, project it for lists, and provide the same comparator the backend uses:
6000
6137
 
@@ -6032,9 +6169,9 @@ deleted payload without guessing. The same resolved detail key drives the
6032
6169
  `isFresh` echo guard. Shape checks also leave neighbouring detail caches alone
6033
6170
  when a list key is intentionally used as a partial query-key prefix.
6034
6171
 
6035
- The helper deliberately does **not** flatten pages, update totals, derive a
6036
- sort order or replace arbitrary `setQueryData` logic. Those are application
6037
- policies; this helper only applies declared CRUD semantics.
6172
+ The helper deliberately does **not** flatten pages, infer filter semantics,
6173
+ derive a sort order or replace arbitrary `setQueryData` logic. Those remain
6174
+ declared application policies; Stitchkit applies their generic cache mechanics.
6038
6175
 
6039
6176
  ## Raw binary lane (Bun)
6040
6177
 
@@ -7643,6 +7780,11 @@ runtime or type-only package outside a case's budget fails with both the case id
7643
7780
  and package name, so an accidental eager import cannot hide behind another
7644
7781
  fixture's transitive dependency.
7645
7782
 
7783
+ That includes `stitchkit/tools/invoker`: a minimal packed consumer imports it
7784
+ without MCP/AI peers and executes validation, output projection and normalized
7785
+ errors on Bun and Node. The broader `stitchkit/tools` barrel deliberately keeps
7786
+ the adapter peer budget.
7787
+
7646
7788
  Beside the matrix, one case is about the ARTIFACT rather than the inventory: a
7647
7789
  program that injects the Socket.IO peer loaders is bundled and started in a
7648
7790
  directory with no `node_modules`, under Node and under Bun with auto-install
@@ -7674,6 +7816,11 @@ const socket = await createSocketIOServer({
7674
7816
  })
7675
7817
  ```
7676
7818
 
7819
+ The packed Next/Webpack gate compiles the browser
7820
+ `peers.client: () => import('socket.io-client')` loader and rejects Webpack's
7821
+ "request is an expression" warning. Stitchkit's runtime fallback remains lazy;
7822
+ its emitted import carries a count-checked ignore directive.
7823
+
7677
7824
  Omit `peers` and nothing changes: the peers stay lazy and are resolved from the
7678
7825
  machine. Both peers must be listed as dependencies of the package you bundle,
7679
7826
  because they now genuinely are.
@@ -10712,7 +10859,7 @@ The browser-and-server entrypoint. Re-exports everything from
10712
10859
  | `contractEndpointMatchers` | function | compile exact pathname matchers for selected HTTP contract operations and expected-401 policy |
10713
10860
  | `PathPrefixArgs` | _type_ | required string-valued keys exposed to a typed dynamic `pathPrefix` callback |
10714
10861
  | `createHttpClient` | function | the Ky-based HTTP transport; on Next.js SSR its first attempt stays request-memoizable while every retry is a distinct transport attempt — [guide](../guide/client.md#createhttpclient) |
10715
- | `ApiError` | class | a non-2xx response, with `code` / `status` / `details` / `hint` and optional readonly `traceId` from `x-request-id` |
10862
+ | `ApiError` | class | a non-2xx or client failure, with `code` / `status` / `details` / `hint`, optional readonly `traceId` from `x-request-id`, and standard `cause` preserving an injected transport failure |
10716
10863
  | `HttpClient` | _type_ | the transport interface `createClient` builds on |
10717
10864
  | `ConfiguredHttpClient` | _type_ | a framework-created `HttpClient` carrying its readonly `baseUrl` for URL builders |
10718
10865
  | `HttpClientConfig` | _type_ | config for `createHttpClient`; retry `limit` counts retries after the initial attempt (default 2 = at most 3 GET attempts), with `statusCodes: []` by default; `fetch` installs an explicit transport and is mutually exclusive with the legacy Bun-only `unix` option — [details](../guide/client.md#createhttpclient) |
@@ -11119,7 +11266,7 @@ cutovers are covered by the executable
11119
11266
  | `ManagedResourceDependency` | _type_ | a dependency named by id or given as the resource itself — the second form is what `context.use(...)` can type |
11120
11267
  | `ManagedResourcePublished` | _type_ | the value type `context.use(resource)` returns, recovered from that resource's own `start` |
11121
11268
  | `ManagedResourcePublishesNoValue` | _type_ | what `context.use(...)` returns for a resource that publishes nothing — a branded refusal rather than `never`, so reading it does not silently compile |
11122
- | `ManagedServerResourceConfig` | _type_ | the server or a thunk that makes one, stable ID, dependencies and policy for `managedServerResource` |
11269
+ | `ManagedServerResourceConfig` | _type_ | the server or a sync/async factory receiving `ManagedResourceContext`, plus stable ID, dependencies and shutdown policy for `managedServerResource` |
11123
11270
  | `ManagedServerResource` | _type_ | the resource `managedServerResource` returns, whose `start` publishes the `ManagedServerHandle` |
11124
11271
  | `ApplicationHealthHandlerOptions` / `ApplicationHealthHandlerOptionsSchema` | _type_ / schema | liveness/readiness selection and sanitized `Retry-After` policy |
11125
11272
  | `ApplicationOperationalHandlers` / `ApplicationOperationalHandlersOptions` / `ApplicationOperationalHandlersOptionsSchema` | _type_ / schema | conventional status/readiness/liveness route surface and shared retry policy |
@@ -11247,7 +11394,8 @@ Server-only optional application runtime. See the
11247
11394
  | Export | Kind | Summary |
11248
11395
  |--------|------|---------|
11249
11396
  | `createAgentRuntime` | function | compose durable acceptance, stream loop, checkpoints, coordination, managed tools and winner-only terminal publication; reconciles same-owner terminal/interrupt/head CAS races before releasing the lane |
11250
- | `defineAgentProtocol` | function | declare and validate context, input metadata and canonical message parts |
11397
+ | `defineAgentProtocol` | function | declare context, input metadata, canonical parts and optional pre-CAS terminal acceptance (`allow-empty`, `require-output` or callback) |
11398
+ | `hasAgentTerminalOutput` | function | generic `require-output` predicate for non-blank text, generated files, structured provider parts and explicit tool-only policy stops |
11251
11399
  | `AgentMessageSchema` / `AgentRunSchema` / `AgentSnapshotSchema` | schema | versioned canonical engine records |
11252
11400
  | `AgentRuntimeStore` | _type_ | aggregate CAS transaction boundary for message, run and compaction mutations |
11253
11401
  | `createAgentRuntimeStore` | function | build the aggregate store from one coherent transaction driver; framework owns every state transition |
@@ -11260,7 +11408,7 @@ Server-only optional application runtime. See the
11260
11408
  | `createMemoryAgentRuntimeStore` | function | process-local reference adapter, not production durability |
11261
11409
  | `projectAgentHistory` | function | asynchronously project canonical records and resolved multimodal files into provider-valid AI SDK messages |
11262
11410
  | `defineModelRegistry` | function | typed language-model descriptors, capabilities and provider construction |
11263
- | `composeAgentPrompt` | function | ordered prompt contributions and provenance-aware context budget |
11411
+ | `composeAgentPrompt` | function | ordered prompt contributions and provenance-aware signed context budget; irreducible reservation deficits are `oversized`, not compactable history |
11264
11412
  | `structuredCompaction` | function | summarize a provider-valid snapshot range and replace it through CAS |
11265
11413
  | `createAgentSessionCoordinator` | function | strict process-local queue/interrupt/supersede lifecycle |
11266
11414
  | `AgentRuntimeStopPolicy` | _type_ | named custom AI SDK stop condition persisted and published on policy stop |
@@ -11289,7 +11437,8 @@ transport adapters validate the same records. Runtime composition types are `Age
11289
11437
  `AgentSessionCoordinator`, `AgentCompactionContext`, `AgentCompactionResult` and
11290
11438
  `StructuredCompactionConfig`.
11291
11439
 
11292
- Canonical protocol exports are `AgentProtocol`, `AgentProtocolConfig`, `AgentRecordIdSchema`, `AgentRecordVersionSchema`,
11440
+ Canonical protocol exports are `AgentProtocol`, `AgentProtocolConfig`, `AgentTerminalAcceptance`,
11441
+ `AgentTerminalAcceptanceInput`, `hasAgentTerminalOutput`, `AgentRecordIdSchema`, `AgentRecordVersionSchema`,
11293
11442
  `AgentTimestampSchema`, `AgentJsonObjectSchema`, `AgentProviderEnvelopeSchema`,
11294
11443
  `AgentProviderEnvelope`, `AgentMessagePartSchema`, `AgentMessagePart`, `AgentTextPartSchema`,
11295
11444
  `AgentReasoningPartSchema`, `AgentFilePartSchema`, `AgentSourcePartSchema`,
@@ -11485,7 +11634,7 @@ payload.
11485
11634
  | `mountAgent` | function | a Vercel AI SDK `ToolSet` from a service — [guide](../guide/mcp-and-agents.md#ai-agents--mountagent) |
11486
11635
  | `defineRuntimeTool` | function | define one validated pathless operation for explicit MCP, Agent and/or CLI surfaces — [guide](../guide/mcp-and-agents.md#pathless-runtime-tools-and-multimodal-results) |
11487
11636
  | `createRuntimeToolFactory` | function | bind shared identity and Zod-validated per-call context for runtime tools — [guide](../guide/mcp-and-agents.md#pathless-runtime-tools-and-multimodal-results) |
11488
- | `createToolInvoker` | function | compile an exposure-aware in-process dispatcher over the canonical tool runner — [guide](../guide/mcp-and-agents.md#in-process-calls--createtoolinvoker) |
11637
+ | `createToolInvoker` | function | compile an exposure-aware in-process dispatcher over the canonical tool runner; use peer-free `stitchkit/tools/invoker`, or the full `stitchkit/tools` adapter barrel — [guide](../guide/mcp-and-agents.md#in-process-calls--createtoolinvoker) |
11489
11638
  | `createCli` | function | a command-line program from contracts — [guide](../guide/cli.md) (also on `stitchkit/cli`) |
11490
11639
  | `defineCliCommand` | function | define one typed CLI-only command with optional post-validation `present` and successful `exitCode` policy — [guide](../guide/cli.md#native-binary-commands) (also on `stitchkit/cli`) |
11491
11640
  | `createToolkit` | function | context-typed tool mounts — [guide](../guide/cli.md#typed-context) |
@@ -11930,6 +12079,8 @@ and `react-query-kit` peers.
11930
12079
  | `createCacheBridge` | function | sync socket events into the Query cache — [guide](../guide/realtime.md#cache-bridge) |
11931
12080
  | `createEntityCacheHandlers` | function | created/updated/deleted cache handlers for one entity — [guide](../guide/realtime.md#entity-cache-handlers) |
11932
12081
  | `EntityCacheConfig` | _type_ | config for `createEntityCacheHandlers` |
12082
+ | `EntityCacheMembership` / `EntityCacheMembershipPolicy` | _type_ | per-exact-query `include | exclude | unknown` filter decision and unknown invalidation policy |
12083
+ | `EntityCacheTotalPolicy` / `EntityCacheTotalDeltaInput` | _type_ | evidence-aware reconciliation of numeric totals on paginated cache shapes |
11933
12084
  | `EntityCacheHandlers` | _type_ | the `{ created, updated, deleted }` handlers it returns |
11934
12085
  | `EntityCacheEvent` | _type_ | discriminated created/updated/deleted input for dynamic cache keys |
11935
12086
  | `EntityCacheKey` | _type_ | static `QueryKey` or event-aware key factory |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stitchkit",
3
- "version": "0.68.0",
3
+ "version": "0.68.1",
4
4
  "description": "Contract-first backend framework — one defineContract() into an HTTP API, MCP tools, AI-agent tools and a typed client. Bun and Node.",
5
5
  "keywords": [
6
6
  "bun",
@@ -56,6 +56,10 @@
56
56
  "types": "./dist/tools.d.ts",
57
57
  "import": "./dist/tools.js"
58
58
  },
59
+ "./tools/invoker": {
60
+ "types": "./dist/tool-invoker.d.ts",
61
+ "import": "./dist/tool-invoker.js"
62
+ },
59
63
  "./cli": {
60
64
  "types": "./dist/cli.d.ts",
61
65
  "import": "./dist/cli.js"
@@ -119,9 +123,9 @@
119
123
  "scripts": {
120
124
  "check": "bun x tsc --noEmit",
121
125
  "build:browser": "bun build src/index.ts src/react.ts src/contract/index.ts src/declaration.ts --outdir dist --target node --packages external --splitting --root src",
122
- "build:server": "bun build src/server/index.ts src/node.ts src/tools.ts src/cli.ts src/remote.ts src/files.ts src/testing.ts src/observability/index.ts src/agent-runtime.ts src/agent-runtime-openrouter.ts src/application.ts src/application-grammy.ts src/application-opentelemetry.ts --outdir dist --target node --packages external --splitting --root src",
123
- "build:js": "bun run build:browser && bun run build:server",
124
- "build:types": "bun x tsc -p tsconfig.build.json --emitDeclarationOnly",
126
+ "build:server": "bun build src/server/index.ts src/node.ts src/tools.ts src/tool-invoker.ts src/cli.ts src/remote.ts src/files.ts src/testing.ts src/observability/index.ts src/agent-runtime.ts src/agent-runtime-openrouter.ts src/application.ts src/application-grammy.ts src/application-opentelemetry.ts --outdir dist --target node --packages external --splitting --root src",
127
+ "build:js": "bun run build:browser && bun run build:server && bun scripts/preserve-webpack-ignore.mjs",
128
+ "build:types": "bun x tsc -p tsconfig.build.json --emitDeclarationOnly && bun scripts/rewrite-declaration-specifiers.mjs",
125
129
  "build": "rm -rf dist && bun run build:js && bun run build:types && bun scripts/check-browser-clean.mjs && bun scripts/check-env-live.mjs && bun scripts/check-public-types.mjs",
126
130
  "dev": "bun run build:js -- --watch",
127
131
  "prepack": "cp ../../README.md ./README.md && bun ../../scripts/gen-llms.ts && bun run build",
@@ -1,10 +1,10 @@
1
- import {
2
- objectShapeKeys
3
- } from "./index-6djpbnda.js";
4
1
  import {
5
2
  getRequestContext,
6
3
  runWithRequestContext
7
4
  } from "./index-69m2278y.js";
5
+ import {
6
+ objectShapeKeys
7
+ } from "./index-6djpbnda.js";
8
8
  import {
9
9
  formatZodError,
10
10
  isUnsafeKey,