stitchkit 0.92.0 → 0.94.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 (793) hide show
  1. package/CHANGELOG.md +191 -0
  2. package/README.md +5 -2
  3. package/dist/agent-runtime/children-control.d.ts +6 -0
  4. package/dist/agent-runtime/children-control.d.ts.map +1 -0
  5. package/dist/agent-runtime/children-spawn.d.ts +6 -0
  6. package/dist/agent-runtime/children-spawn.d.ts.map +1 -0
  7. package/dist/agent-runtime/children-state.d.ts +46 -0
  8. package/dist/agent-runtime/children-state.d.ts.map +1 -0
  9. package/dist/agent-runtime/children-usage.d.ts +8 -0
  10. package/dist/agent-runtime/children-usage.d.ts.map +1 -0
  11. package/dist/agent-runtime/children.d.ts +11 -14
  12. package/dist/agent-runtime/children.d.ts.map +1 -1
  13. package/dist/agent-runtime/coding-tool-contract.d.ts +2 -1
  14. package/dist/agent-runtime/coding-tool-contract.d.ts.map +1 -1
  15. package/dist/agent-runtime/deferred-tool-types.d.ts +2 -2
  16. package/dist/agent-runtime/deferred-tool-types.d.ts.map +1 -1
  17. package/dist/agent-runtime/events.d.ts +1 -1
  18. package/dist/agent-runtime/events.d.ts.map +1 -1
  19. package/dist/agent-runtime/managed-tools.d.ts +1 -1
  20. package/dist/agent-runtime/managed-tools.d.ts.map +1 -1
  21. package/dist/agent-runtime/observability.d.ts +1 -1
  22. package/dist/agent-runtime/observability.d.ts.map +1 -1
  23. package/dist/{agent-runtime-openrouter.d.ts → agent-runtime/openrouter.d.ts} +3 -3
  24. package/dist/agent-runtime/openrouter.d.ts.map +1 -0
  25. package/dist/agent-runtime/projections.d.ts +1 -1
  26. package/dist/agent-runtime/projections.d.ts.map +1 -1
  27. package/dist/agent-runtime/run-acquisition.d.ts +17 -0
  28. package/dist/agent-runtime/run-acquisition.d.ts.map +1 -0
  29. package/dist/agent-runtime/run-execution-state.d.ts +133 -0
  30. package/dist/agent-runtime/run-execution-state.d.ts.map +1 -0
  31. package/dist/agent-runtime/run-execution.d.ts +17 -33
  32. package/dist/agent-runtime/run-execution.d.ts.map +1 -1
  33. package/dist/agent-runtime/run-failure.d.ts +18 -0
  34. package/dist/agent-runtime/run-failure.d.ts.map +1 -0
  35. package/dist/agent-runtime/run-model-attempts.d.ts +6 -0
  36. package/dist/agent-runtime/run-model-attempts.d.ts.map +1 -0
  37. package/dist/agent-runtime/run-prompt-history.d.ts +58 -0
  38. package/dist/agent-runtime/run-prompt-history.d.ts.map +1 -0
  39. package/dist/agent-runtime/run-provider-ledger.d.ts +26 -0
  40. package/dist/agent-runtime/run-provider-ledger.d.ts.map +1 -0
  41. package/dist/agent-runtime/run-stream-parts.d.ts +17 -0
  42. package/dist/agent-runtime/run-stream-parts.d.ts.map +1 -0
  43. package/dist/agent-runtime/run-terminal.d.ts +11 -0
  44. package/dist/agent-runtime/run-terminal.d.ts.map +1 -0
  45. package/dist/agent-runtime/run-turn-preparation.d.ts +22 -0
  46. package/dist/agent-runtime/run-turn-preparation.d.ts.map +1 -0
  47. package/dist/agent-runtime/runtime-admission-gate.d.ts +29 -0
  48. package/dist/agent-runtime/runtime-admission-gate.d.ts.map +1 -0
  49. package/dist/agent-runtime/runtime-control.d.ts +9 -0
  50. package/dist/agent-runtime/runtime-control.d.ts.map +1 -0
  51. package/dist/agent-runtime/runtime-recovery.d.ts +10 -0
  52. package/dist/agent-runtime/runtime-recovery.d.ts.map +1 -0
  53. package/dist/agent-runtime/runtime-state.d.ts +36 -0
  54. package/dist/agent-runtime/runtime-state.d.ts.map +1 -0
  55. package/dist/agent-runtime/runtime-submit.d.ts +5 -0
  56. package/dist/agent-runtime/runtime-submit.d.ts.map +1 -0
  57. package/dist/agent-runtime/runtime.d.ts +9 -4
  58. package/dist/agent-runtime/runtime.d.ts.map +1 -1
  59. package/dist/{agent-runtime-sqlite-bun.d.ts → agent-runtime/sqlite-bun.d.ts} +5 -4
  60. package/dist/agent-runtime/sqlite-bun.d.ts.map +1 -0
  61. package/dist/agent-runtime/sqlite-events.d.ts +5 -0
  62. package/dist/agent-runtime/sqlite-events.d.ts.map +1 -0
  63. package/dist/agent-runtime/sqlite-history.d.ts +7 -0
  64. package/dist/agent-runtime/sqlite-history.d.ts.map +1 -0
  65. package/dist/agent-runtime/sqlite-ledger.d.ts +7 -0
  66. package/dist/agent-runtime/sqlite-ledger.d.ts.map +1 -0
  67. package/dist/{agent-runtime-sqlite-node.d.ts → agent-runtime/sqlite-node.d.ts} +5 -4
  68. package/dist/agent-runtime/sqlite-node.d.ts.map +1 -0
  69. package/dist/agent-runtime/sqlite-reads.d.ts +14 -0
  70. package/dist/agent-runtime/sqlite-reads.d.ts.map +1 -0
  71. package/dist/agent-runtime/sqlite-rows.d.ts +178 -0
  72. package/dist/agent-runtime/sqlite-rows.d.ts.map +1 -0
  73. package/dist/agent-runtime/sqlite-schema.d.ts +7 -0
  74. package/dist/agent-runtime/sqlite-schema.d.ts.map +1 -0
  75. package/dist/agent-runtime/sqlite-transactions.d.ts +25 -0
  76. package/dist/agent-runtime/sqlite-transactions.d.ts.map +1 -0
  77. package/dist/agent-runtime/sqlite.d.ts +10 -6
  78. package/dist/agent-runtime/sqlite.d.ts.map +1 -1
  79. package/dist/agent-runtime/store-archive.d.ts +16 -0
  80. package/dist/agent-runtime/store-archive.d.ts.map +1 -0
  81. package/dist/{testing/agent-store-conformance.d.ts → agent-runtime/store-conformance.d.ts} +2 -2
  82. package/dist/agent-runtime/store-conformance.d.ts.map +1 -0
  83. package/dist/agent-runtime/store-create.d.ts +11 -0
  84. package/dist/agent-runtime/store-create.d.ts.map +1 -0
  85. package/dist/agent-runtime/{store-driver.d.ts → store-driver-contract.d.ts} +7 -7
  86. package/dist/agent-runtime/store-driver-contract.d.ts.map +1 -0
  87. package/dist/agent-runtime/store-events.d.ts +7 -89
  88. package/dist/agent-runtime/store-events.d.ts.map +1 -1
  89. package/dist/agent-runtime/store-memory.d.ts +4 -0
  90. package/dist/agent-runtime/store-memory.d.ts.map +1 -0
  91. package/dist/agent-runtime/store-mutate.d.ts +13 -0
  92. package/dist/agent-runtime/store-mutate.d.ts.map +1 -0
  93. package/dist/agent-runtime/store-purge.d.ts +1 -1
  94. package/dist/agent-runtime/store-purge.d.ts.map +1 -1
  95. package/dist/agent-runtime/store-reads.d.ts +29 -0
  96. package/dist/agent-runtime/store-reads.d.ts.map +1 -0
  97. package/dist/agent-runtime/store-reduce-history.d.ts +10 -0
  98. package/dist/agent-runtime/store-reduce-history.d.ts.map +1 -0
  99. package/dist/agent-runtime/store-reduce-run.d.ts +14 -0
  100. package/dist/agent-runtime/store-reduce-run.d.ts.map +1 -0
  101. package/dist/agent-runtime/store-reduce-shared.d.ts +76 -0
  102. package/dist/agent-runtime/store-reduce-shared.d.ts.map +1 -0
  103. package/dist/agent-runtime/store-reduce-terminal.d.ts +6 -0
  104. package/dist/agent-runtime/store-reduce-terminal.d.ts.map +1 -0
  105. package/dist/agent-runtime/store-reducer.d.ts +24 -0
  106. package/dist/agent-runtime/store-reducer.d.ts.map +1 -0
  107. package/dist/agent-runtime/store-snapshot.d.ts +19 -0
  108. package/dist/agent-runtime/store-snapshot.d.ts.map +1 -0
  109. package/dist/agent-runtime/store.d.ts +1 -1
  110. package/dist/agent-runtime/store.d.ts.map +1 -1
  111. package/dist/application/admission.d.ts +1 -1
  112. package/dist/application/admission.d.ts.map +1 -1
  113. package/dist/application/events.d.ts +1 -1
  114. package/dist/application/events.d.ts.map +1 -1
  115. package/dist/{server → application}/file-state-store.d.ts +1 -1
  116. package/dist/application/file-state-store.d.ts.map +1 -0
  117. package/dist/application/health.d.ts +1 -1
  118. package/dist/application/health.d.ts.map +1 -1
  119. package/dist/application/kernel-admission.d.ts +8 -0
  120. package/dist/application/kernel-admission.d.ts.map +1 -0
  121. package/dist/application/kernel-contract.d.ts +142 -0
  122. package/dist/application/kernel-contract.d.ts.map +1 -0
  123. package/dist/application/kernel-resource-context.d.ts +24 -0
  124. package/dist/application/kernel-resource-context.d.ts.map +1 -0
  125. package/dist/application/kernel-restart.d.ts +5 -0
  126. package/dist/application/kernel-restart.d.ts.map +1 -0
  127. package/dist/application/kernel-rollback.d.ts +4 -0
  128. package/dist/application/kernel-rollback.d.ts.map +1 -0
  129. package/dist/application/kernel-shutdown.d.ts +6 -0
  130. package/dist/application/kernel-shutdown.d.ts.map +1 -0
  131. package/dist/application/kernel-start.d.ts +20 -0
  132. package/dist/application/kernel-start.d.ts.map +1 -0
  133. package/dist/application/kernel-state.d.ts +116 -0
  134. package/dist/application/kernel-state.d.ts.map +1 -0
  135. package/dist/application/kernel.d.ts +9 -140
  136. package/dist/application/kernel.d.ts.map +1 -1
  137. package/dist/application/latest-sink.d.ts +1 -1
  138. package/dist/application/latest-sink.d.ts.map +1 -1
  139. package/dist/application/opentelemetry.d.ts +1 -1
  140. package/dist/application/opentelemetry.d.ts.map +1 -1
  141. package/dist/application/watch-hub.d.ts +2 -2
  142. package/dist/application/watch-hub.d.ts.map +1 -1
  143. package/dist/browser/client-multipart.d.ts +1 -1
  144. package/dist/browser/client-multipart.d.ts.map +1 -1
  145. package/dist/browser/client-url.d.ts +1 -1
  146. package/dist/browser/client-url.d.ts.map +1 -1
  147. package/dist/browser/client.d.ts +1 -1
  148. package/dist/browser/client.d.ts.map +1 -1
  149. package/dist/browser/contract-stream.d.ts +1 -1
  150. package/dist/browser/contract-stream.d.ts.map +1 -1
  151. package/dist/browser/http.d.ts +1 -1
  152. package/dist/browser/http.d.ts.map +1 -1
  153. package/dist/browser/resumable.d.ts +1 -28
  154. package/dist/browser/resumable.d.ts.map +1 -1
  155. package/dist/browser/retained.d.ts.map +1 -0
  156. package/dist/browser/socket-io.d.ts +23 -1
  157. package/dist/browser/socket-io.d.ts.map +1 -1
  158. package/dist/browser/stream.d.ts +14 -2
  159. package/dist/browser/stream.d.ts.map +1 -1
  160. package/dist/contract/define.d.ts +72 -65
  161. package/dist/contract/define.d.ts.map +1 -1
  162. package/dist/{internal/errors.d.ts → contract/normalize.d.ts} +3 -39
  163. package/dist/contract/normalize.d.ts.map +1 -0
  164. package/dist/contract/tool-view.d.ts +135 -0
  165. package/dist/contract/tool-view.d.ts.map +1 -0
  166. package/dist/declaration/declaration.d.ts.map +1 -0
  167. package/dist/{agent-runtime/durability-contract.d.ts → durability/contract.d.ts} +2 -2
  168. package/dist/durability/contract.d.ts.map +1 -0
  169. package/dist/{agent-runtime/durability.d.ts → durability/engine.d.ts} +4 -4
  170. package/dist/durability/engine.d.ts.map +1 -0
  171. package/dist/durability/events.d.ts +101 -0
  172. package/dist/durability/events.d.ts.map +1 -0
  173. package/dist/{agent-runtime/durability-json.d.ts → durability/json.d.ts} +1 -1
  174. package/dist/durability/json.d.ts.map +1 -0
  175. package/dist/{agent-runtime/durability-ledger.d.ts → durability/ledger.d.ts} +2 -2
  176. package/dist/durability/ledger.d.ts.map +1 -0
  177. package/dist/{agent-runtime/durability-scheduler.d.ts → durability/scheduler.d.ts} +2 -2
  178. package/dist/durability/scheduler.d.ts.map +1 -0
  179. package/dist/entrypoints/agent-runtime/browser.d.ts +5 -0
  180. package/dist/entrypoints/agent-runtime/browser.d.ts.map +1 -0
  181. package/dist/{agent-runtime-browser.js → entrypoints/agent-runtime/browser.js} +3 -3
  182. package/dist/{agent-runtime-coding-tools.d.ts → entrypoints/agent-runtime/coding-tools.d.ts} +2 -2
  183. package/dist/entrypoints/agent-runtime/coding-tools.d.ts.map +1 -0
  184. package/dist/entrypoints/agent-runtime/coding-tools.js +22 -0
  185. package/dist/{agent-runtime-harness.d.ts → entrypoints/agent-runtime/harness.d.ts} +2 -2
  186. package/dist/entrypoints/agent-runtime/harness.d.ts.map +1 -0
  187. package/dist/{agent-runtime-harness.js → entrypoints/agent-runtime/harness.js} +24 -25
  188. package/dist/entrypoints/agent-runtime/openrouter.d.ts +2 -0
  189. package/dist/entrypoints/agent-runtime/openrouter.d.ts.map +1 -0
  190. package/dist/{agent-runtime-openrouter.js → entrypoints/agent-runtime/openrouter.js} +3 -3
  191. package/dist/{agent-runtime-sandbox.d.ts → entrypoints/agent-runtime/sandbox.d.ts} +5 -5
  192. package/dist/entrypoints/agent-runtime/sandbox.d.ts.map +1 -0
  193. package/dist/{agent-runtime-sandbox.js → entrypoints/agent-runtime/sandbox.js} +11 -12
  194. package/dist/entrypoints/agent-runtime/sqlite/bun.d.ts +2 -0
  195. package/dist/entrypoints/agent-runtime/sqlite/bun.d.ts.map +1 -0
  196. package/dist/{agent-runtime-sqlite-bun.js → entrypoints/agent-runtime/sqlite/bun.js} +8 -6
  197. package/dist/entrypoints/agent-runtime/sqlite/node.d.ts +2 -0
  198. package/dist/entrypoints/agent-runtime/sqlite/node.d.ts.map +1 -0
  199. package/dist/{agent-runtime-sqlite-node.js → entrypoints/agent-runtime/sqlite/node.js} +8 -6
  200. package/dist/entrypoints/agent-runtime/testing.d.ts +4 -0
  201. package/dist/entrypoints/agent-runtime/testing.d.ts.map +1 -0
  202. package/dist/entrypoints/agent-runtime/testing.js +1084 -0
  203. package/dist/{agent-runtime.d.ts → entrypoints/agent-runtime.d.ts} +41 -37
  204. package/dist/entrypoints/agent-runtime.d.ts.map +1 -0
  205. package/dist/{agent-runtime.js → entrypoints/agent-runtime.js} +408 -366
  206. package/dist/{application-diagnostic-journal.d.ts → entrypoints/application/diagnostic-journal.d.ts} +2 -2
  207. package/dist/entrypoints/application/diagnostic-journal.d.ts.map +1 -0
  208. package/dist/{application-diagnostic-journal.js → entrypoints/application/diagnostic-journal.js} +3 -3
  209. package/dist/{application-grammy.d.ts → entrypoints/application/grammy.d.ts} +2 -2
  210. package/dist/entrypoints/application/grammy.d.ts.map +1 -0
  211. package/dist/{application-grammy.js → entrypoints/application/grammy.js} +2 -2
  212. package/dist/{application-opentelemetry.d.ts → entrypoints/application/opentelemetry.d.ts} +2 -2
  213. package/dist/entrypoints/application/opentelemetry.d.ts.map +1 -0
  214. package/dist/{application-opentelemetry.js → entrypoints/application/opentelemetry.js} +4 -4
  215. package/dist/{application-schemas.d.ts → entrypoints/application/schemas.d.ts} +2 -2
  216. package/dist/entrypoints/application/schemas.d.ts.map +1 -0
  217. package/dist/{application-schemas.js → entrypoints/application/schemas.js} +2 -2
  218. package/dist/{application.d.ts → entrypoints/application.d.ts} +22 -21
  219. package/dist/entrypoints/application.d.ts.map +1 -0
  220. package/dist/{application.js → entrypoints/application.js} +24 -22
  221. package/dist/entrypoints/bin/upgrade-cli.d.ts.map +1 -0
  222. package/dist/{upgrade-cli.js → entrypoints/bin/upgrade-cli.js} +3 -3
  223. package/dist/{cli.d.ts → entrypoints/cli.d.ts} +15 -15
  224. package/dist/entrypoints/cli.d.ts.map +1 -0
  225. package/dist/{cli.js → entrypoints/cli.js} +37 -32
  226. package/dist/entrypoints/contract.d.ts +9 -0
  227. package/dist/entrypoints/contract.d.ts.map +1 -0
  228. package/dist/{contract/index.js → entrypoints/contract.js} +14 -6
  229. package/dist/entrypoints/declaration.d.ts +2 -0
  230. package/dist/entrypoints/declaration.d.ts.map +1 -0
  231. package/dist/{declaration.js → entrypoints/declaration.js} +1 -1
  232. package/dist/{files.d.ts → entrypoints/files.d.ts} +2 -2
  233. package/dist/entrypoints/files.d.ts.map +1 -0
  234. package/dist/{files.js → entrypoints/files.js} +3 -3
  235. package/dist/{geo.d.ts → entrypoints/geo.d.ts} +1 -1
  236. package/dist/entrypoints/geo.d.ts.map +1 -0
  237. package/dist/{geo.js → entrypoints/geo.js} +4 -4
  238. package/dist/entrypoints/google.d.ts +2 -0
  239. package/dist/entrypoints/google.d.ts.map +1 -0
  240. package/dist/{google.js → entrypoints/google.js} +1 -1
  241. package/dist/{index.d.ts → entrypoints/index.d.ts} +14 -13
  242. package/dist/entrypoints/index.d.ts.map +1 -0
  243. package/dist/{index.js → entrypoints/index.js} +99 -33
  244. package/dist/{live.d.ts → entrypoints/live.d.ts} +4 -4
  245. package/dist/entrypoints/live.d.ts.map +1 -0
  246. package/dist/{live.js → entrypoints/live.js} +6 -4
  247. package/dist/{node.d.ts → entrypoints/node.d.ts} +11 -11
  248. package/dist/entrypoints/node.d.ts.map +1 -0
  249. package/dist/{node.js → entrypoints/node.js} +20 -16
  250. package/dist/entrypoints/oauth.d.ts +2 -0
  251. package/dist/entrypoints/oauth.d.ts.map +1 -0
  252. package/dist/{oauth.js → entrypoints/oauth.js} +3 -3
  253. package/dist/{observability/index.d.ts → entrypoints/observability.d.ts} +11 -11
  254. package/dist/entrypoints/observability.d.ts.map +1 -0
  255. package/dist/{observability/index.js → entrypoints/observability.js} +9 -11
  256. package/dist/entrypoints/primitives.d.ts +3 -0
  257. package/dist/entrypoints/primitives.d.ts.map +1 -0
  258. package/dist/{primitives.js → entrypoints/primitives.js} +1 -6
  259. package/dist/{react.d.ts → entrypoints/react.d.ts} +4 -4
  260. package/dist/entrypoints/react.d.ts.map +1 -0
  261. package/dist/{react.js → entrypoints/react.js} +3 -3
  262. package/dist/{release.d.ts → entrypoints/release.d.ts} +4 -4
  263. package/dist/entrypoints/release.d.ts.map +1 -0
  264. package/dist/{release.js → entrypoints/release.js} +1 -1
  265. package/dist/{remote.d.ts → entrypoints/remote.d.ts} +1 -1
  266. package/dist/entrypoints/remote.d.ts.map +1 -0
  267. package/dist/entrypoints/remote.js +66 -0
  268. package/dist/{server/index.d.ts → entrypoints/server.d.ts} +35 -34
  269. package/dist/entrypoints/server.d.ts.map +1 -0
  270. package/dist/{server/index.js → entrypoints/server.js} +294 -244
  271. package/dist/{telegram.d.ts → entrypoints/telegram.d.ts} +2 -2
  272. package/dist/entrypoints/telegram.d.ts.map +1 -0
  273. package/dist/{telegram.js → entrypoints/telegram.js} +1 -1
  274. package/dist/entrypoints/testing.d.ts +9 -0
  275. package/dist/entrypoints/testing.d.ts.map +1 -0
  276. package/dist/{testing.js → entrypoints/testing.js} +107 -926
  277. package/dist/{tools/connections/index.d.ts → entrypoints/tools/connections.d.ts} +6 -7
  278. package/dist/entrypoints/tools/connections.d.ts.map +1 -0
  279. package/dist/{tools/connections/index.js → entrypoints/tools/connections.js} +7 -4
  280. package/dist/{tools-contract.d.ts → entrypoints/tools/contract.d.ts} +5 -5
  281. package/dist/entrypoints/tools/contract.d.ts.map +1 -0
  282. package/dist/{tools-contract.js → entrypoints/tools/contract.js} +4 -4
  283. package/dist/{tool-invoker.d.ts → entrypoints/tools/invoker.d.ts} +2 -2
  284. package/dist/entrypoints/tools/invoker.d.ts.map +1 -0
  285. package/dist/entrypoints/tools/invoker.js +20 -0
  286. package/dist/entrypoints/tools.d.ts +51 -0
  287. package/dist/entrypoints/tools.d.ts.map +1 -0
  288. package/dist/{tools.js → entrypoints/tools.js} +1787 -1751
  289. package/dist/{tracking-server.d.ts → entrypoints/tracking/server.d.ts} +8 -8
  290. package/dist/entrypoints/tracking/server.d.ts.map +1 -0
  291. package/dist/{tracking.d.ts → entrypoints/tracking.d.ts} +15 -15
  292. package/dist/entrypoints/tracking.d.ts.map +1 -0
  293. package/dist/{tracking.js → entrypoints/tracking.js} +5 -8
  294. package/dist/google/google.d.ts.map +1 -0
  295. package/dist/{index-a916km3r.js → index-0b1ess5e.js} +6 -13
  296. package/dist/{index-zwkgfq1s.js → index-1nd48tm9.js} +113 -118
  297. package/dist/{index-7zbps32p.js → index-1zbbzgfh.js} +2 -2
  298. package/dist/{index-mzvgxp0n.js → index-2cr1cqhn.js} +16 -4
  299. package/dist/{index-f9mb610r.js → index-35mh5bhj.js} +2 -2
  300. package/dist/index-48ffdxgk.js +6 -0
  301. package/dist/index-58k4fp34.js +1023 -0
  302. package/dist/{index-p13mwz16.js → index-83bdg97s.js} +1 -1
  303. package/dist/index-97ac4gph.js +3618 -0
  304. package/dist/{index-kw9t5ayn.js → index-cq4qfycf.js} +5 -5
  305. package/dist/{index-7gnkny4z.js → index-d9pk3td4.js} +1 -1
  306. package/dist/{index-e42wzzz5.js → index-dcpdvjsc.js} +7 -7
  307. package/dist/{index-h9etkkyk.js → index-dydjcp8z.js} +102 -25
  308. package/dist/{index-sr93cwf9.js → index-e2z3ahw9.js} +2 -2
  309. package/dist/{index-yewwh1w4.js → index-e87kakm4.js} +96 -11
  310. package/dist/{index-cby4ar3v.js → index-eqqvgdb3.js} +1 -1
  311. package/dist/index-fdp6hdxn.js +942 -0
  312. package/dist/{index-0a349c33.js → index-gyr48nzg.js} +125 -198
  313. package/dist/{index-wnfk50r0.js → index-h6eeys1v.js} +1 -1
  314. package/dist/{index-77fekveh.js → index-hffjpmq9.js} +1 -15
  315. package/dist/{index-yn8remb1.js → index-j05z5gn4.js} +50 -14
  316. package/dist/index-k5hsfc3j.js +31 -0
  317. package/dist/{index-fq77yfzc.js → index-kj2wbeta.js} +1 -1
  318. package/dist/index-kvj7f4hq.js +39 -0
  319. package/dist/{index-4fpa9dy2.js → index-m9zn6cpq.js} +2 -2
  320. package/dist/{index-2na0qrfn.js → index-mdzh02yc.js} +7 -7
  321. package/dist/{index-ywd0y6m1.js → index-mkm15s49.js} +1 -1
  322. package/dist/index-mp5sn43f.js +1084 -0
  323. package/dist/{index-7n145nbe.js → index-n6hxg8as.js} +530 -387
  324. package/dist/index-ngfhvfpd.js +30 -0
  325. package/dist/{index-e0znv5gn.js → index-p5r7qpdd.js} +2 -93
  326. package/dist/{index-n0f51dfn.js → index-p81267c2.js} +608 -549
  327. package/dist/{index-wc4x00bn.js → index-qwhynv6x.js} +1 -1
  328. package/dist/index-r7nmqpsg.js +154 -0
  329. package/dist/{index-bx75zwt7.js → index-rewkc2hj.js} +5 -4
  330. package/dist/{index-9f8ztey6.js → index-sees8yf8.js} +2 -2
  331. package/dist/{index-vjpvjqpn.js → index-v38qyerb.js} +16 -2
  332. package/dist/{index-2c2bjw3s.js → index-vcvkq30w.js} +3 -3
  333. package/dist/index-wqgjfstn.js +18 -0
  334. package/dist/{index-f477k430.js → index-x4799c19.js} +1 -1
  335. package/dist/{index-cxqhvq21.js → index-xnj9bgxe.js} +142 -129
  336. package/dist/index-xsqjkha9.js +281 -0
  337. package/dist/{index-6kyksz9y.js → index-yw4fzmdz.js} +1 -1
  338. package/dist/{index-3xwxfj4z.js → index-zeemqhqx.js} +1 -1
  339. package/dist/{index-tmwcrptx.js → index-zfrhfn82.js} +1 -1
  340. package/dist/index-znfs20ss.js +98 -0
  341. package/dist/internal/backoff.d.ts +29 -0
  342. package/dist/internal/backoff.d.ts.map +1 -0
  343. package/dist/internal/canonical-json.d.ts +21 -11
  344. package/dist/internal/canonical-json.d.ts.map +1 -1
  345. package/dist/internal/channel.d.ts.map +1 -0
  346. package/dist/internal/logger.d.ts.map +1 -0
  347. package/dist/internal/request.d.ts.map +1 -0
  348. package/dist/internal/secure-fetch.d.ts +12 -0
  349. package/dist/internal/secure-fetch.d.ts.map +1 -1
  350. package/dist/internal/stable-digest.d.ts +0 -43
  351. package/dist/internal/stable-digest.d.ts.map +1 -1
  352. package/dist/internal/typed.d.ts +0 -8
  353. package/dist/internal/typed.d.ts.map +1 -1
  354. package/dist/internal/zod-issues.d.ts +38 -0
  355. package/dist/internal/zod-issues.d.ts.map +1 -0
  356. package/dist/{tools/json-schema-dialect.d.ts → json-schema/dialect.d.ts} +1 -1
  357. package/dist/json-schema/dialect.d.ts.map +1 -0
  358. package/dist/json-schema/json-schema.d.ts.map +1 -0
  359. package/dist/live/watch-delta.d.ts.map +1 -1
  360. package/dist/{oauth.d.ts → oauth/authorization-code.d.ts} +1 -1
  361. package/dist/oauth/authorization-code.d.ts.map +1 -0
  362. package/dist/observability/audit.d.ts +2 -2
  363. package/dist/observability/audit.d.ts.map +1 -1
  364. package/dist/observability/bounded-logger.d.ts +1 -1
  365. package/dist/observability/bounded-logger.d.ts.map +1 -1
  366. package/dist/{internal/observability-sink.d.ts → observability/bounded-sink.d.ts} +2 -2
  367. package/dist/observability/bounded-sink.d.ts.map +1 -0
  368. package/dist/observability/context.d.ts +1 -1
  369. package/dist/observability/context.d.ts.map +1 -1
  370. package/dist/observability/event.d.ts +1 -1
  371. package/dist/observability/event.d.ts.map +1 -1
  372. package/dist/observability/work.d.ts +1 -1
  373. package/dist/observability/work.d.ts.map +1 -1
  374. package/dist/primitives/audit.d.ts +1 -1
  375. package/dist/primitives/audit.d.ts.map +1 -1
  376. package/dist/primitives/export-operation.d.ts +4 -2
  377. package/dist/primitives/export-operation.d.ts.map +1 -1
  378. package/dist/realtime/socket.d.ts +1 -1
  379. package/dist/realtime/socket.d.ts.map +1 -1
  380. package/dist/server/context-contribution.d.ts +1 -1
  381. package/dist/server/context-contribution.d.ts.map +1 -1
  382. package/dist/server/context.d.ts +2 -2
  383. package/dist/server/context.d.ts.map +1 -1
  384. package/dist/server/contract-method.d.ts +15 -0
  385. package/dist/server/contract-method.d.ts.map +1 -0
  386. package/dist/server/contract-stream.d.ts +1 -1
  387. package/dist/server/contract-stream.d.ts.map +1 -1
  388. package/dist/server/create.d.ts +8 -0
  389. package/dist/server/create.d.ts.map +1 -1
  390. package/dist/server/endpoint-dispatch.d.ts +10 -0
  391. package/dist/server/endpoint-dispatch.d.ts.map +1 -0
  392. package/dist/server/endpoint-response.d.ts +18 -0
  393. package/dist/server/endpoint-response.d.ts.map +1 -0
  394. package/dist/server/error-dispatch.d.ts +17 -1
  395. package/dist/server/error-dispatch.d.ts.map +1 -1
  396. package/dist/server/error-hook.d.ts +2 -2
  397. package/dist/server/error-hook.d.ts.map +1 -1
  398. package/dist/server/handler-state.d.ts +44 -0
  399. package/dist/server/handler-state.d.ts.map +1 -0
  400. package/dist/server/implement.d.ts +1 -1
  401. package/dist/server/implement.d.ts.map +1 -1
  402. package/dist/server/middleware/auth.d.ts +1 -1
  403. package/dist/server/middleware/auth.d.ts.map +1 -1
  404. package/dist/server/middleware/cors.d.ts +17 -0
  405. package/dist/server/middleware/cors.d.ts.map +1 -1
  406. package/dist/server/middleware/trust-fence.d.ts +1 -1
  407. package/dist/server/middleware/trust-fence.d.ts.map +1 -1
  408. package/dist/server/multipart.d.ts +1 -1
  409. package/dist/server/multipart.d.ts.map +1 -1
  410. package/dist/{tools/oauth-metadata.d.ts → server/oauth/metadata.d.ts} +2 -2
  411. package/dist/server/oauth/metadata.d.ts.map +1 -0
  412. package/dist/{tools/oauth-provider.d.ts → server/oauth/provider.d.ts} +2 -2
  413. package/dist/server/oauth/provider.d.ts.map +1 -0
  414. package/dist/server/realtime.d.ts +1 -1
  415. package/dist/server/realtime.d.ts.map +1 -1
  416. package/dist/server/request-completion.d.ts +16 -0
  417. package/dist/server/request-completion.d.ts.map +1 -0
  418. package/dist/server/response-metadata.d.ts +1 -1
  419. package/dist/server/response-metadata.d.ts.map +1 -1
  420. package/dist/server/route-table.d.ts +9 -0
  421. package/dist/server/route-table.d.ts.map +1 -0
  422. package/dist/server/stream.d.ts +0 -13
  423. package/dist/server/stream.d.ts.map +1 -1
  424. package/dist/server/types.d.ts +7 -4
  425. package/dist/server/types.d.ts.map +1 -1
  426. package/dist/testing/handler-clients.d.ts +31 -0
  427. package/dist/testing/handler-clients.d.ts.map +1 -0
  428. package/dist/testing/managed-resource-conformance-scenarios.d.ts.map +1 -1
  429. package/dist/testing/surface-conformance.d.ts +2 -1
  430. package/dist/testing/surface-conformance.d.ts.map +1 -1
  431. package/dist/testing/surface-manifest.d.ts +64 -5
  432. package/dist/testing/surface-manifest.d.ts.map +1 -1
  433. package/dist/tools/{cli-args.d.ts → cli/args.d.ts} +1 -1
  434. package/dist/tools/cli/args.d.ts.map +1 -0
  435. package/dist/tools/{cli-checkpoint.d.ts → cli/checkpoint.d.ts} +1 -1
  436. package/dist/tools/cli/checkpoint.d.ts.map +1 -0
  437. package/dist/tools/{cli-command.d.ts → cli/command.d.ts} +22 -4
  438. package/dist/tools/cli/command.d.ts.map +1 -0
  439. package/dist/tools/{cli.d.ts → cli/config.d.ts} +5 -12
  440. package/dist/tools/cli/config.d.ts.map +1 -0
  441. package/dist/tools/cli/create-cli.d.ts +36 -0
  442. package/dist/tools/cli/create-cli.d.ts.map +1 -0
  443. package/dist/tools/cli/download.d.ts +8 -0
  444. package/dist/tools/cli/download.d.ts.map +1 -0
  445. package/dist/tools/{cli-format.d.ts → cli/format.d.ts} +2 -2
  446. package/dist/tools/cli/format.d.ts.map +1 -0
  447. package/dist/tools/cli/help.d.ts +24 -0
  448. package/dist/tools/cli/help.d.ts.map +1 -0
  449. package/dist/tools/{cli-installer.d.ts → cli/installer.d.ts} +2 -2
  450. package/dist/tools/cli/installer.d.ts.map +1 -0
  451. package/dist/tools/{cli-invoke.d.ts → cli/invoke.d.ts} +35 -10
  452. package/dist/tools/cli/invoke.d.ts.map +1 -0
  453. package/dist/tools/cli/io.d.ts +10 -0
  454. package/dist/tools/cli/io.d.ts.map +1 -0
  455. package/dist/tools/cli/managed-surface.d.ts +30 -0
  456. package/dist/tools/cli/managed-surface.d.ts.map +1 -0
  457. package/dist/tools/{cli-manifest.d.ts → cli/manifest.d.ts} +1 -1
  458. package/dist/tools/cli/manifest.d.ts.map +1 -0
  459. package/dist/tools/{cli-policy.d.ts → cli/policy.d.ts} +2 -2
  460. package/dist/tools/cli/policy.d.ts.map +1 -0
  461. package/dist/tools/cli/prepare.d.ts +14 -0
  462. package/dist/tools/cli/prepare.d.ts.map +1 -0
  463. package/dist/tools/{cli-profile.d.ts → cli/profile.d.ts} +2 -2
  464. package/dist/tools/cli/profile.d.ts.map +1 -0
  465. package/dist/tools/cli/run-managed.d.ts +5 -0
  466. package/dist/tools/cli/run-managed.d.ts.map +1 -0
  467. package/dist/tools/cli/run-native.d.ts +9 -0
  468. package/dist/tools/cli/run-native.d.ts.map +1 -0
  469. package/dist/tools/cli/session.d.ts +40 -0
  470. package/dist/tools/cli/session.d.ts.map +1 -0
  471. package/dist/tools/{cli-signature.d.ts → cli/signature.d.ts} +2 -2
  472. package/dist/tools/cli/signature.d.ts.map +1 -0
  473. package/dist/tools/{cli-stream.d.ts → cli/stream.d.ts} +4 -4
  474. package/dist/tools/cli/stream.d.ts.map +1 -0
  475. package/dist/tools/{cli-update.d.ts → cli/update.d.ts} +3 -3
  476. package/dist/tools/cli/update.d.ts.map +1 -0
  477. package/dist/tools/{cli-view.d.ts → cli/view.d.ts} +2 -2
  478. package/dist/tools/cli/view.d.ts.map +1 -0
  479. package/dist/tools/{cli-wait.d.ts → cli/wait.d.ts} +2 -2
  480. package/dist/tools/cli/wait.d.ts.map +1 -0
  481. package/dist/tools/connections/runtime.d.ts +1 -1
  482. package/dist/tools/connections/runtime.d.ts.map +1 -1
  483. package/dist/tools/connections/types.d.ts +3 -3
  484. package/dist/tools/connections/types.d.ts.map +1 -1
  485. package/dist/tools/durability-context.d.ts +1 -1
  486. package/dist/tools/durability-context.d.ts.map +1 -1
  487. package/dist/tools/execute.d.ts +30 -3
  488. package/dist/tools/execute.d.ts.map +1 -1
  489. package/dist/tools/internal/surface-projector.d.ts +8 -6
  490. package/dist/tools/internal/surface-projector.d.ts.map +1 -1
  491. package/dist/tools/internal/tool-view.d.ts +41 -0
  492. package/dist/tools/internal/tool-view.d.ts.map +1 -0
  493. package/dist/tools/invoker.d.ts +11 -3
  494. package/dist/tools/invoker.d.ts.map +1 -1
  495. package/dist/tools/list-names.d.ts +3 -3
  496. package/dist/tools/list-names.d.ts.map +1 -1
  497. package/dist/tools/manifest.d.ts +2 -2
  498. package/dist/tools/manifest.d.ts.map +1 -1
  499. package/dist/tools/{mcp-app.d.ts → mcp/app.d.ts} +1 -1
  500. package/dist/tools/mcp/app.d.ts.map +1 -0
  501. package/dist/tools/{mcp-catalog.d.ts → mcp/catalog.d.ts} +2 -2
  502. package/dist/tools/mcp/catalog.d.ts.map +1 -0
  503. package/dist/tools/{mcp-handler.d.ts → mcp/handler.d.ts} +5 -5
  504. package/dist/tools/mcp/handler.d.ts.map +1 -0
  505. package/dist/tools/{mcp.d.ts → mcp/mount.d.ts} +9 -9
  506. package/dist/tools/mcp/mount.d.ts.map +1 -0
  507. package/dist/tools/{mcp-prepare.d.ts → mcp/prepare.d.ts} +9 -9
  508. package/dist/tools/mcp/prepare.d.ts.map +1 -0
  509. package/dist/tools/{mcp-progress.d.ts → mcp/progress.d.ts} +2 -2
  510. package/dist/tools/mcp/progress.d.ts.map +1 -0
  511. package/dist/tools/mcp/register.d.ts +35 -0
  512. package/dist/tools/mcp/register.d.ts.map +1 -0
  513. package/dist/tools/{mcp-round-policy.d.ts → mcp/round-policy.d.ts} +2 -2
  514. package/dist/tools/mcp/round-policy.d.ts.map +1 -0
  515. package/dist/tools/{mcp-round.d.ts → mcp/round.d.ts} +4 -4
  516. package/dist/tools/mcp/round.d.ts.map +1 -0
  517. package/dist/tools/mcp/runtime-tools.d.ts +24 -0
  518. package/dist/tools/mcp/runtime-tools.d.ts.map +1 -0
  519. package/dist/tools/{mcp-stdio-signals.d.ts → mcp/stdio-signals.d.ts} +3 -3
  520. package/dist/tools/mcp/stdio-signals.d.ts.map +1 -0
  521. package/dist/tools/{mcp-stdio.d.ts → mcp/stdio.d.ts} +4 -4
  522. package/dist/tools/mcp/stdio.d.ts.map +1 -0
  523. package/dist/tools/{mcp-trace.d.ts → mcp/trace.d.ts} +1 -1
  524. package/dist/tools/mcp/trace.d.ts.map +1 -0
  525. package/dist/tools/mount.d.ts +12 -7
  526. package/dist/tools/mount.d.ts.map +1 -1
  527. package/dist/tools/native-definition.d.ts +3 -3
  528. package/dist/tools/native-definition.d.ts.map +1 -1
  529. package/dist/tools/operations/async-operation-binding-types.d.ts +127 -0
  530. package/dist/tools/operations/async-operation-binding-types.d.ts.map +1 -0
  531. package/dist/tools/operations/async-operation-binding.d.ts +28 -0
  532. package/dist/tools/operations/async-operation-binding.d.ts.map +1 -0
  533. package/dist/tools/operations/async-operation-canonical-types.d.ts +110 -0
  534. package/dist/tools/operations/async-operation-canonical-types.d.ts.map +1 -0
  535. package/dist/tools/operations/async-operation-canonical.d.ts +7 -0
  536. package/dist/tools/operations/async-operation-canonical.d.ts.map +1 -0
  537. package/dist/tools/operations/async-operation-contract.d.ts.map +1 -0
  538. package/dist/tools/operations/async-operation-id.d.ts +23 -0
  539. package/dist/tools/operations/async-operation-id.d.ts.map +1 -0
  540. package/dist/tools/operations/async-operation-runtime-tools.d.ts +40 -0
  541. package/dist/tools/operations/async-operation-runtime-tools.d.ts.map +1 -0
  542. package/dist/tools/operations/async-operation-runtime-types.d.ts +68 -0
  543. package/dist/tools/operations/async-operation-runtime-types.d.ts.map +1 -0
  544. package/dist/tools/operations/async-operation-runtime.d.ts +5 -0
  545. package/dist/tools/operations/async-operation-runtime.d.ts.map +1 -0
  546. package/dist/tools/{define-wait-tool.d.ts → operations/define-wait-tool.d.ts} +2 -2
  547. package/dist/tools/operations/define-wait-tool.d.ts.map +1 -0
  548. package/dist/tools/operations/mount-wait.d.ts.map +1 -0
  549. package/dist/tools/operations/wait-core.d.ts.map +1 -0
  550. package/dist/tools/remote.d.ts +1 -1
  551. package/dist/tools/remote.d.ts.map +1 -1
  552. package/dist/tools/runtime-tool.d.ts +11 -4
  553. package/dist/tools/runtime-tool.d.ts.map +1 -1
  554. package/dist/tools/schema/coerce.d.ts.map +1 -0
  555. package/dist/tools/schema/flatten-join.d.ts.map +1 -0
  556. package/dist/tools/schema/flatten.d.ts.map +1 -0
  557. package/dist/tools/schema/portable-formats.d.ts.map +1 -0
  558. package/dist/tools/{presentation.d.ts → schema/presentation.d.ts} +2 -0
  559. package/dist/tools/schema/presentation.d.ts.map +1 -0
  560. package/dist/tools/schema/schema.d.ts.map +1 -0
  561. package/dist/tools/schema/untyped-properties.d.ts.map +1 -0
  562. package/dist/tools/surface.d.ts +2 -3
  563. package/dist/tools/surface.d.ts.map +1 -1
  564. package/dist/tools/toolkit.d.ts +4 -4
  565. package/dist/tools/toolkit.d.ts.map +1 -1
  566. package/dist/tools/{define-download-tool.d.ts → transfer/define-download-tool.d.ts} +4 -4
  567. package/dist/tools/transfer/define-download-tool.d.ts.map +1 -0
  568. package/dist/tools/{define-upload-tool.d.ts → transfer/define-upload-tool.d.ts} +3 -3
  569. package/dist/tools/transfer/define-upload-tool.d.ts.map +1 -0
  570. package/dist/tools/{define-view-file-tool.d.ts → transfer/define-view-file-tool.d.ts} +2 -2
  571. package/dist/tools/transfer/define-view-file-tool.d.ts.map +1 -0
  572. package/dist/tools/{download-core.d.ts → transfer/download-core.d.ts} +2 -2
  573. package/dist/tools/transfer/download-core.d.ts.map +1 -0
  574. package/dist/tools/{managed-file-error.d.ts → transfer/managed-file-error.d.ts} +1 -1
  575. package/dist/tools/transfer/managed-file-error.d.ts.map +1 -0
  576. package/dist/tools/{mount-download.d.ts → transfer/mount-download.d.ts} +1 -1
  577. package/dist/tools/transfer/mount-download.d.ts.map +1 -0
  578. package/dist/tools/{mount-upload.d.ts → transfer/mount-upload.d.ts} +1 -1
  579. package/dist/tools/transfer/mount-upload.d.ts.map +1 -0
  580. package/dist/tools/transfer/native-result.d.ts.map +1 -0
  581. package/dist/tools/{upload-core.d.ts → transfer/upload-core.d.ts} +1 -1
  582. package/dist/tools/transfer/upload-core.d.ts.map +1 -0
  583. package/dist/tools/transfer/view-file-contract.d.ts.map +1 -0
  584. package/dist/tools/{view-file.d.ts → transfer/view-file.d.ts} +1 -1
  585. package/dist/tools/transfer/view-file.d.ts.map +1 -0
  586. package/dist/tools/transports.d.ts +1 -1
  587. package/dist/tools/transports.d.ts.map +1 -1
  588. package/dist/tracking/contract.d.ts +1 -1
  589. package/dist/tracking/contract.d.ts.map +1 -1
  590. package/llms/agent-runtime-browser.txt +33 -0
  591. package/llms/agent-runtime-coding-tools.txt +58 -0
  592. package/llms/agent-runtime-harness.txt +45 -0
  593. package/llms/agent-runtime-openrouter.txt +22 -0
  594. package/llms/agent-runtime-sandbox.txt +159 -0
  595. package/llms/agent-runtime-sqlite-bun.txt +29 -0
  596. package/llms/agent-runtime-sqlite-node.txt +26 -0
  597. package/llms/agent-runtime-testing.txt +30 -0
  598. package/llms/agent-runtime.2.txt +550 -0
  599. package/llms/agent-runtime.3.txt +311 -0
  600. package/llms/agent-runtime.txt +893 -0
  601. package/llms/application-diagnostic-journal.txt +30 -0
  602. package/llms/application-grammy.txt +27 -0
  603. package/llms/application-opentelemetry.txt +27 -0
  604. package/llms/application-schemas.txt +42 -0
  605. package/llms/application.2.txt +223 -0
  606. package/llms/application.txt +1144 -0
  607. package/llms/cli.txt +977 -0
  608. package/llms/contract.txt +606 -0
  609. package/llms/declaration.txt +286 -0
  610. package/llms/files.txt +30 -0
  611. package/llms/geo.txt +114 -0
  612. package/llms/google.txt +27 -0
  613. package/llms/live.txt +471 -0
  614. package/llms/node.txt +43 -0
  615. package/llms/oauth.txt +136 -0
  616. package/llms/observability.txt +893 -0
  617. package/llms/primitives.txt +158 -0
  618. package/llms/react.txt +184 -0
  619. package/llms/release.txt +176 -0
  620. package/llms/remote.txt +25 -0
  621. package/llms/server.2.txt +361 -0
  622. package/llms/server.3.txt +1031 -0
  623. package/llms/server.4.txt +905 -0
  624. package/llms/server.5.txt +250 -0
  625. package/llms/server.txt +996 -0
  626. package/llms/stitchkit.2.txt +836 -0
  627. package/llms/stitchkit.3.txt +147 -0
  628. package/llms/stitchkit.txt +260 -0
  629. package/llms/telegram.txt +30 -0
  630. package/llms/testing.txt +676 -0
  631. package/llms/tools-connections.txt +45 -0
  632. package/llms/tools-contract.txt +9 -0
  633. package/llms/tools-invoker.txt +9 -0
  634. package/llms/tools.2.txt +838 -0
  635. package/llms/tools.txt +1004 -0
  636. package/llms/tracking-server.txt +32 -0
  637. package/llms/tracking.txt +263 -0
  638. package/llms/upgrading-0.37.0-0.50.0.txt +947 -0
  639. package/llms/upgrading-0.53.0-0.67.0.txt +1174 -0
  640. package/llms/upgrading-0.68.0-0.94.0.txt +1159 -0
  641. package/llms/upgrading.txt +215 -0
  642. package/llms-full.txt +305 -75
  643. package/llms.txt +54 -5
  644. package/package.json +84 -83
  645. package/dist/agent-runtime/durability-contract.d.ts.map +0 -1
  646. package/dist/agent-runtime/durability-json.d.ts.map +0 -1
  647. package/dist/agent-runtime/durability-ledger.d.ts.map +0 -1
  648. package/dist/agent-runtime/durability-scheduler.d.ts.map +0 -1
  649. package/dist/agent-runtime/durability.d.ts.map +0 -1
  650. package/dist/agent-runtime/store-driver.d.ts.map +0 -1
  651. package/dist/agent-runtime-browser.d.ts +0 -5
  652. package/dist/agent-runtime-browser.d.ts.map +0 -1
  653. package/dist/agent-runtime-coding-tools.d.ts.map +0 -1
  654. package/dist/agent-runtime-coding-tools.js +0 -23
  655. package/dist/agent-runtime-harness.d.ts.map +0 -1
  656. package/dist/agent-runtime-openrouter.d.ts.map +0 -1
  657. package/dist/agent-runtime-sandbox.d.ts.map +0 -1
  658. package/dist/agent-runtime-sqlite-bun.d.ts.map +0 -1
  659. package/dist/agent-runtime-sqlite-node.d.ts.map +0 -1
  660. package/dist/agent-runtime-testing.d.ts +0 -3
  661. package/dist/agent-runtime-testing.d.ts.map +0 -1
  662. package/dist/agent-runtime-testing.js +0 -156
  663. package/dist/agent-runtime.d.ts.map +0 -1
  664. package/dist/application/channel.d.ts.map +0 -1
  665. package/dist/application-diagnostic-journal.d.ts.map +0 -1
  666. package/dist/application-grammy.d.ts.map +0 -1
  667. package/dist/application-opentelemetry.d.ts.map +0 -1
  668. package/dist/application-schemas.d.ts.map +0 -1
  669. package/dist/application.d.ts.map +0 -1
  670. package/dist/cli.d.ts.map +0 -1
  671. package/dist/contract/index.d.ts +0 -8
  672. package/dist/contract/index.d.ts.map +0 -1
  673. package/dist/declaration.d.ts.map +0 -1
  674. package/dist/files.d.ts.map +0 -1
  675. package/dist/geo.d.ts.map +0 -1
  676. package/dist/google.d.ts.map +0 -1
  677. package/dist/index-0j3vcp5m.js +0 -28
  678. package/dist/index-a11g2kry.js +0 -866
  679. package/dist/index-cnyk6te3.js +0 -77
  680. package/dist/index-fadnxwna.js +0 -1046
  681. package/dist/index-hrbajay7.js +0 -1196
  682. package/dist/index-s8cnx02s.js +0 -90
  683. package/dist/index-v5573g1k.js +0 -142
  684. package/dist/index-vk3kq9sb.js +0 -3344
  685. package/dist/index.d.ts.map +0 -1
  686. package/dist/internal/errors.d.ts.map +0 -1
  687. package/dist/internal/observability-sink.d.ts.map +0 -1
  688. package/dist/live.d.ts.map +0 -1
  689. package/dist/logger.d.ts.map +0 -1
  690. package/dist/node.d.ts.map +0 -1
  691. package/dist/oauth.d.ts.map +0 -1
  692. package/dist/observability/index.d.ts.map +0 -1
  693. package/dist/primitives.d.ts +0 -3
  694. package/dist/primitives.d.ts.map +0 -1
  695. package/dist/react.d.ts.map +0 -1
  696. package/dist/release.d.ts.map +0 -1
  697. package/dist/remote.d.ts.map +0 -1
  698. package/dist/remote.js +0 -88
  699. package/dist/retained.d.ts.map +0 -1
  700. package/dist/server/file-state-store.d.ts.map +0 -1
  701. package/dist/server/index.d.ts.map +0 -1
  702. package/dist/server/request.d.ts.map +0 -1
  703. package/dist/telegram.d.ts.map +0 -1
  704. package/dist/testing/agent-store-conformance.d.ts.map +0 -1
  705. package/dist/testing.d.ts +0 -39
  706. package/dist/testing.d.ts.map +0 -1
  707. package/dist/tool-invoker.d.ts.map +0 -1
  708. package/dist/tool-invoker.js +0 -21
  709. package/dist/tools/async-operation-contract.d.ts.map +0 -1
  710. package/dist/tools/async-operation.d.ts +0 -332
  711. package/dist/tools/async-operation.d.ts.map +0 -1
  712. package/dist/tools/cli-args.d.ts.map +0 -1
  713. package/dist/tools/cli-checkpoint.d.ts.map +0 -1
  714. package/dist/tools/cli-command.d.ts.map +0 -1
  715. package/dist/tools/cli-format.d.ts.map +0 -1
  716. package/dist/tools/cli-installer.d.ts.map +0 -1
  717. package/dist/tools/cli-invoke.d.ts.map +0 -1
  718. package/dist/tools/cli-manifest.d.ts.map +0 -1
  719. package/dist/tools/cli-policy.d.ts.map +0 -1
  720. package/dist/tools/cli-profile.d.ts.map +0 -1
  721. package/dist/tools/cli-signature.d.ts.map +0 -1
  722. package/dist/tools/cli-stream.d.ts.map +0 -1
  723. package/dist/tools/cli-update.d.ts.map +0 -1
  724. package/dist/tools/cli-view.d.ts.map +0 -1
  725. package/dist/tools/cli-wait.d.ts.map +0 -1
  726. package/dist/tools/cli.d.ts.map +0 -1
  727. package/dist/tools/coerce.d.ts.map +0 -1
  728. package/dist/tools/connections/index.d.ts.map +0 -1
  729. package/dist/tools/define-download-tool.d.ts.map +0 -1
  730. package/dist/tools/define-upload-tool.d.ts.map +0 -1
  731. package/dist/tools/define-view-file-tool.d.ts.map +0 -1
  732. package/dist/tools/define-wait-tool.d.ts.map +0 -1
  733. package/dist/tools/download-core.d.ts.map +0 -1
  734. package/dist/tools/flatten-join.d.ts.map +0 -1
  735. package/dist/tools/flatten.d.ts.map +0 -1
  736. package/dist/tools/json-schema-dialect.d.ts.map +0 -1
  737. package/dist/tools/json-schema.d.ts.map +0 -1
  738. package/dist/tools/managed-file-error.d.ts.map +0 -1
  739. package/dist/tools/mcp-app.d.ts.map +0 -1
  740. package/dist/tools/mcp-catalog.d.ts.map +0 -1
  741. package/dist/tools/mcp-handler.d.ts.map +0 -1
  742. package/dist/tools/mcp-prepare.d.ts.map +0 -1
  743. package/dist/tools/mcp-progress.d.ts.map +0 -1
  744. package/dist/tools/mcp-round-policy.d.ts.map +0 -1
  745. package/dist/tools/mcp-round.d.ts.map +0 -1
  746. package/dist/tools/mcp-stdio-signals.d.ts.map +0 -1
  747. package/dist/tools/mcp-stdio.d.ts.map +0 -1
  748. package/dist/tools/mcp-trace.d.ts.map +0 -1
  749. package/dist/tools/mcp.d.ts.map +0 -1
  750. package/dist/tools/mount-download.d.ts.map +0 -1
  751. package/dist/tools/mount-upload.d.ts.map +0 -1
  752. package/dist/tools/mount-wait.d.ts.map +0 -1
  753. package/dist/tools/native-mcp.d.ts +0 -20
  754. package/dist/tools/native-mcp.d.ts.map +0 -1
  755. package/dist/tools/native-result.d.ts.map +0 -1
  756. package/dist/tools/oauth-metadata.d.ts.map +0 -1
  757. package/dist/tools/oauth-provider.d.ts.map +0 -1
  758. package/dist/tools/portable-formats.d.ts.map +0 -1
  759. package/dist/tools/presentation.d.ts.map +0 -1
  760. package/dist/tools/schema.d.ts.map +0 -1
  761. package/dist/tools/untyped-properties.d.ts.map +0 -1
  762. package/dist/tools/upload-core.d.ts.map +0 -1
  763. package/dist/tools/view-file-contract.d.ts.map +0 -1
  764. package/dist/tools/view-file.d.ts.map +0 -1
  765. package/dist/tools/wait-core.d.ts.map +0 -1
  766. package/dist/tools-contract.d.ts.map +0 -1
  767. package/dist/tools.d.ts +0 -50
  768. package/dist/tools.d.ts.map +0 -1
  769. package/dist/tracking-server.d.ts.map +0 -1
  770. package/dist/tracking.d.ts.map +0 -1
  771. package/dist/upgrade-cli.d.ts.map +0 -1
  772. package/dist/{retained.d.ts → browser/retained.d.ts} +0 -0
  773. package/dist/{declaration.d.ts → declaration/declaration.d.ts} +0 -0
  774. package/dist/{upgrade-cli.d.ts → entrypoints/bin/upgrade-cli.d.ts} +0 -0
  775. package/dist/{tracking-server.js → entrypoints/tracking/server.js} +0 -0
  776. package/dist/{google.d.ts → google/google.d.ts} +0 -0
  777. package/dist/{index-pq95qkbf.js → index-5jm36zv1.js} +0 -0
  778. package/dist/{index-actkayzn.js → index-70yj2ebz.js} +3 -3
  779. /package/dist/{application → internal}/channel.d.ts +0 -0
  780. /package/dist/{logger.d.ts → internal/logger.d.ts} +0 -0
  781. /package/dist/{server → internal}/request.d.ts +0 -0
  782. /package/dist/{tools → json-schema}/json-schema.d.ts +0 -0
  783. /package/dist/tools/{async-operation-contract.d.ts → operations/async-operation-contract.d.ts} +0 -0
  784. /package/dist/tools/{mount-wait.d.ts → operations/mount-wait.d.ts} +0 -0
  785. /package/dist/tools/{wait-core.d.ts → operations/wait-core.d.ts} +0 -0
  786. /package/dist/tools/{coerce.d.ts → schema/coerce.d.ts} +0 -0
  787. /package/dist/tools/{flatten-join.d.ts → schema/flatten-join.d.ts} +0 -0
  788. /package/dist/tools/{flatten.d.ts → schema/flatten.d.ts} +0 -0
  789. /package/dist/tools/{portable-formats.d.ts → schema/portable-formats.d.ts} +0 -0
  790. /package/dist/tools/{schema.d.ts → schema/schema.d.ts} +0 -0
  791. /package/dist/tools/{untyped-properties.d.ts → schema/untyped-properties.d.ts} +0 -0
  792. /package/dist/tools/{native-result.d.ts → transfer/native-result.d.ts} +0 -0
  793. /package/dist/tools/{view-file-contract.d.ts → transfer/view-file-contract.d.ts} +0 -0
@@ -0,0 +1,1144 @@
1
+ # stitchkit/application — stitchkit docs slice, part 1 of 2
2
+
3
+ > Generated from the `docs/` tree by `bun run gen:llms`. The index of all slices is
4
+ > `llms.txt` in this package.
5
+ > Continues in `llms/application.2.txt`.
6
+
7
+ Parts of this slice:
8
+ - `llms/application.txt`: Guide: Managed application kernel (docs/guide/application-kernel.md) · Guide: Application migration recipes (docs/guide/application-migration-recipes.md)
9
+ - `llms/application.2.txt`: API reference: `stitchkit/application` (docs/api/reference.md)
10
+
11
+ ==============================================================================
12
+ # Guide: Managed application kernel (docs/guide/application-kernel.md)
13
+ ==============================================================================
14
+
15
+ ---
16
+ title: Managed application kernel
17
+ description: Compose process-local resources, schedules, readiness, drain and optional provider adapters without building a second job platform.
18
+ type: architecture
19
+ status: active
20
+ created: 2026-08-23
21
+ updated: 2026-09-04 14:11 +07:00
22
+ ---
23
+
24
+ # Managed application kernel
25
+
26
+ > **Maturity: evolving.** This surface is still finding its shape and may be
27
+ > redefined in any minor release — always with a `### ⚠️ Breaking changes` entry
28
+ > and a migration section, never silently. The server, contract and client
29
+ > surfaces it composes are stable.
30
+
31
+ Use `stitchkit/application` when several process-local resources must become
32
+ ready and shut down as one application. Keep using the lower-level server and
33
+ signal APIs when one managed server is already the complete lifecycle boundary.
34
+
35
+ The neutral entrypoint is server-only and works on Bun and Node ≥ 22. It does
36
+ not import provider SDKs.
37
+
38
+ For complete database, poller, queue-consumer and operational-publisher
39
+ cutovers, continue with the executable
40
+ [application migration recipes](./application-migration-recipes.md).
41
+
42
+ ## Minimal composition
43
+
44
+ ```ts
45
+ import {
46
+ createApplication,
47
+ createManagedSchedule,
48
+ defineManagedResource,
49
+ managedServerResource,
50
+ } from 'stitchkit/application'
51
+ import { bindProcessSignals } from 'stitchkit/server'
52
+
53
+ const database = defineManagedResource({
54
+ id: 'database',
55
+ required: true,
56
+ start: async ({ signal, reportHealth }) => {
57
+ await db.connect({ signal })
58
+ reportHealth('healthy')
59
+ },
60
+ close: () => db.disconnect(),
61
+ })
62
+
63
+ const cleanup = createManagedSchedule({
64
+ id: 'cleanup',
65
+ dependsOn: ['database'],
66
+ everyMs: 60_000,
67
+ startAfterMs: 60_000,
68
+ overlap: { mode: 'skip' },
69
+ errorPolicy: 'continue',
70
+ run: ({ signal }) => removeExpiredRecords(signal),
71
+ })
72
+
73
+ const http = managedServerResource({
74
+ id: 'http',
75
+ dependsOn: [database],
76
+ // Called during `start`, after `database` is ready. The factory receives the
77
+ // same declared-dependency and startup-signal context as any resource.
78
+ server: (context) => {
79
+ const db = context.use(database)
80
+ return createServer({ port: env.PORT, services: createServices(db) })
81
+ },
82
+ })
83
+
84
+ const app = createApplication({
85
+ id: 'service',
86
+ resources: [database, http, cleanup],
87
+ // One number for how long this application may take to stop. `shutdown()`
88
+ // with no options and the signal path both spend it.
89
+ shutdown: { gracePeriodMs: 30_000, forceTimeoutMs: 5_000 },
90
+ })
91
+
92
+ const signals = bindProcessSignals(app, {
93
+ onComplete: (result) => {
94
+ process.exitCode = result.outcome === 'clean' ? 0 : 1
95
+ },
96
+ })
97
+
98
+ await app.start()
99
+ ```
100
+
101
+ **Bind before you start, and the order is load-bearing.** Reading it the other way
102
+ round — start serving, then arrange for shutdown — leaves a window between the
103
+ first accepted request and the first listener, and a supervisor that sends
104
+ `SIGTERM` inside that window kills the process outright: exit 143, no shutdown
105
+ chain, no `onComplete`, nothing drained. The window is small and opens exactly
106
+ when the machine is busiest, which is when a supervisor is most likely to be
107
+ restarting something. `bindProcessSignals` does not start anything, so there is
108
+ no cost to binding first.
109
+
110
+ The exact resource callbacks are typed by their public configuration. The
111
+ important ownership rule is stable: the application decides what the
112
+ database/server/provider objects are and how they are configured; Stitchkit
113
+ orders their process-local lifecycle and decides *when* they come into
114
+ existence.
115
+
116
+ ## Resource authoring
117
+
118
+ Give every resource a stable, bounded ID and list its dependencies explicitly.
119
+ The graph is validated before any start. Required resources may depend only on
120
+ required resources; an optional integration cannot silently become a required
121
+ dependency.
122
+
123
+ Start and readiness are different. A connection can finish setup and return a
124
+ ready handle. A poller can return a handle immediately, settle `ready` later,
125
+ and keep a long-lived `completion` promise. Stitchkit observes both.
126
+
127
+ Once Stitchkit invokes start/activation, cleanup is guaranteed to be attempted.
128
+ Write `close` so it is safe when setup was partial:
129
+
130
+ ```ts
131
+ let cacheClient: CacheClient | undefined
132
+
133
+ const cache = defineManagedResource({
134
+ id: 'cache',
135
+ required: false,
136
+ start: async ({ signal, reportHealth }) => {
137
+ cacheClient = new CacheClient()
138
+ await cacheClient.connect(signal)
139
+ reportHealth('healthy')
140
+ },
141
+ close: async () => {
142
+ await cacheClient?.close()
143
+ cacheClient = undefined
144
+ },
145
+ })
146
+ ```
147
+
148
+ Invoking `start` makes the descriptor rollback-eligible immediately. Its
149
+ `close` callback must therefore clean side effects even when `start` rejects
150
+ before returning a runtime handle. The kernel calls cleanup once and continues
151
+ cleaning other attempted resources even if one close fails.
152
+
153
+ ### Handing a resource to the resources that depend on it
154
+
155
+ `dependsOn` says *when*. To say *what*, return a `value` from `start` and read
156
+ it with `context.use(...)`:
157
+
158
+ ```ts
159
+ const database = defineManagedResource({
160
+ id: 'database',
161
+ start: async ({ signal }) => ({ value: await connect(env.DATABASE_URL, signal) }),
162
+ })
163
+
164
+ const worker = defineManagedResource({
165
+ id: 'worker',
166
+ dependsOn: [database],
167
+ start: (context) => {
168
+ const db = context.use(database) // Connection — not Connection | null
169
+ return { completion: consume(db, context.signal) }
170
+ },
171
+ })
172
+ ```
173
+
174
+ Declare the dependency with the **resource**, not its id, whenever you intend to
175
+ read from it: that is the form `use` can type, and it keeps the declaration and
176
+ the read from drifting apart. A string still works when all you need is order.
177
+
178
+ `managedServerResource` follows the same rule. Its factory receives this context
179
+ during `start`, so constructing routes from a database/service/socket value does
180
+ not need an outer mutable handoff or a custom `start` override. A zero-argument
181
+ factory remains valid when it needs only ordering, and an already-running handle
182
+ can still be passed directly. → ADR 0121.
183
+
184
+ The value is published when `start` resolves and stays readable for the rest of
185
+ the application's life — from `activate` and from the shutdown phases too, where
186
+ a dependant may still need the handle it was given.
187
+
188
+ `use` refuses two things, both loudly: a resource that was never declared in
189
+ `dependsOn` (it happens to work whenever declaration order is lucky), and a
190
+ resource that published nothing. The second is refused by the compiler as well —
191
+ reading a value off a resource with no `value` in its `start` does not type.
192
+
193
+ ## Readiness and health
194
+
195
+ `await app.start()` resolves only after every required resource is ready and
196
+ every required post-ready activation has succeeded. Lifecycle `ready` is
197
+ published before activation so schedules never arm during `starting`;
198
+ application admission opens only after successful activation. Optional failure
199
+ may retain lifecycle `ready`, but snapshot health is `degraded`, never
200
+ `healthy`.
201
+
202
+ Readiness is not hidden polling. A resource reports health changes through its
203
+ lifecycle context; the application decides when a database/provider probe runs.
204
+
205
+ **A `reportHealth` call inside `start` is kept.** A resource that says nothing
206
+ is assumed healthy once it is ready; one that reports its own health has already
207
+ answered the question, and the answer stands. (It used to be overwritten — and
208
+ the example above hides that, because `healthy` is the same value that
209
+ overwrote it.)
210
+
211
+ **A resource is required unless you write `required: false`.** That default is
212
+ what makes the next sentence bite.
213
+
214
+ **Readiness requires every required resource to be healthy**, so "ready but
215
+ degraded" is unreachable for a required resource by construction: an
216
+ application whose required resource reports anything but `healthy` refuses to
217
+ start, and says which resource and in what state. The refusal distinguishes the
218
+ two ways to get there — a resource that was never healthy is pointed at
219
+ `required: false`; one that was healthy and stopped is pointed at
220
+ `onResourceFailure`. A resource that is *expected* to start
221
+ degraded — up, but still dialling something external — belongs behind
222
+ `required: false`, where it keeps its own health and does not gate the
223
+ application:
224
+
225
+ ```ts
226
+ defineManagedResource({
227
+ id: 'dialling',
228
+ required: false,
229
+ start: ({ reportHealth }) => { reportHealth('degraded') },
230
+ })
231
+ ```
232
+
233
+ An optional resource reporting non-healthy does not gate readiness, but it does
234
+ move the application **aggregate** to `degraded` — which a readiness endpoint
235
+ mapping `degraded` to non-200 will notice.
236
+
237
+ If startup fails, every resource that was already started is closed in reverse
238
+ order. The rollback runs **one** phase — `close` — not the five a real shutdown
239
+ runs, and `close` receives the same deadlines a shutdown would give it, so a
240
+ server drains what is in flight instead of aborting it.
241
+
242
+ Those deadlines come from the application's declared budget, and it is worth
243
+ knowing what they cost. With nothing in flight the rollback returns at once: a
244
+ grace period is a ceiling, not a sleep. With something in flight it waits for
245
+ it — that is the point — and with something that **never finishes**, a hung
246
+ upstream or a client that ignores a close frame, it waits out the whole budget
247
+ before forcing. Under the default 30s+5s that turns a failed `start()` that used
248
+ to reject in milliseconds into one that can take 35 seconds to reject.
249
+
250
+ An application that would rather hear about a broken start immediately says so,
251
+ in the one place both stopping paths read:
252
+
253
+ ```ts
254
+ createApplication({
255
+ id: 'app',
256
+ resources,
257
+ // Applies to `shutdown()` called with no options AND to the rollback of a
258
+ // failed `start()`, which has no call site of its own to be told.
259
+ shutdown: { gracePeriodMs: 5_000, forceTimeoutMs: 1_000 },
260
+ })
261
+ ```
262
+
263
+ The budget is a real bound, not just a number handed to each resource: a `close`
264
+ that never returns is abandoned when the budget runs out, reported as a `close`
265
+ failure, and the startup error stays the `cause` of the `AggregateError` that
266
+ `start()` rejects with. Without that, one unresponsive resource could keep a
267
+ failed startup from ever reporting why it failed.
268
+
269
+ A required long-lived completion that rejects after startup makes readiness
270
+ false and health unhealthy. Stitchkit records the failure but does not restart
271
+ the resource or process.
272
+
273
+ `ApplicationResourceShutdown.failures` names the phase that failed — `start`,
274
+ `ready`, `completion`, `admission`, `drain`, `close`, `force` — and nothing
275
+ else. To learn *why*, pass `onResourceFailure`:
276
+
277
+ ```ts
278
+ createApplication({
279
+ id: 'app',
280
+ resources,
281
+ onResourceFailure: ({ resourceId, phase, error }) => {
282
+ log.error({ resourceId, phase, err: error }, 'managed resource failed')
283
+ },
284
+ })
285
+ ```
286
+
287
+ It fires for every phase, including the one place the cause would otherwise be
288
+ lost entirely: an **optional** resource failing to start. A required one
289
+ rethrows, so its cause reaches you anyway; an optional one is swallowed on
290
+ purpose, because the application keeps running. A throwing observer cannot
291
+ break the lifecycle it observes.
292
+
293
+ `createApplicationHealthHandler` publishes an `ApplicationStatusProjection`
294
+ through a Fetch-compatible handler, suitable for a raw route on Bun or Node.
295
+ The projection carries the verdict — the application's own `id`, `lifecycle`,
296
+ `health`, `ready`, `capturedAt` and resource **counts** — and never the internal
297
+ topology: no per-resource ids, no `dependsOn` edges, no process `epoch`, no
298
+ admission counters.
299
+ Those stay in `getSnapshot()`, which never leaves the process, and in whatever
300
+ telemetry you wire to it. Product-specific probes may be composed beside it; do
301
+ not put secrets or raw provider failures in the response.
302
+
303
+ For the conventional three-route surface, reuse the same semantics instead of
304
+ copying them into the application:
305
+
306
+ ```ts
307
+ const operational = createApplicationOperationalHandlers(app)
308
+
309
+ const rawRoutes = [
310
+ { method: 'GET', path: '/status', handler: operational.status },
311
+ { method: 'GET', path: '/ready', handler: operational.readiness },
312
+ { method: 'GET', path: '/live', handler: operational.liveness },
313
+ ]
314
+ ```
315
+
316
+ `status` always returns the current published projection with HTTP 200,
317
+ including while starting, draining or stopped. To read the full snapshot — every
318
+ resource, its dependency edges and the live counters — call `app.getSnapshot()`
319
+ in-process; there is no option that publishes it over HTTP, because these routes
320
+ are meant to be reachable. The two probes retain the existing
321
+ readiness/liveness status and `Retry-After` policy.
322
+
323
+ Applications that already own an OpenTelemetry SDK may inject its `Meter` into
324
+ the isolated adapter:
325
+
326
+ ```ts
327
+ import { createApplicationOpenTelemetry } from 'stitchkit/application/opentelemetry'
328
+
329
+ const telemetry = createApplicationOpenTelemetry({
330
+ meter,
331
+ application: app,
332
+ activities: [activity],
333
+ schedules: [schedule],
334
+ })
335
+
336
+ // During application cleanup:
337
+ telemetry.close()
338
+ ```
339
+
340
+ The adapter registers fixed observable gauges and pulls the latest canonical
341
+ snapshots on every collection. It owns no exporter, SDK lifecycle, cache,
342
+ subscription or polling loop. Attributes are limited to declared application,
343
+ resource, activity, stage and schedule IDs plus bounded framework states;
344
+ epoch, revision, timestamps, failures and product/provider identities are never
345
+ metric attributes. Install `@opentelemetry/api` only when this entrypoint is
346
+ used; the neutral `stitchkit/application` graph remains peer-free.
347
+
348
+ Every instrument uses unit `1` and reports an absolute current/lifetime value:
349
+
350
+ | Instruments | Meaning |
351
+ |---|---|
352
+ | `stitchkit.application.lifecycle`, `.ready` | current lifecycle/health fact and readiness |
353
+ | `stitchkit.application.admission.accepting`, `.accepted`, `.completed`, `.pending` | current gate and absolute lifetime admission counts |
354
+ | `stitchkit.application.resource.ready` | readiness for each declared resource with required/state/health attributes |
355
+ | `stitchkit.application.schedule.accepting`, `.active`, `.queued`, `.runs_started`, `.runs_completed`, `.runs_failed`, `.ticks_skipped` | current schedule state and absolute run/tick counts |
356
+ | `stitchkit.application.activity.active`, `.queued`, `.completed`, `.failed` | absolute stage projections for declared activity sources |
357
+
358
+ ## Replacing part of the graph without stopping the process
359
+
360
+ `restart` takes down one resource **and everything that depends on it**, then
361
+ brings that subtree back. Everything else keeps running, and the process epoch
362
+ does not move.
363
+
364
+ ```ts
365
+ const result = await app.restart({ resourceId: 'database' })
366
+
367
+ result.outcome // 'restarted' | 'failed' | 'refused'
368
+ result.affected // ['database', 'repository', 'api'] — in start order
369
+ ```
370
+
371
+ The dependants come down with it because they are holding what the resource
372
+ published. A repository that kept running across a database replacement holds a
373
+ pool that has been closed: it still typechecks, still has methods, and fails at
374
+ whatever moment the first call happens. There is no version of this where a
375
+ dependant keeps a live handle, so the subtree — not the resource — is the unit.
376
+
377
+ A leaf restart affects one resource, and an independent neighbour is never
378
+ touched:
379
+
380
+ ```ts
381
+ await app.restart({ resourceId: 'cache' })
382
+ // mailer and database were not stopped, not started, not activated
383
+ ```
384
+
385
+ **Refused is not failed.** An unknown id, a restart during shutdown, and a
386
+ restart before the application is ready all return `refused` with a reason and
387
+ touch nothing. `failed` means the subtree came down and the new generation did
388
+ not come up — and the result agrees with the snapshot: if any affected resource
389
+ ends the restart in `failed`, so does the restart, including an optional one
390
+ whose failure the start loop does not re-throw.
391
+
392
+ **The close phase is bounded**, by the application's shutdown budget or by one
393
+ this call names:
394
+
395
+ ```ts
396
+ await app.restart({ resourceId: 'database', gracePeriodMs: 5_000, forceTimeoutMs: 2_000 })
397
+ ```
398
+
399
+ **A resource has to be able to start twice.** The kernel calls `start` again, so
400
+ a resource holding state across its own lifetime rebuilds it there. The ones this
401
+ framework ships do — a schedule re-arms, a keyspace opens a new generation and
402
+ re-loads, a managed server built from a factory gets a fresh server. A managed
403
+ server given a server *instance* cannot, and says so by name rather than
404
+ republishing something it has shut down. Give a keyspace a
405
+ `backend: () => …` factory when its backend cannot be re-opened after `close()`.
406
+
407
+ → [ADR 0157](../decisions/0157-a-restartable-resource-begins-a-generation.md).
408
+
409
+ Restarts of overlapping subtrees queue behind each other rather than being
410
+ refused. Two callers asking at once is ordinary; two generations of one resource
411
+ alive at once is the thing this must make impossible.
412
+
413
+ ```ts
414
+ // Both succeed, one complete pass after the other.
415
+ await Promise.all([
416
+ app.restart({ resourceId: 'database' }),
417
+ app.restart({ resourceId: 'database' }),
418
+ ])
419
+ ```
420
+
421
+ What a restart is **not** is a process restart: it replaces resources, and does
422
+ not re-read configuration the kernel captured when it was constructed.
423
+
424
+ → [ADR 0154](../decisions/0154-the-unit-of-a-restart-is-the-subtree.md).
425
+
426
+ ## Decisions a policy set makes together
427
+
428
+ `createDecisionPipeline` runs an ordered list of policies that each vote
429
+ `allow`, `deny` (with a reason) or `defer`. The first terminal verdict wins and
430
+ the rest do not run.
431
+
432
+ ```ts
433
+ import { createDecisionPipeline } from 'stitchkit/application'
434
+
435
+ const pipeline = createDecisionPipeline<{ userId: string; scope: string }>([
436
+ { id: 'banned', decide: (r) => (isBanned(r.userId)
437
+ ? { outcome: 'deny', reason: 'account suspended' }
438
+ : { outcome: 'defer' }) },
439
+ { id: 'scope', decide: (r) => (r.scope === 'admin'
440
+ ? { outcome: 'allow' }
441
+ : { outcome: 'defer' }) },
442
+ { id: 'default', decide: () => ({ outcome: 'deny', reason: 'no policy allowed this' }) },
443
+ ], { policyTimeoutMs: 2_000 })
444
+
445
+ const result = await pipeline.decide(request)
446
+ result.outcome // 'allow' | 'deny' — never 'defer'
447
+ result.trace // the policies that actually ran, in order
448
+ ```
449
+
450
+ Three things are deliberate.
451
+
452
+ **A deny carries a reason, by schema.** `{ outcome: 'deny' }` alone does not
453
+ typecheck. A refusal whose cause exists only in the log of whoever refused is a
454
+ support ticket.
455
+
456
+ **The trace is what ran, not what was declared.** It stops at the terminal
457
+ verdict. When something was denied the question is which policy denied it and
458
+ what the ones before it said, and a trace listing policies that never ran would
459
+ answer that wrongly while looking complete.
460
+
461
+ **Every policy deferring raises.** `DecisionUndecidedError`, not a default —
462
+ defaulting to `allow` turns an incomplete policy set into an open door, and
463
+ defaulting to `deny` turns it into an outage whose cause reads as a legitimate
464
+ refusal.
465
+
466
+ **A policy that does not answer raises too.** A non-decision, a throw, and running
467
+ past `policyTimeoutMs` are one error — `DecisionPolicyError`, naming the policy
468
+ and carrying the trace so far — because they are indistinguishable downstream and
469
+ handling one but not the others is how a broken policy becomes a skipped one. The
470
+ chain stops there rather than falling through to whatever the next policy would
471
+ have said.
472
+
473
+ `policyTimeoutMs` is required and has no default. Pick a number your slowest
474
+ policy comfortably beats. The framework will not choose it for you: a policy that
475
+ never settles hangs every caller of the operation it guards, and a default here
476
+ is a number nobody chose applied to code the framework has never seen.
477
+
478
+ The same `allow`/`deny`/`defer` type is what an event topic declared
479
+ `mode: 'decision'` uses in `stitchkit/live` — one vocabulary, because a listener
480
+ voting on an event and a policy voting on a request are answering the same
481
+ question.
482
+
483
+ → [ADR 0155](../decisions/0155-one-decision-vocabulary-and-an-unanswered-question-is-an-error.md).
484
+
485
+ ## Admission and graceful shutdown
486
+
487
+ Use the application operation lease for work that is not already counted by a
488
+ managed resource:
489
+
490
+ ```ts
491
+ const operation = app.admission.acquire()
492
+ if (!operation) return Response.json({ error: 'unavailable' }, { status: 503 })
493
+
494
+ try {
495
+ await performAcceptedWork()
496
+ } finally {
497
+ operation.release()
498
+ }
499
+ ```
500
+
501
+ `release()` is idempotent. Admission and counter increment are atomic, so work
502
+ cannot slip between the shutdown check and drain accounting.
503
+
504
+ `managedServerResource` already owns contract/streaming-route response lifetimes. It cancels
505
+ their supplied signals at admission close and awaits source cleanup before dependent resources
506
+ close. Do not add application admission leases or a second cancellation registry for those
507
+ streams. A source that ignores cancellation or fails its cleanup prevents a clean shutdown;
508
+ the existing grace and force budgets still bound the result.
509
+
510
+ ### Bounded operation admission
511
+
512
+ Compose `createBoundedAdmission` when accepted work also competes for a finite
513
+ process-local resource:
514
+
515
+ ```ts
516
+ const generations = createBoundedAdmission({
517
+ upstream: app.admission,
518
+ policy: {
519
+ global: { maxConcurrent: 8, rate: { limit: 120, intervalMs: 60_000 } },
520
+ perKey: { maxConcurrent: 1, maxKeys: 2_000 },
521
+ },
522
+ })
523
+
524
+ await generations.run(accountId, ({ signal }) => generate({ signal }), {
525
+ signal: request.signal,
526
+ timeoutMs: 30_000,
527
+ })
528
+ ```
529
+
530
+ Acquisition is no-queue and atomic across every configured budget. Refusal names
531
+ the exact bound; only a rate refusal carries `retryAfterMs`. `maxKeys` keeps the
532
+ per-key registry finite, and expired idle entries are retired.
533
+
534
+ The caller timeout is a wait budget, not proof that the resource stopped. It
535
+ aborts the signal and settles the caller, but the lease remains active until the
536
+ underlying Promise actually settles. `drain()` therefore reports real work;
537
+ `force()` closes admission and reports remaining work without claiming to have
538
+ terminated it. → ADR 0118.
539
+
540
+ ### Bounded revision wake-up
541
+
542
+ Use `createRevisionSignal` when several operations need to wait for the same
543
+ process-local fact to change, but the change itself is not a queue item:
544
+
545
+ ```ts
546
+ const connectionsChanged = createRevisionSignal({ maxWaiters: 256 })
547
+
548
+ const observed = connectionsChanged.getSnapshot().revision
549
+ const result = await connectionsChanged.wait(observed, {
550
+ signal: request.signal,
551
+ timeoutMs: 10_000,
552
+ })
553
+
554
+ // After changing the canonical connection state:
555
+ connectionsChanged.advance()
556
+ ```
557
+
558
+ `wait(after)` resolves immediately when the signal is already newer than
559
+ `after`; this closes the race between reading a snapshot and registering the
560
+ wait. Waiting on the current revision parks one operation, up to `maxWaiters`.
561
+ Every terminal result carries the revision it observed and distinguishes
562
+ `changed`, `timed-out`, `aborted`, `closed` and `capacity`. A future `after` is
563
+ a caller error rather than a revision the signal could honestly promise to
564
+ reach.
565
+
566
+ One advance wakes every older waiter. It is not consumed by the first reader,
567
+ does not retain event payloads and has no replay history. A bounded channel is
568
+ for delivering items to one reader; a credit window grants a finite resource.
569
+
570
+ The signal is already its whole lifecycle handle. Call its idempotent `close()`
571
+ from the `close` phase of the managed resource that owns the changing fact;
572
+ there is no second managed-resource wrapper around the same state. → ADR 0163.
573
+
574
+ ### Bounded delivery and byte credit
575
+
576
+ `createBoundedChannel` is for one asynchronous reader when an event bus is not a
577
+ queue:
578
+
579
+ ```ts
580
+ const output = createBoundedChannel<string>({
581
+ policy: 'ordered',
582
+ maxItems: 64,
583
+ maxBytes: 256 * 1024,
584
+ sizeOf: (value) => new TextEncoder().encode(value).byteLength,
585
+ })
586
+
587
+ const progress = createBoundedChannel<{ revision: number }>({
588
+ policy: 'latest',
589
+ maxItems: 1,
590
+ maxBytes: 128,
591
+ sizeOf: () => 128,
592
+ })
593
+ ```
594
+
595
+ `ordered` never overwrites accepted values; overflow is a reasoned refusal.
596
+ `latest` retains exactly one pending replaceable value and reports
597
+ `coalesced`. Offers never create a hidden writer queue, and only one `next()` may
598
+ wait. Close chooses `drain` (default) or `discard`; abort discards; failure
599
+ rejects the parked and all later reads.
600
+
601
+ `createCreditWindow({ capacityBytes })` is the smaller primitive for a protocol
602
+ that already owns its queue but needs exact byte permission. Each credit lease
603
+ replenishes once; it is flow-control credit, not a durable acknowledgement. The
604
+ application snapshot sink now shares the same latest-value mechanics without
605
+ changing its revision or status contract. → ADR 0119.
606
+
607
+ ### Bounded local diagnostic journal
608
+
609
+ Use `createDiagnosticJournal` when a process needs finite, ordered local metadata evidence and the
610
+ deployment log pipeline is not the right boundary:
611
+
612
+ It lives at `stitchkit/application/diagnostic-journal`, not in the main barrel:
613
+ it is the one part of the kernel that spawns, locks and writes files, and while it
614
+ was exported from `stitchkit/application` that single line made the whole
615
+ entrypoint unusable in a browser bundle. Its schemas stay in
616
+ `stitchkit/application`.
617
+
618
+ ```ts
619
+ import { createDiagnosticJournal } from 'stitchkit/application/diagnostic-journal'
620
+ import { z } from 'zod'
621
+
622
+ const journal = await createDiagnosticJournal({
623
+ eventSchema: z.object({
624
+ kind: z.enum(['resource_failed', 'recovery_started']),
625
+ resource: z.string().max(80),
626
+ }).strict(),
627
+ path: '/var/lib/example/diagnostic.jsonl', // operator configuration, never request data
628
+ limits: {
629
+ maxEventBytes: 4 * 1024,
630
+ maxPendingItems: 128,
631
+ maxPendingBytes: 512 * 1024,
632
+ maxFileBytes: 8 * 1024 * 1024,
633
+ maxFiles: 4,
634
+ },
635
+ onFailure: (failure) => internalLogger.error(failure),
636
+ })
637
+
638
+ const result = journal.submit({ kind: 'recovery_started', resource: 'database' })
639
+ if (result.outcome === 'refused') internalCounter.add(1, { reason: result.reason })
640
+
641
+ // During managed-resource close. Timeout ends this wait, not the physical append.
642
+ await journal.close({ timeoutMs: 5_000 })
643
+ ```
644
+
645
+ The owner schema and JSON serialization run synchronously before admission. Accepted frames carry
646
+ a process epoch and contiguous sequence and retain their complete bytes inside both pending limits
647
+ until their append attempt settles. Capacity, invalid, oversized, closed and terminal-failure
648
+ refusals are explicit; accepted ordered frames are never evicted.
649
+
650
+ The absolute path's parent must already exist and be operator-controlled. One manager owns it via
651
+ an exclusive `.lock`; new files use mode `0600` by default. `maxFiles` includes the active file,
652
+ and a non-newline startup tail is rotated intact rather than guessed or repaired. An abrupt process
653
+ death may leave the lock for an operator to remove only after proving the former owner is gone.
654
+
655
+ `flush()` means every accepted append through that call's boundary settled. It is not `fsync`, a
656
+ durable receipt, exactly-once execution or remote delivery. Timeout/cancellation bound only the
657
+ waiter; the writer retains physical capacity until settlement. There is no reader or upload API.
658
+ Use a durable application store or deployment-owned log collector when restart recovery, replay or
659
+ aggregation is required. → [ADR 0134](../decisions/0134-diagnostic-journal-is-bounded-local-evidence.md).
660
+
661
+ Shutdown performs one phase barrier at a time: stop admission everywhere,
662
+ cancel future schedules, drain admitted work, then close in reverse stable
663
+ topological order. Every hook shares the same grace deadline. Forced cleanup
664
+ shares one force deadline. Repeated `shutdown()` calls return the cached promise;
665
+ a repeated process signal forces that same chain.
666
+
667
+ Do not add a second `process.on('SIGTERM')` handler around the application.
668
+ `bindProcessSignals(app)` is the force/escalation owner. Exit code and hard-exit
669
+ policy remain application/supervisor choices.
670
+
671
+ **Where the budget comes from on the signal path.** `bindProcessSignals(app)`
672
+ with no `shutdown` forwards nothing, so the application spends the budget it
673
+ declared in `createApplication({ shutdown })`. Pass `shutdown` to the binding
674
+ only to override that budget for signals specifically; passing one key overrides
675
+ that key alone and leaves the other at the declaration. Declare the budget once,
676
+ on the application — repeating it in both places is how the two numbers start to
677
+ disagree, and the operator's supervisor timeout is calculated from the one they
678
+ can read.
679
+
680
+ ## Managed schedules
681
+
682
+ Schedules activate only after top-level readiness:
683
+
684
+ ```ts
685
+ createManagedSchedule({
686
+ id: 'reconcile',
687
+ everyMs: 5_000,
688
+ startAfterMs: 0,
689
+ overlap: { mode: 'queue-one' },
690
+ errorPolicy: 'continue',
691
+ onError: (error) => internalLogger.error(error),
692
+ run: ({ signal }) => reconcile(signal),
693
+ })
694
+ ```
695
+
696
+ - `skip` ignores a due tick while one execution is active.
697
+ - `queue-one` retains one successor; additional due ticks coalesce.
698
+ - `parallel` requires `maxConcurrent`; overflow skips rather than creating a
699
+ hidden queue.
700
+
701
+ The callback receives the application shutdown signal. Normal shutdown waits
702
+ for admitted executions; force aborts the shared signal. There are no retries,
703
+ cron/timezone rules, persisted cursors, backfill or cross-process locks. Put
704
+ those semantics in a durable application scheduler when they are required.
705
+ Schedule cadence stays monotonic, while status snapshots expose ISO wall-clock
706
+ `capturedAt`, `changedAt` and next/last-run timestamps for portable observation.
707
+
708
+ ## Operational projection
709
+
710
+ Declare aggregate activity stages, then update them with anonymous handles:
711
+
712
+ ```ts
713
+ const generations = createActivityProjection({
714
+ id: 'generation',
715
+ stages: ['queued', 'running', 'finalizing'],
716
+ })
717
+
718
+ const activity = generations.open('queued', 'queued')
719
+ generations.transition(activity, { stage: 'running', state: 'active' })
720
+ generations.transition(activity, { stage: 'finalizing', state: 'active' })
721
+ generations.complete(activity)
722
+ ```
723
+
724
+ Item identity is deliberately absent from the snapshot. Observers receive
725
+ aggregate counts with application identity, process epoch, revision and
726
+ timestamps. Calling a terminal method twice does not double-count.
727
+
728
+ ```ts
729
+ const sink = createApplicationSnapshotSink({
730
+ write: (snapshot) => publishOperationalSnapshot(snapshot),
731
+ })
732
+
733
+ const unsubscribe = generations.subscribe((snapshot) => {
734
+ sink.publish(snapshot)
735
+ })
736
+
737
+ // During application cleanup:
738
+ unsubscribe()
739
+ await sink.close()
740
+ ```
741
+
742
+ The sink replays the current absolute value and coalesces obsolete pending
743
+ revisions behind a slow write. Sink failure is observable but cannot fail the
744
+ application operation that changed the projection.
745
+
746
+ ## Optional grammY adapter
747
+
748
+ Install grammY only in an application that imports the adapter:
749
+
750
+ ```ts
751
+ import { Bot } from 'grammy'
752
+ import {
753
+ createGrammyWebhookResource,
754
+ grammyPollingResource,
755
+ } from 'stitchkit/application/grammy'
756
+ ```
757
+
758
+ For simple long polling, pass an already-configured bot:
759
+
760
+ ```ts
761
+ const bot = new Bot(env.BOT_TOKEN)
762
+ bot.command('start', (ctx) => ctx.reply('Hello'))
763
+ bot.catch(({ error }) => internalLogger.error(error))
764
+
765
+ const telegram = grammyPollingResource({
766
+ id: 'telegram',
767
+ bot,
768
+ required: true,
769
+ })
770
+ ```
771
+
772
+ Readiness follows grammY's `onStart`. Shutdown calls `bot.stop()` once and then
773
+ awaits the retained `bot.start()` promise, because grammY documents that
774
+ `stop()` alone does not wait for middleware completion.
775
+
776
+ For webhook ingress, `createGrammyWebhookResource` wraps provider-owned update
777
+ handling with admission and drain. The application still mounts the HTTP route,
778
+ verifies/configures its webhook and chooses the grammY framework adapter. An
779
+ update accepted before shutdown may finish; a later update is rejected.
780
+
781
+ The adapter never reads the token/env, installs commands, changes `bot.catch`,
782
+ chooses retry plugins, drops pending updates, sends outbound messages or stores
783
+ updates. A durable inbox/retry worker remains an application component, not a
784
+ mode of this adapter.
785
+
786
+ ## What disappears from an application
787
+
788
+ A typical small service can replace roughly 120–220 lines of generic signal,
789
+ timer, admission and close bookkeeping with resource declarations. A larger
790
+ multi-resource service commonly carries 250–450 generic lifecycle lines plus
791
+ 15–30 lines for each periodic timer. These are directional review estimates,
792
+ not an API guarantee.
793
+
794
+ The responsibility change is more important than line count:
795
+
796
+ | Before | After |
797
+ |---|---|
798
+ | hand-written phase enum and readiness waiters | `createApplication` snapshot |
799
+ | `process.on` signal loop and escalation | `bindProcessSignals(app)` |
800
+ | interval/timeout handles and overlap flag | `createManagedSchedule` |
801
+ | global in-flight counter and drain waiter set | application operation leases |
802
+ | manual stop/close fan-out | resource graph + bounded shutdown |
803
+ | progress delta events | absolute activity projection |
804
+
805
+ Durable job tables, lifecycle journals/outboxes, provider inboxes and business
806
+ retry rules do **not** disappear. They were never process-local glue and remain
807
+ application-owned.
808
+
809
+ ## Durable process facts and owner notifications
810
+
811
+ `createProcessLifecycleLedger` records a bounded versioned list of process runs.
812
+ Start, readiness and shutdown target both `runId` and `pid`, so hot reload and
813
+ PID reuse cannot close the wrong generation. A start classifies what happened to
814
+ the newest run before it, and the classification is decided by three facts —
815
+ whether that run recorded its own exit, whether the pid is the same, and whether
816
+ the version changed:
817
+
818
+ | newest run | same pid | version | `previousExit` | predecessor's `termination` |
819
+ |---|---|---|---|---|
820
+ | none | — | — | `first-boot` | — |
821
+ | recorded `stoppedAt` | — | — | `clean` / `forced` / `abnormal` as recorded | unchanged |
822
+ | still `active` | yes | — | `hot-reload` | `hot-reload`, closed at the new start |
823
+ | still `active` | no | changed | `handoff` | stays `active`; it records its own stop later |
824
+ | still `active` | no | same | `abnormal` (default) | `abnormal`, closed at the new start — an upper bound, the crash time is unknown |
825
+
826
+ A version of `unknown` on either side is never a version change, so a dev build
827
+ after a crashed release reads `abnormal`, not `handoff`. `forced` means the
828
+ process itself acknowledged a kill; `abnormal` means a successor found it dead.
829
+
830
+ The last row is a choice, and the default is the single-process deployment:
831
+ one process per build, a new pid of the same build means the old one stopped
832
+ answering. Where two processes of **one** build overlap on purpose — a
833
+ cluster, a zero-downtime reload of the same build — pass
834
+ `sameVersionOverlap: 'handoff'` to the ledger, and the predecessor stays
835
+ `active` until it records its own shutdown. The cost of that setting is
836
+ symmetric: a real crash under it is reported as a handoff and the dead run
837
+ stays `active` in the ledger until retention drops it. The list is kept in the
838
+ order the transitions wrote it — every write goes through one atomic update,
839
+ so that order is the causal one, and a successor whose clock lags its
840
+ predecessor still finds it at the head; `startedAt` is data, not the sort key.
841
+ Retention (`retain`, default 20) drops finished runs first and an active one —
842
+ a live handoff predecessor — only when nothing finished is left. Facts are
843
+ published through the ledger's own subscription and resource value;
844
+ `ApplicationEventSink` remains the strict application-state stream.
845
+
846
+ `createNotificationOutbox` is the transport-neutral durable delivery side. It
847
+ persists before send, claims an item with an expiring lease, carries one stable
848
+ idempotency key into the transport, retries under an injected clock and records
849
+ terminal drops. The guarantee is at-least-once: a crash after remote acceptance
850
+ but before the receipt is persisted may redeliver, so transports should use the
851
+ key when they support deduplication. The retry budget is sized for the outage
852
+ an owner notification has to outlive, not for a flaky call: the default backoff
853
+ doubles from one second and caps at sixty (`backoffDelay`, the one formula the
854
+ client's resumable streams also use, with jitter 0), and the 99 waits between
855
+ the default `maxAttempts` of 100 sum to 1+2+4+8+16+32 s plus 93 × 60 s — about
856
+ 94 minutes — before `onDropped` sees `attempt-limit`.
857
+ `state()` is a read and never fails on the bounds a transition enforces — a file
858
+ that grew past `maxStateBytes` under an older limit is inspectable and is
859
+ trimmed by the next transition. Two bounds do fail loudly: `enqueue` past
860
+ `maxQueue` throws rather than dropping silently, and a `backoffMs` that returns
861
+ `NaN`, a negative or an infinite delay rejects the flush. `stop()` lets the
862
+ send in flight finish and claims nothing more; a `send` without its own
863
+ deadline holds `stop()` — and so the resource's `force()` — for that one call,
864
+ so give the transport a timeout. Superseding a key that is being sent right now
865
+ does not recall it: the send completes, and only its receipt is not written.
866
+
867
+ Both primitives depend on the structural `StateStore`. On a server,
868
+ `createFileStateStore` supplies the shared Zod-validated JSON adapter with an
869
+ inter-process lock, unique temporary file, fsync and atomic rename. The lock
870
+ is a file with a heartbeat: the holder refreshes its mtime every third of
871
+ `staleLockMs` (default 3 s), a contender waits up to `lockTimeoutMs` (default
872
+ 10 s), and the stale bound must sit inside the timeout — otherwise a crashed
873
+ holder blocks every update until the lock ages out, which the constructor
874
+ refuses. A lock whose heartbeat is stale is reclaimed once its recorded pid is
875
+ gone; a live or unverifiable pid (a reused number, another user's process)
876
+ keeps it for ten stale bounds — and never fewer than thirty missed heartbeats,
877
+ so a scheduler stall on a loaded host cannot pull a live lock from under its
878
+ holder — after which the heartbeat wins and the lock is abandoned. Temporary files a crashed writer left beside the state are swept on
879
+ the store's first update. Ledger corruption may be declared reconstructable;
880
+ an outbox must fail closed rather than silently discard pending delivery.
881
+
882
+ ==============================================================================
883
+ # Guide: Application migration recipes (docs/guide/application-migration-recipes.md)
884
+ ==============================================================================
885
+
886
+ ---
887
+ title: Application migration recipes
888
+ description: Executable patterns for moving database, poller, queue and operational publishing lifecycle into the managed application kernel.
889
+ type: architecture
890
+ status: active
891
+ created: 2026-08-24
892
+ updated: 2026-08-24
893
+ ---
894
+
895
+ # Application migration recipes
896
+
897
+ These recipes are the migration companion to the
898
+ [managed application kernel](./application-kernel.md). Their canonical source is
899
+ the packed-consumer fixture
900
+ [`application-migration-recipes.ts`](../../packages/core/scripts/consumer-lane/fixtures/minimal/src/application-migration-recipes.ts):
901
+ the consumer lane installs the package tarball, typechecks that file and runs it
902
+ only through `stitchkit/application` exports.
903
+
904
+ ## Database connection
905
+
906
+ Wrap connection allocation and readiness in `start`, and make `close` safe after
907
+ partial setup. Stitchkit invokes cleanup for every attempted start, including a
908
+ start that allocates a client and then rejects.
909
+
910
+ ```ts
911
+ const database = defineManagedResource({
912
+ id: 'database',
913
+ async start({ signal, reportHealth }) {
914
+ await databaseClient.connect(signal)
915
+ await databaseClient.assertReady()
916
+ reportHealth('healthy')
917
+ },
918
+ close: () => databaseClient.close(),
919
+ })
920
+ ```
921
+
922
+ The application still owns the client, ORM configuration, transactions,
923
+ migrations and reconnect policy. The executable recipe deliberately fails after
924
+ allocation and proves one rollback close.
925
+
926
+ ## Long-running poller
927
+
928
+ Return separate readiness and completion promises. Readiness says dependants may
929
+ start; completion represents the whole background lifetime.
930
+
931
+ ```ts
932
+ const poller = defineManagedResource({
933
+ id: 'poller',
934
+ start: ({ signal }) => ({
935
+ ready: providerPoller.ready,
936
+ completion: providerPoller.run(signal),
937
+ }),
938
+ stopAdmission: () => providerPoller.stop(),
939
+ drain: () => providerPoller.completion,
940
+ close: () => providerPoller.close(),
941
+ })
942
+ ```
943
+
944
+ Completion before readiness fails startup and rolls back. Completion after
945
+ readiness removes application readiness. Provider cursor persistence, retry,
946
+ backoff and restart policy remain application/provider concerns.
947
+
948
+ ## Queue consumer
949
+
950
+ Acquire the application lease only after provider delivery/claim. If admission
951
+ is already closed, reject the delivery through the provider's own nack/requeue
952
+ primitive. Work admitted before shutdown releases its lease after ack/nack and
953
+ therefore participates in application drain.
954
+
955
+ ```ts
956
+ async function handleDelivery(delivery: Delivery) {
957
+ const lease = app.admission.acquire()
958
+ if (!lease) return delivery.nack({ requeue: true })
959
+ try {
960
+ await processClaim(delivery.claim)
961
+ await delivery.ack()
962
+ } catch (error) {
963
+ await delivery.nack({ requeue: shouldRetry(error) })
964
+ throw error
965
+ } finally {
966
+ lease.release()
967
+ }
968
+ }
969
+ ```
970
+
971
+ Stitchkit owns only process-local admission accounting and drain. Durable claims,
972
+ visibility timeouts, deduplication, idempotency and retry classification remain
973
+ in the queue/product layer.
974
+
975
+ ## Operational publisher
976
+
977
+ Project anonymous aggregate activity, then feed absolute snapshots into the
978
+ latest-value sink. A slow transport holds one write plus one replaceable latest
979
+ revision rather than an unbounded event queue.
980
+
981
+ ```ts
982
+ const publisher = createApplicationSnapshotSink({
983
+ write: (snapshot) => monitoring.publish(snapshot),
984
+ })
985
+ const activity = createActivityProjection({
986
+ id: 'generation',
987
+ stages: ['queued', 'running'],
988
+ })
989
+ const unsubscribe = activity.subscribe((snapshot) => {
990
+ publisher.publish(snapshot)
991
+ })
992
+
993
+ // cleanup boundary
994
+ unsubscribe()
995
+ publisher.publish(activity.getSnapshot())
996
+ await publisher.close()
997
+ ```
998
+
999
+ The monitoring backend, transport retry and cross-process aggregation remain
1000
+ outside Stitchkit. The executable recipe blocks revision 0, coalesces
1001
+ intermediate revisions, explicitly admits the final absolute snapshot after
1002
+ unsubscribe and proves that `close()` flushes revision 3. Do not rely on an
1003
+ asynchronous subscriber callback racing cleanup: publish `getSnapshot()` before
1004
+ closing the outer sink, so any older or duplicate late delivery is rejected as
1005
+ stale instead of dropping the final state.
1006
+
1007
+ ## Bound a handler and a local worker with one lease policy
1008
+
1009
+ Use a bounded admission when two entry paths consume the same finite local
1010
+ capacity. Composing it with `application.admission` keeps readiness and shutdown
1011
+ as the upstream gate:
1012
+
1013
+ ```ts
1014
+ const work = createBoundedAdmission({
1015
+ upstream: app.admission,
1016
+ policy: {
1017
+ global: { maxConcurrent: 4 },
1018
+ perKey: { maxConcurrent: 1, maxKeys: 1_000 },
1019
+ },
1020
+ })
1021
+
1022
+ const fromHttp = (key: string, signal: AbortSignal) =>
1023
+ work.run(key, (context) => render(context.signal), { signal, timeoutMs: 20_000 })
1024
+
1025
+ const fromWorker = (key: string) =>
1026
+ work.run(key, (context) => reconcile(context.signal))
1027
+ ```
1028
+
1029
+ A timeout in `fromHttp` does not free a permit while `render` remains active.
1030
+ At shutdown call `work.stopAdmission()` with the other admission owners and
1031
+ await `work.drain(...)`; the result reports the actual remainder.
1032
+
1033
+ ## Replace ad-hoc output and progress queues
1034
+
1035
+ Ordered output and replaceable progress are separate declarations:
1036
+
1037
+ ```ts
1038
+ const lines = createBoundedChannel<string>({
1039
+ policy: 'ordered', maxItems: 100, maxBytes: 1_000_000,
1040
+ sizeOf: (line) => new TextEncoder().encode(line).byteLength,
1041
+ })
1042
+
1043
+ const state = createBoundedChannel<{ revision: number; percent: number }>({
1044
+ policy: 'latest', maxItems: 1, maxBytes: 64,
1045
+ sizeOf: () => 64,
1046
+ })
1047
+
1048
+ const lineResult = lines.offer('one durable-in-process ordering unit')
1049
+ const stateResult = state.offer({ revision: 2, percent: 50 })
1050
+ ```
1051
+
1052
+ Handle `refused` from `lines` at the protocol boundary; do not turn it into
1053
+ implicit loss. A `coalesced` state result is expected latest-value behaviour,
1054
+ not evidence that an ordered event was delivered. Neither channel is durable;
1055
+ persist first when restart replay is required.
1056
+
1057
+ ## Handing a handle to the resources that depend on it
1058
+
1059
+ `dependsOn` carries ordering. To carry the object as well, return a `value` from
1060
+ `start` and read it with `context.use(...)`. This replaces the module-local
1061
+ `let handle: T | null` with the guard the graph makes unreachable.
1062
+
1063
+ ```ts
1064
+ const database = defineManagedResource({
1065
+ id: 'database',
1066
+ start: async () => ({ value: await connect(env.DATABASE_URL) }),
1067
+ })
1068
+
1069
+ const worker = defineManagedResource({
1070
+ id: 'worker',
1071
+ dependsOn: [database],
1072
+ start(context) {
1073
+ const db = context.use(database) // Connection — not Connection | null
1074
+ },
1075
+ })
1076
+ ```
1077
+
1078
+ Declare the dependency with the **resource** whenever you intend to read from
1079
+ it: that is the form `use` can type, and it stops the declaration and the read
1080
+ from drifting. A string still expresses order on its own.
1081
+
1082
+ The value is published when `start` resolves and stays readable from `activate`
1083
+ and from the shutdown phases. `use` refuses a resource that was not declared in
1084
+ `dependsOn` — that only ever worked by luck of declaration order — and refuses a
1085
+ resource that published nothing, which the compiler refuses too. The executable
1086
+ recipe proves both the read and the refusal.
1087
+
1088
+ ## Managed HTTP server
1089
+
1090
+ The main resource of a web backend, and the one whose ownership rule is
1091
+ counter-intuitive: give `managedServerResource` a **thunk** and it creates the
1092
+ server during `start`, after its dependencies are ready. Give it an
1093
+ already-listening server and it adopts that one instead.
1094
+
1095
+ ```ts
1096
+ const http = managedServerResource({
1097
+ id: 'http',
1098
+ dependsOn: [database],
1099
+ server: (context) => {
1100
+ const db = context.use(database)
1101
+ return createServer({ port: env.PORT, services: createServices(db) })
1102
+ },
1103
+ })
1104
+
1105
+ const app = createApplication({ id: 'service', resources: [database, http] })
1106
+ await app.start() // the port is bound; the snapshot means it
1107
+ ```
1108
+
1109
+ The server resource publishes its `ManagedServerHandle`, so anything that needs
1110
+ the running server — a Socket.IO attachment, a URL to log, a probe — reads it
1111
+ with `context.use(http)` rather than through a module-local.
1112
+
1113
+ The factory itself receives `ManagedResourceContext` too. It can read only the
1114
+ dependencies declared on the server resource and shares the graph's startup
1115
+ signal. A dependency failure prevents the factory from binding; a factory
1116
+ rejection is rolled back without invoking the factory a second time.
1117
+
1118
+ Do not spread this resource over your own `start` to control creation order:
1119
+ that shape exists only as a workaround for the version whose `start` was empty,
1120
+ and `dependsOn` now expresses the order directly. The executable recipe binds a
1121
+ real port, proves a request reaches it after `start()` resolves, and proves the
1122
+ port is closed after `shutdown()`.
1123
+
1124
+ ## Deletion checklist
1125
+
1126
+ After the cutover, remove the old generic lifecycle path completely:
1127
+
1128
+ - duplicate `process.on(...)` handlers and shutdown promise caches;
1129
+ - manual readiness waiters and resource close fan-out;
1130
+ - raw interval handles, overlap flags and timer drain code;
1131
+ - global in-flight counters and waiter sets replaced by application leases;
1132
+ - progress delta queues replaced by absolute snapshot publishing.
1133
+
1134
+ Keep the product code that still owns durable state and policy:
1135
+
1136
+ - database schema, transactions and migrations;
1137
+ - queue claims, ack/nack, deduplication and external-effect idempotency;
1138
+ - provider cursor, retry/backoff and credentials;
1139
+ - monitoring transport configuration and durable retention;
1140
+ - process exit code, hard-exit and deployment/supervisor policy.
1141
+
1142
+ Run the old and new lifecycle paths separately during development if needed,
1143
+ but do not ship both. Before cutover, verify there is exactly one signal binding,
1144
+ one timer owner, one admission gate and one resource cleanup chain.