airaknit 1.1.2-rc.9

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 (440) hide show
  1. package/LICENSE +84 -0
  2. package/README.md +202 -0
  3. package/bin/airaknit +9 -0
  4. package/bin/airaknit-project +14 -0
  5. package/bin/kanna +9 -0
  6. package/dist/client/assets/CompactSummaryMessage-Yw0BDWEJ.js +1 -0
  7. package/dist/client/assets/ExitPlanModeMessage-DIdkQ4uF.js +1 -0
  8. package/dist/client/assets/LocalFilePreviewDialog-DQx2eiCc.js +3 -0
  9. package/dist/client/assets/LocalProjectsSection-C4xlWkgS.js +1 -0
  10. package/dist/client/assets/TextMessage-B5G39DEJ.js +1 -0
  11. package/dist/client/assets/UserMessage-CIkWk-0L.js +1 -0
  12. package/dist/client/assets/_basePickBy-CVrAFfnZ.js +1 -0
  13. package/dist/client/assets/_baseUniq-JL-aaF4P.js +1 -0
  14. package/dist/client/assets/arc-B07zg7ol.js +1 -0
  15. package/dist/client/assets/architecture-YZFGNWBL-PSLVJL3p.js +1 -0
  16. package/dist/client/assets/architectureDiagram-Q4EWVU46-DfWIF1G_.js +36 -0
  17. package/dist/client/assets/array-BGFCBI0e.js +1 -0
  18. package/dist/client/assets/blockDiagram-DXYQGD6D-CzwIeo_B.js +132 -0
  19. package/dist/client/assets/bundle-mjs-BDE2gWbQ.js +1 -0
  20. package/dist/client/assets/button-DO50qOGv.js +1 -0
  21. package/dist/client/assets/c4Diagram-AHTNJAMY-CR8DCQRE.js +10 -0
  22. package/dist/client/assets/channel-Dj-UUfaF.js +1 -0
  23. package/dist/client/assets/chunk-2KRD3SAO-dznP-cn8.js +1 -0
  24. package/dist/client/assets/chunk-336JU56O-Dqss5Vu6.js +2 -0
  25. package/dist/client/assets/chunk-426QAEUC-CEKis_0_.js +1 -0
  26. package/dist/client/assets/chunk-4BX2VUAB-BYOv0Gm1.js +1 -0
  27. package/dist/client/assets/chunk-4TB4RGXK-BxzubH5S.js +206 -0
  28. package/dist/client/assets/chunk-55IACEB6-BSlTj03a.js +1 -0
  29. package/dist/client/assets/chunk-5FUZZQ4R-9Au93Bi1.js +62 -0
  30. package/dist/client/assets/chunk-5PVQY5BW-BhksHFEZ.js +2 -0
  31. package/dist/client/assets/chunk-67CJDMHE-BFwhz-8t.js +1 -0
  32. package/dist/client/assets/chunk-7N4EOEYR-BDUPds87.js +1 -0
  33. package/dist/client/assets/chunk-AA7GKIK3-CEWTdyXO.js +1 -0
  34. package/dist/client/assets/chunk-BO2N2NFS-D0LvxnhU.js +103 -0
  35. package/dist/client/assets/chunk-BSJP7CBP-BNJnK6sq.js +1 -0
  36. package/dist/client/assets/chunk-Bj-mKKzh.js +1 -0
  37. package/dist/client/assets/chunk-CIAEETIT-CYhfoCeN.js +1 -0
  38. package/dist/client/assets/chunk-EDXVE4YY-C5ovJLc0.js +1 -0
  39. package/dist/client/assets/chunk-ENJZ2VHE-HOhYaeGr.js +10 -0
  40. package/dist/client/assets/chunk-FMBD7UC4-BLCiKcAQ.js +15 -0
  41. package/dist/client/assets/chunk-FOC6F5B3-B6GtY2ek.js +1 -0
  42. package/dist/client/assets/chunk-ICPOFSXX-DPoIZoC5.js +122 -0
  43. package/dist/client/assets/chunk-K5T4RW27-BsKN63rv.js +94 -0
  44. package/dist/client/assets/chunk-KGLVRYIC-BUGn9uuY.js +1 -0
  45. package/dist/client/assets/chunk-LIHQZDEY-DhaZyo03.js +1 -0
  46. package/dist/client/assets/chunk-ORNJ4GCN-DlpeeJyi.js +1 -0
  47. package/dist/client/assets/chunk-OYMX7WX6-Dc9q7aYA.js +231 -0
  48. package/dist/client/assets/chunk-QZHKN3VN-BEdrPoSb.js +1 -0
  49. package/dist/client/assets/chunk-U2HBQHQK-CIB3Bjjd.js +70 -0
  50. package/dist/client/assets/chunk-X2U36JSP-CtB-o8Yp.js +1 -0
  51. package/dist/client/assets/chunk-XPW4576I-C6iHhX_8.js +32 -0
  52. package/dist/client/assets/chunk-YZCP3GAM-CTmKr6ZH.js +1 -0
  53. package/dist/client/assets/chunk-ZZ45TVLE-BgU8A2RF.js +1 -0
  54. package/dist/client/assets/classDiagram-6PBFFD2Q-Bqk5e679.js +1 -0
  55. package/dist/client/assets/classDiagram-v2-HSJHXN6E-6pSaZOkC.js +1 -0
  56. package/dist/client/assets/client-BrKWI4CM.js +1 -0
  57. package/dist/client/assets/client-CGgNRU9w.js +1 -0
  58. package/dist/client/assets/client-DMSLRzg9.js +6 -0
  59. package/dist/client/assets/clone-DWcL7whJ.js +1 -0
  60. package/dist/client/assets/cose-bilkent-S5V4N54A-CrV5wsV_.js +1 -0
  61. package/dist/client/assets/cytoscape.esm--aLzKuep.js +321 -0
  62. package/dist/client/assets/dagre-CuRxWcrj.js +1 -0
  63. package/dist/client/assets/dagre-KV5264BT-BIDiVnkA.js +4 -0
  64. package/dist/client/assets/defaultLocale-CRZydyG6.js +1 -0
  65. package/dist/client/assets/diagram-5BDNPKRD-i1kjKRCB.js +10 -0
  66. package/dist/client/assets/diagram-G4DWMVQ6-9ZSLuhbl.js +24 -0
  67. package/dist/client/assets/diagram-MMDJMWI5-B4_CUjgv.js +43 -0
  68. package/dist/client/assets/diagram-TYMM5635-Ct5eTGS8.js +24 -0
  69. package/dist/client/assets/dist-CuB4kiSK.js +1 -0
  70. package/dist/client/assets/erDiagram-SMLLAGMA-Cy38ercc.js +85 -0
  71. package/dist/client/assets/flowDiagram-DWJPFMVM-CZKuYl0V.js +162 -0
  72. package/dist/client/assets/ganttDiagram-T4ZO3ILL-DLPjCh7a.js +292 -0
  73. package/dist/client/assets/gitGraph-7Q5UKJZL-DqbrtEp9.js +1 -0
  74. package/dist/client/assets/gitGraphDiagram-UUTBAWPF-BoRBkDhQ.js +106 -0
  75. package/dist/client/assets/graphlib-BcQ6qlQh.js +1 -0
  76. package/dist/client/assets/highlighted-body-OFNGDK62-BEpBVDTX.js +1 -0
  77. package/dist/client/assets/index-CetCiuqP.js +105 -0
  78. package/dist/client/assets/index-N29Mip7A.css +1 -0
  79. package/dist/client/assets/info-OMHHGYJF-D98DRBJX.js +1 -0
  80. package/dist/client/assets/infoDiagram-42DDH7IO-BAcdTWbt.js +2 -0
  81. package/dist/client/assets/init-B8gtcn7T.js +1 -0
  82. package/dist/client/assets/isArrayLikeObject-D8SJFmkN.js +1 -0
  83. package/dist/client/assets/isEmpty-BF3YX5Jk.js +1 -0
  84. package/dist/client/assets/ishikawaDiagram-UXIWVN3A-Ynu2VKdC.js +70 -0
  85. package/dist/client/assets/journeyDiagram-VCZTEJTY-BjfhQaN3.js +139 -0
  86. package/dist/client/assets/jsx-runtime-CyI9ICYU.js +1 -0
  87. package/dist/client/assets/kanban-definition-6JOO6SKY-JLXH9zUJ.js +89 -0
  88. package/dist/client/assets/katex-B94qP8b6.js +265 -0
  89. package/dist/client/assets/lib--QVjyxmL.js +29 -0
  90. package/dist/client/assets/lib-B6rgJiZ9.js +1 -0
  91. package/dist/client/assets/line-DCrYfLBn.js +1 -0
  92. package/dist/client/assets/linear-_4upLmeo.js +1 -0
  93. package/dist/client/assets/mermaid-GHXKKRXX-rwJHYUmW.js +1 -0
  94. package/dist/client/assets/mermaid-parser.core-KZinfW8o.js +4 -0
  95. package/dist/client/assets/mermaid.core-QqY9gSNe.js +11 -0
  96. package/dist/client/assets/mindmap-definition-QFDTVHPH-TWgHDAzp.js +96 -0
  97. package/dist/client/assets/ordinal-CCj7PWgZ.js +1 -0
  98. package/dist/client/assets/packet-4T2RLAQJ-DEvfkn3F.js +1 -0
  99. package/dist/client/assets/path-DZF-JdEe.js +1 -0
  100. package/dist/client/assets/pie-ZZUOXDRM-72e6WVjb.js +1 -0
  101. package/dist/client/assets/pieDiagram-DEJITSTG-Cl8PCsoj.js +30 -0
  102. package/dist/client/assets/preload-helper-rov5CBGT.js +1 -0
  103. package/dist/client/assets/pty-client-DZ27IS00.js +1 -0
  104. package/dist/client/assets/ptyInstancesStore-D9ag7SYd.js +1 -0
  105. package/dist/client/assets/quadrantDiagram-34T5L4WZ-CHyVGp9E.js +7 -0
  106. package/dist/client/assets/radar-PYXPWWZC-Cp7xd_EY.js +1 -0
  107. package/dist/client/assets/react-CClhXMB2.js +1 -0
  108. package/dist/client/assets/react-Dd6D81m0.js +1 -0
  109. package/dist/client/assets/react-dom--G6_6fQ_.js +1 -0
  110. package/dist/client/assets/requirementDiagram-MS252O5E-DaanG2iM.js +84 -0
  111. package/dist/client/assets/rough.esm-BsmKo2S5.js +1 -0
  112. package/dist/client/assets/sankeyDiagram-XADWPNL6-B_fhLY36.js +10 -0
  113. package/dist/client/assets/sequenceDiagram-FGHM5R23-C5FNrveI.js +157 -0
  114. package/dist/client/assets/src-DeTlMJAU.js +1 -0
  115. package/dist/client/assets/stateDiagram-FHFEXIEX-nTTcdjjQ.js +1 -0
  116. package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-Dw0632j_.js +1 -0
  117. package/dist/client/assets/timeline-definition-GMOUNBTQ-DkQV1yP8.js +120 -0
  118. package/dist/client/assets/treeView-SZITEDCU-ZLIgC7_K.js +1 -0
  119. package/dist/client/assets/treemap-W4RFUUIX-BqaMbB6N.js +1 -0
  120. package/dist/client/assets/uiIdentityOverlay-Ba7GNj7m.js +1 -0
  121. package/dist/client/assets/vennDiagram-DHZGUBPP-DbZ2xgs6.js +34 -0
  122. package/dist/client/assets/wardley-RL74JXVD-DXQS8zf4.js +1 -0
  123. package/dist/client/assets/wardleyDiagram-NUSXRM2D-BzCJ6MAu.js +20 -0
  124. package/dist/client/assets/xychartDiagram-5P7HB3ND-BSlFecop.js +7 -0
  125. package/dist/client/favicon.png +0 -0
  126. package/dist/client/favicon.svg +15 -0
  127. package/dist/client/fonts/body-medium.woff2 +0 -0
  128. package/dist/client/fonts/body-regular-italic.woff2 +0 -0
  129. package/dist/client/fonts/body-regular.woff2 +0 -0
  130. package/dist/client/fonts/body-semibold.woff2 +0 -0
  131. package/dist/client/index.html +31 -0
  132. package/dist/client/manifest.webmanifest +12 -0
  133. package/dist/client/sw.js +32 -0
  134. package/package.json +122 -0
  135. package/src/nats/auth-callout/callout-config.test.ts +93 -0
  136. package/src/nats/auth-callout/callout-config.ts +109 -0
  137. package/src/nats/auth-callout/callout.integration.test.ts +332 -0
  138. package/src/nats/auth-callout/keys.ts +103 -0
  139. package/src/nats/auth-callout/responder.ts +241 -0
  140. package/src/nats/auth-callout/scope-policy.test.ts +159 -0
  141. package/src/nats/auth-callout/scope-policy.ts +210 -0
  142. package/src/nats/auth-callout/token.test.ts +163 -0
  143. package/src/nats/auth-callout/token.ts +157 -0
  144. package/src/nats/nats-daemon-callout.ts +194 -0
  145. package/src/nats/nats-daemon.test.ts +77 -0
  146. package/src/nats/nats-daemon.ts +50 -0
  147. package/src/nats/nats-token.test.ts +61 -0
  148. package/src/nats/nats-token.ts +59 -0
  149. package/src/runner/coordination-mcp-integration.test.ts +134 -0
  150. package/src/runner/nats-coordination-client.test.ts +49 -0
  151. package/src/runner/nats-coordination-client.ts +94 -0
  152. package/src/runner/runner-agent.test.ts +469 -0
  153. package/src/runner/runner-agent.ts +453 -0
  154. package/src/runner/runner-credential.test.ts +93 -0
  155. package/src/runner/runner-credential.ts +82 -0
  156. package/src/runner/runner-nats.test.ts +495 -0
  157. package/src/runner/runner-nats.ts +323 -0
  158. package/src/runner/runner-pair.test.ts +107 -0
  159. package/src/runner/runner-pair.ts +81 -0
  160. package/src/runner/runner.test.ts +135 -0
  161. package/src/runner/runner.ts +212 -0
  162. package/src/runner/turn-factories.test.ts +97 -0
  163. package/src/runner/turn-factories.ts +475 -0
  164. package/src/server/agent-config-journey.test.ts +106 -0
  165. package/src/server/agent.ts +8 -0
  166. package/src/server/auto-continue/auth-error-detector.ts +66 -0
  167. package/src/server/auto-continue/limit-detector.ts +194 -0
  168. package/src/server/bm25.test.ts +92 -0
  169. package/src/server/bm25.ts +101 -0
  170. package/src/server/chat-events-jetstream.test.ts +135 -0
  171. package/src/server/claude-harness.ts +360 -0
  172. package/src/server/claude-pty/agent-normalizers.ts +309 -0
  173. package/src/server/claude-pty/auth.test.ts +38 -0
  174. package/src/server/claude-pty/auth.ts +32 -0
  175. package/src/server/claude-pty/claude-session-registry.adapter.ts +81 -0
  176. package/src/server/claude-pty/claude-session-registry.test.ts +149 -0
  177. package/src/server/claude-pty/driver.test.ts +902 -0
  178. package/src/server/claude-pty/driver.ts +807 -0
  179. package/src/server/claude-pty/jsonl-path.adapter.ts +57 -0
  180. package/src/server/claude-pty/jsonl-path.test.ts +114 -0
  181. package/src/server/claude-pty/jsonl-to-event.test.ts +241 -0
  182. package/src/server/claude-pty/jsonl-to-event.ts +174 -0
  183. package/src/server/claude-pty/output-ring.test.ts +35 -0
  184. package/src/server/claude-pty/output-ring.ts +25 -0
  185. package/src/server/claude-pty/parity-matrix.test.ts +227 -0
  186. package/src/server/claude-pty/pid-registry.adapter.ts +135 -0
  187. package/src/server/claude-pty/pid-registry.test.ts +122 -0
  188. package/src/server/claude-pty/preflight/binary-fingerprint.adapter.ts +20 -0
  189. package/src/server/claude-pty/preflight/binary-fingerprint.test.ts +32 -0
  190. package/src/server/claude-pty/pty-instance-registry.test.ts +177 -0
  191. package/src/server/claude-pty/pty-instance-registry.ts +166 -0
  192. package/src/server/claude-pty/pty-memory-sampler.adapter.test.ts +103 -0
  193. package/src/server/claude-pty/pty-memory-sampler.adapter.ts +85 -0
  194. package/src/server/claude-pty/pty-process.adapter.ts +66 -0
  195. package/src/server/claude-pty/pty-process.test.ts +49 -0
  196. package/src/server/claude-pty/resolve-binary.adapter.ts +106 -0
  197. package/src/server/claude-pty/resolve-binary.test.ts +118 -0
  198. package/src/server/claude-pty/runtime-dir.adapter.ts +19 -0
  199. package/src/server/claude-pty/settings-writer.adapter.ts +27 -0
  200. package/src/server/claude-pty/settings-writer.test.ts +22 -0
  201. package/src/server/claude-pty/smoke-test-io.adapter.ts +28 -0
  202. package/src/server/claude-pty/smoke-test.test.ts +191 -0
  203. package/src/server/claude-pty/smoke-test.ts +185 -0
  204. package/src/server/claude-pty/subagent-orchestrator.ts +887 -0
  205. package/src/server/claude-pty/tool-callback.ts +274 -0
  206. package/src/server/claude-pty/tui-control.test.ts +272 -0
  207. package/src/server/claude-pty/tui-control.ts +182 -0
  208. package/src/server/claude-pty/tui-source.adapter.test.ts +360 -0
  209. package/src/server/claude-pty/tui-source.adapter.ts +343 -0
  210. package/src/server/claude-pty/tunnel-gateway.ts +12 -0
  211. package/src/server/claude-pty-mcp/canonical-args.ts +15 -0
  212. package/src/server/claude-pty-mcp/fs-stat.adapter.ts +8 -0
  213. package/src/server/claude-pty-mcp/history-primer.ts +90 -0
  214. package/src/server/claude-pty-mcp/http-server.adapter.ts +33 -0
  215. package/src/server/claude-pty-mcp/mcp-http.ts +177 -0
  216. package/src/server/claude-pty-mcp/mcp.ts +412 -0
  217. package/src/server/claude-pty-mcp/mention-parser.ts +25 -0
  218. package/src/server/claude-pty-mcp/paths.ts +24 -0
  219. package/src/server/claude-pty-mcp/permission-gate.ts +243 -0
  220. package/src/server/claude-pty-mcp/terminal-pid-registry.adapter.ts +107 -0
  221. package/src/server/claude-pty-mcp/tools/ask-user-question.test.ts +119 -0
  222. package/src/server/claude-pty-mcp/tools/ask-user-question.ts +61 -0
  223. package/src/server/claude-pty-mcp/tools/bash.adapter.ts +76 -0
  224. package/src/server/claude-pty-mcp/tools/bash.test.ts +56 -0
  225. package/src/server/claude-pty-mcp/tools/delegate-subagent.test.ts +155 -0
  226. package/src/server/claude-pty-mcp/tools/delegate-subagent.ts +111 -0
  227. package/src/server/claude-pty-mcp/tools/edit.adapter.ts +95 -0
  228. package/src/server/claude-pty-mcp/tools/edit.test.ts +93 -0
  229. package/src/server/claude-pty-mcp/tools/exit-plan-mode.test.ts +61 -0
  230. package/src/server/claude-pty-mcp/tools/exit-plan-mode.ts +50 -0
  231. package/src/server/claude-pty-mcp/tools/glob.adapter.ts +86 -0
  232. package/src/server/claude-pty-mcp/tools/glob.test.ts +61 -0
  233. package/src/server/claude-pty-mcp/tools/grep.adapter.ts +126 -0
  234. package/src/server/claude-pty-mcp/tools/grep.test.ts +62 -0
  235. package/src/server/claude-pty-mcp/tools/read.adapter.ts +58 -0
  236. package/src/server/claude-pty-mcp/tools/read.test.ts +62 -0
  237. package/src/server/claude-pty-mcp/tools/tool-callback-shim.ts +42 -0
  238. package/src/server/claude-pty-mcp/tools/webfetch.test.ts +81 -0
  239. package/src/server/claude-pty-mcp/tools/webfetch.ts +82 -0
  240. package/src/server/claude-pty-mcp/tools/websearch.test.ts +40 -0
  241. package/src/server/claude-pty-mcp/tools/websearch.ts +42 -0
  242. package/src/server/claude-pty-mcp/tools/write.adapter.ts +60 -0
  243. package/src/server/claude-pty-mcp/tools/write.test.ts +52 -0
  244. package/src/server/claude-pty-mcp/uploads.adapter.ts +98 -0
  245. package/src/server/claude-pty-mcp/uploads.ts +38 -0
  246. package/src/server/claude-turn.test.ts +176 -0
  247. package/src/server/cli-runtime.test.ts +456 -0
  248. package/src/server/cli-runtime.ts +374 -0
  249. package/src/server/cli-supervisor.ts +81 -0
  250. package/src/server/cli.ts +78 -0
  251. package/src/server/client-log-forwarder.test.ts +74 -0
  252. package/src/server/client-log-forwarder.ts +75 -0
  253. package/src/server/codex-app-server-protocol.ts +449 -0
  254. package/src/server/codex-app-server.test.ts +2990 -0
  255. package/src/server/codex-app-server.ts +1713 -0
  256. package/src/server/coordination-integration.test.ts +63 -0
  257. package/src/server/coordination-mcp.test.ts +149 -0
  258. package/src/server/coordination-mcp.ts +197 -0
  259. package/src/server/delegation-coordinator.test.ts +675 -0
  260. package/src/server/delegation-coordinator.ts +454 -0
  261. package/src/server/discovery.test.ts +211 -0
  262. package/src/server/discovery.ts +301 -0
  263. package/src/server/event-store-agent-config.test.ts +124 -0
  264. package/src/server/event-store-coordination.test.ts +149 -0
  265. package/src/server/event-store-profile.test.ts +132 -0
  266. package/src/server/event-store-repo.test.ts +154 -0
  267. package/src/server/event-store-runner-team.test.ts +104 -0
  268. package/src/server/event-store.test.ts +342 -0
  269. package/src/server/event-store.ts +2208 -0
  270. package/src/server/events.ts +379 -0
  271. package/src/server/extension-router.test.ts +183 -0
  272. package/src/server/extension-router.ts +114 -0
  273. package/src/server/extensions/agents/server.test.ts +191 -0
  274. package/src/server/extensions/agents/server.ts +108 -0
  275. package/src/server/extensions/c3/server.test.ts +284 -0
  276. package/src/server/extensions/c3/server.ts +212 -0
  277. package/src/server/extensions/code/server.test.ts +200 -0
  278. package/src/server/extensions/code/server.ts +150 -0
  279. package/src/server/extensions.config.ts +10 -0
  280. package/src/server/external-open.ts +69 -0
  281. package/src/server/generate-fork-context.ts +58 -0
  282. package/src/server/generate-merge-context.test.ts +290 -0
  283. package/src/server/generate-merge-context.ts +141 -0
  284. package/src/server/generate-title.ts +36 -0
  285. package/src/server/git-clone-policy.test.ts +138 -0
  286. package/src/server/git-clone-policy.ts +27 -0
  287. package/src/server/harness-types.ts +1 -0
  288. package/src/server/journey-verification.test.ts +640 -0
  289. package/src/server/journey-verification.ts +195 -0
  290. package/src/server/machine-name.ts +22 -0
  291. package/src/server/nats-auth.test.ts +92 -0
  292. package/src/server/nats-auth.ts +6 -0
  293. package/src/server/nats-bind-guard.test.ts +71 -0
  294. package/src/server/nats-bind-guard.ts +42 -0
  295. package/src/server/nats-bridge.test.ts +141 -0
  296. package/src/server/nats-bridge.ts +111 -0
  297. package/src/server/nats-connector.test.ts +56 -0
  298. package/src/server/nats-connector.ts +71 -0
  299. package/src/server/nats-daemon-manager.test.ts +76 -0
  300. package/src/server/nats-daemon-manager.ts +174 -0
  301. package/src/server/nats-publisher.test.ts +356 -0
  302. package/src/server/nats-publisher.ts +271 -0
  303. package/src/server/nats-responders.test.ts +1018 -0
  304. package/src/server/nats-responders.ts +925 -0
  305. package/src/server/nats-streams.test.ts +112 -0
  306. package/src/server/nats-streams.ts +129 -0
  307. package/src/server/oauth-pool/oauth-responders.ts +185 -0
  308. package/src/server/oauth-pool/oauth-settings-store.ts +173 -0
  309. package/src/server/oauth-pool/oauth-token-pool.ts +303 -0
  310. package/src/server/orchestration.test.ts +1063 -0
  311. package/src/server/orchestration.ts +716 -0
  312. package/src/server/pairing-endpoints.test.ts +171 -0
  313. package/src/server/pairing-store.test.ts +154 -0
  314. package/src/server/pairing-store.ts +124 -0
  315. package/src/server/paths.ts +27 -0
  316. package/src/server/pr3-liveness.test.ts +252 -0
  317. package/src/server/process-utils.ts +10 -0
  318. package/src/server/project-cli.ts +180 -0
  319. package/src/server/provider-catalog.test.ts +177 -0
  320. package/src/server/provider-catalog.ts +146 -0
  321. package/src/server/pty-responders.ts +345 -0
  322. package/src/server/push-notifications.test.ts +234 -0
  323. package/src/server/push-notifications.ts +188 -0
  324. package/src/server/quick-response.test.ts +196 -0
  325. package/src/server/quick-response.ts +154 -0
  326. package/src/server/read-models-agent-config.test.ts +59 -0
  327. package/src/server/read-models-coordination.test.ts +69 -0
  328. package/src/server/read-models.test.ts +332 -0
  329. package/src/server/read-models.ts +258 -0
  330. package/src/server/repo-journey.test.ts +96 -0
  331. package/src/server/repo-manager.test.ts +118 -0
  332. package/src/server/repo-manager.ts +97 -0
  333. package/src/server/repo-status.test.ts +54 -0
  334. package/src/server/repo-status.ts +82 -0
  335. package/src/server/restart.test.ts +27 -0
  336. package/src/server/restart.ts +30 -0
  337. package/src/server/runner-incompatible-gate.test.ts +383 -0
  338. package/src/server/runner-manager.test.ts +72 -0
  339. package/src/server/runner-manager.ts +312 -0
  340. package/src/server/runner-pairing-urls.test.ts +59 -0
  341. package/src/server/runner-pairing-urls.ts +67 -0
  342. package/src/server/runner-proxy.test.ts +456 -0
  343. package/src/server/runner-proxy.ts +494 -0
  344. package/src/server/runner-router.test.ts +429 -0
  345. package/src/server/runner-router.ts +212 -0
  346. package/src/server/runner-routing.test.ts +584 -0
  347. package/src/server/runtime-registry.test.ts +436 -0
  348. package/src/server/runtime-registry.ts +307 -0
  349. package/src/server/sandbox-health.test.ts +127 -0
  350. package/src/server/sandbox-health.ts +94 -0
  351. package/src/server/sandbox-journey.test.ts +232 -0
  352. package/src/server/sandbox-manager.test.ts +146 -0
  353. package/src/server/sandbox-manager.ts +159 -0
  354. package/src/server/server.test.ts +287 -0
  355. package/src/server/server.ts +1108 -0
  356. package/src/server/session-discovery.test.ts +129 -0
  357. package/src/server/session-discovery.ts +475 -0
  358. package/src/server/session-index.test.ts +362 -0
  359. package/src/server/session-index.ts +119 -0
  360. package/src/server/session-seed.ts +288 -0
  361. package/src/server/share.test.ts +108 -0
  362. package/src/server/share.ts +113 -0
  363. package/src/server/skill-discovery.test.ts +201 -0
  364. package/src/server/skill-discovery.ts +77 -0
  365. package/src/server/storage/test-helpers.ts +67 -0
  366. package/src/server/terminal-manager.test.ts +309 -0
  367. package/src/server/terminal-manager.ts +354 -0
  368. package/src/server/transcript-consumer.test.ts +339 -0
  369. package/src/server/transcript-consumer.ts +162 -0
  370. package/src/server/transcript-search.test.ts +193 -0
  371. package/src/server/transcript-search.ts +83 -0
  372. package/src/server/transcript-utils.ts +52 -0
  373. package/src/server/update-manager.test.ts +107 -0
  374. package/src/server/update-manager.ts +230 -0
  375. package/src/server/workflow-engine.test.ts +251 -0
  376. package/src/server/workflow-engine.ts +169 -0
  377. package/src/server/workflow-mcp.ts +49 -0
  378. package/src/server/workflow-store.test.ts +155 -0
  379. package/src/server/workflow-store.ts +139 -0
  380. package/src/server/workspace-agent-integration.test.ts +167 -0
  381. package/src/server/workspace-agent-routes.test.ts +127 -0
  382. package/src/server/workspace-agent-routes.ts +89 -0
  383. package/src/server/workspace-agent.test.ts +103 -0
  384. package/src/server/workspace-agent.ts +102 -0
  385. package/src/server/workspace-cli.test.ts +79 -0
  386. package/src/server/workspace-config-manager.test.ts +109 -0
  387. package/src/server/workspace-config-manager.ts +83 -0
  388. package/src/server/workspace-directory-policy.test.ts +109 -0
  389. package/src/server/workspace-directory-policy.ts +56 -0
  390. package/src/shared/agent-config-types.ts +25 -0
  391. package/src/shared/branding.test.ts +42 -0
  392. package/src/shared/branding.ts +54 -0
  393. package/src/shared/compression.test.ts +85 -0
  394. package/src/shared/compression.ts +42 -0
  395. package/src/shared/coordination-store.test.ts +24 -0
  396. package/src/shared/coordination-store.ts +26 -0
  397. package/src/shared/dev-ports.test.ts +84 -0
  398. package/src/shared/dev-ports.ts +100 -0
  399. package/src/shared/extension-types.ts +45 -0
  400. package/src/shared/fork-presets.ts +54 -0
  401. package/src/shared/harness-types.test.ts +15 -0
  402. package/src/shared/harness-types.ts +21 -0
  403. package/src/shared/log-sink.test.ts +112 -0
  404. package/src/shared/log-sink.ts +185 -0
  405. package/src/shared/mention-pattern.ts +7 -0
  406. package/src/shared/merge-presets.ts +41 -0
  407. package/src/shared/nats-subjects.test.ts +61 -0
  408. package/src/shared/nats-subjects.ts +131 -0
  409. package/src/shared/permission-policy.ts +136 -0
  410. package/src/shared/ports.ts +3 -0
  411. package/src/shared/preset-types.ts +15 -0
  412. package/src/shared/profile-types.ts +49 -0
  413. package/src/shared/projectFileUrl.ts +36 -0
  414. package/src/shared/protocol.ts +153 -0
  415. package/src/shared/pty-instance.ts +43 -0
  416. package/src/shared/puggy/diagnostics/result.ts +18 -0
  417. package/src/shared/puggy/expressions/evaluate.ts +292 -0
  418. package/src/shared/puggy/index.test.ts +101 -0
  419. package/src/shared/puggy/index.ts +69 -0
  420. package/src/shared/puggy/parser/ast.ts +110 -0
  421. package/src/shared/puggy/parser/parser.ts +624 -0
  422. package/src/shared/puggy/renderer/html.ts +447 -0
  423. package/src/shared/runner-protocol.test.ts +277 -0
  424. package/src/shared/runner-protocol.ts +210 -0
  425. package/src/shared/runner-team-types.ts +73 -0
  426. package/src/shared/runtime-types.ts +48 -0
  427. package/src/shared/sandbox-types.ts +53 -0
  428. package/src/shared/tailwind-build.test.ts +12 -0
  429. package/src/shared/tinkaria-system-prompt.ts +101 -0
  430. package/src/shared/tools.test.ts +335 -0
  431. package/src/shared/tools.ts +397 -0
  432. package/src/shared/transcript-entries.ts +27 -0
  433. package/src/shared/transcript-render.test.ts +225 -0
  434. package/src/shared/transcript-render.ts +467 -0
  435. package/src/shared/types.ts +1031 -0
  436. package/src/shared/vite-config.test.ts +47 -0
  437. package/src/shared/web-context.test.ts +110 -0
  438. package/src/shared/web-context.ts +76 -0
  439. package/src/shared/workflow-types.ts +51 -0
  440. package/src/shared/workspace-types.ts +100 -0
@@ -0,0 +1,436 @@
1
+ import { afterEach, describe, expect, test } from "bun:test"
2
+ import { mkdtemp, rm } from "node:fs/promises"
3
+ import { join } from "node:path"
4
+ import { tmpdir } from "node:os"
5
+ import { RuntimeRegistry } from "./runtime-registry"
6
+ import type { DiscoveredModel } from "../shared/runtime-types"
7
+
8
+ const tempDirs: string[] = []
9
+
10
+ afterEach(async () => {
11
+ await Promise.all(tempDirs.splice(0).map((dir) => rm(dir, { recursive: true, force: true })))
12
+ })
13
+
14
+ async function createTempDir() {
15
+ const dir = await mkdtemp(join(tmpdir(), "kanna-rt-"))
16
+ tempDirs.push(dir)
17
+ return dir
18
+ }
19
+
20
+ describe("RuntimeRegistry", () => {
21
+ describe("detectSystemRuntime", () => {
22
+ test("detects binary on PATH and returns entry", async () => {
23
+ const dir = await createTempDir()
24
+ const registry = new RuntimeRegistry(dir)
25
+ await registry.initialize()
26
+
27
+ const result = await registry.detectSystemRuntime("claude", {
28
+ binaryName: "echo",
29
+ packageName: "@anthropic-ai/claude-code",
30
+ versionParser: () => "1.0.0",
31
+ })
32
+
33
+ expect(result).toBeDefined()
34
+ expect(result!.source).toBe("system")
35
+ expect(result!.version).toBe("1.0.0")
36
+ })
37
+
38
+ test("returns null when binary not found", async () => {
39
+ const dir = await createTempDir()
40
+ const registry = new RuntimeRegistry(dir)
41
+ await registry.initialize()
42
+
43
+ const result = await registry.detectSystemRuntime("claude", {
44
+ binaryName: "definitely-not-a-real-binary-xyzzy",
45
+ packageName: "@anthropic-ai/claude-code",
46
+ versionParser: () => "1.0.0",
47
+ })
48
+
49
+ expect(result).toBeNull()
50
+ })
51
+ })
52
+
53
+ describe("resolve", () => {
54
+ test("returns managed entry over system when both exist", async () => {
55
+ const dir = await createTempDir()
56
+ const registry = new RuntimeRegistry(dir)
57
+ await registry.initialize()
58
+
59
+ await registry.detectSystemRuntime("claude", {
60
+ binaryName: "echo",
61
+ packageName: "@anthropic-ai/claude-code",
62
+ versionParser: () => "1.0.0",
63
+ })
64
+
65
+ await registry.detectSystemRuntime("claude", {
66
+ binaryName: "echo",
67
+ packageName: "@anthropic-ai/claude-code",
68
+ versionParser: () => "1.0.1",
69
+ })
70
+
71
+ const result = registry.resolve("claude")
72
+ expect(result).toBeDefined()
73
+ expect(result!.version).toBe("1.0.1") // Re-detect replaces stale system entry
74
+ })
75
+
76
+ test("re-detecting system runtime replaces the old entry instead of accumulating", async () => {
77
+ const dir = await createTempDir()
78
+ const registry = new RuntimeRegistry(dir)
79
+ await registry.initialize()
80
+
81
+ await registry.detectSystemRuntime("claude", {
82
+ binaryName: "echo",
83
+ packageName: "@anthropic-ai/claude-code",
84
+ versionParser: () => "1.0.0",
85
+ })
86
+
87
+ await registry.detectSystemRuntime("claude", {
88
+ binaryName: "echo",
89
+ packageName: "@anthropic-ai/claude-code",
90
+ versionParser: () => "1.0.1",
91
+ })
92
+
93
+ const snapshot = registry.getSnapshot()
94
+ const claudeEntries = snapshot.runtimes.filter((r) => r.provider === "claude" && r.source === "system")
95
+ expect(claudeEntries).toHaveLength(1)
96
+ expect(claudeEntries[0].version).toBe("1.0.1")
97
+ })
98
+
99
+ test("default updates to newly detected system version", async () => {
100
+ const dir = await createTempDir()
101
+ const registry = new RuntimeRegistry(dir)
102
+ await registry.initialize()
103
+
104
+ await registry.detectSystemRuntime("claude", {
105
+ binaryName: "echo",
106
+ packageName: "@anthropic-ai/claude-code",
107
+ versionParser: () => "1.0.0",
108
+ })
109
+
110
+ expect(registry.resolve("claude")!.version).toBe("1.0.0")
111
+
112
+ await registry.detectSystemRuntime("claude", {
113
+ binaryName: "echo",
114
+ packageName: "@anthropic-ai/claude-code",
115
+ versionParser: () => "2.0.0",
116
+ })
117
+
118
+ expect(registry.resolve("claude")!.version).toBe("2.0.0")
119
+ })
120
+
121
+ test("defaults persist correctly after system re-detect across instances", async () => {
122
+ const dir = await createTempDir()
123
+
124
+ const registry1 = new RuntimeRegistry(dir)
125
+ await registry1.initialize()
126
+ await registry1.detectSystemRuntime("codex", {
127
+ binaryName: "echo",
128
+ packageName: "@openai/codex",
129
+ versionParser: () => "0.118.0",
130
+ })
131
+ await registry1.detectSystemRuntime("codex", {
132
+ binaryName: "echo",
133
+ packageName: "@openai/codex",
134
+ versionParser: () => "0.121.0",
135
+ })
136
+
137
+ const registry2 = new RuntimeRegistry(dir)
138
+ await registry2.initialize()
139
+ const resolved = registry2.resolve("codex")
140
+ expect(resolved).toBeDefined()
141
+ expect(resolved!.version).toBe("0.121.0")
142
+ })
143
+
144
+ test("returns null for unknown provider", async () => {
145
+ const dir = await createTempDir()
146
+ const registry = new RuntimeRegistry(dir)
147
+ await registry.initialize()
148
+
149
+ const result = registry.resolve("unknown-provider")
150
+ expect(result).toBeNull()
151
+ })
152
+ })
153
+
154
+ describe("healthCheck", () => {
155
+ test("returns healthy for working binary", async () => {
156
+ const dir = await createTempDir()
157
+ const registry = new RuntimeRegistry(dir)
158
+ await registry.initialize()
159
+
160
+ await registry.detectSystemRuntime("claude", {
161
+ binaryName: "echo",
162
+ packageName: "@anthropic-ai/claude-code",
163
+ versionParser: () => "1.0.0",
164
+ })
165
+
166
+ const health = await registry.healthCheck("claude")
167
+ expect(health.status).toBe("healthy")
168
+ expect(health.latencyMs).toBeGreaterThanOrEqual(0)
169
+ })
170
+
171
+ test("returns unavailable when no runtime registered", async () => {
172
+ const dir = await createTempDir()
173
+ const registry = new RuntimeRegistry(dir)
174
+ await registry.initialize()
175
+
176
+ const health = await registry.healthCheck("codex")
177
+ expect(health.status).toBe("unavailable")
178
+ expect(health.error).toBe("No runtime registered")
179
+ })
180
+ })
181
+
182
+ describe("installManaged", () => {
183
+ test("installs npm package into versioned directory", async () => {
184
+ const dir = await createTempDir()
185
+ const registry = new RuntimeRegistry(dir)
186
+ await registry.initialize()
187
+
188
+ // Use a small, fast package for testing
189
+ const result = await registry.installManaged("claude", {
190
+ packageName: "is-odd",
191
+ version: "3.0.1",
192
+ binaryName: "is-odd",
193
+ })
194
+
195
+ expect(result.success).toBe(true)
196
+ expect(result.entry).toBeDefined()
197
+ expect(result.entry!.source).toBe("managed")
198
+ expect(result.entry!.version).toBe("3.0.1")
199
+ }, 30_000)
200
+
201
+ test("returns failure for invalid package", async () => {
202
+ const dir = await createTempDir()
203
+ const registry = new RuntimeRegistry(dir)
204
+ await registry.initialize()
205
+
206
+ const result = await registry.installManaged("claude", {
207
+ packageName: "@definitely-not-real/package-xyzzy-999",
208
+ version: "0.0.0",
209
+ binaryName: "xyzzy",
210
+ })
211
+
212
+ expect(result.success).toBe(false)
213
+ expect(result.error).toBeDefined()
214
+ }, 30_000)
215
+ })
216
+
217
+ describe("persistence", () => {
218
+ test("persists and reloads entries across instances", async () => {
219
+ const dir = await createTempDir()
220
+
221
+ const registry1 = new RuntimeRegistry(dir)
222
+ await registry1.initialize()
223
+ await registry1.detectSystemRuntime("claude", {
224
+ binaryName: "echo",
225
+ packageName: "@anthropic-ai/claude-code",
226
+ versionParser: () => "2.0.0",
227
+ })
228
+
229
+ const registry2 = new RuntimeRegistry(dir)
230
+ await registry2.initialize()
231
+ const result = registry2.resolve("claude")
232
+ expect(result).toBeDefined()
233
+ expect(result!.version).toBe("2.0.0")
234
+ expect(result!.source).toBe("system")
235
+ })
236
+
237
+ test("deduplicates stale system entries on load", async () => {
238
+ const dir = await createTempDir()
239
+ const { writeFile } = await import("node:fs/promises")
240
+ const { join } = await import("node:path")
241
+
242
+ // Simulate a registry written by the old buggy code
243
+ await writeFile(join(dir, "registry.json"), JSON.stringify({
244
+ entries: [
245
+ { provider: "claude", version: "2.1.105", source: "system", binaryPath: "/usr/bin/claude", installedAt: 1000, packageName: "@anthropic-ai/claude-code" },
246
+ { provider: "claude", version: "2.1.109", source: "system", binaryPath: "/usr/bin/claude", installedAt: 2000, packageName: "@anthropic-ai/claude-code" },
247
+ { provider: "claude", version: "2.1.112", source: "system", binaryPath: "/usr/bin/claude", installedAt: 3000, packageName: "@anthropic-ai/claude-code" },
248
+ { provider: "codex", version: "0.118.0", source: "system", binaryPath: "/usr/bin/codex", installedAt: 1000, packageName: "@openai/codex" },
249
+ { provider: "codex", version: "0.120.0", source: "system", binaryPath: "/usr/bin/codex", installedAt: 2000, packageName: "@openai/codex" },
250
+ ],
251
+ defaults: { claude: "2.1.105", codex: "0.118.0" },
252
+ }))
253
+
254
+ const registry = new RuntimeRegistry(dir)
255
+ await registry.initialize()
256
+
257
+ const snapshot = registry.getSnapshot()
258
+ const claudeEntries = snapshot.runtimes.filter((r) => r.provider === "claude" && r.source === "system")
259
+ const codexEntries = snapshot.runtimes.filter((r) => r.provider === "codex" && r.source === "system")
260
+ expect(claudeEntries).toHaveLength(1)
261
+ expect(claudeEntries[0].version).toBe("2.1.112")
262
+ expect(codexEntries).toHaveLength(1)
263
+ expect(codexEntries[0].version).toBe("0.120.0")
264
+
265
+ // Defaults should also point to the latest
266
+ expect(registry.resolve("claude")!.version).toBe("2.1.112")
267
+ expect(registry.resolve("codex")!.version).toBe("0.120.0")
268
+ })
269
+ })
270
+
271
+ describe("probeCapabilities", () => {
272
+ const FAKE_MODELS: DiscoveredModel[] = [
273
+ { value: "default", displayName: "Default", description: "Opus 4.6", supportsEffort: true, supportedEffortLevels: ["low", "high", "max"] },
274
+ { value: "sonnet", displayName: "Sonnet", description: "Sonnet 4.6" },
275
+ ]
276
+
277
+ async function createRegistryWithClaude(dir: string, probeResult: DiscoveredModel[] | Error) {
278
+ const probeFn = async (_binaryPath: string) => {
279
+ if (probeResult instanceof Error) throw probeResult
280
+ return probeResult
281
+ }
282
+ const registry = new RuntimeRegistry(dir, { probeClaudeModels: probeFn })
283
+ await registry.initialize()
284
+ await registry.detectSystemRuntime("claude", {
285
+ binaryName: "echo",
286
+ packageName: "@anthropic-ai/claude-code",
287
+ versionParser: () => "1.0.0",
288
+ })
289
+ return registry
290
+ }
291
+
292
+ test("caches discovered models on success", async () => {
293
+ const dir = await createTempDir()
294
+ const registry = await createRegistryWithClaude(dir, FAKE_MODELS)
295
+
296
+ await registry.probeCapabilities("claude")
297
+
298
+ const caps = registry.getProviderCapabilities("claude")
299
+ expect(caps).not.toBeNull()
300
+ expect(caps!.models).toEqual(FAKE_MODELS)
301
+ expect(caps!.runtimeVersion).toBe("1.0.0")
302
+ expect(caps!.error).toBeUndefined()
303
+ })
304
+
305
+ test("stores error on failure but keeps empty models", async () => {
306
+ const dir = await createTempDir()
307
+ const registry = await createRegistryWithClaude(dir, new Error("SDK timeout"))
308
+
309
+ await registry.probeCapabilities("claude")
310
+
311
+ const caps = registry.getProviderCapabilities("claude")
312
+ expect(caps).not.toBeNull()
313
+ expect(caps!.models).toEqual([])
314
+ expect(caps!.error).toBe("SDK timeout")
315
+ })
316
+
317
+ test("is a no-op for codex", async () => {
318
+ const dir = await createTempDir()
319
+ let probeCalled = false
320
+ const registry = new RuntimeRegistry(dir, {
321
+ probeClaudeModels: async () => { probeCalled = true; return [] },
322
+ })
323
+ await registry.initialize()
324
+ await registry.detectSystemRuntime("codex", {
325
+ binaryName: "echo",
326
+ packageName: "@openai/codex",
327
+ versionParser: () => "0.118.0",
328
+ })
329
+
330
+ await registry.probeCapabilities("codex")
331
+ expect(probeCalled).toBe(false)
332
+ })
333
+
334
+ test("skips probe when already probed for same version", async () => {
335
+ const dir = await createTempDir()
336
+ let probeCount = 0
337
+ const registry = new RuntimeRegistry(dir, {
338
+ probeClaudeModels: async () => { probeCount++; return FAKE_MODELS },
339
+ })
340
+ await registry.initialize()
341
+ await registry.detectSystemRuntime("claude", {
342
+ binaryName: "echo",
343
+ packageName: "@anthropic-ai/claude-code",
344
+ versionParser: () => "1.0.0",
345
+ })
346
+
347
+ await registry.probeCapabilities("claude")
348
+ await registry.probeCapabilities("claude")
349
+ expect(probeCount).toBe(1)
350
+ })
351
+
352
+ test("de-dupes concurrent probes — same promise returned", async () => {
353
+ const dir = await createTempDir()
354
+ let probeCount = 0
355
+ const registry = new RuntimeRegistry(dir, {
356
+ probeClaudeModels: async () => {
357
+ probeCount++
358
+ await new Promise((r) => setTimeout(r, 50))
359
+ return FAKE_MODELS
360
+ },
361
+ })
362
+ await registry.initialize()
363
+ await registry.detectSystemRuntime("claude", {
364
+ binaryName: "echo",
365
+ packageName: "@anthropic-ai/claude-code",
366
+ versionParser: () => "1.0.0",
367
+ })
368
+
369
+ await Promise.all([
370
+ registry.probeCapabilities("claude"),
371
+ registry.probeCapabilities("claude"),
372
+ registry.probeCapabilities("claude"),
373
+ ])
374
+ expect(probeCount).toBe(1)
375
+ })
376
+
377
+ test("version change clears capabilities and re-probes", async () => {
378
+ const dir = await createTempDir()
379
+ let probeCount = 0
380
+ const registry = new RuntimeRegistry(dir, {
381
+ probeClaudeModels: async () => { probeCount++; return FAKE_MODELS },
382
+ })
383
+ await registry.initialize()
384
+ await registry.detectSystemRuntime("claude", {
385
+ binaryName: "echo",
386
+ packageName: "@anthropic-ai/claude-code",
387
+ versionParser: () => "1.0.0",
388
+ })
389
+ await registry.probeCapabilities("claude")
390
+ expect(probeCount).toBe(1)
391
+
392
+ // Re-detect with new version
393
+ await registry.detectSystemRuntime("claude", {
394
+ binaryName: "echo",
395
+ packageName: "@anthropic-ai/claude-code",
396
+ versionParser: () => "2.0.0",
397
+ })
398
+ // Capabilities should be cleared
399
+ expect(registry.getProviderCapabilities("claude")).toBeNull()
400
+
401
+ await registry.probeCapabilities("claude")
402
+ expect(probeCount).toBe(2)
403
+ expect(registry.getProviderCapabilities("claude")!.runtimeVersion).toBe("2.0.0")
404
+ })
405
+
406
+ test("getProviderCapabilities returns null when no data", async () => {
407
+ const dir = await createTempDir()
408
+ const registry = new RuntimeRegistry(dir)
409
+ await registry.initialize()
410
+ expect(registry.getProviderCapabilities("claude")).toBeNull()
411
+ })
412
+
413
+ test("capabilities persist across registry instances", async () => {
414
+ const dir = await createTempDir()
415
+ const registry1 = await createRegistryWithClaude(dir, FAKE_MODELS)
416
+ await registry1.probeCapabilities("claude")
417
+
418
+ const registry2 = new RuntimeRegistry(dir)
419
+ await registry2.initialize()
420
+ const caps = registry2.getProviderCapabilities("claude")
421
+ expect(caps).not.toBeNull()
422
+ expect(caps!.models).toEqual(FAKE_MODELS)
423
+ })
424
+
425
+ test("snapshot includes capabilities", async () => {
426
+ const dir = await createTempDir()
427
+ const registry = await createRegistryWithClaude(dir, FAKE_MODELS)
428
+ await registry.probeCapabilities("claude")
429
+
430
+ const snapshot = registry.getSnapshot()
431
+ const claudeEntry = snapshot.runtimes.find((r) => r.provider === "claude")
432
+ expect(claudeEntry?.capabilities).toBeDefined()
433
+ expect(claudeEntry?.capabilities?.models).toEqual(FAKE_MODELS)
434
+ })
435
+ })
436
+ })