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,132 @@
1
+ import { afterEach, describe, expect, test } from "bun:test"
2
+ import { rm } from "node:fs/promises"
3
+ import { mkdtemp } from "node:fs/promises"
4
+ import { join } from "node:path"
5
+ import { tmpdir } from "node:os"
6
+ import { EventStore } from "./event-store"
7
+ import type { ProviderProfile } from "../shared/profile-types"
8
+
9
+ const tempDirs: string[] = []
10
+
11
+ afterEach(async () => {
12
+ await Promise.all(tempDirs.splice(0).map((dir) => rm(dir, { recursive: true, force: true })))
13
+ })
14
+
15
+ async function createTempDataDir() {
16
+ const dir = await mkdtemp(join(tmpdir(), "kanna-pf-"))
17
+ tempDirs.push(dir)
18
+ return dir
19
+ }
20
+
21
+ const makeProfile = (id: string): ProviderProfile => ({
22
+ id,
23
+ name: `Profile ${id}`,
24
+ provider: "claude",
25
+ runtime: "system",
26
+ model: "opus-4",
27
+ systemPrompt: "You are helpful.",
28
+ })
29
+
30
+ describe("EventStore provider profiles", () => {
31
+ test("saveProviderProfile creates record", async () => {
32
+ const dataDir = await createTempDataDir()
33
+ const store = new EventStore(dataDir)
34
+ await store.initialize()
35
+
36
+ await store.saveProviderProfile("p1", makeProfile("p1"))
37
+
38
+ const record = store.state.providerProfiles.get("p1")
39
+ expect(record).toBeDefined()
40
+ expect(record!.profile.name).toBe("Profile p1")
41
+ expect(record!.createdAt).toBeGreaterThan(0)
42
+ })
43
+
44
+ test("saveProviderProfile preserves createdAt on update", async () => {
45
+ const dataDir = await createTempDataDir()
46
+ const store = new EventStore(dataDir)
47
+ await store.initialize()
48
+
49
+ await store.saveProviderProfile("p1", makeProfile("p1"))
50
+ const firstCreated = store.state.providerProfiles.get("p1")!.createdAt
51
+
52
+ const updated = { ...makeProfile("p1"), name: "Updated" }
53
+ await store.saveProviderProfile("p1", updated)
54
+
55
+ const record = store.state.providerProfiles.get("p1")!
56
+ expect(record.createdAt).toBe(firstCreated)
57
+ expect(record.updatedAt).toBeGreaterThanOrEqual(firstCreated)
58
+ expect(record.profile.name).toBe("Updated")
59
+ })
60
+
61
+ test("removeProviderProfile deletes record and cleans overrides", async () => {
62
+ const dataDir = await createTempDataDir()
63
+ const store = new EventStore(dataDir)
64
+ await store.initialize()
65
+
66
+ await store.saveProviderProfile("p1", makeProfile("p1"))
67
+ await store.setWorkspaceProfileOverride("ws1", "p1", { model: "sonnet-4" })
68
+ await store.removeProviderProfile("p1")
69
+
70
+ expect(store.state.providerProfiles.get("p1")).toBeUndefined()
71
+ expect(store.state.workspaceProfileOverrides.get("ws1")?.get("p1")).toBeUndefined()
72
+ })
73
+
74
+ test("setWorkspaceProfileOverride stores override", async () => {
75
+ const dataDir = await createTempDataDir()
76
+ const store = new EventStore(dataDir)
77
+ await store.initialize()
78
+
79
+ await store.saveProviderProfile("p1", makeProfile("p1"))
80
+ await store.setWorkspaceProfileOverride("ws1", "p1", { model: "sonnet-4" })
81
+
82
+ const override = store.state.workspaceProfileOverrides.get("ws1")?.get("p1")
83
+ expect(override).toBeDefined()
84
+ expect(override!.overrides.model).toBe("sonnet-4")
85
+ })
86
+
87
+ test("removeWorkspaceProfileOverride deletes override", async () => {
88
+ const dataDir = await createTempDataDir()
89
+ const store = new EventStore(dataDir)
90
+ await store.initialize()
91
+
92
+ await store.saveProviderProfile("p1", makeProfile("p1"))
93
+ await store.setWorkspaceProfileOverride("ws1", "p1", { model: "sonnet-4" })
94
+ await store.removeWorkspaceProfileOverride("ws1", "p1")
95
+
96
+ expect(store.state.workspaceProfileOverrides.get("ws1")?.get("p1")).toBeUndefined()
97
+ })
98
+
99
+ test("profiles survive snapshot round-trip", async () => {
100
+ const dataDir = await createTempDataDir()
101
+ const store1 = new EventStore(dataDir)
102
+ await store1.initialize()
103
+
104
+ await store1.saveProviderProfile("p1", makeProfile("p1"))
105
+ await store1.setWorkspaceProfileOverride("ws1", "p1", { model: "haiku-4" })
106
+ await store1.compact()
107
+
108
+ const store2 = new EventStore(dataDir)
109
+ await store2.initialize()
110
+
111
+ expect(store2.state.providerProfiles.get("p1")).toBeDefined()
112
+ expect(store2.state.providerProfiles.get("p1")!.profile.name).toBe("Profile p1")
113
+ expect(store2.state.workspaceProfileOverrides.get("ws1")?.get("p1")?.overrides.model).toBe("haiku-4")
114
+ })
115
+
116
+ test("profiles survive log replay without snapshot", async () => {
117
+ const dataDir = await createTempDataDir()
118
+ const store1 = new EventStore(dataDir)
119
+ await store1.initialize()
120
+
121
+ await store1.saveProviderProfile("p1", makeProfile("p1"))
122
+ await store1.setWorkspaceProfileOverride("ws1", "p1", { model: "haiku-4" })
123
+ // No compact — force log replay on next load
124
+
125
+ const store2 = new EventStore(dataDir)
126
+ await store2.initialize()
127
+
128
+ expect(store2.state.providerProfiles.get("p1")).toBeDefined()
129
+ expect(store2.state.providerProfiles.get("p1")!.profile.name).toBe("Profile p1")
130
+ expect(store2.state.workspaceProfileOverrides.get("ws1")?.get("p1")?.overrides.model).toBe("haiku-4")
131
+ })
132
+ })
@@ -0,0 +1,154 @@
1
+ import { afterEach, describe, expect, test } from "bun:test"
2
+ import { mkdtemp, readFile, rm } from "node:fs/promises"
3
+ import { join } from "node:path"
4
+ import { tmpdir } from "node:os"
5
+ import { EventStore } from "./event-store"
6
+ import type { SnapshotFile } from "./events"
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 createTempDataDir() {
15
+ const dir = await mkdtemp(join(tmpdir(), "kanna-repo-"))
16
+ tempDirs.push(dir)
17
+ return dir
18
+ }
19
+
20
+ async function createStoreWithWorkspace() {
21
+ const dataDir = await createTempDataDir()
22
+ const store = new EventStore(dataDir)
23
+ await store.initialize()
24
+ const workspace = await store.openProject("/tmp/repo-workspace")
25
+ return { dataDir, store, workspaceId: workspace.id }
26
+ }
27
+
28
+ describe("EventStore repo reducers", () => {
29
+ test("addRepo creates record in reposById with status cloned", async () => {
30
+ const { store, workspaceId } = await createStoreWithWorkspace()
31
+
32
+ await store.addRepo("r1", workspaceId, "/tmp/my-repo", "https://github.com/org/repo.git", "My Repo", "main")
33
+
34
+ const repo = store.state.reposById.get("r1")
35
+ expect(repo).toBeDefined()
36
+ expect(repo!.id).toBe("r1")
37
+ expect(repo!.workspaceId).toBe(workspaceId)
38
+ expect(repo!.origin).toBe("https://github.com/org/repo.git")
39
+ expect(repo!.localPath).toBe("/tmp/my-repo")
40
+ expect(repo!.label).toBe("My Repo")
41
+ expect(repo!.status).toBe("cloned")
42
+ expect(repo!.branch).toBe("main")
43
+ expect(repo!.createdAt).toBeGreaterThan(0)
44
+ expect(store.state.reposByPath.get("/tmp/my-repo")).toBe("r1")
45
+ })
46
+
47
+ test("startRepoClone creates record with status pending and indexes reposByPath", async () => {
48
+ const { store, workspaceId } = await createStoreWithWorkspace()
49
+
50
+ await store.startRepoClone("r2", workspaceId, "https://github.com/org/repo.git", "/tmp/target", "Clone Label")
51
+
52
+ const repo = store.state.reposById.get("r2")
53
+ expect(repo).toBeDefined()
54
+ expect(repo!.status).toBe("pending")
55
+ expect(repo!.origin).toBe("https://github.com/org/repo.git")
56
+ expect(repo!.localPath).toBe("/tmp/target")
57
+ expect(repo!.branch).toBeNull()
58
+ expect(store.state.reposByPath.get("/tmp/target")).toBe("r2")
59
+ })
60
+
61
+ test("markRepoCloned transitions status to cloned and sets localPath", async () => {
62
+ const { store, workspaceId } = await createStoreWithWorkspace()
63
+ await store.startRepoClone("r3", workspaceId, "https://github.com/org/repo.git", "/tmp/target", null)
64
+
65
+ await store.markRepoCloned("r3", "/tmp/cloned-path", "develop")
66
+
67
+ const repo = store.state.reposById.get("r3")
68
+ expect(repo!.status).toBe("cloned")
69
+ expect(repo!.localPath).toBe("/tmp/cloned-path")
70
+ expect(repo!.branch).toBe("develop")
71
+ expect(store.state.reposByPath.get("/tmp/cloned-path")).toBe("r3")
72
+ })
73
+
74
+ test("markRepoCloneFailed transitions status to error", async () => {
75
+ const { store, workspaceId } = await createStoreWithWorkspace()
76
+ await store.startRepoClone("r4", workspaceId, "https://github.com/org/repo.git", "/tmp/target", null)
77
+
78
+ await store.markRepoCloneFailed("r4", "clone failed: timeout")
79
+
80
+ const repo = store.state.reposById.get("r4")
81
+ expect(repo!.status).toBe("error")
82
+ })
83
+
84
+ test("removeRepo deletes from both maps", async () => {
85
+ const { store, workspaceId } = await createStoreWithWorkspace()
86
+ await store.addRepo("r5", workspaceId, "/tmp/to-remove", null, null, null)
87
+
88
+ await store.removeRepo("r5", workspaceId)
89
+
90
+ expect(store.state.reposById.has("r5")).toBe(false)
91
+ expect(store.state.reposByPath.has("/tmp/to-remove")).toBe(false)
92
+ })
93
+
94
+ test("updateRepoLabel updates label", async () => {
95
+ const { store, workspaceId } = await createStoreWithWorkspace()
96
+ await store.addRepo("r6", workspaceId, "/tmp/label-repo", null, "Old Label", null)
97
+
98
+ await store.updateRepoLabel("r6", "New Label")
99
+
100
+ const repo = store.state.reposById.get("r6")
101
+ expect(repo!.label).toBe("New Label")
102
+ expect(repo!.updatedAt).toBeGreaterThan(repo!.createdAt - 1)
103
+ })
104
+
105
+ test("createChat with repoId stores the association", async () => {
106
+ const { store, workspaceId } = await createStoreWithWorkspace()
107
+ await store.addRepo("r-chat", workspaceId, "/tmp/chat-repo", null, null, null)
108
+
109
+ const chat = await store.createChat(workspaceId, "r-chat")
110
+
111
+ expect(chat.repoId).toBe("r-chat")
112
+ })
113
+
114
+ test("createChat without repoId defaults to null", async () => {
115
+ const { store, workspaceId } = await createStoreWithWorkspace()
116
+
117
+ const chat = await store.createChat(workspaceId)
118
+
119
+ expect(chat.repoId).toBeNull()
120
+ })
121
+
122
+ test("removeRepo nullifies repoId on orphaned chats", async () => {
123
+ const { store, workspaceId } = await createStoreWithWorkspace()
124
+ await store.addRepo("r-orphan", workspaceId, "/tmp/orphan-repo", null, null, null)
125
+ const chat = await store.createChat(workspaceId, "r-orphan")
126
+
127
+ expect(store.state.chatsById.get(chat.id)!.repoId).toBe("r-orphan")
128
+
129
+ await store.removeRepo("r-orphan", workspaceId)
130
+
131
+ expect(store.state.chatsById.get(chat.id)!.repoId).toBeNull()
132
+ })
133
+
134
+ test("snapshot round-trip preserves repos", async () => {
135
+ const { dataDir, store, workspaceId } = await createStoreWithWorkspace()
136
+ await store.addRepo("r7", workspaceId, "/tmp/snap-repo", "https://github.com/org/snap.git", "Snap Repo", "main")
137
+ await store.addRepo("r8", workspaceId, "/tmp/snap-repo2", null, null, null)
138
+
139
+ await store.compact()
140
+
141
+ const snapshot = JSON.parse(await readFile(join(dataDir, "snapshot.json"), "utf8")) as SnapshotFile
142
+ expect(snapshot.repos).toBeDefined()
143
+ expect(snapshot.repos!.length).toBe(2)
144
+
145
+ const store2 = new EventStore(dataDir)
146
+ await store2.initialize()
147
+
148
+ expect(store2.state.reposById.size).toBe(2)
149
+ expect(store2.state.reposById.get("r7")!.label).toBe("Snap Repo")
150
+ expect(store2.state.reposById.get("r7")!.origin).toBe("https://github.com/org/snap.git")
151
+ expect(store2.state.reposByPath.get("/tmp/snap-repo")).toBe("r7")
152
+ expect(store2.state.reposByPath.get("/tmp/snap-repo2")).toBe("r8")
153
+ })
154
+ })
@@ -0,0 +1,104 @@
1
+ import { afterEach, describe, expect, test } from "bun:test"
2
+ import { rm, mkdtemp } from "node:fs/promises"
3
+ import { join } from "node:path"
4
+ import { tmpdir } from "node:os"
5
+ import { EventStore } from "./event-store"
6
+
7
+ const tempDirs: string[] = []
8
+
9
+ afterEach(async () => {
10
+ await Promise.all(tempDirs.splice(0).map((dir) => rm(dir, { recursive: true, force: true })))
11
+ })
12
+
13
+ async function createTempDataDir() {
14
+ const dir = await mkdtemp(join(tmpdir(), "kanna-rt-"))
15
+ tempDirs.push(dir)
16
+ return dir
17
+ }
18
+
19
+ describe("EventStore runner team (US-RTN)", () => {
20
+ test("saveTeamMember creates member", async () => {
21
+ const store = new EventStore(await createTempDataDir())
22
+ await store.initialize()
23
+
24
+ await store.saveTeamMember({ id: "m1", name: "Alice" })
25
+
26
+ expect(store.state.teamMembers.get("m1")).toEqual({ id: "m1", name: "Alice" })
27
+ })
28
+
29
+ test("setRunnerLabel upserts name + assignment", async () => {
30
+ const store = new EventStore(await createTempDataDir())
31
+ await store.initialize()
32
+
33
+ await store.setRunnerLabel("runner-1", "Studio Mac", "m1")
34
+ const first = store.state.runnerLabels.get("runner-1")!
35
+ expect(first.name).toBe("Studio Mac")
36
+ expect(first.memberId).toBe("m1")
37
+ expect(first.updatedAt).toBeGreaterThan(0)
38
+
39
+ await store.setRunnerLabel("runner-1", "Renamed", null)
40
+ const second = store.state.runnerLabels.get("runner-1")!
41
+ expect(second.name).toBe("Renamed")
42
+ expect(second.memberId).toBeNull()
43
+ })
44
+
45
+ test("removeTeamMember cascades to unassign runners", async () => {
46
+ const store = new EventStore(await createTempDataDir())
47
+ await store.initialize()
48
+
49
+ await store.saveTeamMember({ id: "m1", name: "Alice" })
50
+ await store.setRunnerLabel("runner-1", "Box A", "m1")
51
+ await store.setRunnerLabel("runner-2", "Box B", "m1")
52
+ await store.setRunnerLabel("runner-3", "Box C", "m2")
53
+
54
+ await store.removeTeamMember("m1")
55
+
56
+ expect(store.state.teamMembers.get("m1")).toBeUndefined()
57
+ // runners that pointed at m1 are unassigned; their names are preserved.
58
+ expect(store.state.runnerLabels.get("runner-1")!.memberId).toBeNull()
59
+ expect(store.state.runnerLabels.get("runner-1")!.name).toBe("Box A")
60
+ expect(store.state.runnerLabels.get("runner-2")!.memberId).toBeNull()
61
+ // a runner assigned to a different member is untouched.
62
+ expect(store.state.runnerLabels.get("runner-3")!.memberId).toBe("m2")
63
+ })
64
+
65
+ test("removeRunnerLabel deletes the label", async () => {
66
+ const store = new EventStore(await createTempDataDir())
67
+ await store.initialize()
68
+
69
+ await store.setRunnerLabel("runner-1", "Box A", null)
70
+ await store.removeRunnerLabel("runner-1")
71
+
72
+ expect(store.state.runnerLabels.get("runner-1")).toBeUndefined()
73
+ })
74
+
75
+ test("survive log replay without snapshot", async () => {
76
+ const dataDir = await createTempDataDir()
77
+ const store1 = new EventStore(dataDir)
78
+ await store1.initialize()
79
+ await store1.saveTeamMember({ id: "m1", name: "Alice" })
80
+ await store1.setRunnerLabel("runner-1", "Studio Mac", "m1")
81
+
82
+ const store2 = new EventStore(dataDir)
83
+ await store2.initialize()
84
+
85
+ expect(store2.state.teamMembers.get("m1")?.name).toBe("Alice")
86
+ expect(store2.state.runnerLabels.get("runner-1")?.name).toBe("Studio Mac")
87
+ expect(store2.state.runnerLabels.get("runner-1")?.memberId).toBe("m1")
88
+ })
89
+
90
+ test("survive snapshot round-trip (compaction)", async () => {
91
+ const dataDir = await createTempDataDir()
92
+ const store1 = new EventStore(dataDir)
93
+ await store1.initialize()
94
+ await store1.saveTeamMember({ id: "m1", name: "Alice" })
95
+ await store1.setRunnerLabel("runner-1", "Studio Mac", "m1")
96
+ await store1.compact()
97
+
98
+ const store2 = new EventStore(dataDir)
99
+ await store2.initialize()
100
+
101
+ expect(store2.state.teamMembers.get("m1")?.name).toBe("Alice")
102
+ expect(store2.state.runnerLabels.get("runner-1")?.memberId).toBe("m1")
103
+ })
104
+ })