stitchkit 0.106.1 → 0.107.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 (96) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/darwin-native.cjs +16 -4
  3. package/dist/agent-runtime/deferred-tool-types.d.ts +6 -27
  4. package/dist/agent-runtime/deferred-tool-types.d.ts.map +1 -1
  5. package/dist/entrypoints/agent-runtime/browser.js +2 -3
  6. package/dist/entrypoints/agent-runtime/coding-tools.js +6 -8
  7. package/dist/entrypoints/agent-runtime/harness.js +7 -11
  8. package/dist/entrypoints/agent-runtime/realtime.js +2 -3
  9. package/dist/entrypoints/agent-runtime/sandbox.js +6 -8
  10. package/dist/entrypoints/agent-runtime.d.ts +2 -1
  11. package/dist/entrypoints/agent-runtime.d.ts.map +1 -1
  12. package/dist/entrypoints/agent-runtime.js +20 -23
  13. package/dist/entrypoints/application/diagnostic-journal.js +3 -3
  14. package/dist/entrypoints/application/directory-inbox.js +8 -9
  15. package/dist/entrypoints/application/grammy.js +3 -3
  16. package/dist/entrypoints/application.js +7 -8
  17. package/dist/entrypoints/cli/publish.js +10 -11
  18. package/dist/entrypoints/cli.js +12 -16
  19. package/dist/entrypoints/contract.js +1 -1
  20. package/dist/entrypoints/files/packaging.d.ts +1 -1
  21. package/dist/entrypoints/files/packaging.d.ts.map +1 -1
  22. package/dist/entrypoints/files/packaging.js +99 -47
  23. package/dist/entrypoints/files.js +16 -16
  24. package/dist/entrypoints/index.js +41 -41
  25. package/dist/entrypoints/node.js +27 -29
  26. package/dist/entrypoints/observability.js +10 -12
  27. package/dist/entrypoints/process.js +2 -2
  28. package/dist/entrypoints/react.js +3 -4
  29. package/dist/entrypoints/remote.js +8 -9
  30. package/dist/entrypoints/server.js +48 -51
  31. package/dist/entrypoints/telegram/html.js +3 -3
  32. package/dist/entrypoints/telegram/screens.js +5 -5
  33. package/dist/entrypoints/telegram.js +9 -10
  34. package/dist/entrypoints/testing.js +8 -11
  35. package/dist/entrypoints/tools/connections.js +11 -11
  36. package/dist/entrypoints/tools/invoker.js +5 -9
  37. package/dist/entrypoints/tools/mcp.js +8 -14
  38. package/dist/entrypoints/tools.js +19 -25
  39. package/dist/entrypoints/tracking.js +3 -3
  40. package/dist/files/native-packaging-layout.d.ts +6 -2
  41. package/dist/files/native-packaging-layout.d.ts.map +1 -1
  42. package/dist/files/native-packaging.d.ts +45 -10
  43. package/dist/files/native-packaging.d.ts.map +1 -1
  44. package/dist/{index-v5ee8ath.js → index-1h2zv8rx.js} +10 -40
  45. package/dist/index-2kbysk9s.js +42 -0
  46. package/dist/{index-wbhdzxar.js → index-2s6fpehp.js} +5 -5
  47. package/dist/{index-4vsby8n8.js → index-4f37d3bg.js} +1 -1
  48. package/dist/{index-ksfagmyz.js → index-4qh90tyw.js} +8 -8
  49. package/dist/{index-yvfk3y36.js → index-636mggad.js} +4 -3
  50. package/dist/{index-f199nfq5.js → index-6y9t2fwz.js} +7 -7
  51. package/dist/{index-azx12jgv.js → index-7r74re56.js} +1 -1
  52. package/dist/{index-w8etpm8j.js → index-9j2atjte.js} +1 -1
  53. package/dist/{index-dsnjzb62.js → index-bnf8s6v3.js} +1 -1
  54. package/dist/{index-pz3y6b6g.js → index-cx2nh595.js} +3 -3
  55. package/dist/{index-2k91mewf.js → index-dm2fv45z.js} +9 -9
  56. package/dist/{index-9bskshe3.js → index-dwf0gymy.js} +10 -10
  57. package/dist/{index-qaqbdm7s.js → index-h7qms8f9.js} +8 -8
  58. package/dist/{index-drs41arz.js → index-ktjmgq9p.js} +1 -1
  59. package/dist/{index-1ptj98e0.js → index-mbf4h8kp.js} +2 -2
  60. package/dist/{index-916yh4e2.js → index-mep4sb48.js} +14 -14
  61. package/dist/{index-wdy68sh6.js → index-njs9gvrh.js} +17 -17
  62. package/dist/{index-sj28htvf.js → index-pvh3z03x.js} +1 -1
  63. package/dist/{index-r393tnfp.js → index-q6crhe1n.js} +4 -4
  64. package/dist/{index-z23rfxhj.js → index-xmgjtkvr.js} +1 -1
  65. package/dist/{index-gr5g3xfw.js → index-yz8x0hbx.js} +1 -1
  66. package/dist/{index-gxm9rc97.js → index-zrtrjkbf.js} +1 -1
  67. package/dist/{index-1pwwan01.js → index-zsqt5q98.js} +5 -5
  68. package/dist/internal/darwin-binding-error.d.ts +9 -1
  69. package/dist/internal/darwin-binding-error.d.ts.map +1 -1
  70. package/dist/internal/darwin-binding.d.ts.map +1 -1
  71. package/dist/tools/internal/surface-projector.d.ts +0 -7
  72. package/dist/tools/internal/surface-projector.d.ts.map +1 -1
  73. package/dist/tools/runtime-tool-declaration.d.ts +11 -0
  74. package/dist/tools/runtime-tool-declaration.d.ts.map +1 -1
  75. package/dist/tools/runtime-tool.d.ts +2 -3
  76. package/dist/tools/runtime-tool.d.ts.map +1 -1
  77. package/llms/files-packaging.txt +10 -6
  78. package/llms/process.txt +57 -15
  79. package/llms/stitchkit.txt +3 -3
  80. package/llms/{upgrading-0.37.0-0.53.0.txt → upgrading-0.37.0-0.58.0.txt} +209 -3
  81. package/llms/{upgrading-0.55.0-0.68.0.txt → upgrading-0.59.0-0.71.0.txt} +149 -209
  82. package/llms/{upgrading-0.69.0-0.95.0.txt → upgrading-0.72.0-0.97.0.txt} +76 -149
  83. package/llms/{upgrading-0.96.0-0.106.0.txt → upgrading-0.98.0-0.107.0.txt} +56 -83
  84. package/llms/upgrading.txt +4 -4
  85. package/llms-full.txt +123 -31
  86. package/llms.txt +6 -6
  87. package/package.json +2 -1
  88. package/dist/{index-cazts87s.js → index-07dcf2yn.js} +3 -3
  89. package/dist/{index-n1nszyk0.js → index-7jvwrjqa.js} +3 -3
  90. package/dist/{index-cmzvhhtd.js → index-85qve8mq.js} +3 -3
  91. package/dist/{index-rpzewktb.js → index-fynr93w4.js} +3 -3
  92. package/dist/{index-37asdw3a.js → index-k7qdkh3n.js} +3 -3
  93. package/dist/{index-x7w1z6pf.js → index-q4hjtyye.js} +4 -4
  94. package/dist/{index-7n68nmc6.js → index-y3nemndz.js} +3 -3
  95. package/dist/{index-12zsej7b.js → index-y70v24cw.js} +3 -3
  96. package/dist/{index-pzb63z66.js → index-ykdcnq1f.js} +3 -3
@@ -1,14 +1,160 @@
1
- # Upgrading 0.55.0 → 0.68.0 — stitchkit docs slice
1
+ # Upgrading 0.59.0 → 0.71.0 — stitchkit docs slice
2
2
 
3
3
  > Generated from the `docs/` tree by `bun run gen:llms`. The index of all slices is
4
4
  > `llms.txt` in this package.
5
5
 
6
- Contains: Guide: Upgrading, 0.55.0 → 0.68.0 (docs/guide/upgrading.md)
6
+ Contains: Guide: Upgrading, 0.59.0 → 0.71.0 (docs/guide/upgrading.md)
7
7
 
8
8
  ==============================================================================
9
- # Guide: Upgrading, 0.55.0 → 0.68.0 (docs/guide/upgrading.md)
9
+ # Guide: Upgrading, 0.59.0 → 0.71.0 (docs/guide/upgrading.md)
10
10
  ==============================================================================
11
11
 
12
+ ## Released migration: 0.71.0
13
+
14
+ The Agent coding tools. Two of the three changes are visible to the compiler;
15
+ the third is the one to read carefully, because nothing will point at it.
16
+
17
+ ### If you implement `authorize`
18
+
19
+ The operation union gained `edit`, `list` and `glob` and lost `patch`. An
20
+ exhaustive matcher stops compiling and the compiler shows you every arm. **A
21
+ matcher with a default branch does not**, and that is the dangerous case:
22
+
23
+ ```ts
24
+ // before — and after this upgrade, silently wrong in both directions
25
+ if (request.operation === 'patch') return reviewPatch(request)
26
+ return true // now also authorizes edit, list and glob
27
+ // …or: return false // now also kills edit_file
28
+ ```
29
+
30
+ ```ts
31
+ // after
32
+ switch (request.operation) {
33
+ case 'edit': return reviewEdit(request) // the old `patch` payload, unchanged
34
+ case 'list':
35
+ case 'glob': return true // or your own policy
36
+ // …existing read / write / search / shell / artifact-read arms
37
+ }
38
+ ```
39
+
40
+ `write` gained `createsDirectories` — the workspace-relative directories the
41
+ call would create, outermost first, reported **before** anything is created. A
42
+ host that wants to refuse implicit directory creation now can.
43
+
44
+ ### If you call `apply_patch`
45
+
46
+ It is `edit_file`, and it is one call:
47
+
48
+ ```ts
49
+ // before
50
+ const read = await readFile({ path })
51
+ await applyPatch({ path, baseSha256: read.sha256, oldText, newText, dryRun: true })
52
+ await applyPatch({ path, baseSha256: read.sha256, oldText, newText, dryRun: false })
53
+
54
+ // after
55
+ await editFile({ path, oldText, newText })
56
+ ```
57
+
58
+ `expectedSha256` is optional and still refuses a stale base with `CONFLICT` when
59
+ you pass it; `edit_file` returns the resulting `sha256`, so a chain of edits
60
+ never needs to re-read. If you key an approval policy or a UI label on the string
61
+ `apply_patch`, update the key — nothing will fail loudly.
62
+
63
+ ### If you match on `INTERNAL_SERVER_ERROR` from a coding tool
64
+
65
+ Ordinary outcomes no longer arrive that way. A missing file is `NOT_FOUND`, an
66
+ existing file without `overwrite` is `CONFLICT`, an ambiguous snippet is
67
+ `CONFLICT` with the occurrence count, a path outside the root is `FORBIDDEN`.
68
+ Code that treated any coding-tool failure as an internal fault will now see
69
+ codes it did not before; code that showed the model an empty error now has a
70
+ sentence and a `hint` to show it. Host-level causes are unchanged and still
71
+ scrubbed.
72
+
73
+ ### If you write files into new directories
74
+
75
+ Nothing to change: `write_file` creates missing parents inside the root. Read
76
+ `createdDirectories` in the result if you want to notice a typo — a path that
77
+ was a failure before is now a successful write into a new tree.
78
+
79
+ ### If you want a step to know its context budget
80
+
81
+ Opt in by reading it; nothing is injected for you:
82
+
83
+ ```ts
84
+ loop: {
85
+ prepareStep: ({ contextUsage }) => {
86
+ const used = contextUsage?.usedTokens
87
+ if (used?.provenance === 'unavailable') return {} // no step has landed yet
88
+ const fraction = (used?.value ?? 0) / (contextUsage?.contextWindow ?? 1)
89
+ // …render it wherever you put it
90
+ return {}
91
+ },
92
+ }
93
+ ```
94
+
95
+ Put it at the **tail** of the conversation rather than in the system
96
+ instructions unless you have a reason: changing the system prompt on every step
97
+ invalidates the provider's prefix cache for the whole conversation, and on a long
98
+ run that is a multiple of the input cost.
99
+
100
+ ## Released migration: 0.70.0
101
+
102
+ ### Descriptor-backed Agent filesystem containment
103
+
104
+ Built-in coding file/search tools and `createAgentHarnessFileResources` now require a runtime
105
+ that can address an opened directory descriptor: Linux `/proc/self/fd`, or the packaged macOS
106
+ Node-API backend added in 0.70.1. This is what keeps a mutable parent rename or outside-symlink replacement from changing
107
+ the authorized target between validation and the actual effect.
108
+
109
+ No call-site change is needed on those platforms. The 0.70.0 notes incorrectly inferred macOS and
110
+ FreeBSD support from `/dev/fd`; macOS is restored by 0.70.1 and FreeBSD remains unsupported. On
111
+ Windows or another platform without that
112
+ boundary, move the built-in filesystem operations to a supported worker or replace them with
113
+ application-owned tools backed by an equivalent native handle API. They fail closed rather than
114
+ falling back to path spelling. `run_command` remains separately available under its explicit
115
+ executable alias and authorization policy; this change does not claim an executable sandbox.
116
+
117
+ ## Released migration: 0.69.0
118
+
119
+ ### Direct coding-tool operation names
120
+
121
+ `createAgentCodingTools` no longer prefixes durable operation identity with `coding_`, and the
122
+ unguarded exact-string edit tool is gone. Update approval maps, presenters and tests together:
123
+
124
+ ```ts
125
+ // before
126
+ { coding_read_file: 'approved', coding_search: 'approved', coding_patch_file: 'user-approval' }
127
+
128
+ // after
129
+ { read_file: 'approved', search_files: 'approved', apply_patch: 'user-approval' }
130
+ ```
131
+
132
+ The full mapping is `coding_read_file → read_file`, `coding_write_file → write_file`,
133
+ `coding_search → search_files`, `coding_patch_file → apply_patch`, `coding_shell → run_command`,
134
+ `coding_read_artifact → read_output` and `harness_read_resource → read_resource`. Replace
135
+ `coding_edit_file` with `read_file` followed by guarded `apply_patch`; `read_file` now returns the
136
+ required SHA-256. If the host declares no executable aliases, expect `run_command` to be absent.
137
+
138
+ ### Durable Agent approval message variants
139
+
140
+ If a renderer, store adapter or export pipeline exhaustively switches over
141
+ `AgentMessage.role`, add the `tool` branch. If it switches over
142
+ `AgentMessagePart.type`, add `tool-approval-request` and `tool-approval-response`.
143
+ They are durable provider-continuation evidence: preserve them in storage and provider history;
144
+ a UI may render them as approval state or intentionally omit their visual row.
145
+
146
+ ```ts
147
+ // before
148
+ const unreachable: never = message.role
149
+
150
+ // after
151
+ if (message.role === 'tool') renderToolContinuation(message.parts)
152
+ else renderExistingRole(message)
153
+ ```
154
+
155
+ No data migration is needed. The schema still accepts all earlier records, and applications that
156
+ do not exhaustively branch over these unions compile unchanged.
157
+
12
158
  ## Released migration: 0.68.0
13
159
 
14
160
  ### Make Unix transport selection explicit outside Bun
@@ -994,209 +1140,3 @@ createAgentRuntimeStore({
994
1140
  `runAgentStoreConformance()` against the migrated adapter before switching production traffic.
995
1141
  If an application implements `AgentRuntimeStore` directly, its duplicate result must also include
996
1142
  the canonical `run` and the retained `assistant` for a terminal run.
997
-
998
- ## Released migration: 0.58.0
999
-
1000
- ### The default history projection rejects invalid chronology
1001
-
1002
- `projectAgentHistory` no longer forwards records a provider contract cannot
1003
- accept. A completed assistant record before the first user message, and an
1004
- assistant record whose tool calls have no matching results, are omitted with an
1005
- inspectable decision instead of being sent upstream:
1006
-
1007
- ```ts
1008
- // before — a leading assistant record was forwarded as-is
1009
- projectAgentHistory(messages)
1010
- // after — opt in explicitly, and only where the provider contract permits it
1011
- projectAgentHistory(messages, { leadingAssistant: 'allow' })
1012
- ```
1013
-
1014
- Two consequences the changelog does not spell out. First, the projection can now
1015
- return **fewer** messages than the history holds, so any assertion or metric
1016
- that compared projected length against stored length will move; read the
1017
- detailed projection instead — it reports what was omitted and why, which is the
1018
- supported way to see the difference. Second, the omission is silent to the
1019
- provider but not to you: if a conversation suddenly loses its leading context,
1020
- the decision record is where that shows up, not the transcript.
1021
-
1022
- ### Operator events redact `internalCause` by default
1023
-
1024
- Raw provider and tool failures no longer travel in operator events unless the
1025
- sink asks for them:
1026
-
1027
- ```ts
1028
- // before — internalCause was present
1029
- createAgentObservability({ write })
1030
- // after — an explicit operator-only opt-in
1031
- createAgentObservability({ write, includeInternalCause: true })
1032
- ```
1033
-
1034
- The consequence to check before upgrading: any dashboard, alert or log
1035
- processor keyed on `internalCause` goes blind the moment you upgrade, and it
1036
- goes blind quietly — the field is absent, not empty. Set the flag on the
1037
- operator sink you own. Product delivery stays redacted regardless of the flag;
1038
- this option cannot widen what reaches a user.
1039
-
1040
- ## Released migration: 0.57.0
1041
-
1042
- ### Duplicate admission results carry the complete identity
1043
-
1044
- Custom `AgentRuntimeStore` adapters must persist and return the input and
1045
- assistant identities associated with an idempotency key:
1046
-
1047
- ```ts
1048
- // before
1049
- return { outcome: 'duplicate', runId, snapshot }
1050
-
1051
- // after
1052
- return { outcome: 'duplicate', input, inputMessageId, runId, assistantMessageId, snapshot }
1053
- ```
1054
-
1055
- Prefer replacing the custom aggregate reducer with `createAgentRuntimeStore()`;
1056
- its admission record and transaction driver implement this contract
1057
- automatically. Historical note: 0.59.0 reshaped this driver again, so an adapter
1058
- crossing both versions should read that section first and migrate once.
1059
-
1060
- ### `AgentRuntimeEvent` adds a post-commit `admission` variant
1061
-
1062
- Add it to any exhaustive publisher switch. Its `assistant` is either the pending
1063
- placeholder for a new assignment or the canonical persisted assistant for a
1064
- duplicate:
1065
-
1066
- ```ts
1067
- case 'admission':
1068
- await persistProductProjection(event.input, event.run, event.assistant)
1069
- break
1070
- ```
1071
-
1072
- The consequence for an exhaustive switch written without a `default` branch is a
1073
- compile error, which is the point. The consequence for a switch that *has* a
1074
- `default` is worse and silent: post-commit admissions fall into it and are
1075
- projected as an unknown event. Grep for publisher switches before upgrading.
1076
-
1077
- ## Released migration: 0.56.0
1078
-
1079
- ### Surface manifests are version 2
1080
-
1081
- `operation.tools` could not describe a role-selected MCP surface, a different
1082
- Agent or CLI selection, or an advertised `extend` schema, so projections moved
1083
- out of the canonical operation:
1084
-
1085
- ```ts
1086
- // before
1087
- manifest.operations[0].tools.MCP
1088
- // after
1089
- manifest.toolSurfaces.find((s) => s.transport === 'MCP' && s.surface === null)?.tools
1090
-
1091
- // before
1092
- buildSurfaceManifest({ mcpSurfaces: { admin: { services, extend } } })
1093
- // after
1094
- buildSurfaceManifest({ mcpSurfaces: { admin: { services } }, mcpPreparation: { extend } })
1095
- ```
1096
-
1097
- A committed snapshot is regenerated once, deliberately: `manifestVersion` is
1098
- `2`, and `ConformanceTransport` gained `REALTIME`, so any exhaustive
1099
- `Record<ConformanceTransport, …>` must handle it.
1100
-
1101
- ### `FILE_*` codes joined the error registry
1102
-
1103
- `StitchErrorCode` gained `FILE_INVALID_PATH`, `FILE_OUTSIDE_ROOT`,
1104
- `FILE_NOT_FOUND`, `FILE_NOT_REGULAR`, `FILE_INSPECTION_REJECTED`,
1105
- `FILE_TOO_LARGE` and `FILE_EXISTS`. Only exhaustive maps break:
1106
-
1107
- ```ts
1108
- // before — compiled while the registry had no file codes
1109
- const copy: Record<StitchErrorCode, string> = { …, RATE_LIMITED: '…' }
1110
- // after — add the seven managed-file codes (or use Partial<Record<…>>)
1111
- ```
1112
-
1113
- Unexpected IO stays scrubbed as `INTERNAL_SERVER_ERROR`: the new codes are the
1114
- caller-safe ones only.
1115
-
1116
- ### `ScopedAuthHook` is nominal
1117
-
1118
- A hand-written function shaped like an auth hook is no longer assignable —
1119
- identity now comes from the factory, so scope ownership and the inferred
1120
- context cannot drift apart:
1121
-
1122
- ```ts
1123
- // before — a structural stand-in
1124
- const auth: ScopedAuthHook<Scopes> = async (ctx, endpoint) => { … }
1125
- // after — create it, then compose domains
1126
- const auth = createAuthHook({ resolve, rules })
1127
- const composed = composeAuthHooks({ hooks: [auth, billingAuth], defaultScope: 'public' })
1128
- ```
1129
-
1130
- ### Managed-file inspectors also run on reads
1131
-
1132
- An inspector is no longer write-only, and it has a finite default deadline
1133
- (15 s). Make it read-aware and idempotent — a read carries no
1134
- `declaredMediaType`:
1135
-
1136
- ```ts
1137
- // before
1138
- inspect: ({ declaredMediaType }) => inspectDeclaredType(declaredMediaType!)
1139
- // after
1140
- inspect: ({ prefix, declaredMediaType, signal }) =>
1141
- inspectBytes(prefix, { declaredMediaType, signal })
1142
- ```
1143
-
1144
- Set `inspectionTimeoutMs` explicitly when 15 seconds is the wrong budget.
1145
-
1146
- ### Direct async-operation binding needs a wire-stable ID
1147
-
1148
- A direct binding reuses the start output as the follow-up wire input, so the ID
1149
- schema must parse to itself (`z.input` equals `z.output`, no transform,
1150
- coercion, default or overwrite). Anything else is parsed twice:
1151
-
1152
- ```ts
1153
- // before — a transform silently ran on start and again on every follow-up
1154
- defineAsyncOperationContract({ binding: 'direct', id: z.string().transform(Number) })
1155
- // after — keep the wire shape, adapt explicitly
1156
- defineAsyncOperationContract({
1157
- binding: 'adapted',
1158
- id,
1159
- adapters: { idFromStart, inputFor },
1160
- })
1161
- ```
1162
-
1163
- ## Released migration: 0.55.0
1164
-
1165
- ### Peer-free `implementRemote`
1166
-
1167
- `implementRemote` now has one canonical, optional-peer-free owner. This keeps
1168
- MCP SDK and AI SDK modules out of CLI bundles that only proxy HTTP calls:
1169
-
1170
- ```ts
1171
- // before
1172
- import { implementRemote } from 'stitchkit/tools'
1173
- // after
1174
- import { implementRemote } from 'stitchkit/remote'
1175
- ```
1176
-
1177
- ### Managed file boundary and strict auth returns
1178
-
1179
- Create one boundary during application bootstrap and pass the capability, never
1180
- a per-call directory or host path:
1181
-
1182
- ```ts
1183
- import { createManagedFileBoundary } from 'stitchkit/files'
1184
-
1185
- const files = await createManagedFileBoundary({ root: '/srv/app-files' })
1186
-
1187
- // before
1188
- defineDownloadTool({ defaultDir: '/srv/app-files', resolveUrl, ...common })
1189
- defineUploadTool({ upload: (path) => provider.uploadFile(path), ...common })
1190
- defineViewFileTool({ baseDir: '/srv/app-files', ...common })
1191
-
1192
- // after
1193
- defineDownloadTool({ files, resolveUrl, ...common })
1194
- defineUploadTool({ files, upload: ({ bytes }) => provider.upload(bytes), ...common })
1195
- defineViewFileTool({ files, ...common })
1196
- ```
1197
-
1198
- Downloaded `path` is now relative to the boundary and MIME metadata is named
1199
- `mediaType`. Update raw `mountDownload`/`mountUpload`/`mountViewFile` configs the
1200
- same way. Auth predicates must explicitly return `true`, `false`, or a plain
1201
- object of context fields; replace accidental `undefined` fallthroughs with the
1202
- intended boolean.
@@ -1,14 +1,87 @@
1
- # Upgrading 0.69.0 → 0.95.0 — stitchkit docs slice
1
+ # Upgrading 0.72.0 → 0.97.0 — stitchkit docs slice
2
2
 
3
3
  > Generated from the `docs/` tree by `bun run gen:llms`. The index of all slices is
4
4
  > `llms.txt` in this package.
5
5
 
6
- Contains: Guide: Upgrading, 0.69.0 → 0.95.0 (docs/guide/upgrading.md)
6
+ Contains: Guide: Upgrading, 0.72.0 → 0.97.0 (docs/guide/upgrading.md)
7
7
 
8
8
  ==============================================================================
9
- # Guide: Upgrading, 0.69.0 → 0.95.0 (docs/guide/upgrading.md)
9
+ # Guide: Upgrading, 0.72.0 → 0.97.0 (docs/guide/upgrading.md)
10
10
  ==============================================================================
11
11
 
12
+ ## Released migration: 0.97.0
13
+
14
+ ### schedule delivery
15
+
16
+ **Who must act:** consumers of `createAgentScheduleService`, exhaustive switches on
17
+ `AgentSchedule.state`, and operators opening existing agent-runtime SQLite stores.
18
+
19
+ - Stop old scheduler processes and back up SQLite before startup. The store migrates
20
+ transactionally to v4; old binaries cannot open it. Rollback uses the backup.
21
+ - Handle `failed` as a terminal schedule state. To refuse future delivery (including
22
+ recurring delivery), return `{ status: 'terminal', reason: 'destination closed' }`.
23
+ The occurrence remains unadvanced; `schedule/failed` carries `terminal: true`.
24
+ - A throw or `{ status: 'retry', reason: 'temporarily unavailable' }` retries the same
25
+ key after 1, 2, 4, 8, 16, 32, then 60 seconds. `nextAt` remains the original due time;
26
+ `retryAt`, `attempts` and `lastError` expose retry diagnostics. Success clears them.
27
+ - Resolve `void` only after durable consumer admission. Honor the supplied `signal`:
28
+ dispatch has a 30-second deadline and a 60-second lease. Durable deduplication by
29
+ `idempotencyKey` is required even after abort or crash; do not implement sleeps in dispatch.
30
+ - Stale/cancelled attempts emit no `schedule/fired` or `schedule/late`. Observe the
31
+ cancellation event instead of relying on a synthetic cancelled firing.
32
+
33
+ ```ts
34
+ // before
35
+ async function dispatch(request) {
36
+ if (await destinationClosed(request.conversationId)) throw new Error('closed')
37
+ await admit(request)
38
+ }
39
+ // after: use this callback as createAgentScheduleService({ dispatch, ... })
40
+ async function dispatch(request) {
41
+ if (await destinationClosed(request.conversationId)) {
42
+ return { status: 'terminal', reason: 'destination closed' }
43
+ }
44
+ await admit({ ...request, signal: request.signal }) // durably deduplicates idempotencyKey
45
+ }
46
+ ```
47
+
48
+ ## Released migration: 0.96.0
49
+
50
+ ### resource-context-admission
51
+
52
+ One breaking change in `stitchkit/application`: `ManagedResourceContext` gains a
53
+ required `admission`. Every context the kernel hands a resource already carries
54
+ it; only a context built by hand needs it.
55
+
56
+ 1. **Give a hand-built resource context an `admission`.** **Who must act:** a
57
+ project whose tests call a resource's phase directly with a context object
58
+ they wrote themselves (`resource.close?.({ applicationId, signal, … })`).
59
+ The type checker names each one:
60
+
61
+ ```ts
62
+ // before
63
+ await resource.close?.({ applicationId: 'test', signal, now, reportHealth, use })
64
+ // after
65
+ await resource.close?.({
66
+ applicationId: 'test',
67
+ signal,
68
+ now,
69
+ reportHealth,
70
+ use,
71
+ admission: { acquire: () => null, acquireWhenAccepting: () => new Promise(() => {}) },
72
+ })
73
+ ```
74
+
75
+ A test that needs real admission starts the resource inside
76
+ `createApplication` instead.
77
+
78
+ 2. **Nothing to do for grammY polling, but know what changed.** **Who must
79
+ act:** nobody. `grammyPollingResource` now admits updates by batch: it does
80
+ not fetch while the application is not accepting, and finishes the batch in
81
+ hand before `bot.stop()`. A project that wrote its own `getUpdates`
82
+ transformer for this (waiting on `app.admission` before returning a batch)
83
+ deletes it; keeping both waits twice and is harmless.
84
+
12
85
  ## Released migration: 0.95.0
13
86
 
14
87
  One breaking change in `stitchkit/application`: the process lifecycle ledger
@@ -1003,149 +1076,3 @@ const snapshot: CreditWindowSnapshot = { state: 'open', capacityBytes: 100, /*
1003
1076
  // after
1004
1077
  const snapshot: CreditWindowSnapshot = { state: 'open', capacityBytes: 100, /* … */ waiting: 0 }
1005
1078
  ```
1006
-
1007
- ## Released migration: 0.71.0
1008
-
1009
- The Agent coding tools. Two of the three changes are visible to the compiler;
1010
- the third is the one to read carefully, because nothing will point at it.
1011
-
1012
- ### If you implement `authorize`
1013
-
1014
- The operation union gained `edit`, `list` and `glob` and lost `patch`. An
1015
- exhaustive matcher stops compiling and the compiler shows you every arm. **A
1016
- matcher with a default branch does not**, and that is the dangerous case:
1017
-
1018
- ```ts
1019
- // before — and after this upgrade, silently wrong in both directions
1020
- if (request.operation === 'patch') return reviewPatch(request)
1021
- return true // now also authorizes edit, list and glob
1022
- // …or: return false // now also kills edit_file
1023
- ```
1024
-
1025
- ```ts
1026
- // after
1027
- switch (request.operation) {
1028
- case 'edit': return reviewEdit(request) // the old `patch` payload, unchanged
1029
- case 'list':
1030
- case 'glob': return true // or your own policy
1031
- // …existing read / write / search / shell / artifact-read arms
1032
- }
1033
- ```
1034
-
1035
- `write` gained `createsDirectories` — the workspace-relative directories the
1036
- call would create, outermost first, reported **before** anything is created. A
1037
- host that wants to refuse implicit directory creation now can.
1038
-
1039
- ### If you call `apply_patch`
1040
-
1041
- It is `edit_file`, and it is one call:
1042
-
1043
- ```ts
1044
- // before
1045
- const read = await readFile({ path })
1046
- await applyPatch({ path, baseSha256: read.sha256, oldText, newText, dryRun: true })
1047
- await applyPatch({ path, baseSha256: read.sha256, oldText, newText, dryRun: false })
1048
-
1049
- // after
1050
- await editFile({ path, oldText, newText })
1051
- ```
1052
-
1053
- `expectedSha256` is optional and still refuses a stale base with `CONFLICT` when
1054
- you pass it; `edit_file` returns the resulting `sha256`, so a chain of edits
1055
- never needs to re-read. If you key an approval policy or a UI label on the string
1056
- `apply_patch`, update the key — nothing will fail loudly.
1057
-
1058
- ### If you match on `INTERNAL_SERVER_ERROR` from a coding tool
1059
-
1060
- Ordinary outcomes no longer arrive that way. A missing file is `NOT_FOUND`, an
1061
- existing file without `overwrite` is `CONFLICT`, an ambiguous snippet is
1062
- `CONFLICT` with the occurrence count, a path outside the root is `FORBIDDEN`.
1063
- Code that treated any coding-tool failure as an internal fault will now see
1064
- codes it did not before; code that showed the model an empty error now has a
1065
- sentence and a `hint` to show it. Host-level causes are unchanged and still
1066
- scrubbed.
1067
-
1068
- ### If you write files into new directories
1069
-
1070
- Nothing to change: `write_file` creates missing parents inside the root. Read
1071
- `createdDirectories` in the result if you want to notice a typo — a path that
1072
- was a failure before is now a successful write into a new tree.
1073
-
1074
- ### If you want a step to know its context budget
1075
-
1076
- Opt in by reading it; nothing is injected for you:
1077
-
1078
- ```ts
1079
- loop: {
1080
- prepareStep: ({ contextUsage }) => {
1081
- const used = contextUsage?.usedTokens
1082
- if (used?.provenance === 'unavailable') return {} // no step has landed yet
1083
- const fraction = (used?.value ?? 0) / (contextUsage?.contextWindow ?? 1)
1084
- // …render it wherever you put it
1085
- return {}
1086
- },
1087
- }
1088
- ```
1089
-
1090
- Put it at the **tail** of the conversation rather than in the system
1091
- instructions unless you have a reason: changing the system prompt on every step
1092
- invalidates the provider's prefix cache for the whole conversation, and on a long
1093
- run that is a multiple of the input cost.
1094
-
1095
- ## Released migration: 0.70.0
1096
-
1097
- ### Descriptor-backed Agent filesystem containment
1098
-
1099
- Built-in coding file/search tools and `createAgentHarnessFileResources` now require a runtime
1100
- that can address an opened directory descriptor: Linux `/proc/self/fd`, or the packaged macOS
1101
- Node-API backend added in 0.70.1. This is what keeps a mutable parent rename or outside-symlink replacement from changing
1102
- the authorized target between validation and the actual effect.
1103
-
1104
- No call-site change is needed on those platforms. The 0.70.0 notes incorrectly inferred macOS and
1105
- FreeBSD support from `/dev/fd`; macOS is restored by 0.70.1 and FreeBSD remains unsupported. On
1106
- Windows or another platform without that
1107
- boundary, move the built-in filesystem operations to a supported worker or replace them with
1108
- application-owned tools backed by an equivalent native handle API. They fail closed rather than
1109
- falling back to path spelling. `run_command` remains separately available under its explicit
1110
- executable alias and authorization policy; this change does not claim an executable sandbox.
1111
-
1112
- ## Released migration: 0.69.0
1113
-
1114
- ### Direct coding-tool operation names
1115
-
1116
- `createAgentCodingTools` no longer prefixes durable operation identity with `coding_`, and the
1117
- unguarded exact-string edit tool is gone. Update approval maps, presenters and tests together:
1118
-
1119
- ```ts
1120
- // before
1121
- { coding_read_file: 'approved', coding_search: 'approved', coding_patch_file: 'user-approval' }
1122
-
1123
- // after
1124
- { read_file: 'approved', search_files: 'approved', apply_patch: 'user-approval' }
1125
- ```
1126
-
1127
- The full mapping is `coding_read_file → read_file`, `coding_write_file → write_file`,
1128
- `coding_search → search_files`, `coding_patch_file → apply_patch`, `coding_shell → run_command`,
1129
- `coding_read_artifact → read_output` and `harness_read_resource → read_resource`. Replace
1130
- `coding_edit_file` with `read_file` followed by guarded `apply_patch`; `read_file` now returns the
1131
- required SHA-256. If the host declares no executable aliases, expect `run_command` to be absent.
1132
-
1133
- ### Durable Agent approval message variants
1134
-
1135
- If a renderer, store adapter or export pipeline exhaustively switches over
1136
- `AgentMessage.role`, add the `tool` branch. If it switches over
1137
- `AgentMessagePart.type`, add `tool-approval-request` and `tool-approval-response`.
1138
- They are durable provider-continuation evidence: preserve them in storage and provider history;
1139
- a UI may render them as approval state or intentionally omit their visual row.
1140
-
1141
- ```ts
1142
- // before
1143
- const unreachable: never = message.role
1144
-
1145
- // after
1146
- if (message.role === 'tool') renderToolContinuation(message.parts)
1147
- else renderExistingRole(message)
1148
- ```
1149
-
1150
- No data migration is needed. The schema still accepts all earlier records, and applications that
1151
- do not exhaustively branch over these unions compile unchanged.