stitchkit 0.102.0 → 0.103.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 (103) hide show
  1. package/CHANGELOG.md +64 -0
  2. package/dist/agent-runtime/browser-control-contract.d.ts +1118 -0
  3. package/dist/agent-runtime/browser-control-contract.d.ts.map +1 -0
  4. package/dist/agent-runtime/browser-controller.d.ts +31 -0
  5. package/dist/agent-runtime/browser-controller.d.ts.map +1 -0
  6. package/dist/agent-runtime/harness-control.d.ts.map +1 -1
  7. package/dist/agent-runtime/harness-realtime.d.ts +25 -0
  8. package/dist/agent-runtime/harness-realtime.d.ts.map +1 -0
  9. package/dist/agent-runtime/harness-tools.d.ts +11 -0
  10. package/dist/agent-runtime/harness-tools.d.ts.map +1 -0
  11. package/dist/agent-runtime/react.d.ts +4 -0
  12. package/dist/agent-runtime/react.d.ts.map +1 -0
  13. package/dist/agent-runtime/run-assertions.d.ts +63 -0
  14. package/dist/agent-runtime/run-assertions.d.ts.map +1 -0
  15. package/dist/application/diagnostic-journal-contract.d.ts +46 -7
  16. package/dist/application/diagnostic-journal-contract.d.ts.map +1 -1
  17. package/dist/application/diagnostic-journal-frame.d.ts +9 -0
  18. package/dist/application/diagnostic-journal-frame.d.ts.map +1 -0
  19. package/dist/application/diagnostic-journal-manager.d.ts.map +1 -1
  20. package/dist/application/diagnostic-journal-read-contract.d.ts +110 -0
  21. package/dist/application/diagnostic-journal-read-contract.d.ts.map +1 -0
  22. package/dist/application/diagnostic-journal-reader.d.ts +13 -0
  23. package/dist/application/diagnostic-journal-reader.d.ts.map +1 -0
  24. package/dist/application/diagnostic-journal-recovery.d.ts +4 -0
  25. package/dist/application/diagnostic-journal-recovery.d.ts.map +1 -0
  26. package/dist/application/diagnostic-journal-storage.d.ts +2 -0
  27. package/dist/application/diagnostic-journal-storage.d.ts.map +1 -1
  28. package/dist/entrypoints/agent-runtime/browser.d.ts +2 -0
  29. package/dist/entrypoints/agent-runtime/browser.d.ts.map +1 -1
  30. package/dist/entrypoints/agent-runtime/browser.js +235 -0
  31. package/dist/entrypoints/agent-runtime/harness-tools.d.ts +2 -0
  32. package/dist/entrypoints/agent-runtime/harness-tools.d.ts.map +1 -0
  33. package/dist/entrypoints/agent-runtime/harness-tools.js +32 -0
  34. package/dist/entrypoints/agent-runtime/harness.js +11 -226
  35. package/dist/entrypoints/agent-runtime/react.d.ts +2 -0
  36. package/dist/entrypoints/agent-runtime/react.d.ts.map +1 -0
  37. package/dist/entrypoints/agent-runtime/react.js +8 -0
  38. package/dist/entrypoints/agent-runtime/realtime.d.ts +2 -0
  39. package/dist/entrypoints/agent-runtime/realtime.d.ts.map +1 -0
  40. package/dist/entrypoints/agent-runtime/realtime.js +159 -0
  41. package/dist/entrypoints/agent-runtime/testing.d.ts +1 -0
  42. package/dist/entrypoints/agent-runtime/testing.d.ts.map +1 -1
  43. package/dist/entrypoints/agent-runtime/testing.js +67 -2
  44. package/dist/entrypoints/agent-runtime.js +23 -18
  45. package/dist/entrypoints/application/diagnostic-journal.d.ts +1 -0
  46. package/dist/entrypoints/application/diagnostic-journal.d.ts.map +1 -1
  47. package/dist/entrypoints/application/diagnostic-journal.js +213 -19
  48. package/dist/entrypoints/application.d.ts +1 -0
  49. package/dist/entrypoints/application.d.ts.map +1 -1
  50. package/dist/entrypoints/application.js +10 -2
  51. package/dist/entrypoints/cli.js +6 -6
  52. package/dist/entrypoints/index.js +15 -226
  53. package/dist/entrypoints/node.js +7 -5
  54. package/dist/entrypoints/observability.js +2 -2
  55. package/dist/entrypoints/react.js +2 -2
  56. package/dist/entrypoints/remote.js +3 -3
  57. package/dist/entrypoints/server.js +10 -8
  58. package/dist/entrypoints/testing.js +3 -3
  59. package/dist/entrypoints/tools/invoker.js +5 -5
  60. package/dist/entrypoints/tools.js +23 -34
  61. package/dist/entrypoints/tracking.js +2 -2
  62. package/dist/{index-d82d3xg4.js → index-0c419yx7.js} +1 -1
  63. package/dist/{index-dvwj1f43.js → index-0efgsyav.js} +1 -1
  64. package/dist/index-20yvtn9a.js +38 -0
  65. package/dist/{index-a9pd417t.js → index-5vyd0fkb.js} +1 -34
  66. package/dist/{index-r1z0rd9c.js → index-7n68nmc6.js} +1 -1
  67. package/dist/index-860vjkgm.js +48 -0
  68. package/dist/index-c9d05kvt.js +11 -0
  69. package/dist/{index-m9fndta6.js → index-ds7jdhep.js} +2 -2
  70. package/dist/index-jn9g8xdt.js +246 -0
  71. package/dist/{index-n9tyz8z3.js → index-kgmh97hf.js} +1 -1
  72. package/dist/{index-c6aagrbd.js → index-kkk1wzsq.js} +3 -3
  73. package/dist/index-nggfa2yn.js +34 -0
  74. package/dist/{index-m79yr938.js → index-pw99k9h5.js} +1 -10
  75. package/dist/index-qapzv4p5.js +54 -0
  76. package/dist/index-r34mvse1.js +225 -0
  77. package/dist/index-srs8hj9c.js +10 -0
  78. package/dist/index-vgkbcnkc.js +29 -0
  79. package/dist/{index-ewbaywk5.js → index-x1dkwx5x.js} +1 -1
  80. package/dist/{index-xkhk5d6g.js → index-xgc94hy6.js} +5 -48
  81. package/dist/{index-3ct7hhq6.js → index-xwq9j1sf.js} +6 -56
  82. package/dist/{index-hby4qhax.js → index-yex7eg1v.js} +4 -10
  83. package/dist/{index-1h6gtdrj.js → index-ygkka6zn.js} +1 -1
  84. package/dist/{index-zs4ms3th.js → index-z3pqcy7r.js} +7 -30
  85. package/dist/index-z94wht4y.js +156 -0
  86. package/dist/index-ze1eph1k.js +20 -0
  87. package/llms/agent-runtime-browser.txt +26 -0
  88. package/llms/agent-runtime-harness-tools.txt +25 -0
  89. package/llms/agent-runtime-harness.txt +140 -1
  90. package/llms/agent-runtime-react.txt +21 -0
  91. package/llms/agent-runtime-realtime.txt +30 -0
  92. package/llms/agent-runtime-testing.txt +6 -0
  93. package/llms/application-diagnostic-journal.txt +2 -0
  94. package/llms/application.2.txt +157 -267
  95. package/llms/application.3.txt +278 -0
  96. package/llms/application.txt +43 -158
  97. package/llms/stitchkit.txt +9 -5
  98. package/llms/{upgrading-0.75.0-0.102.0.txt → upgrading-0.75.0-0.103.0.txt} +32 -3
  99. package/llms/upgrading.txt +1 -1
  100. package/llms-full.txt +289 -9
  101. package/llms.txt +11 -7
  102. package/package.json +13 -1
  103. package/dist/index-h124epcf.js +0 -103
package/llms-full.txt CHANGED
@@ -70,26 +70,29 @@ own, recorded as an ADR.
70
70
  | `stitchkit/geo` | server (Bun or Node) | evolving | managed GeoIP reader generations, last-known-good reload and the optional MaxMind adapter |
71
71
  | `stitchkit/oauth` | browser **and** server | evolving | provider-neutral Authorization Code + PKCE request and one-shot callback transaction mechanics |
72
72
  | `stitchkit/google` | server (Bun or Node) | evolving | optional Google code exchange and verified OIDC identity adapter |
73
- | `stitchkit/observability` | server | stable<br>_redefined in 2 of the 47 minors since 0.56.2, most recently 0.92.0_ | request/tool event projections — `createObservability`, trace context, sanitisation |
73
+ | `stitchkit/observability` | server | stable<br>_redefined in 2 of the 48 minors since 0.56.2, most recently 0.92.0_ | request/tool event projections — `createObservability`, trace context, sanitisation |
74
74
  | `stitchkit/testing` | tests on Bun or Node | stable | in-process generated clients over a real Fetch handler, plus the managed-resource conformance kit |
75
75
  | `stitchkit/declaration` | browser + build and deployment tooling (Bun or Node) | evolving | `ProjectDeclarationSchema` — the one machine-readable statement a repository makes about itself |
76
76
  | `stitchkit/react` | browser + server rendering | stable | `createCursorQuery`, `createCacheBridge`, QueryClient and `ApiError` retry policy |
77
77
  | `stitchkit/react/keyboard` | browser | evolving | which part of a screen gets a key — ordered layers, one Escape per level, list zones with real focus; see [keyboard guide](keyboard.md) |
78
- | `stitchkit/agent-runtime` | server | evolving<br>_redefined in 22 of the 47 minors since 0.56.2, most recently 0.97.0_ | optional durable conversation/run loop, history, models, prompts, fencing and events |
78
+ | `stitchkit/agent-runtime` | server | evolving<br>_redefined in 22 of the 48 minors since 0.56.2, most recently 0.97.0_ | optional durable conversation/run loop, history, models, prompts, fencing and events |
79
79
  | `stitchkit/agent-runtime/sandbox` | server | evolving | optional Linux Bubblewrap sessions, durable workspaces and a host HTTP credential gateway; see [sandbox guide](sandbox.md) |
80
80
  | `stitchkit/agent-runtime/testing` | tests on Bun or Node | evolving | credential-free replay, scripted provider faults, deterministic race controls and the agent-store conformance kit |
81
81
  | `stitchkit/agent-runtime/harness` | server | evolving | resource-aware process-local facade over the canonical Agent runtime; supervision stays outside |
82
82
  | `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 |
83
83
  | `stitchkit/agent-runtime/openrouter` | server | evolving | isolated OpenRouter language-model adapter |
84
- | `stitchkit/agent-runtime/browser` | browser + server | evolving | canonical agent records, events and reconnect cursor without execution or sinks |
84
+ | `stitchkit/agent-runtime/browser` | browser + server | evolving | canonical agent records, events, reconnect cursor and optional conversation controller |
85
+ | `stitchkit/agent-runtime/harness-tools` | server | evolving | full mountAgent configuration with the current run fence |
86
+ | `stitchkit/agent-runtime/react` | browser + server | evolving | React subscription to an application-owned agent controller |
87
+ | `stitchkit/agent-runtime/realtime` | server (Bun or Node) | evolving | authorized agent control over the existing Socket.IO server |
85
88
  | `stitchkit/agent-runtime/sqlite/bun` | server (Bun) | evolving | durable built-in SQLite store for the agent runtime |
86
89
  | `stitchkit/agent-runtime/sqlite/node` | server (Node ≥ 22.5) | evolving | durable built-in SQLite store for the agent runtime |
87
90
  | `stitchkit-tui` | terminal (Bun) | evolving | optional official OpenTUI host over a caller-composed headless runtime |
88
- | `stitchkit/application` | browser + server | evolving<br>_redefined in 10 of the 47 minors since 0.56.2, most recently 0.100.0_ | managed resource graph, readiness, admission, schedules, subtree restart and bounded shutdown |
91
+ | `stitchkit/application` | browser + server | evolving<br>_redefined in 11 of the 48 minors since 0.56.2, most recently 0.103.0_ | managed resource graph, readiness, admission, schedules, subtree restart and bounded shutdown |
89
92
  | `stitchkit/application/grammy` | server | evolving | a grammY bot as application resources — configuration, then polling with updates admitted by batch — and the webhook adapter |
90
93
  | `stitchkit/application/opentelemetry` | server | evolving | maps application snapshots onto an injected OpenTelemetry `Meter` |
91
94
  | `stitchkit/application/schemas` | browser + server | evolving | the application's snapshot, health and shutdown schemas alone, without the kernel |
92
- | `stitchkit/application/diagnostic-journal` | server | evolving | the local diagnostic journal — the one part of the kernel that spawns, locks and writes files |
95
+ | `stitchkit/application/diagnostic-journal` | server | evolving | the local diagnostic journal — an exclusive bounded writer and snapshot reader with explicit anomalies |
93
96
  | `stitchkit/application/directory-inbox` | server | evolving | the directory inbox — entries another program drops into a directory, delivered to the application at least once |
94
97
 
95
98
  Rule of thumb: browser code imports `stitchkit` and `stitchkit/react`; server
@@ -191,6 +194,7 @@ map — feature → packages:
191
194
  | MCP / agent adapters (`stitchkit/tools`) | `@modelcontextprotocol/server` `ai` |
192
195
  | Agent application runtime (`stitchkit/agent-runtime`) | `ai` |
193
196
  | Headless Agent harness (`stitchkit/agent-runtime/harness`) | `ai` |
197
+ | Harness tools (`stitchkit/agent-runtime/harness-tools`) | `ai` `@modelcontextprotocol/server` (tool declarations) |
194
198
  | Agent coding tools (`stitchkit/agent-runtime/coding-tools`) | — |
195
199
  | OpenRouter runtime adapter (`stitchkit/agent-runtime/openrouter`) | `ai` `@openrouter/ai-sdk-provider` |
196
200
  | SQLite agent store (`stitchkit/agent-runtime/sqlite/bun` or `/node`) | — (runtime built-in) |
@@ -6612,6 +6616,146 @@ for receipt queries; do not import runtime internals. Available since 0.100.0;
6612
6616
  existing runtime configurations need no migration.
6613
6617
 
6614
6618
 
6619
+ ==============================================================================
6620
+ # Guide: Agent composition (docs/guide/agent-composition.md)
6621
+ ==============================================================================
6622
+
6623
+ ---
6624
+ title: "Agent composition without a second runtime"
6625
+ description: "Compose contract tools, authenticated realtime control, React views and exact-run behavioral checks."
6626
+ type: architecture
6627
+ status: active
6628
+ created: 2026-09-30 22:45 +07:00
6629
+ updated: 2026-09-30 23:03 +07:00
6630
+ participants:
6631
+ - role: authored
6632
+ harness: Codex
6633
+ model: GPT-6
6634
+ at: 2026-09-30 22:45 +07:00
6635
+ ---
6636
+
6637
+ # Compose an agent application
6638
+
6639
+ Use these pieces when an application wants the existing headless harness and a generic
6640
+ conversation view. An application with its own AI SDK loop keeps `mountAgent`; a product
6641
+ with custom message projections can keep its transport and UI. No consumer migration is
6642
+ required. Model selection, storage, compaction, approvals and recovery stay with their
6643
+ existing owners.
6644
+
6645
+ ## Resources and tools
6646
+
6647
+ ```ts
6648
+ import {
6649
+ createAgentHarnessFileResources,
6650
+ createHeadlessAgentHarness,
6651
+ } from 'stitchkit/agent-runtime/harness';
6652
+ import { createAgentHarnessTools } from 'stitchkit/agent-runtime/harness-tools';
6653
+
6654
+ const resources = createAgentHarnessFileResources({
6655
+ roots: [{ id: 'guide', kind: 'instruction', path: instructionRoot }],
6656
+ limits: { maxTotalBytes: 256 * 1024 },
6657
+ });
6658
+ const harness = createHeadlessAgentHarness({
6659
+ protocol, store, models, promptBudget,
6660
+ resources,
6661
+ tools: createAgentHarnessTools(({ context, run }) => ({
6662
+ services: [catalogService],
6663
+ context: { ...context, messageId: run.assistantMessageId },
6664
+ runtimeTools: resources.runtimeTools,
6665
+ lifecycle: authorizeTools,
6666
+ hooks: observeTools,
6667
+ })),
6668
+ });
6669
+ ```
6670
+
6671
+ The factory composes application authorization then the runtime fence through `mountAgent`.
6672
+ The optional harness-tools leaf preserves the complete tool types, including MCP presenter
6673
+ declarations; install the same `ai` and `@modelcontextprotocol/server` peers as for
6674
+ `stitchkit/tools`. The base harness stays AI-only. Every mount option remains available, including registry, runtime tools, extension,
6675
+ coercion, output stripping, hooks and durability. Async per-run configuration is supported.
6676
+ The original tools callback still accepts arbitrary typed AI SDK tools and prepareStep.
6677
+ The resource reader is explicitly selected: filtered allowlists do not gain tools merely
6678
+ because a loader exists. Root IDs, kinds, provenance and limits are unchanged.
6679
+
6680
+ ## Server and browser
6681
+
6682
+ ```ts
6683
+ import { bindAgentHarnessRealtime } from 'stitchkit/agent-runtime/realtime';
6684
+
6685
+ const binding = bindAgentHarnessRealtime(harness, socket, {
6686
+ async authorize({ identity, request, signal }) {
6687
+ // socket.data comes from your verified Socket.IO handshake, not a browser context.
6688
+ if (!await mayAccessConversation(identity, request, signal)) return null;
6689
+ return { context: { userId: identity.userId } };
6690
+ },
6691
+ onError: reportServerError,
6692
+ });
6693
+ ```
6694
+
6695
+ `socket` is the existing `createSocketIOServer` handle, attached to `createServer` (Bun)
6696
+ or the Node adapter. The access policy checks every operation, file/reference and metadata
6697
+ as well as snapshot/event reads. Session handshake authentication alone is insufficient.
6698
+ Conversation ownership and observer/controller roles are application policy; the canonical
6699
+ control server additionally enforces its exclusive controller lease.
6700
+
6701
+ ```ts
6702
+ import { createSocketIOClient } from 'stitchkit';
6703
+ import { createAgentController } from 'stitchkit/agent-runtime/browser';
6704
+ import { useAgent } from 'stitchkit/agent-runtime/react';
6705
+
6706
+ const transport = createSocketIOClient({ url: serverUrl, auth: sessionAuth });
6707
+ const agent = createAgentController({ transport, conversationId, access: 'control' });
6708
+ transport.connect();
6709
+
6710
+ function Conversation() {
6711
+ const state = useAgent(agent);
6712
+ const conversation = state.view.conversations[conversationId];
6713
+ // Render canonical messages/parts, transient progress, approvals and state.error.
6714
+ return <Transcript conversation={conversation} status={state.status} error={state.error} />;
6715
+ }
6716
+
6717
+ await agent.request({
6718
+ operation: 'submit', idempotencyKey: crypto.randomUUID(),
6719
+ parts: [{ type: 'text', text: 'Find available items' }],
6720
+ });
6721
+ await agent.request({ operation: 'interrupt', runId });
6722
+ await agent.request({ operation: 'respond-approval', approvalId, approved: true });
6723
+ await agent.close(); // leaves transport and harness alive
6724
+ ```
6725
+
6726
+ Wait for `ready` before sending. Share a controller among views of the same conversation;
6727
+ create it at session scope, not during React render. Unmount only unsubscribes the view.
6728
+ To release the session, await `close`; to stop the application, separately close the
6729
+ binding, transport and harness through the application's shutdown lifecycle. Closing a
6730
+ view does not interrupt its remote run. Use explicit `interrupt` for cancellation.
6731
+
6732
+ Reconnect reattaches and reads durable state. Mutations are not retried automatically:
6733
+ if an acknowledgement is lost, retain the original idempotency key. Incoming event
6734
+ buffers and outgoing requests have finite limits; capacity/overflow/lease failures stay
6735
+ visible. A server overflow deliberately disconnects the transport; reconnect explicitly.
6736
+
6737
+ ## Check behavior, not just admission
6738
+
6739
+ ```ts
6740
+ import { inspectAgentRun } from 'stitchkit/agent-runtime/testing';
6741
+
6742
+ const ticket = harness.submit(input);
6743
+ const admitted = await ticket.admission;
6744
+ await ticket.result;
6745
+ const result = inspectAgentRun(await harness.snapshot(input.conversationId), admitted.runId);
6746
+ result.calledTool('catalog_search');
6747
+ result.toolSucceeded('catalog_search');
6748
+ result.notCalledTool('catalog_delete');
6749
+ result.completed();
6750
+ ```
6751
+
6752
+ `calledTool` proves a call record (including an approved continuation linked through that
6753
+ run’s exact input messages); `toolSucceeded` also needs a matching successful result.
6754
+ `completed` requires successful terminal output with no pending approval. Prior runs,
6755
+ provider/policy stops, failed calls and unfinished runs cannot satisfy those assertions.
6756
+ The helper does not invoke a model or poll; the existing runtime ticket owns execution.
6757
+
6758
+
6615
6759
  ==============================================================================
6616
6760
  # Guide: Managed application kernel (docs/guide/application-kernel.md)
6617
6761
  ==============================================================================
@@ -6622,7 +6766,7 @@ description: Compose process-local resources, schedules, readiness, drain and op
6622
6766
  type: architecture
6623
6767
  status: active
6624
6768
  created: 2026-08-23
6625
- updated: 2026-09-04 14:11 +07:00
6769
+ updated: 2026-09-30 17:41 +07:00
6626
6770
  ---
6627
6771
 
6628
6772
  # Managed application kernel
@@ -7269,10 +7413,47 @@ short-lived reclaim guard.
7269
7413
 
7270
7414
  `flush()` means every accepted append through that call's boundary settled. It is not `fsync`, a
7271
7415
  durable receipt, exactly-once execution or remote delivery. Timeout/cancellation bound only the
7272
- waiter; the writer retains physical capacity until settlement. There is no reader or upload API.
7273
- Use a durable application store or deployment-owned log collector when restart recovery, replay or
7416
+ waiter; the writer retains physical capacity until settlement. There is no upload or managed replay API.
7417
+ Use a durable application store or deployment-owned log collector when durable restart recovery, replay or
7274
7418
  aggregation is required. → [ADR 0134](../decisions/0134-diagnostic-journal-is-bounded-local-evidence.md).
7275
7419
 
7420
+ For finite inspection, use the shared reader with an explicit oldest-to-newest list of existing
7421
+ files. Keep anomaly reporting outside the journal being inspected:
7422
+
7423
+ ```ts
7424
+ import { readDiagnosticJournal } from 'stitchkit/application/diagnostic-journal'
7425
+ import { z } from 'zod'
7426
+
7427
+ const eventSchema = z.object({
7428
+ kind: z.enum(['resource_failed', 'recovery_started']),
7429
+ resource: z.string().max(80),
7430
+ }).strict()
7431
+
7432
+ for await (const row of readDiagnosticJournal({
7433
+ paths: ['/var/lib/example/diagnostic.jsonl.1', '/var/lib/example/diagnostic.jsonl'],
7434
+ eventSchema,
7435
+ maxLineBytes: 4 * 1024,
7436
+ })) {
7437
+ if (row.type === 'anomaly') internalLogger.warn(row.anomaly)
7438
+ else inspectEvent(row.frame.event)
7439
+ }
7440
+ ```
7441
+
7442
+ The reader bounds memory by line size plus a fixed chunk, skips oversized/damaged rows with
7443
+ explicit anomalies, and still returns valid rows before and after them. `offset` is zero-based
7444
+ bytes; `line` is one-based. `position` distinguishes the file's tail from interior damage.
7445
+ A valid frame lacking its final LF yields a warning with `skippedBytes: 0` and its frame.
7446
+ Each file's size is captured at open; concurrent appends are excluded. Missing files, permissions,
7447
+ symlinks, non-regular files and mid-read truncation throw rather than masquerading as bad data.
7448
+ The caller owns file selection and coordination with an active rotator.
7449
+
7450
+ Writer startup inspects retained and active files under its lock. On damage,
7451
+ `journal.getStatus().recovery` contains counts and first/last anomaly locations, reconstructed
7452
+ again on restart from the preserved bytes. This describes startup observations, not live
7453
+ continuous inspection. `maxFiles: 1` cannot preserve a torn active file by rotation and throws
7454
+ `DiagnosticJournalRecoveryError` before removing any evidence; configure at least two slots.
7455
+ Normal rotation retains the existing finite eviction policy. → [ADR 0219](../decisions/0219-journal-damage-is-data-and-io-failure-is-failure.md).
7456
+
7276
7457
  Shutdown performs one phase barrier at a time: stop admission everywhere,
7277
7458
  cancel future schedules, drain admitted work, then close in reverse stable
7278
7459
  topological order. Every hook shares the same grace deadline. Forced cleanup
@@ -14238,6 +14419,35 @@ analytics policy belong to the application.
14238
14419
 
14239
14420
  # Upgrading stitchkit
14240
14421
 
14422
+ ## Released migration: 0.103.0
14423
+
14424
+ ### Diagnostic journal startup preserves torn evidence and inspects archives
14425
+
14426
+ **Who must act:** operators using `maxFiles: 1` who can encounter a torn active
14427
+ file, or whose retained files are unreadable by the writer. Clean single-file
14428
+ journals continue to work; successful startup now requires read access to every
14429
+ retained generation.
14430
+
14431
+ ```ts
14432
+ import { createDiagnosticJournal } from 'stitchkit/application/diagnostic-journal'
14433
+
14434
+ // Before: a torn active file could be discarded during startup.
14435
+ await createDiagnosticJournal({ ...config, limits: { ...config.limits, maxFiles: 1 } })
14436
+ // After: retain the torn file while the fresh writer starts in a new active file.
14437
+ await createDiagnosticJournal({ ...config, limits: { ...config.limits, maxFiles: 2 } })
14438
+ ```
14439
+
14440
+ With single-file retention, a torn active file throws `DiagnosticJournalRecoveryError`
14441
+ from `stitchkit/application`, carrying `recovery` observations and releasing its lock
14442
+ without deleting evidence. Inspection I/O errors also fail startup and release the
14443
+ lock; restore filesystem access rather than treating that failure as a bad JSON row.
14444
+ Normal rotation retains the configured finite eviction policy.
14445
+
14446
+ For archive inspection, replace ad hoc line parsing with `readDiagnosticJournal`
14447
+ from the same filesystem leaf. Handle its `frame | anomaly` stream explicitly;
14448
+ missing files, permissions and unsafe paths still throw. See the
14449
+ [journal guide](application-kernel.md#bounded-local-diagnostic-journal).
14450
+
14241
14451
  ## Released migration: 0.102.0
14242
14452
 
14243
14453
  ### `view_file` receives an array, not an array encoded as text
@@ -18916,9 +19126,13 @@ cutovers are covered by the executable
18916
19126
  | `DiagnosticJournalRefusalReasonSchema` / `DiagnosticJournalRefusalReason` | schema / _type_ | `closed \| failed \| invalid \| oversized \| item-capacity \| byte-capacity` |
18917
19127
  | `DiagnosticJournalFailurePhaseSchema` / `DiagnosticJournalFailurePhase` | schema / _type_ | internal `write \| rotation \| close` failure phase exposed only to status and the isolated observer |
18918
19128
  | `DiagnosticJournalWaitOptions` / `DiagnosticJournalFailure` | _type_ | caller wait signal/timeout and isolated internal failure callback record |
19129
+ | `DiagnosticJournalAnomalySchema` / `DiagnosticJournalAnomaly` | schema / _type_ | corrupt-row reason, file, zero-based byte offset, one-based line, tail/interior position and skipped bytes |
19130
+ | `createDiagnosticJournalReadResultSchema` / `DiagnosticJournalReadResult` | function / _type_ | owner-schema frame output or explicit anomaly; retains transformed event output types |
19131
+ | `DiagnosticJournalRecoveryStatusSchema` / `DiagnosticJournalRecoveryStatus` | schema / _type_ | bounded startup inspection counts and first/last anomaly locations |
19132
+ | `DiagnosticJournalRecoveryError` | class | torn single-file startup refusal carrying recovery observations, preserving evidence and releasing its lock |
18919
19133
 
18920
19134
  `accepted` is bounded in-memory admission and `written` is completed append, not `fsync` or durable
18921
- delivery. The journal has no reader/replay/upload API. See the
19135
+ delivery. Its filesystem reader is in the diagnostic-journal leaf; there is no managed replay/upload API. See the
18922
19136
  [guide](../guide/application-kernel.md#bounded-local-diagnostic-journal),
18923
19137
  [architecture](../architecture/diagnostic-journal.md) and [ADR
18924
19138
  0134](../decisions/0134-diagnostic-journal-is-bounded-local-evidence.md).
@@ -19093,6 +19307,8 @@ snapshots; the adapter owns no SDK lifecycle, polling or delta state.
19093
19307
  | Export | Kind | Summary |
19094
19308
  |--------|------|---------|
19095
19309
  | `createDiagnosticJournal` | function | the bounded local journal: a file lock, a spawn to diagnose a stale one, and framed writes |
19310
+ | `readDiagnosticJournal` | function | bounded async stream of validated frames and explicit anomalies from finite snapshots of caller-selected files; I/O failures throw |
19311
+ | `DiagnosticJournalReaderConfig` | _type_ | normalized absolute `paths`, owner `eventSchema`, positive safe-integer `maxLineBytes` and optional cancellation `signal` |
19096
19312
 
19097
19313
  Its own entrypoint because of what it reaches — `node:child_process`,
19098
19314
  `node:fs`, `node:os`, `node:util` — with `promisify(execFile)` evaluated while
@@ -19434,6 +19650,11 @@ Credential-free provider and concurrency fixtures for Bun and Node tests.
19434
19650
  | `AgentStoreConformanceConfig` | _type_ | `{ createStore(context), cleanup?(context) }` — the factory the contract runs against, plus a teardown that runs once whether the scenario passed or failed |
19435
19651
  | `AgentStoreConformanceContext` | _type_ | `{ conversationIds }` — every conversation the scenario will mutate, handed over **before** the first mutation so an adapter can provision application-owned parent rows; a zero-argument factory stays valid |
19436
19652
 
19653
+ `inspectAgentRun` takes `(snapshot, runId)` and returns `completed()`, `calledTool(name)`,
19654
+ `notCalledTool(name)` and `toolSucceeded(name)` assertions over durable evidence for
19655
+ that exact run. Completion requires terminal reason `success`, not `policy_stop` or
19656
+ `provider_stop`, and no pending approval. Successful tools require matching call/result IDs.
19657
+
19437
19658
  ## `stitchkit/agent-runtime/harness`
19438
19659
 
19439
19660
  Server-only evolving facade over the canonical Agent runtime. It requires the optional `ai` peer
@@ -19531,6 +19752,31 @@ Use this entrypoint from client components and shared DTO packages. The full
19531
19752
 
19532
19753
  ---
19533
19754
 
19755
+ ### Browser control composition
19756
+
19757
+ `AgentBrowserRequestSchema` / `AgentBrowserRequest` derive from the trusted control
19758
+ protocol but exclude runtime `context`. Submit permits only strict text/file parts;
19759
+ file ownership and metadata policy are checked by server authorization. The shared
19760
+ `agentControlRealtimeContract` owns `agent:control` acknowledgements and `agent:delivery`.
19761
+
19762
+ `createAgentController` / `AgentControllerConfig` take an existing Stitchkit
19763
+ realtime `transport`, `conversationId`, `access` (`observe` or `control`), optional
19764
+ `timeoutMs` (10000), `maxBufferedEvents` (256), `maxBufferedBytes` (1048576) and
19765
+ `maxPendingRequests` (32). All bounds are positive safe integers. One controller owns one
19766
+ attachment per conversation on that transport; share the controller between views.
19767
+
19768
+ `AgentController` exposes stable `subscribe`, `getSnapshot`, `request(command)` and async
19769
+ `close`. `AgentBrowserCommand` uses the canonical operations, without request/conversation identity;
19770
+ `submit` requires a caller-owned idempotency key. Unknown-outcome mutations are never
19771
+ replayed automatically. `AgentControllerState` distinguishes connecting, ready,
19772
+ disconnected, error and closed and retains the canonical full `view` plus safe error
19773
+ code/message. Errors in automatic attach/refresh appear there. Reconnect attaches again
19774
+ and reads a snapshot; snapshot gaps coalesce, stale generations cannot overwrite state,
19775
+ and buffers/queues are bounded. Overflow or failed refresh is visible and requires
19776
+ explicit recovery. Closing detaches without closing the shared transport or remote run.
19777
+
19778
+ See [agent composition](../guide/agent-composition.md) for a complete wiring example.
19779
+
19534
19780
  ## `stitchkit/agent-runtime/openrouter`
19535
19781
 
19536
19782
  | Export | Kind | Summary |
@@ -20596,3 +20842,37 @@ Its types are `BubblewrapSandboxConfig`, `SandboxBackend`, `SandboxCommand`,
20596
20842
  `SandboxPrewarmInput`, `SandboxProcess`, `SandboxRunOptions`, `SandboxSession`,
20597
20843
  and `SandboxState`. The [sandbox guide](../guide/sandbox.md) specifies lifecycle,
20598
20844
  network enforcement, gateway credentials and platform/resource boundaries.
20845
+
20846
+ ## `stitchkit/agent-runtime/realtime`
20847
+
20848
+ Optional evolving Socket.IO server binding. `bindAgentHarnessRealtime` takes `(harness, socket, config)` and returns `close()` for its subscriptions and control connections, without closing
20849
+ socket or harness. `AgentHarnessRealtimeConfig` requires `authorize({ identity, request,
20850
+ signal })`: return `{ context }` after verifying the session principal, conversation,
20851
+ operation, files and metadata, or `null`. Identity is `socket.data` from the application's
20852
+ verified handshake. Every request and event delivery is authorized. Observe access does
20853
+ not grant mutation; controller leases and approval policy still belong to the harness.
20854
+
20855
+ `maxPendingEvents` and `maxPendingAttachments` forward to the canonical control server;
20856
+ `maxPendingRequests` bounds in-flight authorization/control requests per socket (32);
20857
+ `authorizationTimeoutMs` bounds each authorization (10000 ms). Honor its AbortSignal.
20858
+ `onError` receives internal errors; peers receive generic denials. Revoking a conversation
20859
+ releases only its attachment. Event overflow closes the socket; explicitly reconnect the
20860
+ application transport. A transport's Engine.IO payload limit remains application-owned.
20861
+
20862
+ ## `stitchkit/agent-runtime/react`
20863
+
20864
+ Optional evolving React peer leaf. `useAgent` takes a controller and subscribes through
20865
+ `useSyncExternalStore`, returning the same `AgentControllerState` as `getSnapshot()`.
20866
+ Create and close the controller at application/session scope. Multiple components can
20867
+ observe it; StrictMode and unmount release only the component's own subscription.
20868
+
20869
+ ## `stitchkit/agent-runtime/harness-tools`
20870
+
20871
+ Optional evolving composition of the full `mountAgent` configuration with the runtime
20872
+ fence. Its runtime peer is `ai`; its full tool presenter declarations also require
20873
+ `@modelcontextprotocol/server`, as `stitchkit/tools` does. The base harness retains its
20874
+ AI-only peer boundary. Existing custom tool callbacks need no new import.
20875
+
20876
+ | Export | Kind | Summary |
20877
+ |--------|------|---------|
20878
+ | `createAgentHarnessTools` / `AgentHarnessToolsConfig` | function / _type_ | async per-run full mount configuration (`services` plus all `AgentMountConfig` options); composes application lifecycle then runtime fence exactly once |
package/llms.txt CHANGED
@@ -9,7 +9,7 @@ Build with stitchkit: define a contract once, then `implement` it and serve it (
9
9
  Load the slice for each entrypoint your code imports — `import … from 'stitchkit/server'` → `llms/server.txt`; the root `stitchkit` import → `llms/stitchkit.txt`. A slice holds that entrypoint's API reference section and the guide pages whose home it is; every guide lives in exactly one slice, and a slice that needs another's guide names it under "Also read". Each file is at most 50.0 KB; a longer one continues in numbered parts, each naming the next at its top. Moving across versions: load `llms/upgrading.txt` and the range slices it lists between your version and the target. `llms-full.txt` inlines everything; it is far larger than a context window, so do not read it whole.
10
10
 
11
11
  ## Entrypoint slices
12
- - **stitchkit**: [llms/stitchkit.txt](llms/stitchkit.txt) 16.5 KB → [llms/stitchkit.2.txt](llms/stitchkit.2.txt) 45.2 KB → [llms/stitchkit.3.txt](llms/stitchkit.3.txt) 17.1 KB
12
+ - **stitchkit**: [llms/stitchkit.txt](llms/stitchkit.txt) 17.0 KB → [llms/stitchkit.2.txt](llms/stitchkit.2.txt) 45.2 KB → [llms/stitchkit.3.txt](llms/stitchkit.3.txt) 17.1 KB
13
13
  - **stitchkit/live**: [llms/live.txt](llms/live.txt) 21.6 KB
14
14
  - **stitchkit/react**: [llms/react.txt](llms/react.txt) 9.0 KB
15
15
  - **stitchkit/react/keyboard**: [llms/react-keyboard.txt](llms/react-keyboard.txt) 9.4 KB
@@ -24,18 +24,18 @@ Load the slice for each entrypoint your code imports — `import … from 'stitc
24
24
  - **stitchkit/server**: [llms/server.txt](llms/server.txt) 45.3 KB → [llms/server.2.txt](llms/server.2.txt) 14.6 KB → [llms/server.3.txt](llms/server.3.txt) 45.6 KB → [llms/server.4.txt](llms/server.4.txt) 38.1 KB → [llms/server.5.txt](llms/server.5.txt) 21.8 KB
25
25
  - **stitchkit/observability**: [llms/observability.txt](llms/observability.txt) 44.8 KB
26
26
  - **stitchkit/agent-runtime**: [llms/agent-runtime.txt](llms/agent-runtime.txt) 36.8 KB → [llms/agent-runtime.2.txt](llms/agent-runtime.2.txt) 46.7 KB → [llms/agent-runtime.3.txt](llms/agent-runtime.3.txt) 34.3 KB
27
- - **stitchkit/agent-runtime/testing**: [llms/agent-runtime-testing.txt](llms/agent-runtime-testing.txt) 2.2 KB
28
- - **stitchkit/agent-runtime/harness**: [llms/agent-runtime-harness.txt](llms/agent-runtime-harness.txt) 4.1 KB
27
+ - **stitchkit/agent-runtime/testing**: [llms/agent-runtime-testing.txt](llms/agent-runtime-testing.txt) 2.6 KB
28
+ - **stitchkit/agent-runtime/harness**: [llms/agent-runtime-harness.txt](llms/agent-runtime-harness.txt) 10.1 KB
29
29
  - **stitchkit/agent-runtime/coding-tools**: [llms/agent-runtime-coding-tools.txt](llms/agent-runtime-coding-tools.txt) 4.9 KB
30
- - **stitchkit/agent-runtime/browser**: [llms/agent-runtime-browser.txt](llms/agent-runtime-browser.txt) 1.6 KB
30
+ - **stitchkit/agent-runtime/browser**: [llms/agent-runtime-browser.txt](llms/agent-runtime-browser.txt) 3.3 KB
31
31
  - **stitchkit/agent-runtime/openrouter**: [llms/agent-runtime-openrouter.txt](llms/agent-runtime-openrouter.txt) 1.1 KB
32
32
  - **stitchkit/agent-runtime/sqlite/bun**: [llms/agent-runtime-sqlite-bun.txt](llms/agent-runtime-sqlite-bun.txt) 1.8 KB
33
33
  - **stitchkit/agent-runtime/sqlite/node**: [llms/agent-runtime-sqlite-node.txt](llms/agent-runtime-sqlite-node.txt) 1.7 KB
34
- - **stitchkit/application**: [llms/application.txt](llms/application.txt) 46.0 KB → [llms/application.2.txt](llms/application.2.txt) 40.0 KB
34
+ - **stitchkit/application**: [llms/application.txt](llms/application.txt) 37.9 KB → [llms/application.2.txt](llms/application.2.txt) 24.1 KB → [llms/application.3.txt](llms/application.3.txt) 27.3 KB
35
35
  - **stitchkit/application/grammy**: [llms/application-grammy.txt](llms/application-grammy.txt) 2.3 KB
36
36
  - **stitchkit/application/opentelemetry**: [llms/application-opentelemetry.txt](llms/application-opentelemetry.txt) 1.6 KB
37
37
  - **stitchkit/application/directory-inbox**: [llms/application-directory-inbox.txt](llms/application-directory-inbox.txt) 0.3 KB
38
- - **stitchkit/application/diagnostic-journal**: [llms/application-diagnostic-journal.txt](llms/application-diagnostic-journal.txt) 1.4 KB
38
+ - **stitchkit/application/diagnostic-journal**: [llms/application-diagnostic-journal.txt](llms/application-diagnostic-journal.txt) 1.8 KB
39
39
  - **stitchkit/application/schemas**: [llms/application-schemas.txt](llms/application-schemas.txt) 1.8 KB
40
40
  - **stitchkit/testing**: [llms/testing.txt](llms/testing.txt) 30.8 KB
41
41
  - **stitchkit/agent-runtime/sandbox**: [llms/agent-runtime-sandbox.txt](llms/agent-runtime-sandbox.txt) 8.1 KB
@@ -52,10 +52,13 @@ Load the slice for each entrypoint your code imports — `import … from 'stitc
52
52
  - **stitchkit/google**: [llms/google.txt](llms/google.txt) 1.4 KB
53
53
  - **stitchkit/declaration**: [llms/declaration.txt](llms/declaration.txt) 16.0 KB
54
54
  - **stitchkit/node**: [llms/node.txt](llms/node.txt) 3.1 KB
55
+ - **stitchkit/agent-runtime/react**: [llms/agent-runtime-react.txt](llms/agent-runtime-react.txt) 1.0 KB
56
+ - **stitchkit/agent-runtime/realtime**: [llms/agent-runtime-realtime.txt](llms/agent-runtime-realtime.txt) 1.8 KB
57
+ - **stitchkit/agent-runtime/harness-tools**: [llms/agent-runtime-harness-tools.txt](llms/agent-runtime-harness-tools.txt) 1.3 KB
55
58
 
56
59
  ## Upgrading slices
57
60
  - **Upgrading — how to move across versions**: [llms/upgrading.txt](llms/upgrading.txt) 10.3 KB
58
- - **Upgrading 0.75.0 → 0.102.0**: [llms/upgrading-0.75.0-0.102.0.txt](llms/upgrading-0.75.0-0.102.0.txt) 44.8 KB
61
+ - **Upgrading 0.75.0 → 0.103.0**: [llms/upgrading-0.75.0-0.103.0.txt](llms/upgrading-0.75.0-0.103.0.txt) 46.3 KB
59
62
  - **Upgrading 0.61.0 → 0.74.0**: [llms/upgrading-0.61.0-0.74.0.txt](llms/upgrading-0.61.0-0.74.0.txt) 43.5 KB
60
63
  - **Upgrading 0.44.0 → 0.60.0**: [llms/upgrading-0.44.0-0.60.0.txt](llms/upgrading-0.44.0-0.60.0.txt) 43.9 KB
61
64
  - **Upgrading 0.37.0 → 0.37.0**: [llms/upgrading-0.37.0.txt](llms/upgrading-0.37.0.txt) 6.2 KB
@@ -69,6 +72,7 @@ Load the slice for each entrypoint your code imports — `import … from 'stitc
69
72
  - [Typed client](https://github.com/max-listov/stitchkit/blob/master/docs/guide/client.md): createClient/createHttpClient, the typed call surface, scoped clients, SSE
70
73
  - [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, a separate tool answer (withToolView)
71
74
  - [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
75
+ - [Agent composition](https://github.com/max-listov/stitchkit/blob/master/docs/guide/agent-composition.md): tool factories, authorized realtime control, shared React views and exact-run behavior checks
72
76
  - [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
73
77
  - [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
74
78
  - [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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stitchkit",
3
- "version": "0.102.0",
3
+ "version": "0.103.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",
@@ -221,6 +221,18 @@
221
221
  "./node": {
222
222
  "types": "./dist/entrypoints/node.d.ts",
223
223
  "import": "./dist/entrypoints/node.js"
224
+ },
225
+ "./agent-runtime/react": {
226
+ "types": "./dist/entrypoints/agent-runtime/react.d.ts",
227
+ "import": "./dist/entrypoints/agent-runtime/react.js"
228
+ },
229
+ "./agent-runtime/realtime": {
230
+ "types": "./dist/entrypoints/agent-runtime/realtime.d.ts",
231
+ "import": "./dist/entrypoints/agent-runtime/realtime.js"
232
+ },
233
+ "./agent-runtime/harness-tools": {
234
+ "types": "./dist/entrypoints/agent-runtime/harness-tools.d.ts",
235
+ "import": "./dist/entrypoints/agent-runtime/harness-tools.js"
224
236
  }
225
237
  },
226
238
  "publishConfig": {
@@ -1,103 +0,0 @@
1
- import {
2
- isRecord
3
- } from "./index-9jfdm5tg.js";
4
-
5
- // src/application/diagnostic-journal-contract.ts
6
- import { z } from "zod";
7
- var PositiveSafeIntegerSchema = z.number().int().positive().safe();
8
- var FileModeSchema = z.number().int().min(0).max(511);
9
- var DiagnosticJournalLimitsSchema2 = z.object({
10
- maxEventBytes: PositiveSafeIntegerSchema,
11
- maxPendingItems: PositiveSafeIntegerSchema,
12
- maxPendingBytes: PositiveSafeIntegerSchema,
13
- maxFileBytes: PositiveSafeIntegerSchema,
14
- maxFiles: PositiveSafeIntegerSchema
15
- }).strict().readonly();
16
- var DiagnosticJournalLockPolicySchema2 = z.enum(["refuse", "reclaim-stale"]);
17
- var DiagnosticJournalStateSchema2 = z.enum(["open", "draining", "closed", "failed"]);
18
- var DiagnosticJournalRefusalReasonSchema2 = z.enum([
19
- "closed",
20
- "failed",
21
- "invalid",
22
- "oversized",
23
- "item-capacity",
24
- "byte-capacity"
25
- ]);
26
- var DiagnosticJournalRefusalCountersSchema = z.object({
27
- closed: z.number().int().nonnegative(),
28
- failed: z.number().int().nonnegative(),
29
- invalid: z.number().int().nonnegative(),
30
- oversized: z.number().int().nonnegative(),
31
- "item-capacity": z.number().int().nonnegative(),
32
- "byte-capacity": z.number().int().nonnegative()
33
- }).strict().readonly();
34
- var DiagnosticJournalFailurePhaseSchema2 = z.enum(["write", "rotation", "close"]);
35
- var DiagnosticJournalStatusSchema2 = z.object({
36
- state: DiagnosticJournalStateSchema2,
37
- epoch: z.uuid(),
38
- limits: DiagnosticJournalLimitsSchema2,
39
- lock: z.object({
40
- policy: DiagnosticJournalLockPolicySchema2,
41
- reclaimedStale: z.boolean()
42
- }).strict().readonly(),
43
- received: z.number().int().nonnegative(),
44
- accepted: z.number().int().nonnegative(),
45
- refused: z.number().int().nonnegative(),
46
- refusals: DiagnosticJournalRefusalCountersSchema,
47
- written: z.number().int().nonnegative(),
48
- failedRecords: z.number().int().nonnegative(),
49
- pendingItems: z.number().int().nonnegative(),
50
- pendingBytes: z.number().int().nonnegative(),
51
- inFlight: z.boolean(),
52
- rotations: z.number().int().nonnegative(),
53
- rotationFailures: z.number().int().nonnegative(),
54
- partialTails: z.number().int().nonnegative(),
55
- currentFileBytes: z.number().int().nonnegative(),
56
- retainedFiles: z.number().int().nonnegative(),
57
- lastAcceptedSequence: z.number().int().positive().optional(),
58
- lastWrittenSequence: z.number().int().positive().optional(),
59
- lastSettledSequence: z.number().int().positive().optional(),
60
- lastFailure: z.object({
61
- phase: DiagnosticJournalFailurePhaseSchema2,
62
- sequence: z.number().int().positive().optional()
63
- }).strict().readonly().optional()
64
- }).strict().readonly();
65
- var DiagnosticJournalSubmitResultSchema2 = z.discriminatedUnion("outcome", [
66
- z.object({
67
- outcome: z.literal("accepted"),
68
- epoch: z.uuid(),
69
- sequence: z.number().int().positive()
70
- }).strict().readonly(),
71
- z.object({
72
- outcome: z.literal("refused"),
73
- reason: DiagnosticJournalRefusalReasonSchema2
74
- }).strict().readonly()
75
- ]);
76
- var DiagnosticJournalWaitResultSchema2 = z.object({
77
- outcome: z.enum(["settled", "timed-out", "cancelled"]),
78
- state: DiagnosticJournalStateSchema2,
79
- throughSequence: z.number().int().nonnegative(),
80
- settledSequence: z.number().int().nonnegative()
81
- }).strict().readonly();
82
- var DiagnosticJournalCloseResultSchema2 = z.object({
83
- outcome: z.enum(["closed", "timed-out", "cancelled"]),
84
- state: DiagnosticJournalStateSchema2,
85
- pendingItems: z.number().int().nonnegative()
86
- }).strict().readonly();
87
- var DiagnosticJournalFrameSchema2 = z.object({
88
- schemaVersion: z.literal(1),
89
- epoch: z.uuid(),
90
- sequence: z.number().int().positive(),
91
- event: z.json()
92
- }).strict().readonly();
93
- function parseDiagnosticJournalMode(mode) {
94
- return FileModeSchema.parse(mode ?? 384);
95
- }
96
- function readDiagnosticJournalLockDiagnosis2(error) {
97
- if (!isRecord(error))
98
- return;
99
- const diagnosis = error.journalLock;
100
- return isRecord(diagnosis) ? diagnosis : undefined;
101
- }
102
-
103
- export { DiagnosticJournalLimitsSchema2, DiagnosticJournalLockPolicySchema2, DiagnosticJournalStateSchema2, DiagnosticJournalRefusalReasonSchema2, DiagnosticJournalFailurePhaseSchema2, DiagnosticJournalStatusSchema2, DiagnosticJournalSubmitResultSchema2, DiagnosticJournalWaitResultSchema2, DiagnosticJournalCloseResultSchema2, DiagnosticJournalFrameSchema2, parseDiagnosticJournalMode, readDiagnosticJournalLockDiagnosis2 };