stitchkit 0.88.0 → 0.89.0

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 (164) hide show
  1. package/CHANGELOG.md +126 -0
  2. package/dist/agent-runtime/child-blocking.d.ts +17 -0
  3. package/dist/agent-runtime/child-blocking.d.ts.map +1 -0
  4. package/dist/agent-runtime/child-budget-policy.d.ts +23 -0
  5. package/dist/agent-runtime/child-budget-policy.d.ts.map +1 -0
  6. package/dist/agent-runtime/children-contract.d.ts +155 -0
  7. package/dist/agent-runtime/children-contract.d.ts.map +1 -0
  8. package/dist/agent-runtime/children.d.ts +4 -99
  9. package/dist/agent-runtime/children.d.ts.map +1 -1
  10. package/dist/agent-runtime/coding-shell-process.d.ts +33 -0
  11. package/dist/agent-runtime/coding-shell-process.d.ts.map +1 -0
  12. package/dist/agent-runtime/coding-tool-contract.d.ts +18 -0
  13. package/dist/agent-runtime/coding-tool-contract.d.ts.map +1 -1
  14. package/dist/agent-runtime/coding-tool-files.d.ts.map +1 -1
  15. package/dist/agent-runtime/coding-tool-listing.d.ts.map +1 -1
  16. package/dist/agent-runtime/coding-tool-search-patch.d.ts.map +1 -1
  17. package/dist/agent-runtime/coding-tool-shell.d.ts.map +1 -1
  18. package/dist/agent-runtime/coding-tool-utf8.d.ts +28 -0
  19. package/dist/agent-runtime/coding-tool-utf8.d.ts.map +1 -0
  20. package/dist/agent-runtime/contained-files.d.ts +20 -0
  21. package/dist/agent-runtime/contained-files.d.ts.map +1 -1
  22. package/dist/agent-runtime/durability-contract.d.ts +176 -0
  23. package/dist/agent-runtime/durability-contract.d.ts.map +1 -0
  24. package/dist/agent-runtime/durability-json.d.ts +3 -0
  25. package/dist/agent-runtime/durability-json.d.ts.map +1 -0
  26. package/dist/agent-runtime/durability-ledger.d.ts +16 -0
  27. package/dist/agent-runtime/durability-ledger.d.ts.map +1 -0
  28. package/dist/agent-runtime/durability-scheduler.d.ts +29 -0
  29. package/dist/agent-runtime/durability-scheduler.d.ts.map +1 -0
  30. package/dist/agent-runtime/durability.d.ts +14 -0
  31. package/dist/agent-runtime/durability.d.ts.map +1 -0
  32. package/dist/agent-runtime/event-search.d.ts.map +1 -1
  33. package/dist/agent-runtime/harness-contract.d.ts +37 -0
  34. package/dist/agent-runtime/harness-contract.d.ts.map +1 -1
  35. package/dist/agent-runtime/harness.d.ts +8 -0
  36. package/dist/agent-runtime/harness.d.ts.map +1 -1
  37. package/dist/agent-runtime/prompt.d.ts +23 -0
  38. package/dist/agent-runtime/prompt.d.ts.map +1 -1
  39. package/dist/agent-runtime/run-execution.d.ts.map +1 -1
  40. package/dist/agent-runtime/runtime-internals.d.ts +4 -0
  41. package/dist/agent-runtime/runtime-internals.d.ts.map +1 -1
  42. package/dist/agent-runtime/runtime.d.ts +13 -0
  43. package/dist/agent-runtime/runtime.d.ts.map +1 -1
  44. package/dist/agent-runtime/sandbox-broker.d.ts +7 -0
  45. package/dist/agent-runtime/sandbox-broker.d.ts.map +1 -0
  46. package/dist/agent-runtime/sandbox-bubblewrap-args.d.ts +9 -0
  47. package/dist/agent-runtime/sandbox-bubblewrap-args.d.ts.map +1 -0
  48. package/dist/agent-runtime/sandbox-bubblewrap-storage.d.ts +22 -0
  49. package/dist/agent-runtime/sandbox-bubblewrap-storage.d.ts.map +1 -0
  50. package/dist/agent-runtime/sandbox-bubblewrap.d.ts +14 -0
  51. package/dist/agent-runtime/sandbox-bubblewrap.d.ts.map +1 -0
  52. package/dist/agent-runtime/sandbox-coding-adapter.d.ts +15 -0
  53. package/dist/agent-runtime/sandbox-coding-adapter.d.ts.map +1 -0
  54. package/dist/agent-runtime/sandbox-coding.d.ts +15 -0
  55. package/dist/agent-runtime/sandbox-coding.d.ts.map +1 -0
  56. package/dist/agent-runtime/sandbox-contract.d.ts +93 -0
  57. package/dist/agent-runtime/sandbox-contract.d.ts.map +1 -0
  58. package/dist/agent-runtime/sandbox-process-owner.d.ts +11 -0
  59. package/dist/agent-runtime/sandbox-process-owner.d.ts.map +1 -0
  60. package/dist/agent-runtime/sandbox-process.d.ts +8 -0
  61. package/dist/agent-runtime/sandbox-process.d.ts.map +1 -0
  62. package/dist/agent-runtime/sandbox-session.d.ts +5 -0
  63. package/dist/agent-runtime/sandbox-session.d.ts.map +1 -0
  64. package/dist/agent-runtime/sandbox.d.ts +19 -0
  65. package/dist/agent-runtime/sandbox.d.ts.map +1 -1
  66. package/dist/agent-runtime/sqlite-purge.d.ts.map +1 -1
  67. package/dist/agent-runtime/sqlite.d.ts.map +1 -1
  68. package/dist/agent-runtime/store-driver.d.ts +127 -0
  69. package/dist/agent-runtime/store-driver.d.ts.map +1 -1
  70. package/dist/agent-runtime/store-events.d.ts +104 -0
  71. package/dist/agent-runtime/store-events.d.ts.map +1 -1
  72. package/dist/agent-runtime/store-migrations/v2-to-v3.d.ts +14 -0
  73. package/dist/agent-runtime/store-migrations/v2-to-v3.d.ts.map +1 -0
  74. package/dist/agent-runtime/store.d.ts +115 -0
  75. package/dist/agent-runtime/store.d.ts.map +1 -1
  76. package/dist/agent-runtime-coding-tools.js +11 -1247
  77. package/dist/agent-runtime-harness.d.ts +1 -1
  78. package/dist/agent-runtime-harness.d.ts.map +1 -1
  79. package/dist/agent-runtime-harness.js +65 -15
  80. package/dist/agent-runtime-openrouter.d.ts +3 -12
  81. package/dist/agent-runtime-openrouter.d.ts.map +1 -1
  82. package/dist/agent-runtime-openrouter.js +10 -7
  83. package/dist/agent-runtime-sandbox.d.ts +5 -0
  84. package/dist/agent-runtime-sandbox.d.ts.map +1 -0
  85. package/dist/agent-runtime-sandbox.js +797 -0
  86. package/dist/agent-runtime-sqlite-bun.js +3 -3
  87. package/dist/agent-runtime-sqlite-node.js +3 -3
  88. package/dist/agent-runtime.d.ts +5 -4
  89. package/dist/agent-runtime.d.ts.map +1 -1
  90. package/dist/agent-runtime.js +259 -65
  91. package/dist/application.js +26 -26
  92. package/dist/cli.js +8 -8
  93. package/dist/{index-rcgsnrr6.js → index-31jw8fjq.js} +3 -3
  94. package/dist/{index-9hw9eq48.js → index-7601qfg1.js} +14 -14
  95. package/dist/{index-3xnq72rz.js → index-7rkhw9ec.js} +14 -1
  96. package/dist/{index-0vfdh685.js → index-8c3a7m4g.js} +1 -1
  97. package/dist/{index-t7gh5w3v.js → index-bn2cjajt.js} +27 -6
  98. package/dist/index-cp20z0n6.js +1351 -0
  99. package/dist/{index-qp3vshvc.js → index-fadnxwna.js} +87 -5
  100. package/dist/{index-v1qk37y9.js → index-hrbajay7.js} +106 -4
  101. package/dist/{index-p86mxmpp.js → index-hw2chdvy.js} +646 -43
  102. package/dist/{index-0ydchz76.js → index-mnm4qp0p.js} +5 -5
  103. package/dist/{index-1szetq6f.js → index-q3ve2d1k.js} +30 -8
  104. package/dist/{index-6krwcdcf.js → index-zwkgfq1s.js} +95 -85
  105. package/dist/{index-wn9cb82y.js → index-zyvby92n.js} +12 -9
  106. package/dist/index.js +13 -13
  107. package/dist/server/index.js +9 -9
  108. package/dist/testing/agent-store-conformance.d.ts.map +1 -1
  109. package/dist/testing.js +57 -23
  110. package/dist/tool-invoker.js +6 -6
  111. package/dist/tools/agent.d.ts +6 -0
  112. package/dist/tools/agent.d.ts.map +1 -1
  113. package/dist/tools/connections/define.d.ts +6 -0
  114. package/dist/tools/connections/define.d.ts.map +1 -0
  115. package/dist/tools/connections/errors.d.ts +50 -0
  116. package/dist/tools/connections/errors.d.ts.map +1 -0
  117. package/dist/tools/connections/http.d.ts +3 -0
  118. package/dist/tools/connections/http.d.ts.map +1 -0
  119. package/dist/tools/connections/index.d.ts +19 -0
  120. package/dist/tools/connections/index.d.ts.map +1 -0
  121. package/dist/tools/connections/index.js +1047 -0
  122. package/dist/tools/connections/instance.d.ts +3 -0
  123. package/dist/tools/connections/instance.d.ts.map +1 -0
  124. package/dist/tools/connections/json-rpc.d.ts +8 -0
  125. package/dist/tools/connections/json-rpc.d.ts.map +1 -0
  126. package/dist/tools/connections/limits.d.ts +36 -0
  127. package/dist/tools/connections/limits.d.ts.map +1 -0
  128. package/dist/tools/connections/mcp-client.d.ts +44 -0
  129. package/dist/tools/connections/mcp-client.d.ts.map +1 -0
  130. package/dist/tools/connections/mcp.d.ts +5 -0
  131. package/dist/tools/connections/mcp.d.ts.map +1 -0
  132. package/dist/tools/connections/mount.d.ts +12 -0
  133. package/dist/tools/connections/mount.d.ts.map +1 -0
  134. package/dist/tools/connections/openapi-document.d.ts +4 -0
  135. package/dist/tools/connections/openapi-document.d.ts.map +1 -0
  136. package/dist/tools/connections/openapi.d.ts +5 -0
  137. package/dist/tools/connections/openapi.d.ts.map +1 -0
  138. package/dist/tools/connections/runtime.d.ts +29 -0
  139. package/dist/tools/connections/runtime.d.ts.map +1 -0
  140. package/dist/tools/connections/schema-budget.d.ts +8 -0
  141. package/dist/tools/connections/schema-budget.d.ts.map +1 -0
  142. package/dist/tools/connections/sse-frames.d.ts +7 -0
  143. package/dist/tools/connections/sse-frames.d.ts.map +1 -0
  144. package/dist/tools/connections/sse-session.d.ts +26 -0
  145. package/dist/tools/connections/sse-session.d.ts.map +1 -0
  146. package/dist/tools/connections/ssrf.d.ts +15 -0
  147. package/dist/tools/connections/ssrf.d.ts.map +1 -0
  148. package/dist/tools/connections/types.d.ts +60 -0
  149. package/dist/tools/connections/types.d.ts.map +1 -0
  150. package/dist/tools/durability-context.d.ts +7 -0
  151. package/dist/tools/durability-context.d.ts.map +1 -0
  152. package/dist/tools/execute.d.ts +2 -0
  153. package/dist/tools/execute.d.ts.map +1 -1
  154. package/dist/tools/registry.d.ts +38 -0
  155. package/dist/tools/registry.d.ts.map +1 -0
  156. package/dist/tools/runtime-tool.d.ts +4 -0
  157. package/dist/tools/runtime-tool.d.ts.map +1 -1
  158. package/dist/tools.d.ts +1 -0
  159. package/dist/tools.d.ts.map +1 -1
  160. package/dist/tools.js +83 -26
  161. package/llms-full.txt +246 -7
  162. package/llms.txt +1 -0
  163. package/package.json +9 -1
  164. package/dist/{index-evcnmsc3.js → index-t7fkyxcr.js} +3 -3
package/dist/tools.js CHANGED
@@ -21,8 +21,8 @@ import {
21
21
  buildToolManifest,
22
22
  describeToolCatalog,
23
23
  mountAgent
24
- } from "./index-1szetq6f.js";
25
- import"./index-3xnq72rz.js";
24
+ } from "./index-q3ve2d1k.js";
25
+ import"./index-7rkhw9ec.js";
26
26
  import {
27
27
  argumentsDigest
28
28
  } from "./index-a916km3r.js";
@@ -37,7 +37,7 @@ import {
37
37
  } from "./index-4fpa9dy2.js";
38
38
  import {
39
39
  createToolInvoker
40
- } from "./index-0ydchz76.js";
40
+ } from "./index-mnm4qp0p.js";
41
41
  import {
42
42
  WaitTimeoutError,
43
43
  createCli,
@@ -46,47 +46,28 @@ import {
46
46
  fetchPinnedDocument,
47
47
  readCapped,
48
48
  runWaitOperation
49
- } from "./index-9hw9eq48.js";
49
+ } from "./index-7601qfg1.js";
50
50
  import"./index-sbdmyz75.js";
51
51
  import {
52
52
  collectToolSurface
53
- } from "./index-rcgsnrr6.js";
54
- import {
55
- createRuntimeToolFactory,
56
- defineRuntimeTool
57
- } from "./index-kc6h6hg0.js";
53
+ } from "./index-31jw8fjq.js";
58
54
  import {
59
55
  collectTools,
60
56
  createToolRunner,
61
57
  formatToolError
62
- } from "./index-0vfdh685.js";
58
+ } from "./index-8c3a7m4g.js";
63
59
  import {
64
60
  ToolExecutionControlError,
65
61
  executeToolMethod,
66
62
  isToolExecutionControlError,
67
63
  toolResultFromError
68
- } from "./index-wn9cb82y.js";
64
+ } from "./index-zyvby92n.js";
69
65
  import {
70
66
  getRequestContext,
71
67
  getTraceId,
72
68
  runWithRequestContext
73
69
  } from "./index-vsbzgd7b.js";
74
70
  import"./index-f9mb610r.js";
75
- import {
76
- PORTABLE_JSON_SCHEMA_FORMATS,
77
- assertToolName,
78
- assertUniqueToolName,
79
- findNonPortableFormats,
80
- findUntypedProperties,
81
- flattenToolJsonSchema,
82
- prepareProjectedMcpTools,
83
- presentationMetadata,
84
- validateMcpRoundPolicy
85
- } from "./index-r159gjwy.js";
86
- import"./index-cby4ar3v.js";
87
- import {
88
- coerceJsonArgs
89
- } from "./index-7zbps32p.js";
90
71
  import {
91
72
  normalizeError
92
73
  } from "./index-7evdsyez.js";
@@ -104,7 +85,26 @@ import {
104
85
  import {
105
86
  resolvePropagationContext
106
87
  } from "./index-zcgf3gqf.js";
88
+ import {
89
+ coerceJsonArgs
90
+ } from "./index-7zbps32p.js";
107
91
  import"./index-kzfs85xp.js";
92
+ import {
93
+ createRuntimeToolFactory,
94
+ defineRuntimeTool
95
+ } from "./index-kc6h6hg0.js";
96
+ import {
97
+ PORTABLE_JSON_SCHEMA_FORMATS,
98
+ assertToolName,
99
+ assertUniqueToolName,
100
+ findNonPortableFormats,
101
+ findUntypedProperties,
102
+ flattenToolJsonSchema,
103
+ prepareProjectedMcpTools,
104
+ presentationMetadata,
105
+ validateMcpRoundPolicy
106
+ } from "./index-r159gjwy.js";
107
+ import"./index-cby4ar3v.js";
108
108
  import {
109
109
  isRecord
110
110
  } from "./index-77fekveh.js";
@@ -2521,6 +2521,62 @@ function mountOAuthProvider(config) {
2521
2521
  };
2522
2522
  return dcrEnabled ? [metadataRoute, registerRoute, authorizeRoute, tokenRoute] : [metadataRoute, authorizeRoute, tokenRoute];
2523
2523
  }
2524
+ // src/tools/registry.ts
2525
+ function defineToolRegistry(input) {
2526
+ const defaults = [...input.defaults];
2527
+ const slots = new Set;
2528
+ for (const tool of defaults) {
2529
+ if (!tool.name)
2530
+ throw new Error("A default tool must carry a non-empty name");
2531
+ if (slots.has(tool.name))
2532
+ throw new Error(`Duplicate default tool name: ${tool.name}`);
2533
+ slots.add(tool.name);
2534
+ }
2535
+ const disabled = new Set;
2536
+ const replacements = new Map;
2537
+ const assertKnown = (name, verb) => {
2538
+ if (!slots.has(name)) {
2539
+ throw new Error(`Tool registry ${verb}("${name}") names no default; declared: ${[...slots].sort().join(", ") || "(none)"}`);
2540
+ }
2541
+ };
2542
+ const builder = {
2543
+ replace(name, tool) {
2544
+ assertKnown(name, "replace");
2545
+ if (disabled.has(name)) {
2546
+ throw new Error(`Tool registry cannot replace "${name}": it is disabled`);
2547
+ }
2548
+ if (replacements.has(name)) {
2549
+ throw new Error(`Tool registry already replaced "${name}"`);
2550
+ }
2551
+ if (tool.name !== name) {
2552
+ throw new Error(`A replacement for "${name}" must carry that name, not "${tool.name}"`);
2553
+ }
2554
+ replacements.set(name, tool);
2555
+ return builder;
2556
+ },
2557
+ disable(name) {
2558
+ assertKnown(name, "disable");
2559
+ disabled.add(name);
2560
+ return builder;
2561
+ },
2562
+ build() {
2563
+ const tools = [];
2564
+ const seen = new Set;
2565
+ for (const tool of defaults) {
2566
+ if (disabled.has(tool.name))
2567
+ continue;
2568
+ const effective = replacements.get(tool.name) ?? tool;
2569
+ if (seen.has(effective.name)) {
2570
+ throw new Error(`Duplicate composed tool name: ${effective.name}`);
2571
+ }
2572
+ seen.add(effective.name);
2573
+ tools.push(effective);
2574
+ }
2575
+ return { tools, names: tools.map((tool) => tool.name) };
2576
+ }
2577
+ };
2578
+ return builder;
2579
+ }
2524
2580
  // src/tools/tool-logger.ts
2525
2581
  function createToolLogger(config = {}) {
2526
2582
  const log = config.log ?? ((line) => console.error(line));
@@ -2646,6 +2702,7 @@ export {
2646
2702
  defineWaitTool,
2647
2703
  defineViewFileTool,
2648
2704
  defineUploadTool,
2705
+ defineToolRegistry,
2649
2706
  defineRuntimeTool,
2650
2707
  defineDownloadTool,
2651
2708
  defineCliCommand,
package/llms-full.txt CHANGED
@@ -55,6 +55,7 @@ own, recorded as an ADR.
55
55
  | `stitchkit/tools` | server | stable | `createMcpHandler`, `mountMcp`, `mountAgent`, the OAuth provider, native tools |
56
56
  | `stitchkit/tools/contract` | browser + server | evolving | the shapes a tool surface speaks — async-operation contract, snapshot and cancel schemas, view-file input/output — without the runtime that serves them |
57
57
  | `stitchkit/tools/invoker` | server | stable | peer-free `createToolInvoker` over the canonical contract tool runner |
58
+ | `stitchkit/tools/connections` | server (Bun or Node) | evolving | consume external MCP servers and a bounded OpenAPI subset — typed reauthorization, a per-request host fence and per-call credentials |
58
59
  | `stitchkit/cli` | server | stable | `createCli` — the CLI transport, light (no MCP SDK / `ai`) |
59
60
  | `stitchkit/remote` | browser **and** server | stable | peer-free `implementRemote` for thin HTTP proxy processes |
60
61
  | `stitchkit/files` | server (Bun or Node) | stable | peer-free managed local-file boundary |
@@ -63,11 +64,12 @@ own, recorded as an ADR.
63
64
  | `stitchkit/tracking/server` | server (Bun or Node) | evolving | the decisions a tracking backend makes — dispositions, visit lease over an application-owned store, active intervals, presence; no database |
64
65
  | `stitchkit/release` | browser **and** server | evolving | a page follows the release it was built for — `createReleaseMarker` on the server, `createReleaseWatcher` in the browser, the `X-Build-Id` header and a socket event between them |
65
66
  | `stitchkit/geo` | server (Bun or Node) | evolving | managed GeoIP reader generations, last-known-good reload and the optional MaxMind adapter |
66
- | `stitchkit/observability` | server | stable<br>_redefined in 1 of the 33 minors since 0.56.2, most recently 0.83.0_ | request/tool event projections — `createObservability`, trace context, sanitisation |
67
+ | `stitchkit/observability` | server | stable<br>_redefined in 1 of the 34 minors since 0.56.2, most recently 0.83.0_ | request/tool event projections — `createObservability`, trace context, sanitisation |
67
68
  | `stitchkit/testing` | tests on Bun or Node | stable | in-process generated clients over a real Fetch handler, plus the store and managed-resource conformance kits |
68
69
  | `stitchkit/declaration` | browser + build and deployment tooling (Bun or Node) | evolving | `ProjectDeclarationSchema` — the one machine-readable statement a repository makes about itself |
69
70
  | `stitchkit/react` | browser + server rendering | stable | `createCursorQuery`, `createCacheBridge`, QueryClient and `ApiError` retry policy |
70
- | `stitchkit/agent-runtime` | server | evolving<br>_redefined in 19 of the 33 minors since 0.56.2, most recently 0.88.0_ | optional durable conversation/run loop, history, models, prompts, fencing and events |
71
+ | `stitchkit/agent-runtime` | server | evolving<br>_redefined in 20 of the 34 minors since 0.56.2, most recently 0.89.0_ | optional durable conversation/run loop, history, models, prompts, fencing and events |
72
+ | `stitchkit/agent-runtime/sandbox` | server | evolving | optional Linux Bubblewrap sessions, durable workspaces and a host HTTP credential gateway; see [sandbox guide](sandbox.md) |
71
73
  | `stitchkit/agent-runtime/testing` | tests on Bun or Node | evolving | credential-free replay, scripted provider faults and deterministic race controls |
72
74
  | `stitchkit/agent-runtime/harness` | server | evolving | resource-aware process-local facade over the canonical Agent runtime; supervision stays outside |
73
75
  | `stitchkit/agent-runtime/coding-tools` | server (Bun or Node) | evolving | bounded host-authorized direct file and shell tools; a root boundary, not an OS sandbox |
@@ -76,7 +78,7 @@ own, recorded as an ADR.
76
78
  | `stitchkit/agent-runtime/sqlite/bun` | server (Bun) | evolving | durable built-in SQLite store for the agent runtime |
77
79
  | `stitchkit/agent-runtime/sqlite/node` | server (Node ≥ 22.5) | evolving | durable built-in SQLite store for the agent runtime |
78
80
  | `stitchkit-tui` | terminal (Bun) | evolving | optional official OpenTUI host over a caller-composed headless runtime |
79
- | `stitchkit/application` | browser + server | evolving<br>_redefined in 7 of the 33 minors since 0.56.2, most recently 0.83.0_ | managed resource graph, readiness, admission, schedules, subtree restart and bounded shutdown |
81
+ | `stitchkit/application` | browser + server | evolving<br>_redefined in 7 of the 34 minors since 0.56.2, most recently 0.83.0_ | managed resource graph, readiness, admission, schedules, subtree restart and bounded shutdown |
80
82
  | `stitchkit/application/grammy` | server | evolving | isolated grammY polling and webhook lifecycle adapters |
81
83
  | `stitchkit/application/opentelemetry` | server | evolving | maps application snapshots onto an injected OpenTelemetry `Meter` |
82
84
  | `stitchkit/application/schemas` | browser + server | evolving | the application's snapshot, health and shutdown schemas alone, without the kernel |
@@ -5583,9 +5585,11 @@ the product has a narrower definition; it receives the candidate message,
5583
5585
  terminal reason and optional policy name, and runs before persistence. A false
5584
5586
  result fails the candidate instead of rewriting an already committed success.
5585
5587
 
5586
- `loop.idleTimeoutMs` is inactivity, not total duration: the deadline resets on
5587
- every model stream event. A stalled call aborts with durable reason `timeout`;
5588
- user interruption and shutdown remain distinct.
5588
+ `loop.idleTimeoutMs` measures provider silence. It starts immediately before the
5589
+ provider call, resets on stream activity, and pauses while local tools execute.
5590
+ Resource preparation, child waits and approval waiting do not spend this budget.
5591
+ The host gives tools their own deadlines. A stalled provider still aborts with
5592
+ durable reason `timeout`; caller interruption and shutdown reach tools directly.
5589
5593
 
5590
5594
  Reconnect loads the durable snapshot. Missing transient deltas do not mean the
5591
5595
  canonical result was lost. Exactly-once external delivery requires the
@@ -5593,6 +5597,14 @@ application's transactional outbox or stable-ID deduplication.
5593
5597
 
5594
5598
  ## Managed tools
5595
5599
 
5600
+ Durable `step` bodies return lossless JSON: finite numbers (excluding negative zero),
5601
+ strings, booleans, null, dense arrays and plain data objects. Return `null` explicitly
5602
+ for effect-only bodies and convert Date values to strings. Unsupported values are
5603
+ refused after the body, so external effects still require idempotency. First results
5604
+ and replay are detached snapshots; mutating a returned object cannot rewrite a record.
5605
+ The optional [sandbox coding profile](sandbox.md#coding-tool-integration) reuses the
5606
+ same tool mounting, authorization and output handling for namespace-backed commands.
5607
+
5596
5608
  Always compose `toolFenceLifecycle` into `mountAgent`. It checks ownership
5597
5609
  before a managed side effect and again before accepting its result. Fence loss
5598
5610
  uses an internal control signal: it stops the old loop and is not sent to the
@@ -6690,6 +6702,140 @@ the store's first update. Ledger corruption may be declared reconstructable;
6690
6702
  an outbox must fail closed rather than silently discard pending delivery.
6691
6703
 
6692
6704
 
6705
+ ==============================================================================
6706
+ # Guide: Optional process sandbox (docs/guide/sandbox.md)
6707
+ ==============================================================================
6708
+
6709
+ ---
6710
+ title: Optional process sandbox
6711
+ description: Linux namespace isolation, durable workspaces and a host credential gateway.
6712
+ ---
6713
+
6714
+ # Optional process sandbox
6715
+
6716
+ `stitchkit/agent-runtime/sandbox` is a server-only, evolving API. Existing coding
6717
+ tools and agent configuration retain their current behavior. A host explicitly
6718
+ creates a session and opts into `createSandboxCodingTools`; importing this
6719
+ entrypoint does not redirect existing coding tools.
6720
+
6721
+ ```ts
6722
+ import { createBubblewrapSandboxBackend } from 'stitchkit/agent-runtime/sandbox';
6723
+
6724
+ const backend = await createBubblewrapSandboxBackend({
6725
+ stateDirectory: '/var/lib/my-app/sandboxes',
6726
+ maxConcurrentCommands: 8,
6727
+ onBrokerError: (cause) => console.error('Internal sandbox gateway error', cause),
6728
+ });
6729
+ const template = await backend.prewarm({
6730
+ template: 'agent-workspace',
6731
+ files: { 'hello.txt': new TextEncoder().encode('hello') },
6732
+ });
6733
+ const handle = await backend.create({ template: template.templateKey, network: 'deny-all' });
6734
+ try {
6735
+ const result = await handle.session.run({ executable: '/usr/bin/cat', args: ['hello.txt'] });
6736
+ console.log(result.stdout);
6737
+ const state = handle.captureState(); // Persist this descriptor in the host's store.
6738
+ await handle.stop();
6739
+ const resumed = await backend.create({ template: template.templateKey, state, network: 'deny-all' });
6740
+ try { console.log(await resumed.session.readTextFile('hello.txt')); }
6741
+ finally { await resumed.delete(); }
6742
+ } finally { await handle.shutdown(); }
6743
+ ```
6744
+
6745
+ `prewarm` snapshots the supplied byte files. Its content-addressed key includes
6746
+ the backend name, template name and file contents. It is not a VM image or a
6747
+ package installer. `stop` and `shutdown` kill live commands and retain workspace
6748
+ files; `delete` removes session state and workspace, preserving reusable templates.
6749
+ Reconnect requires the same backend name and template. A live owner holds an
6750
+ exclusive lease: concurrent attach and deletion by an older handle fail with
6751
+ `SANDBOX_BUSY`. After a host crash, an operator must verify that its processes are
6752
+ gone before removing a stale lease; automatic crash recovery is not provided.
6753
+ Storage is process-durable, without a power-loss/fsync guarantee.
6754
+
6755
+ ## Coding tool integration
6756
+
6757
+ ```ts
6758
+ import { createSandboxCodingTools } from 'stitchkit/agent-runtime/sandbox';
6759
+ import { mountAgent } from 'stitchkit/tools';
6760
+
6761
+ const tools = mountAgent([], {
6762
+ runtimeTools: createSandboxCodingTools(handle, {
6763
+ authorize: (operation) => applicationPolicy(operation),
6764
+ executables: { shell: '/usr/bin/sh' },
6765
+ requiredRestrictions: ['network-denied', 'write-contained', 'process-contained', 'secrets-hidden'],
6766
+ limits: { shellTimeoutMs: 10_000, maxShellOutputBytes: 65_536 },
6767
+ }),
6768
+ });
6769
+ ```
6770
+
6771
+ The factory uses the existing coding profile, including its authorization,
6772
+ path containment, UTF-8 handling, output artifacts and command limits. File tools
6773
+ access the same workspace through the host's contained-file implementation;
6774
+ commands run inside the namespace with `/workspace` as their root. The host-only
6775
+ `handle.coding` binding never belongs in model input or persisted state.
6776
+ Unsupported backends omit the binding and the factory refuses explicitly.
6777
+
6778
+ Stop also kills coding commands. Both launch paths share the configured
6779
+ `maxConcurrentCommands` admission limit (default 8); an occupied slot gives
6780
+ `SANDBOX_BUSY` before another process starts. This counts direct commands, not
6781
+ guest descendants. Required restrictions are checked again during preparation;
6782
+ a network-policy change invalidates an outstanding prepared launch. After
6783
+ reconnect, create the coding profile from the new handle; old tools remain stopped.
6784
+
6785
+ ## Network gateway
6786
+
6787
+ `deny-all` isolates the network namespace, including DNS and loopback access to
6788
+ host services. `{ allow: [{ origin, headers }] }` retains that isolation and
6789
+ allows HTTP through a Unix-socket gateway only. Origins are exact HTTP(S) origins,
6790
+ including scheme and port; no wildcard, redirect, arbitrary TCP or CONNECT tunnel
6791
+ is allowed. For HTTPS upstreams the **host** establishes TLS. Guests speak HTTP
6792
+ over the socket with the upstream host in `Host`, for example:
6793
+
6794
+ ```ts
6795
+ await handle.session.setNetworkPolicy({
6796
+ allow: [{ origin: 'https://api.example.com', headers: { authorization: hostCredential } }],
6797
+ });
6798
+ await handle.session.run({
6799
+ executable: '/usr/bin/curl',
6800
+ args: ['--unix-socket', '/run/stitchkit-network.sock', 'http://api.example.com/resource'],
6801
+ });
6802
+ ```
6803
+
6804
+ The host obtains `hostCredential` from its credential store. Headers never enter
6805
+ guest environment, process arguments or persisted reconnect state. Authorized
6806
+ upstreams are trusted: an upstream that reflects its request headers can disclose
6807
+ them in its response. This gateway cannot prevent that. Header values are fixed
6808
+ for the policy; replace the policy to rotate credentials. Policy changes require
6809
+ all commands to finish or stop (`SANDBOX_BUSY` otherwise). `allow-all` explicitly
6810
+ shares host networking and adds no injected headers; use it only when unrestricted
6811
+ egress is intended. Policies are resupplied on every reconnect and are not stored.
6812
+
6813
+ ## Runtime boundary
6814
+
6815
+ The reference backend requires Linux, `/usr/bin/bwrap`, usable namespaces and a
6816
+ conventional `/usr`, `/lib`, `/lib64` layout. Failure to establish isolation gives
6817
+ `SANDBOX_UNAVAILABLE`; there is no host-execution fallback. Runtime directories
6818
+ are read-only, the workspace is writable, environment is cleared, and host home,
6819
+ state storage and other host sockets are not mounted. Each command gets ephemeral
6820
+ `/tmp`; only `/workspace` persists. Runtime binaries and the configured state
6821
+ directory belong to the trusted host. See the
6822
+ [Bubblewrap security model](https://github.com/containers/bubblewrap#system-security).
6823
+
6824
+ This is namespace isolation over the host kernel, not a VM. It does not impose
6825
+ memory, CPU, disk or process-count quotas. A host running mutually untrusted workloads
6826
+ must supply those bounds outside the namespace (for example, a delegated cgroup and
6827
+ quota-controlled storage); command admission is not a substitute. Commands default to a 30-second deadline
6828
+ and 1 MiB combined output; callers can configure both. File I/O is bounded to
6829
+ 1 MiB. The gateway allows 16 concurrent requests, 1 MiB request/response bodies
6830
+ and a 30-second deadline. Do not treat these bounds as resource containment for
6831
+ arbitrary hostile workloads.
6832
+
6833
+ Custom backends implement `SandboxDriver` byte I/O, `spawn` and policy enforcement;
6834
+ `createSandboxSession` supplies text conversion, paths and `run` once. Paths are
6835
+ workspace-relative or canonical `/workspace/...` paths. Unsupported policies must
6836
+ be refused explicitly by the backend.
6837
+
6838
+
6693
6839
  ==============================================================================
6694
6840
  # Guide: Generic application primitives (docs/guide/primitives.md)
6695
6841
  ==============================================================================
@@ -11236,6 +11382,39 @@ analytics policy belong to the application.
11236
11382
 
11237
11383
  # Upgrading stitchkit
11238
11384
 
11385
+ ## Released migration: 0.89.0
11386
+
11387
+ 1. Custom `AgentRuntimeStore` adapters implement `seedConversationInput`; custom
11388
+ `AgentRuntimeStoreDriver` adapters implement `seeds.load` and `seeds.create` together
11389
+ with atomic, ordered history insertion. Use the maintained Prisma example and run
11390
+ `runAgentStoreConformance` against the adapter. Built-in memory and SQLite
11391
+ stores already implement the contract; SQLite migrates to schema version 3.
11392
+ 2. OpenRouter usage normalization consumes each completed SDK step's `usage`, including
11393
+ `raw`, rather than aggregate usage. Missing counters stay `unavailable`.
11394
+
11395
+ ```ts
11396
+ // before: normalizeOpenRouterUsage(await result.usage, metadata)
11397
+ // after:
11398
+ for (const step of await result.steps) {
11399
+ const usage = normalizeOpenRouterUsage(step.usage, step.providerMetadata);
11400
+ // Persist the step's measured usage with its provenance.
11401
+ }
11402
+ ```
11403
+
11404
+ 3. Durable step bodies return lossless JSON. Convert dates explicitly, reject invalid
11405
+ numbers upstream, and return `null` after an effect-only operation.
11406
+
11407
+ ```ts
11408
+ await context.step('send', async () => {
11409
+ await sendIdempotently();
11410
+ return null;
11411
+ });
11412
+ ```
11413
+
11414
+ First execution, replay and concurrent callers receive detached values. Persistence
11415
+ does not make external effects transactional; the host retains idempotency and recovery.
11416
+
11417
+
11239
11418
  How to move a consuming project from one stitchkit version to another — including
11240
11419
  across many versions at once (a project frozen on an old version, then jumped
11241
11420
  forward). The process is mechanical: stitchkit marks every breaking change in one
@@ -15559,6 +15738,12 @@ Server-only optional application runtime. See the
15559
15738
  | `AgentConversationPageSchema` / `AgentConversationPage` | schema / _type_ | cursor-paged conversation summaries |
15560
15739
  | `AgentConversationMessagePageSchema` / `AgentConversationMessagePage` | schema / _type_ | cursor-paged durable message history |
15561
15740
  | `composeAgentPrompt` | function | ordered prompt contributions and provenance-aware signed context budget; irreducible reservation deficits are `oversized`, not compactable history |
15741
+ | `SeedConversationInputSchema` / `SeedConversationInput` | schema / _type_ | atomic once-seeding input; partial imported identity sets are refused |
15742
+ | `AgentSeedReceiptSchema` / `AgentSeedReceipt` | schema / _type_ | durable seed receipt retained beyond compaction and implemented by custom store drivers |
15743
+ | `createLocalStepDurability` | function | record JSON step results and park on time/events; a replay returns recorded results, while unrecorded effects require host idempotency |
15744
+ | `StepDurabilityLedger` / `LocalStepDurability` / `LocalStepDurabilityOptions` / `StepRunOptions` | _type_ | the narrow ledger the port needs, the step/read surface, and its construction and per-step options |
15745
+ | `DURABILITY_STEP_EVENT_KIND` | const | the ledger event kind a recorded step is written under |
15746
+ | `StepResultDecodeError` / `StepResultNotSerializableError` / `StepAbortedError` / `ParkRecordDecodeError` / `ParkAbortedError` | class | fail-closed decode of a recorded step or park, a body whose result cannot be serialized, an aborted step, and a park collapsed around an aborted waiter |
15562
15747
  | `structuredCompaction` | function | summarize a provider-valid snapshot range and replace it through CAS |
15563
15748
  | `selectCompactableHistory` | function | which oldest whole complete turns may be summarised away — the half of compaction that needs no store (→ ADR 0142) |
15564
15749
  | `SelectCompactableHistoryOptions` / `CompactableHistory` | _type_ | message list, retained-turn count and evidence policy in; `leadingSummary`, `compactable` and `retained` out |
@@ -15599,10 +15784,12 @@ Server-only optional application runtime. See the
15599
15784
  | `agentGoalStateSlot` / `agentTodoStateSlot` / `createAgentStateTools` | constants / function | built-in goal/todo state and bound `goal_*` / `todo_write` Agent tools |
15600
15785
  | `AgentSandboxGradeSchema` / `AgentSandboxGrade` / `AgentSandboxRestrictionSchema` / `AgentSandboxRestriction` / `AgentProcessSandbox` | schema / _type_ | host-provided process sandbox capability and explicit restriction vocabulary |
15601
15786
  | `probeAgentProcessSandbox` / `missingSandboxRestrictions` / `recordAgentSandboxProbe` | functions | process-cached probe, fail-closed required-gap calculation and durable probe record |
15787
+ | `AgentSandboxProcess` / `AgentSandboxOutputStream` | _types_ | structural child/output interface for optional lifecycle-owned `AgentProcessSandbox.spawn`, without Node ambient type dependencies |
15602
15788
  | `AgentEventSearchResultSchema` / `AgentEventSearchResult` / `createSqliteAgentEventSearch` / `createAgentEventSearchTools` | schema / _type_ / functions | authorized FTS5 search with exact event addresses and `session_*` tools |
15603
15789
  | `createSqliteAgentSpillStore` | function | durable content-address-checked artifact storage, bounded read/search, retention facts and archive participation |
15604
15790
  | `AgentScheduleSchema` / `AgentSchedule` / `AgentScheduleService` / `createAgentScheduleService` / `createAgentScheduleTools` | schema / _types_ / functions | durable `at`/`after`/timezone-explicit `every`, stable dispatch identity and Agent tools |
15605
15791
  | `AgentChildBudgetSchema` / `AgentChildBudget` / `AgentChildStateSchema` / `AgentChildState` / `AgentChildRecordSchema` / `AgentChildRecord` | schema / _type_ | durable child graph, bounded seed and measured budget state |
15792
+ | `AgentChildBlockingKindSchema` / `AgentChildBlockingKind` / `AgentChildBlockingSourceSchema` / `AgentChildBlockingSource` / `AgentChildBlockingEventSchema` / `AgentChildBlockingEvent` / `AgentChildBlockingDecision` | schemas / _types_ | parent-owned request identities; responses discriminate approval decisions from JSON input values |
15606
15793
  | `AgentChildHandle` / `AgentChildManager` / `createSqliteAgentChildManager` / `createAgentChildTools` / `agentChildBudgetStopPolicy` | _type_ / functions | host execution port, child lifecycle, cascade (given to `createAgentRuntime` as `children`), messaging, Agent tools, and the child runtime's own budget stop policy — `recordStepUsage` at every step boundary, `policy_stop` as `child-budget` when spent |
15607
15794
  | `AgentToolDefinition` | _type_ | peer-neutral shape returned by the bound agent-only state, search, schedule and child tool factories |
15608
15795
  | `AgentProviderStreamCutError` | class | explicit retryable provider stream truncation evidence |
@@ -15630,7 +15817,11 @@ recognises a failure carried inside a *successful* tool result, in both the bare
15630
15817
 
15631
15818
  `normalizeOpenRouterUsage` is the same normalisation `openRouterProvider`
15632
15819
  applies, exported so an application calling the SDK directly gets provenance-correct numbers
15633
- without adopting the runtime.
15820
+ without adopting the runtime. Pass each completed SDK step's usage, including `raw`.
15821
+ Token provenance comes from the original OpenRouter fields: missing fields remain
15822
+ `unavailable`, even when the SDK substitutes zero. Aggregate usage without `raw` cannot
15823
+ establish reported token counts. Explicit zero remains `provider-reported`; cost is never
15824
+ estimated from token prices.
15634
15825
 
15635
15826
  `AgentContextUsage` reaches every step through `AgentRuntimeRunContext.contextUsage`: how full the
15636
15827
  model's context is, as `usedTokens` (an `AgentUsageValue`, so it carries the provenance that says
@@ -15789,6 +15980,9 @@ and introduces no store, queue or model-provider implementation of its own.
15789
15980
  | `AgentHarnessControlServer` / `AgentHarnessControlConnection` | _type_ | host server and detachable connection lifecycle; `deliver` is serialized, while required out-of-band `onOverflow` closes/aborts a slow transport before reconnect |
15790
15981
  | `AgentHarnessControlServerConfig` | _type_ | explicit per-connection pending-event and server-wide concurrent attachment-snapshot bounds for failure-isolated control delivery |
15791
15982
  | `AgentHarnessPendingApproval` / `AgentHarnessApprovalDecision` | _type_ | exact durable pending request and allow/deny successor input |
15983
+ | `AgentHarnessApprovalRequest` | _type_ | the pending request as a response-time policy sees it: approval id, call id, tool name and input |
15984
+ | `AgentHarnessApprovalAuthorization` / `AgentHarnessApprovalAuthorizationResult` | _type_ | response-time policy input (responder, conversation, request, proposed decision) and its `allowed` / `rejected` result |
15985
+ | `AgentHarnessApprovalRejectedError` | class | thrown when the response policy refuses a responder; the pending request is left answerable |
15792
15986
 
15793
15987
  Resources default to at most 64 entries, 1 MiB of total UTF-8 text and 128 diagnostics. Duplicate
15794
15988
  names and exceeded bounds fail before the provider step. Recovery remains the underlying runtime's
@@ -16105,6 +16299,8 @@ payload.
16105
16299
  | `RuntimeAgentModelOutput` | _type_ | AI SDK model-facing text/JSON/content output returned by `present.agent` |
16106
16300
  | `RuntimeToolTransport` | _type_ | runtime exposure: `'MCP' \| 'AGENT' \| 'CLI'`; omission still means MCP+Agent only |
16107
16301
  | `AgentMountConfig` | _type_ | config for `mountAgent` |
16302
+ | `AgentToolRegistry` / `AgentToolRegistryBuilder` / `AgentToolRegistryInput` | _type_ | the composed runtime surface and its builder: declared defaults, `replace`/`disable` by name, and the exact `{ tools, names }` a mount receives |
16303
+ | `defineToolRegistry` | function | compose runtime tools over one declared default set; an unknown `replace`/`disable` name is refused instead of silently leaving the default in place |
16108
16304
  | `AgentContext` | _type_ | the context merged into agent tool handlers |
16109
16305
  | `CliConfig` | _type_ | config for `createCli`, including program-level `defaultCommand` selection and command-scoped `optionAliases` / `positionals` policy |
16110
16306
  | `CliPresentationPolicyConfig` | _type_ | reusable default-command, short-alias and explicit-positional policy inherited by `CliConfig` |
@@ -16267,6 +16463,36 @@ Advanced building blocks — the shared machinery the mounts are built on.
16267
16463
 
16268
16464
  ---
16269
16465
 
16466
+ ## `stitchkit/tools/connections`
16467
+
16468
+ Server-only subexport that consumes external MCP servers and OpenAPI specifications
16469
+ as typed tools, without adding a peer dependency to `stitchkit/tools`. Foreign
16470
+ operations mount as the same `RuntimeToolDefinition`s our own produce, so
16471
+ `mountAgent({ runtimeTools })` runs them through the canonical lifecycle, hooks
16472
+ and approval path.
16473
+
16474
+ | Export | Kind | Summary |
16475
+ |--------|------|---------|
16476
+ | `defineMcpClientConnection` | function | declare one external MCP server connection over Streamable HTTP with an optional SSE fallback |
16477
+ | `defineOpenApiConnection` | function | declare one OpenAPI document (object, JSON text or JSON URL) as a tool surface |
16478
+ | `mountConnections` | function | discover every connection and return readonly `RuntimeToolDefinition`s for `mountAgent` |
16479
+ | `ConnectionAuthorizationRequiredError` | class | typed reauthorization signal raised on `401` with credentials resolved again on the next call |
16480
+ | `ConnectionBudgetExceededError` | class | the mount would expose more foreign tools than its declared budget |
16481
+ | `ConnectionRequestError` | class | any non-`2xx` connection response other than the reauthorization signal |
16482
+ | `ConnectionUrlError` | class | a non-http(s) URL or a request host the SSRF fence refused |
16483
+ | `ConnectionTokenProvider` | _type_ | `() => string \| undefined \| Promise<string \| undefined>` — the lazily resolved credential |
16484
+ | `ConnectionBudget` | _type_ | `{ maxTools? }` ceiling on one `mountConnections` call |
16485
+ | `ConnectionDefinition` | _type_ | either a defined MCP client or OpenAPI connection |
16486
+ | `ConnectionMountOptions` | _type_ | shared `{ lifecycle?, budget? }` mount policy |
16487
+ | `McpClientConnection` | _type_ | a defined MCP client connection |
16488
+ | `McpClientConnectionConfig` | _type_ | name, transport, tool filter, token provider, instance key and allowed hosts |
16489
+ | `McpConnectionTransport` | _type_ | `{ url, headers? }` for one MCP endpoint |
16490
+ | `McpToolFilter` | _type_ | `{ allow?, block? }` discovered-tool filter |
16491
+ | `OpenApiConnection` | _type_ | a defined OpenAPI connection |
16492
+ | `OpenApiConnectionConfig` | _type_ | name, spec, base URL, token provider, instance key and allowed hosts |
16493
+
16494
+ ---
16495
+
16270
16496
  ## `stitchkit/testing`
16271
16497
 
16272
16498
  Fetch-only integration helpers that preserve the real generated-client and
@@ -16639,3 +16865,16 @@ Browser- and server-render-safe React data-layer helpers. Needs the
16639
16865
  For the rationale behind these APIs — why `Bun.serve` and not a framework, why
16640
16866
  two context types, why thin wrappers — see the
16641
16867
  [Architecture Decisions](../decisions/).
16868
+
16869
+ ## `stitchkit/agent-runtime/sandbox`
16870
+
16871
+ Optional server-only namespace sandbox. Exports:
16872
+ `createSandboxCodingTools` composes the existing coding profile over a handle's
16873
+ host-only `SandboxCodingBinding`, with shared authorization, command collection and lifecycle.
16874
+ `createBubblewrapSandboxBackend`, `createSandboxSession`, `SandboxError`,
16875
+ `SandboxCommandSchema`, `SandboxNetworkPolicySchema`, `SandboxStateSchema`.
16876
+ Its types are `BubblewrapSandboxConfig`, `SandboxBackend`, `SandboxCommand`,
16877
+ `SandboxCreateInput`, `SandboxDriver`, `SandboxHandle`, `SandboxNetworkPolicy`,
16878
+ `SandboxPrewarmInput`, `SandboxProcess`, `SandboxRunOptions`, `SandboxSession`,
16879
+ and `SandboxState`. The [sandbox guide](../guide/sandbox.md) specifies lifecycle,
16880
+ network enforcement, gateway credentials and platform/resource boundaries.
package/llms.txt CHANGED
@@ -14,6 +14,7 @@ Build with stitchkit: define a contract once, then `implement` it and serve it (
14
14
  - [MCP & agents](https://github.com/max-listov/stitchkit/blob/master/docs/guide/mcp-and-agents.md): contracts as MCP tools (createMcpHandler) and AI-agent tools (mountAgent); tool lifecycle, extend, identity
15
15
  - [Agent application runtime](https://github.com/max-listov/stitchkit/blob/master/docs/guide/agent-runtime.md): optional durable history, prompt/model composition, stream loop, coordination, fencing and events
16
16
  - [Managed application kernel](https://github.com/max-listov/stitchkit/blob/master/docs/guide/application-kernel.md): process-local resources, readiness, admission, schedules, projections and optional provider adapters
17
+ - [Optional process sandbox](https://github.com/max-listov/stitchkit/blob/master/docs/guide/sandbox.md): Linux Bubblewrap sessions, durable workspace reconnect, network policy and host credential brokering
17
18
  - [Generic application primitives](https://github.com/max-listov/stitchkit/blob/master/docs/guide/primitives.md): lifecycle transitions, owner scope, permissions, exact money and quantities, deadlines, audit, delivery and exports — declared, not persisted
18
19
  - [Application migration recipes](https://github.com/max-listov/stitchkit/blob/master/docs/guide/application-migration-recipes.md): executable database, poller, queue-consumer and operational publishing cutovers
19
20
  - [CLI](https://github.com/max-listov/stitchkit/blob/master/docs/guide/cli.md): contracts as a command-line program
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stitchkit",
3
- "version": "0.88.0",
3
+ "version": "0.89.0",
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",
@@ -73,6 +73,10 @@
73
73
  "types": "./dist/tool-invoker.d.ts",
74
74
  "import": "./dist/tool-invoker.js"
75
75
  },
76
+ "./tools/connections": {
77
+ "types": "./dist/tools/connections/index.d.ts",
78
+ "import": "./dist/tools/connections/index.js"
79
+ },
76
80
  "./cli": {
77
81
  "types": "./dist/cli.d.ts",
78
82
  "import": "./dist/cli.js"
@@ -153,6 +157,10 @@
153
157
  "types": "./dist/testing.d.ts",
154
158
  "import": "./dist/testing.js"
155
159
  },
160
+ "./agent-runtime/sandbox": {
161
+ "types": "./dist/agent-runtime-sandbox.d.ts",
162
+ "import": "./dist/agent-runtime-sandbox.js"
163
+ },
156
164
  "./files": {
157
165
  "types": "./dist/files.d.ts",
158
166
  "import": "./dist/files.js"
@@ -1,11 +1,11 @@
1
- import {
2
- managedResourceDependencyId
3
- } from "./index-2k4yrqkc.js";
4
1
  import {
5
2
  ApplicationIdSchema,
6
3
  ApplicationShutdownResultSchema,
7
4
  ApplicationSnapshotSchema
8
5
  } from "./index-3gye9wzb.js";
6
+ import {
7
+ managedResourceDependencyId
8
+ } from "./index-2k4yrqkc.js";
9
9
  import {
10
10
  ShutdownOptionsSchema
11
11
  } from "./index-3z73fh2c.js";