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,112 @@
1
+ import { describe, test, expect } from "bun:test"
2
+ import {
3
+ toLogLine,
4
+ serializeBatch,
5
+ createLogShipper,
6
+ installConsoleTee,
7
+ type LogLine,
8
+ type LogSinkBase,
9
+ } from "./log-sink"
10
+
11
+ const base: LogSinkBase = { source: "backend", component: "server", host: "h", pid: 42 }
12
+
13
+ describe("toLogLine", () => {
14
+ test("joins string args into _msg and stamps fields", () => {
15
+ const at = new Date("2026-05-27T10:00:00.000Z")
16
+ const line = toLogLine("warn", ["[tinkaria]", "boom", 7], base, at)
17
+ expect(line).toEqual({
18
+ _time: "2026-05-27T10:00:00.000Z",
19
+ _msg: "[tinkaria] boom 7",
20
+ level: "warn",
21
+ source: "backend",
22
+ component: "server",
23
+ host: "h",
24
+ pid: 42,
25
+ })
26
+ })
27
+
28
+ test("serializes Error args to stack/message, objects to JSON", () => {
29
+ const line = toLogLine("error", [new Error("nope"), { a: 1 }], base)
30
+ expect(line._msg).toContain("nope")
31
+ expect(line._msg).toContain('{"a":1}')
32
+ })
33
+
34
+ test("does not throw on circular objects", () => {
35
+ const circular: Record<string, unknown> = {}
36
+ circular.self = circular
37
+ const line = toLogLine("info", [circular], base)
38
+ expect(typeof line._msg).toBe("string")
39
+ })
40
+ })
41
+
42
+ describe("serializeBatch", () => {
43
+ test("produces newline-delimited JSON", () => {
44
+ const lines: LogLine[] = [
45
+ toLogLine("info", ["a"], base, new Date("2026-05-27T10:00:00Z")),
46
+ toLogLine("info", ["b"], base, new Date("2026-05-27T10:00:01Z")),
47
+ ]
48
+ const out = serializeBatch(lines)
49
+ expect(out.split("\n")).toHaveLength(2)
50
+ expect(JSON.parse(out.split("\n")[0])._msg).toBe("a")
51
+ })
52
+ })
53
+
54
+ describe("createLogShipper", () => {
55
+ test("POSTs ndjson to /insert/jsonline with stream fields, and swallows fetch errors", async () => {
56
+ const calls: { url: string; body: string }[] = []
57
+ const fetchFn = (async (url: string, init?: RequestInit) => {
58
+ calls.push({ url, body: String(init?.body) })
59
+ return new Response(null, { status: 204 })
60
+ }) as unknown as typeof fetch
61
+
62
+ const shipper = createLogShipper({ url: "http://127.0.0.1:9428/", base, fetchFn })
63
+ shipper.add(toLogLine("info", ["one"], base))
64
+ shipper.add(toLogLine("info", ["two"], base))
65
+ await shipper.flush()
66
+ shipper.stop()
67
+
68
+ expect(calls).toHaveLength(1)
69
+ expect(calls[0].url).toBe("http://127.0.0.1:9428/insert/jsonline?_stream_fields=source,component")
70
+ expect(calls[0].body.split("\n")).toHaveLength(2)
71
+ })
72
+
73
+ test("flush with empty buffer makes no request", async () => {
74
+ let n = 0
75
+ const fetchFn = (async () => { n++; return new Response(null) }) as unknown as typeof fetch
76
+ const shipper = createLogShipper({ url: "http://x", base, fetchFn })
77
+ await shipper.flush()
78
+ shipper.stop()
79
+ expect(n).toBe(0)
80
+ })
81
+
82
+ test("fetch rejection is swallowed (no throw)", async () => {
83
+ const fetchFn = (async () => { throw new Error("network down") }) as unknown as typeof fetch
84
+ const shipper = createLogShipper({ url: "http://x", base, fetchFn })
85
+ shipper.add(toLogLine("error", ["x"], base))
86
+ await expect(shipper.flush()).resolves.toBeUndefined()
87
+ shipper.stop()
88
+ })
89
+ })
90
+
91
+ describe("installConsoleTee", () => {
92
+ test("no-op when VICTORIALOGS_URL unset (console unchanged)", () => {
93
+ const before = console.warn
94
+ const uninstall = installConsoleTee({} as NodeJS.ProcessEnv, "server")
95
+ expect(console.warn).toBe(before)
96
+ uninstall()
97
+ })
98
+
99
+ test("when set, tees but still calls the original console method", () => {
100
+ const seen: unknown[][] = []
101
+ const origWarn = console.warn
102
+ console.warn = ((...a: unknown[]) => seen.push(a)) as typeof console.warn
103
+ const uninstall = installConsoleTee(
104
+ { VICTORIALOGS_URL: "http://127.0.0.1:9428" } as unknown as NodeJS.ProcessEnv,
105
+ "server",
106
+ )
107
+ console.warn("hello", 1)
108
+ expect(seen).toEqual([["hello", 1]]) // original still invoked
109
+ uninstall()
110
+ console.warn = origWarn
111
+ })
112
+ })
@@ -0,0 +1,185 @@
1
+ /**
2
+ * Backend log sink → VictoriaLogs (observability, decision 0012).
3
+ *
4
+ * Tees `console.*` output to VictoriaLogs' JSON-stream ingest API
5
+ * (`POST /insert/jsonline`) in addition to normal stdout. Used by both the
6
+ * server (`cli.ts`) and the runner (`runner.ts`) processes.
7
+ *
8
+ * Design constraints:
9
+ * - **Never break the app.** All shipping is fire-and-forget; a down or slow
10
+ * VictoriaLogs must not throw into, block, or crash the host process.
11
+ * - **Opt-in.** Disabled unless `VICTORIALOGS_URL` is set, so default runs are
12
+ * byte-identical to before.
13
+ * - **No deps.** Plain `fetch` + a small in-memory batch.
14
+ *
15
+ * Pure helpers (`toLogLine`, `serializeBatch`) are exported for unit tests.
16
+ */
17
+
18
+ export type LogLevel = "debug" | "info" | "warn" | "error"
19
+
20
+ /** One VictoriaLogs jsonline record. `_time`/`_msg` are VL's default time/msg fields. */
21
+ export interface LogLine {
22
+ _time: string
23
+ _msg: string
24
+ level: LogLevel
25
+ source: string
26
+ component: string
27
+ host: string
28
+ pid: number
29
+ }
30
+
31
+ export interface LogSinkBase {
32
+ source: string // "backend"
33
+ component: string // "server" | "runner"
34
+ host: string
35
+ pid: number
36
+ }
37
+
38
+ /** Flatten console arguments into a single message string (no throwing on cycles). */
39
+ function stringifyArgs(args: unknown[]): string {
40
+ return args
41
+ .map((a) => {
42
+ if (typeof a === "string") return a
43
+ if (a instanceof Error) return a.stack ?? `${a.name}: ${a.message}`
44
+ try {
45
+ return JSON.stringify(a)
46
+ } catch {
47
+ return String(a)
48
+ }
49
+ })
50
+ .join(" ")
51
+ }
52
+
53
+ /** Build a single VL record from a console call. Pure. */
54
+ export function toLogLine(
55
+ level: LogLevel,
56
+ args: unknown[],
57
+ base: LogSinkBase,
58
+ now: Date = new Date(),
59
+ ): LogLine {
60
+ return {
61
+ _time: now.toISOString(),
62
+ _msg: stringifyArgs(args),
63
+ level,
64
+ source: base.source,
65
+ component: base.component,
66
+ host: base.host,
67
+ pid: base.pid,
68
+ }
69
+ }
70
+
71
+ /** Serialize a batch as newline-delimited JSON for `/insert/jsonline`. Pure. */
72
+ export function serializeBatch(lines: LogLine[]): string {
73
+ return lines.map((l) => JSON.stringify(l)).join("\n")
74
+ }
75
+
76
+ export interface LogShipperOptions {
77
+ url: string
78
+ base: LogSinkBase
79
+ flushIntervalMs?: number
80
+ maxBatch?: number
81
+ /** Injectable for tests. */
82
+ fetchFn?: typeof fetch
83
+ }
84
+
85
+ export interface LogShipper {
86
+ add(line: LogLine): void
87
+ flush(): Promise<void>
88
+ stop(): void
89
+ }
90
+
91
+ /**
92
+ * Batching shipper. Buffers records and POSTs them to VictoriaLogs on an
93
+ * interval or when the buffer is full. All network errors are swallowed.
94
+ */
95
+ export function createLogShipper(opts: LogShipperOptions): LogShipper {
96
+ const flushIntervalMs = opts.flushIntervalMs ?? 2000
97
+ const maxBatch = opts.maxBatch ?? 500
98
+ const doFetch = opts.fetchFn ?? fetch
99
+ const endpoint = `${opts.url.replace(/\/$/, "")}/insert/jsonline?_stream_fields=source,component`
100
+
101
+ let buffer: LogLine[] = []
102
+ let timer: ReturnType<typeof setInterval> | null = null
103
+
104
+ async function flush(): Promise<void> {
105
+ if (buffer.length === 0) return
106
+ const batch = buffer
107
+ buffer = []
108
+ try {
109
+ await doFetch(endpoint, {
110
+ method: "POST",
111
+ headers: { "Content-Type": "application/x-ndjson" },
112
+ body: serializeBatch(batch),
113
+ })
114
+ } catch {
115
+ // Drop on failure — observability must never back-pressure the app.
116
+ }
117
+ }
118
+
119
+ function add(line: LogLine): void {
120
+ buffer.push(line)
121
+ if (buffer.length >= maxBatch) void flush()
122
+ }
123
+
124
+ timer = setInterval(() => void flush(), flushIntervalMs)
125
+ // Don't keep the event loop alive just for log flushing.
126
+ if (typeof timer === "object" && timer && "unref" in timer) {
127
+ ;(timer as { unref: () => void }).unref()
128
+ }
129
+
130
+ return {
131
+ add,
132
+ flush,
133
+ stop() {
134
+ if (timer) clearInterval(timer)
135
+ timer = null
136
+ },
137
+ }
138
+ }
139
+
140
+ /**
141
+ * Tee `console.{debug,info,warn,error,log}` to VictoriaLogs while preserving the
142
+ * original stdout behavior. No-op (returns a no-op uninstaller) when
143
+ * `VICTORIALOGS_URL` is not set. Returns an uninstall function.
144
+ */
145
+ export function installConsoleTee(env: NodeJS.ProcessEnv, component: string): () => void {
146
+ const url = env.VICTORIALOGS_URL?.trim()
147
+ if (!url) return () => {}
148
+
149
+ const base: LogSinkBase = {
150
+ source: "backend",
151
+ component,
152
+ host: env.HOSTNAME || "unknown",
153
+ pid: typeof process !== "undefined" ? process.pid : 0,
154
+ }
155
+ const shipper = createLogShipper({ url, base })
156
+
157
+ const levels: Array<[keyof Console, LogLevel]> = [
158
+ ["debug", "debug"],
159
+ ["info", "info"],
160
+ ["log", "info"],
161
+ ["warn", "warn"],
162
+ ["error", "error"],
163
+ ]
164
+ const originals = new Map<keyof Console, (...a: unknown[]) => void>()
165
+
166
+ for (const [method, level] of levels) {
167
+ const original = console[method] as (...a: unknown[]) => void
168
+ originals.set(method, original)
169
+ ;(console[method] as unknown) = (...args: unknown[]) => {
170
+ try {
171
+ shipper.add(toLogLine(level, args, base))
172
+ } catch {
173
+ // never let logging shipping break a console call
174
+ }
175
+ original(...args)
176
+ }
177
+ }
178
+
179
+ return () => {
180
+ for (const [method, original] of originals) {
181
+ ;(console[method] as unknown) = original
182
+ }
183
+ shipper.stop()
184
+ }
185
+ }
@@ -0,0 +1,7 @@
1
+ // Single source of truth for `@agent/<name>` mention parsing.
2
+ // Server is authoritative; the client uses this for picker chips only.
3
+ export const AGENT_MENTION_PATTERN = "(^|[\\s\\n\\t])@agent/([a-z0-9_-]+)"
4
+
5
+ export function createAgentMentionRegex(): RegExp {
6
+ return new RegExp(AGENT_MENTION_PATTERN, "gi")
7
+ }
@@ -0,0 +1,41 @@
1
+ import { type PresetDefinition, getPreset } from "./preset-types"
2
+
3
+ export type MergePresetDefinition = PresetDefinition
4
+
5
+ export const MERGE_PRESETS: readonly MergePresetDefinition[] = [
6
+ {
7
+ id: "synthesis",
8
+ label: "Synthesis",
9
+ description: "Combine findings and decisions into a unified understanding.",
10
+ defaultIntent: "Synthesize these sessions into a unified understanding. Extract the key findings, decisions, and constraints from each, resolve any contradictions, and frame the merged context as a single coherent brief for the next step.",
11
+ generatorHint: "Bias toward a cohesive narrative that resolves contradictions and surfaces the strongest decisions from each source session.",
12
+ },
13
+ {
14
+ id: "compare_decide",
15
+ label: "Compare & decide",
16
+ description: "Compare approaches explored in different sessions and surface trade-offs.",
17
+ defaultIntent: "Compare the approaches explored across these sessions. Surface the trade-offs, identify which constraints each approach satisfies or violates, and frame the merged context to support a clear decision.",
18
+ generatorHint: "Emphasize trade-offs, differences in assumptions, and decision criteria. Present approaches side-by-side.",
19
+ },
20
+ {
21
+ id: "consolidate_progress",
22
+ label: "Consolidate progress",
23
+ description: "Merge partial work from several sessions into a single next-step brief.",
24
+ defaultIntent: "Consolidate the progress from these sessions into a single next-step brief. Identify what was completed, what remains, and any blockers or dependencies across the sessions.",
25
+ generatorHint: "Prioritize what was accomplished, what's left to do, and any cross-session dependencies or blockers.",
26
+ },
27
+ {
28
+ id: "knowledge_base",
29
+ label: "Knowledge base",
30
+ description: "Extract and unify learned patterns, constraints, and decisions.",
31
+ defaultIntent: "Extract and unify the learned patterns, constraints, and key decisions from these sessions. Organize them as a reference brief that can guide future work without re-reading the originals.",
32
+ generatorHint: "Bias toward structured reference content: patterns, constraints, conventions, and decisions. Avoid execution steps.",
33
+ },
34
+ ] as const
35
+
36
+ export const MAX_MERGE_SESSIONS = 5
37
+ export const DEFAULT_MERGE_PRESET_ID = MERGE_PRESETS[0]!.id
38
+
39
+ export function getMergePreset(id?: string | null): MergePresetDefinition | null {
40
+ return getPreset(MERGE_PRESETS, id)
41
+ }
@@ -0,0 +1,61 @@
1
+ import { describe, test, expect } from "bun:test"
2
+ import {
3
+ snapshotSubject,
4
+ terminalEventSubject,
5
+ commandSubject,
6
+ ALL_SNAPSHOTS,
7
+ ALL_TERMINAL_EVENTS,
8
+ ALL_COMMANDS,
9
+ } from "./nats-subjects"
10
+
11
+ describe("snapshotSubject", () => {
12
+ test("sidebar", () => {
13
+ expect(snapshotSubject({ type: "sidebar" })).toBe("runtime.snap.sidebar")
14
+ })
15
+
16
+ test("local-workspaces", () => {
17
+ expect(snapshotSubject({ type: "local-workspaces" })).toBe("runtime.snap.local-workspaces")
18
+ })
19
+
20
+ test("update", () => {
21
+ expect(snapshotSubject({ type: "update" })).toBe("runtime.snap.update")
22
+ })
23
+
24
+ test("chat with chatId", () => {
25
+ expect(snapshotSubject({ type: "chat", chatId: "abc-123" })).toBe("runtime.snap.chat.abc-123")
26
+ })
27
+
28
+ test("terminal with terminalId", () => {
29
+ expect(snapshotSubject({ type: "terminal", terminalId: "term-456" })).toBe("runtime.snap.terminal.term-456")
30
+ })
31
+ })
32
+
33
+ describe("terminalEventSubject", () => {
34
+ test("generates correct subject", () => {
35
+ expect(terminalEventSubject("term-789")).toBe("runtime.evt.terminal.term-789")
36
+ })
37
+ })
38
+
39
+ describe("commandSubject", () => {
40
+ test("generates correct subject", () => {
41
+ expect(commandSubject("chat.send")).toBe("runtime.cmd.chat.send")
42
+ })
43
+
44
+ test("system commands", () => {
45
+ expect(commandSubject("system.ping")).toBe("runtime.cmd.system.ping")
46
+ })
47
+ })
48
+
49
+ describe("wildcards", () => {
50
+ test("ALL_SNAPSHOTS", () => {
51
+ expect(ALL_SNAPSHOTS).toBe("runtime.snap.>")
52
+ })
53
+
54
+ test("ALL_TERMINAL_EVENTS", () => {
55
+ expect(ALL_TERMINAL_EVENTS).toBe("runtime.evt.terminal.>")
56
+ })
57
+
58
+ test("ALL_COMMANDS", () => {
59
+ expect(ALL_COMMANDS).toBe("runtime.cmd.>")
60
+ })
61
+ })
@@ -0,0 +1,131 @@
1
+ import type { SubscriptionTopic } from "./protocol"
2
+
3
+ const PREFIX = "runtime"
4
+ const SNAP_PREFIX = `${PREFIX}.snap.`
5
+
6
+ /** Map a subscription topic to a KV key (also the subject suffix after `runtime.snap.`) */
7
+ export function snapshotKvKey(topic: SubscriptionTopic): string {
8
+ switch (topic.type) {
9
+ case "chat": return `chat.${topic.chatId}`
10
+ case "terminal": return `terminal.${topic.terminalId}`
11
+ case "orchestration": return `orchestration.${topic.chatId}`
12
+ case "workspace": return `workspace.${topic.workspaceId}`
13
+ case "agent-config": return `agent-config.${topic.workspaceId}`
14
+ case "repos": return `repos.${topic.workspaceId}`
15
+ case "workflow-runs": return `workflow-runs.${topic.workspaceId}`
16
+ case "sandbox-status": return `sandbox-status.${topic.workspaceId}`
17
+ default: return topic.type
18
+ }
19
+ }
20
+
21
+ export function snapshotSubject(topic: SubscriptionTopic): string {
22
+ return `${SNAP_PREFIX}${snapshotKvKey(topic)}`
23
+ }
24
+
25
+ export function terminalEventSubject(terminalId: string): string {
26
+ return `${PREFIX}.evt.terminal.${terminalId}`
27
+ }
28
+
29
+ export function chatMessageSubject(chatId: string): string {
30
+ return `${PREFIX}.evt.chat.${chatId}`
31
+ }
32
+
33
+ export function commandSubject(commandType: string): string {
34
+ return `${PREFIX}.cmd.${commandType}`
35
+ }
36
+
37
+ /** Wildcard: all snapshot subjects */
38
+ export const ALL_SNAPSHOTS = `${SNAP_PREFIX}>`
39
+
40
+ /** Wildcard: all terminal events */
41
+ export const ALL_TERMINAL_EVENTS = `${PREFIX}.evt.terminal.>`
42
+
43
+ /** Wildcard: all chat message events */
44
+ export const ALL_CHAT_MESSAGE_EVENTS = `${PREFIX}.evt.chat.>`
45
+
46
+ /** Wildcard: all commands */
47
+ export const ALL_COMMANDS = `${PREFIX}.cmd.>`
48
+
49
+ /** JetStream stream name for chat message events */
50
+ export const CHAT_MESSAGE_EVENTS_STREAM_NAME = "KANNA_CHAT_MESSAGE_EVENTS"
51
+
52
+ /** KV bucket name for snapshot caching */
53
+ export const KV_BUCKET = "runtime_snapshots"
54
+
55
+ /** JetStream stream name for workspace coordination events */
56
+ export const WORKSPACE_COORDINATION_EVENTS_STREAM_NAME = "KANNA_WORKSPACE_COORDINATION_EVENTS"
57
+
58
+ /** Subject for workspace coordination events */
59
+ export function workspaceCoordinationEventSubject(workspaceId: string): string {
60
+ return `${PREFIX}.evt.workspace.${workspaceId}`
61
+ }
62
+
63
+ /** Wildcard: all workspace coordination events */
64
+ export const ALL_WORKSPACE_COORDINATION_EVENTS = `${PREFIX}.evt.workspace.>`
65
+
66
+ /** JetStream stream name for workflow run events */
67
+ export const WORKFLOW_RUN_EVENTS_STREAM_NAME = "KANNA_WORKFLOW_RUN_EVENTS"
68
+
69
+ /** Subject for workflow run events */
70
+ export function workflowRunEventSubject(workspaceId: string): string {
71
+ return `${PREFIX}.evt.workflow.${workspaceId}`
72
+ }
73
+
74
+ /** Wildcard: all workflow run events */
75
+ export const ALL_WORKFLOW_RUN_EVENTS = `${PREFIX}.evt.workflow.>`
76
+
77
+ /** JetStream stream name for sandbox events */
78
+ export const SANDBOX_EVENTS_STREAM_NAME = "KANNA_SANDBOX_EVENTS"
79
+
80
+ /** Subject for sandbox events */
81
+ export function sandboxEventSubject(workspaceId: string): string {
82
+ return `${PREFIX}.evt.sandbox.${workspaceId}`
83
+ }
84
+
85
+ /** Wildcard: all sandbox events */
86
+ export const ALL_SANDBOX_EVENTS = `${PREFIX}.evt.sandbox.>`
87
+
88
+ // === claude-pty subjects ===
89
+
90
+ export type PtyCommandType =
91
+ | "pty.spawn"
92
+ | "pty.input"
93
+ | "pty.resize"
94
+ | "pty.cancel"
95
+ | "pty.exit"
96
+ | "pty.snapshot"
97
+
98
+ export function ptyCommandSubject(commandType: PtyCommandType): string {
99
+ return `${PREFIX}.cmd.${commandType}`
100
+ }
101
+
102
+ export function ptyDeltaSubject(): string {
103
+ return `${PREFIX}.evt.pty.delta`
104
+ }
105
+
106
+ export function ptyInstanceEventSubject(chatId: string): string {
107
+ return `${PREFIX}.evt.pty.${chatId}`
108
+ }
109
+
110
+ export const ALL_PTY_COMMANDS = `${PREFIX}.cmd.pty.>`
111
+ export const ALL_PTY_EVENTS = `${PREFIX}.evt.pty.>`
112
+
113
+ // === oauth pool subjects ===
114
+
115
+ export type OAuthCommandType =
116
+ | "oauth.list"
117
+ | "oauth.add"
118
+ | "oauth.remove"
119
+ | "oauth.update"
120
+ | "oauth.setConcurrencyDefault"
121
+
122
+ export function oauthCommandSubject(commandType: OAuthCommandType): string {
123
+ return `${PREFIX}.cmd.${commandType}`
124
+ }
125
+
126
+ export function oauthChangedSubject(): string {
127
+ return `${PREFIX}.evt.oauth.changed`
128
+ }
129
+
130
+ export const ALL_OAUTH_COMMANDS = `${PREFIX}.cmd.oauth.>`
131
+ export const ALL_OAUTH_EVENTS = `${PREFIX}.evt.oauth.>`
@@ -0,0 +1,136 @@
1
+ export type ToolRequestStatus =
2
+ | "pending"
3
+ | "answered"
4
+ | "timeout"
5
+ | "canceled"
6
+ | "session_closed"
7
+ | "arg_mismatch"
8
+
9
+ export const POLICY_TERMINAL_STATUSES: ReadonlySet<ToolRequestStatus> = new Set([
10
+ "answered",
11
+ "timeout",
12
+ "canceled",
13
+ "session_closed",
14
+ "arg_mismatch",
15
+ ])
16
+
17
+ export type PolicyVerdict = "auto-allow" | "auto-deny" | "ask"
18
+
19
+ export interface BashGateConfig {
20
+ autoAllowVerbs: string[]
21
+ }
22
+
23
+ export interface ToolRule {
24
+ tool: string
25
+ /** ECMAScript regex source — no delimiters or flags, passed to `new RegExp(pattern)`. */
26
+ pattern: string
27
+ }
28
+
29
+ export interface ChatPermissionPolicy {
30
+ defaultAction: "ask" | "auto-allow" | "auto-deny"
31
+ bash: BashGateConfig
32
+ readPathDeny: string[]
33
+ /** Paths the model cannot write or edit. Enforced for mcp__kanna__write and mcp__kanna__edit. */
34
+ writePathDeny: string[]
35
+ toolDenyList: ToolRule[]
36
+ toolAllowList: ToolRule[]
37
+ }
38
+
39
+ /**
40
+ * Per-chat policy override. Only set fields override the global policy
41
+ * defaults. Persisted on `ChatRecord.policyOverride` and merged in
42
+ * `AgentCoordinator` before forwarding to the session.
43
+ *
44
+ * `readPathDeny` / `writePathDeny` REPLACE the default list when provided
45
+ * (so the user can both add and remove entries deliberately).
46
+ */
47
+ export interface ChatPermissionPolicyOverride {
48
+ defaultAction?: ChatPermissionPolicy["defaultAction"]
49
+ readPathDeny?: string[]
50
+ writePathDeny?: string[]
51
+ }
52
+
53
+ export function mergePolicyOverride(
54
+ base: ChatPermissionPolicy,
55
+ override: ChatPermissionPolicyOverride | null | undefined,
56
+ ): ChatPermissionPolicy {
57
+ if (!override) return base
58
+ return {
59
+ ...base,
60
+ defaultAction: override.defaultAction ?? base.defaultAction,
61
+ readPathDeny: override.readPathDeny ?? base.readPathDeny,
62
+ writePathDeny: override.writePathDeny ?? base.writePathDeny,
63
+ }
64
+ }
65
+
66
+ export interface ToolRequestDecision {
67
+ kind: "allow" | "deny" | "answer"
68
+ payload?: unknown
69
+ reason?: string
70
+ }
71
+
72
+ export interface ToolRequest {
73
+ id: string
74
+ chatId: string
75
+ sessionId: string
76
+ toolUseId: string
77
+ toolName: string
78
+ arguments: Record<string, unknown> // MCP tool arguments — arbitrary MCP tool args, unknown shape by design
79
+ canonicalArgsHash: string
80
+ policyVerdict: PolicyVerdict
81
+ status: ToolRequestStatus
82
+ decision?: ToolRequestDecision
83
+ mismatchReason?: string
84
+ createdAt: number
85
+ resolvedAt?: number
86
+ expiresAt: number
87
+ }
88
+
89
+ export const POLICY_DEFAULT: ChatPermissionPolicy = {
90
+ defaultAction: "ask",
91
+ bash: {
92
+ autoAllowVerbs: ["ls", "pwd", "git status", "git diff", "git log"],
93
+ },
94
+ readPathDeny: [
95
+ "~/.ssh",
96
+ "~/.aws",
97
+ "~/.gcp",
98
+ "~/.config/gh",
99
+ "~/.claude",
100
+ "~/.kanna",
101
+ "~/Library/Keychains",
102
+ "/etc/shadow",
103
+ "/etc/sudoers",
104
+ "~/.gnupg",
105
+ "~/.gitconfig",
106
+ "**/.git/config",
107
+ "~/.npmrc",
108
+ "~/.netrc",
109
+ "~/.docker/config.json",
110
+ "**/.env",
111
+ "**/.env.*",
112
+ "**/credentials*",
113
+ "**/*.pem",
114
+ "**/*.key",
115
+ "**/id_rsa*",
116
+ "**/id_ed25519*",
117
+ ],
118
+ writePathDeny: [
119
+ "/etc/**",
120
+ "/usr/**",
121
+ "/System/**",
122
+ "~/.ssh/**",
123
+ "~/.aws/**",
124
+ "~/.config/gh/**",
125
+ "~/.claude/**",
126
+ "~/.kanna/**",
127
+ "~/.gnupg/**",
128
+ "~/.gitconfig",
129
+ "**/.git/config",
130
+ ],
131
+ toolDenyList: [
132
+ { tool: "mcp__kanna__bash", pattern: "rm\\s+-rf\\s+(/|~|\\$HOME)(?:\\b|$|\\s)" },
133
+ { tool: "mcp__kanna__bash", pattern: "git\\s+push\\b.*--force" },
134
+ ],
135
+ toolAllowList: [],
136
+ }
@@ -0,0 +1,3 @@
1
+ export const PROD_SERVER_HOST = "127.0.0.1"
2
+ export const PROD_SERVER_PORT = 3210
3
+ export const DEV_CLIENT_PORT = 5174
@@ -0,0 +1,15 @@
1
+ export interface PresetDefinition {
2
+ id: string
3
+ label: string
4
+ description: string
5
+ defaultIntent: string
6
+ generatorHint: string
7
+ }
8
+
9
+ export function getPreset<T extends PresetDefinition>(
10
+ presets: readonly T[],
11
+ id?: string | null,
12
+ ): T | null {
13
+ if (!id) return null
14
+ return presets.find((preset) => preset.id === id) ?? null
15
+ }