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,42 @@
1
+ import { describe, expect, test } from "bun:test"
2
+ import {
3
+ APP_NAME,
4
+ CLI_COMMAND,
5
+ LOG_PREFIX,
6
+ PACKAGE_NAME,
7
+ RUNTIME_PROFILE_ENV_VAR,
8
+ SDK_CLIENT_APP,
9
+ getDataDir,
10
+ getDataDirDisplay,
11
+ getDataRootName,
12
+ getCliInvocation,
13
+ getRuntimeProfile,
14
+ } from "./branding"
15
+
16
+ describe("runtime profile helpers", () => {
17
+ test("defaults to the prod profile when unset", () => {
18
+ expect(APP_NAME).toBe("Tinkaria")
19
+ expect(CLI_COMMAND).toBe("tinkaria")
20
+ expect(PACKAGE_NAME).toBe("tinkaria")
21
+ expect(LOG_PREFIX).toBe("[tinkaria]")
22
+ expect(SDK_CLIENT_APP).toStartWith("tinkaria/")
23
+ expect(getCliInvocation("--port 4000")).toBe("tinkaria --port 4000")
24
+ expect(getRuntimeProfile({})).toBe("prod")
25
+ expect(getDataRootName({})).toBe(".tinkaria")
26
+ expect(getDataDir("/tmp/home", {})).toBe("/tmp/home/.tinkaria/data")
27
+ expect(getDataDirDisplay({})).toBe("~/.tinkaria/data")
28
+ })
29
+
30
+ test("switches to dev paths for the dev profile", () => {
31
+ const env = { [RUNTIME_PROFILE_ENV_VAR]: "dev" }
32
+
33
+ expect(getRuntimeProfile(env)).toBe("dev")
34
+ expect(getDataRootName(env)).toBe(".tinkaria-dev")
35
+ expect(getDataDir("/tmp/home", env)).toBe("/tmp/home/.tinkaria-dev/data")
36
+ expect(getDataDirDisplay(env)).toBe("~/.tinkaria-dev/data")
37
+ })
38
+
39
+ test("still honors the legacy runtime profile environment variable for compatibility", () => {
40
+ expect(getRuntimeProfile({ KANNA_RUNTIME_PROFILE: "dev" })).toBe("dev")
41
+ })
42
+ })
@@ -0,0 +1,54 @@
1
+ export const APP_NAME = "Tinkaria"
2
+ export const CLI_COMMAND = "tinkaria"
3
+ export const DATA_ROOT_NAME = ".tinkaria"
4
+ export const DEV_DATA_ROOT_NAME = ".tinkaria-dev"
5
+ export const PACKAGE_NAME = "tinkaria"
6
+ export const RUNTIME_PROFILE_ENV_VAR = "TINKARIA_RUNTIME_PROFILE"
7
+ export const LEGACY_RUNTIME_PROFILE_ENV_VAR = "KANNA_RUNTIME_PROFILE"
8
+ // Read version from package.json — JSON import works in both Bun and Vite
9
+ import pkg from "../../package.json"
10
+ export const SDK_CLIENT_APP = `tinkaria/${pkg.version}`
11
+ export const LOG_PREFIX = "[tinkaria]"
12
+ export const DEFAULT_NEW_PROJECT_ROOT = `~/${APP_NAME}`
13
+
14
+ export type RuntimeProfile = "dev" | "prod"
15
+
16
+ type RuntimeEnv = Record<string, string | undefined> | undefined
17
+
18
+ function getRuntimeEnv(): RuntimeEnv {
19
+ const candidate = globalThis as typeof globalThis & {
20
+ process?: {
21
+ env?: Record<string, string | undefined>
22
+ }
23
+ }
24
+ return candidate.process?.env
25
+ }
26
+
27
+ export function getRuntimeProfile(env: RuntimeEnv = getRuntimeEnv()): RuntimeProfile {
28
+ const profile = env?.[RUNTIME_PROFILE_ENV_VAR] ?? env?.[LEGACY_RUNTIME_PROFILE_ENV_VAR]
29
+ return profile?.trim().toLowerCase() === "dev" ? "dev" : "prod"
30
+ }
31
+
32
+ export function getDataRootName(env: RuntimeEnv = getRuntimeEnv()) {
33
+ return getRuntimeProfile(env) === "dev" ? DEV_DATA_ROOT_NAME : DATA_ROOT_NAME
34
+ }
35
+
36
+ export function getDataRootDir(homeDir: string, env: RuntimeEnv = getRuntimeEnv()) {
37
+ return `${homeDir}/${getDataRootName(env)}`
38
+ }
39
+
40
+ export function getDataRootDirDisplay(env: RuntimeEnv = getRuntimeEnv()) {
41
+ return `~/${getDataRootName(env)}`
42
+ }
43
+
44
+ export function getDataDir(homeDir: string, env: RuntimeEnv = getRuntimeEnv()) {
45
+ return `${getDataRootDir(homeDir, env)}/data`
46
+ }
47
+
48
+ export function getDataDirDisplay(env: RuntimeEnv = getRuntimeEnv()) {
49
+ return `${getDataRootDirDisplay(env)}/data`
50
+ }
51
+
52
+ export function getCliInvocation(arg?: string) {
53
+ return arg ? `${CLI_COMMAND} ${arg}` : CLI_COMMAND
54
+ }
@@ -0,0 +1,85 @@
1
+ import { describe, test, expect } from "bun:test"
2
+ import { isGzipped, compressPayload, decompressPayload } from "./compression"
3
+
4
+ const encoder = new TextEncoder()
5
+ const decoder = new TextDecoder()
6
+
7
+ function makeJson(sizeHint: number): string {
8
+ const entry = { kind: "text", id: "msg-001", content: "x".repeat(200), timestamp: "2026-03-31T00:00:00Z" }
9
+ const entries: typeof entry[] = []
10
+ while (JSON.stringify(entries).length < sizeHint) {
11
+ entries.push({ ...entry, id: `msg-${entries.length}` })
12
+ }
13
+ return JSON.stringify(entries)
14
+ }
15
+
16
+ describe("isGzipped", () => {
17
+ test("detects gzip magic bytes", () => {
18
+ expect(isGzipped(new Uint8Array([0x1f, 0x8b, 0x08]))).toBe(true)
19
+ })
20
+
21
+ test("rejects plain JSON", () => {
22
+ expect(isGzipped(encoder.encode('{"hello":"world"}'))).toBe(false)
23
+ })
24
+
25
+ test("rejects empty input", () => {
26
+ expect(isGzipped(new Uint8Array([]))).toBe(false)
27
+ })
28
+
29
+ test("rejects single-byte input", () => {
30
+ expect(isGzipped(new Uint8Array([0x1f]))).toBe(false)
31
+ })
32
+ })
33
+
34
+ describe("compressPayload", () => {
35
+ test("passes through small payloads unchanged", () => {
36
+ const small = encoder.encode('{"tiny":true}')
37
+ const result = compressPayload(small)
38
+ expect(result).toBe(small) // same reference — no copy
39
+ })
40
+
41
+ test("compresses payloads above 64 KB threshold", () => {
42
+ const largeJson = makeJson(100_000)
43
+ const raw = encoder.encode(largeJson)
44
+ expect(raw.length).toBeGreaterThan(65_536)
45
+
46
+ const compressed = compressPayload(raw)
47
+ expect(compressed.length).toBeLessThan(raw.length)
48
+ expect(isGzipped(compressed)).toBe(true)
49
+ })
50
+
51
+ test("compressed output is valid gzip that roundtrips", async () => {
52
+ const largeJson = makeJson(100_000)
53
+ const raw = encoder.encode(largeJson)
54
+ const compressed = compressPayload(raw)
55
+
56
+ const decompressed = await decompressPayload(compressed)
57
+ expect(decoder.decode(decompressed)).toBe(largeJson)
58
+ })
59
+ })
60
+
61
+ describe("decompressPayload", () => {
62
+ test("passes through non-gzipped data unchanged", async () => {
63
+ const plain = encoder.encode('{"hello":"world"}')
64
+ const result = await decompressPayload(plain)
65
+ expect(decoder.decode(result)).toBe('{"hello":"world"}')
66
+ })
67
+
68
+ test("decompresses gzipped data correctly", async () => {
69
+ const largeJson = makeJson(100_000)
70
+ const raw = encoder.encode(largeJson)
71
+ const compressed = compressPayload(raw)
72
+
73
+ const result = await decompressPayload(compressed)
74
+ expect(decoder.decode(result)).toBe(largeJson)
75
+ })
76
+
77
+ test("roundtrip: compressPayload -> decompressPayload", async () => {
78
+ const largeJson = makeJson(200_000)
79
+ const raw = encoder.encode(largeJson)
80
+ const compressed = compressPayload(raw)
81
+ const decompressed = await decompressPayload(compressed)
82
+
83
+ expect(decoder.decode(decompressed)).toBe(largeJson)
84
+ })
85
+ })
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Transparent gzip compression for NATS payloads.
3
+ *
4
+ * Large chat snapshots exceed NATS max_payload (8 MB).
5
+ * JSON compresses 10-20x, raising the effective ceiling to ~80-160 MB.
6
+ */
7
+
8
+ const COMPRESS_THRESHOLD = 65_536
9
+
10
+ export function isGzipped(data: Uint8Array): boolean {
11
+ return data.length >= 2 && data[0] === 0x1f && data[1] === 0x8b
12
+ }
13
+
14
+ // TS 5.8 widens Uint8Array to Uint8Array<ArrayBufferLike>, but Bun APIs require Uint8Array<ArrayBuffer>.
15
+ // TextEncoder.encode() always backs by ArrayBuffer, making the narrowing safe.
16
+ type BunBytes = Uint8Array<ArrayBuffer>
17
+
18
+ function toBunBytes(data: Uint8Array): BunBytes {
19
+ if (data.buffer instanceof ArrayBuffer) {
20
+ return new Uint8Array(data.buffer, data.byteOffset, data.byteLength)
21
+ }
22
+
23
+ return new Uint8Array(data.slice())
24
+ }
25
+
26
+ export function compressPayload(raw: Uint8Array): Uint8Array {
27
+ if (raw.length <= COMPRESS_THRESHOLD) return raw
28
+ return Bun.gzipSync(toBunBytes(raw), { level: 1 })
29
+ }
30
+
31
+ export async function decompressPayload(data: Uint8Array): Promise<Uint8Array> {
32
+ if (!isGzipped(data)) return data
33
+ // Server (Bun): use synchronous gunzip — no stream overhead
34
+ if (typeof Bun !== "undefined") {
35
+ return Bun.gunzipSync(toBunBytes(data))
36
+ }
37
+ // Browser fallback: DecompressionStream
38
+ const ds = new DecompressionStream("gzip")
39
+ const writer = ds.writable.getWriter()
40
+ void writer.write(toBunBytes(data)).then(() => writer.close())
41
+ return new Uint8Array(await new Response(ds.readable).arrayBuffer())
42
+ }
@@ -0,0 +1,24 @@
1
+ import { describe, test, expect } from "bun:test"
2
+ import type { CoordinationStore } from "./coordination-store"
3
+
4
+ describe("CoordinationStore interface", () => {
5
+ test("type-checks against EventStore shape", () => {
6
+ // This is a compile-time test — if CoordinationStore is incompatible
7
+ // with EventStore's methods, tsc will fail.
8
+ const mockStore: CoordinationStore = {
9
+ state: { coordinationByWorkspace: new Map() },
10
+ addTodo: async () => {},
11
+ claimTodo: async () => {},
12
+ completeTodo: async () => {},
13
+ abandonTodo: async () => {},
14
+ createClaim: async () => {},
15
+ releaseClaim: async () => {},
16
+ createWorktree: async () => {},
17
+ assignWorktree: async () => {},
18
+ removeWorktree: async () => {},
19
+ setRule: async () => {},
20
+ removeRule: async () => {},
21
+ }
22
+ expect(mockStore).toBeDefined()
23
+ })
24
+ })
@@ -0,0 +1,26 @@
1
+ import type { WorkspaceCoordinationState } from "../server/events"
2
+ import type { WorkspaceCoordinationSnapshot, TodoPriority } from "./workspace-types"
3
+
4
+ /**
5
+ * Minimal interface for project coordination operations.
6
+ * Implemented by EventStore (server-side, in-process) and
7
+ * NatsCoordinationClient (runner-side, over NATS).
8
+ */
9
+ export interface CoordinationStore {
10
+ state: {
11
+ coordinationByWorkspace: Map<string, WorkspaceCoordinationState>
12
+ }
13
+ addTodo(workspaceId: string, todoId: string, description: string, priority: TodoPriority, createdBy: string): Promise<void>
14
+ claimTodo(workspaceId: string, todoId: string, sessionId: string): Promise<void>
15
+ completeTodo(workspaceId: string, todoId: string, outputs: string[]): Promise<void>
16
+ abandonTodo(workspaceId: string, todoId: string): Promise<void>
17
+ createClaim(workspaceId: string, claimId: string, intent: string, files: string[], sessionId: string): Promise<void>
18
+ releaseClaim(workspaceId: string, claimId: string): Promise<void>
19
+ createWorktree(workspaceId: string, worktreeId: string, branch: string, baseBranch: string, path: string): Promise<void>
20
+ assignWorktree(workspaceId: string, worktreeId: string, sessionId: string): Promise<void>
21
+ removeWorktree(workspaceId: string, worktreeId: string): Promise<void>
22
+ setRule(workspaceId: string, ruleId: string, content: string, setBy: string): Promise<void>
23
+ removeRule(workspaceId: string, ruleId: string): Promise<void>
24
+ /** Optional: fetch a full coordination snapshot (used when state is not in-process). */
25
+ getSnapshot?(workspaceId: string): Promise<WorkspaceCoordinationSnapshot>
26
+ }
@@ -0,0 +1,84 @@
1
+ import { describe, expect, test } from "bun:test"
2
+ import {
3
+ DEFAULT_DEV_CLIENT_PORT,
4
+ getDefaultDevServerPort,
5
+ parseDevArgs,
6
+ resolveDevPorts,
7
+ stripPortArg,
8
+ } from "./dev-ports"
9
+
10
+ describe("getDefaultDevServerPort", () => {
11
+ test("derives the default backend port from the client port", () => {
12
+ expect(getDefaultDevServerPort()).toBe(DEFAULT_DEV_CLIENT_PORT + 1)
13
+ expect(getDefaultDevServerPort(4000)).toBe(4001)
14
+ })
15
+ })
16
+
17
+ describe("resolveDevPorts", () => {
18
+ test("uses default dev ports when no port override is provided", () => {
19
+ expect(resolveDevPorts([])).toEqual({
20
+ clientPort: DEFAULT_DEV_CLIENT_PORT,
21
+ serverPort: DEFAULT_DEV_CLIENT_PORT + 1,
22
+ })
23
+ })
24
+
25
+ test("treats --port as the client port and derives the backend port", () => {
26
+ expect(resolveDevPorts(["--remote", "--port", "4000"])).toEqual({
27
+ clientPort: 4000,
28
+ serverPort: 4001,
29
+ })
30
+ })
31
+
32
+ test("uses the last provided --port value", () => {
33
+ expect(resolveDevPorts(["--port", "4000", "--port", "4100"])).toEqual({
34
+ clientPort: 4100,
35
+ serverPort: 4101,
36
+ })
37
+ })
38
+
39
+ test("throws when --port is missing a value", () => {
40
+ expect(() => resolveDevPorts(["--port"])).toThrow("Missing value for --port")
41
+ expect(() => resolveDevPorts(["--port", "--remote"])).toThrow("Missing value for --port")
42
+ })
43
+ })
44
+
45
+ describe("stripPortArg", () => {
46
+ test("removes --port and its value while preserving other args", () => {
47
+ expect(stripPortArg(["--remote", "--port", "4000", "--host", "dev-box"])).toEqual([
48
+ "--remote",
49
+ "--host",
50
+ "dev-box",
51
+ ])
52
+ })
53
+ })
54
+
55
+ describe("parseDevArgs", () => {
56
+ test("derives dev share options from the client port", () => {
57
+ expect(parseDevArgs(["--share", "--port", "3333"], "dev-machine")).toEqual({
58
+ clientPort: 3333,
59
+ serverPort: 3334,
60
+ share: true,
61
+ backendTargetHost: "127.0.0.1",
62
+ allowedHosts: true,
63
+ serverArgs: [],
64
+ })
65
+ })
66
+
67
+ test("rejects combining --share with --host or --remote", () => {
68
+ expect(() => parseDevArgs(["--share", "--host", "dev-box"], "dev-machine")).toThrow("--share cannot be used with --host")
69
+ expect(() => parseDevArgs(["--host", "dev-box", "--share"], "dev-machine")).toThrow("--share cannot be used with --host")
70
+ expect(() => parseDevArgs(["--share", "--remote"], "dev-machine")).toThrow("--share cannot be used with --remote")
71
+ expect(() => parseDevArgs(["--remote", "--share"], "dev-machine")).toThrow("--share cannot be used with --remote")
72
+ })
73
+
74
+ test("preserves existing remote host behavior when share is off", () => {
75
+ expect(parseDevArgs(["--remote", "--port", "3333"], "dev-machine")).toEqual({
76
+ clientPort: 3333,
77
+ serverPort: 3334,
78
+ share: false,
79
+ backendTargetHost: "127.0.0.1",
80
+ allowedHosts: true,
81
+ serverArgs: ["--remote"],
82
+ })
83
+ })
84
+ })
@@ -0,0 +1,100 @@
1
+ export const DEFAULT_DEV_CLIENT_PORT = 5174
2
+
3
+ export function getDefaultDevServerPort(clientPort = DEFAULT_DEV_CLIENT_PORT) {
4
+ return clientPort + 1
5
+ }
6
+
7
+ export interface DevArgResolution {
8
+ clientPort: number
9
+ serverPort: number
10
+ share: boolean
11
+ backendTargetHost: string
12
+ allowedHosts: true | string[]
13
+ serverArgs: string[]
14
+ }
15
+
16
+ export function resolveDevPorts(args: string[]) {
17
+ let clientPort = DEFAULT_DEV_CLIENT_PORT
18
+
19
+ for (let index = 0; index < args.length; index += 1) {
20
+ const arg = args[index]
21
+ if (arg !== "--port") continue
22
+
23
+ const next = args[index + 1]
24
+ if (!next || next.startsWith("-")) {
25
+ throw new Error("Missing value for --port")
26
+ }
27
+
28
+ const parsed = Number(next)
29
+ if (!Number.isFinite(parsed)) throw new Error(`Invalid port: ${next}`)
30
+ clientPort = parsed
31
+ index += 1
32
+ }
33
+
34
+ return {
35
+ clientPort,
36
+ serverPort: getDefaultDevServerPort(clientPort),
37
+ }
38
+ }
39
+
40
+ export function stripPortArg(args: string[]) {
41
+ const stripped: string[] = []
42
+
43
+ for (let index = 0; index < args.length; index += 1) {
44
+ const arg = args[index]
45
+ if (arg === "--port") {
46
+ index += 1
47
+ continue
48
+ }
49
+
50
+ stripped.push(arg)
51
+ }
52
+
53
+ return stripped
54
+ }
55
+
56
+ export function parseDevArgs(args: string[], localHostname: string): DevArgResolution {
57
+ const { clientPort, serverPort } = resolveDevPorts(args)
58
+ const serverArgs = stripPortArg(args).filter((arg) => arg !== "--share")
59
+ let share = false
60
+ let sawHost = false
61
+ let sawRemote = false
62
+ let backendTargetHost = "127.0.0.1"
63
+ let allowAllHosts = false
64
+ const hosts = new Set<string>(["localhost", "127.0.0.1", "0.0.0.0", localHostname])
65
+
66
+ for (let index = 0; index < args.length; index += 1) {
67
+ const arg = args[index]
68
+ if (arg === "--share") {
69
+ if (sawHost) throw new Error("--share cannot be used with --host")
70
+ if (sawRemote) throw new Error("--share cannot be used with --remote")
71
+ share = true
72
+ continue
73
+ }
74
+ if (arg === "--remote") {
75
+ if (share) throw new Error("--share cannot be used with --remote")
76
+ sawRemote = true
77
+ backendTargetHost = "127.0.0.1"
78
+ allowAllHosts = true
79
+ continue
80
+ }
81
+ if (arg !== "--host") continue
82
+
83
+ const next = args[index + 1]
84
+ if (!next || next.startsWith("-")) continue
85
+ if (share) throw new Error("--share cannot be used with --host")
86
+ sawHost = true
87
+ hosts.add(next)
88
+ backendTargetHost = next === "0.0.0.0" ? "127.0.0.1" : next
89
+ index += 1
90
+ }
91
+
92
+ return {
93
+ clientPort,
94
+ serverPort,
95
+ share,
96
+ backendTargetHost,
97
+ allowedHosts: share || allowAllHosts ? true : [...hosts],
98
+ serverArgs,
99
+ }
100
+ }
@@ -0,0 +1,45 @@
1
+ /** Extension manifest — shared metadata declaring identity and detection probes */
2
+ export interface ExtensionManifest {
3
+ id: string
4
+ name: string
5
+ icon: string
6
+ detect: string[]
7
+ }
8
+
9
+ /** A single route declared by a server extension */
10
+ export interface ExtensionRoute {
11
+ method: "GET" | "POST"
12
+ path: string
13
+ handler: (req: Request, params: Record<string, string>) => Promise<Response>
14
+ }
15
+
16
+ /** Server-side extension — declares routes scoped to a project path */
17
+ export interface ServerExtension extends ExtensionManifest {
18
+ routes(ctx: { projectPath: string }): ExtensionRoute[]
19
+ }
20
+
21
+ /** Props passed to every client extension component */
22
+ export interface ExtensionProps {
23
+ localPath: string
24
+ groupKey: string
25
+ }
26
+
27
+ /** Result of filesystem probe detection */
28
+ export interface DetectionResult {
29
+ extensionId: string
30
+ name: string
31
+ icon: string
32
+ detected: boolean
33
+ }
34
+
35
+ /** Persisted user preference for an extension (level 3 of the hierarchy) */
36
+ export interface ExtensionPreference {
37
+ extensionId: string
38
+ enabled: boolean
39
+ updatedAt: number
40
+ }
41
+
42
+ /** Snapshot published to subscribers of extension-preferences topic */
43
+ export interface ExtensionPreferencesSnapshot {
44
+ preferences: ExtensionPreference[]
45
+ }
@@ -0,0 +1,54 @@
1
+ import { type PresetDefinition, getPreset } from "./preset-types"
2
+
3
+ export type ForkPresetDefinition = PresetDefinition
4
+
5
+ export const FORK_PRESETS: readonly ForkPresetDefinition[] = [
6
+ {
7
+ id: "implementation_branch",
8
+ label: "Implementation branch",
9
+ description: "Continue toward a concrete feature or code change.",
10
+ defaultIntent: "Continue this work as an implementation branch. Carry forward the essential technical context, note the main constraints, and focus the new session on the next concrete coding steps.",
11
+ generatorHint: "Bias toward an execution-ready brief with concrete next implementation steps.",
12
+ },
13
+ {
14
+ id: "alternative_approach",
15
+ label: "Alternative approach",
16
+ description: "Explore a different design or implementation path.",
17
+ defaultIntent: "Fork this into an alternative approach. Preserve only the key constraints and decisions from the current chat, then frame the new session around a distinctly different implementation strategy.",
18
+ generatorHint: "Emphasize the constraints and assumptions that still apply, but optimize for exploring a different solution path.",
19
+ },
20
+ {
21
+ id: "bug_investigation",
22
+ label: "Bug investigation",
23
+ description: "Turn the current state into a focused debugging branch.",
24
+ defaultIntent: "Fork this into a bug investigation. Extract the symptoms, likely causes, relevant files, and the strongest reproduction or verification steps so the new session can debug efficiently.",
25
+ generatorHint: "Prioritize symptoms, repro steps, affected surfaces, and likely fault boundaries.",
26
+ },
27
+ {
28
+ id: "cleanup_refactor",
29
+ label: "Cleanup / refactor",
30
+ description: "Narrow the work to code quality and simplification.",
31
+ defaultIntent: "Fork this into a cleanup and refactor pass. Keep the important behavioral constraints, identify the code areas most worth simplifying, and focus the new session on safer structural improvement.",
32
+ generatorHint: "Prioritize invariants, areas of complexity, and low-risk refactor opportunities.",
33
+ },
34
+ {
35
+ id: "tests",
36
+ label: "Write tests",
37
+ description: "Build a testing-focused branch from the current work.",
38
+ defaultIntent: "Fork this into a test-writing pass. Capture the intended behavior, risky edges, missing verification, and the best targets for regression or integration tests.",
39
+ generatorHint: "Emphasize expected behavior, regressions to guard against, and concrete verification targets.",
40
+ },
41
+ {
42
+ id: "docs_spec",
43
+ label: "Docs / spec",
44
+ description: "Extract the current work into a clearer brief or spec.",
45
+ defaultIntent: "Fork this into a docs or spec-writing session. Distill the relevant decisions, architecture, constraints, and open questions into a cleaner written brief for follow-up work.",
46
+ generatorHint: "Bias toward structured explanation, decisions, constraints, and unresolved questions.",
47
+ },
48
+ ] as const
49
+
50
+ export const DEFAULT_FORK_PRESET_ID = FORK_PRESETS[0]!.id
51
+
52
+ export function getForkPreset(id?: string | null): ForkPresetDefinition | null {
53
+ return getPreset(FORK_PRESETS, id)
54
+ }
@@ -0,0 +1,15 @@
1
+ import { describe, test, expect } from "bun:test"
2
+
3
+ describe("shared harness-types", () => {
4
+ test("HarnessEvent type and HarnessTurn type are exportable from shared", async () => {
5
+ // Dynamic import to test module resolution
6
+ const mod = await import("./harness-types")
7
+ // Module should export these (even if type-only, the module must resolve)
8
+ expect(mod).toBeDefined()
9
+ })
10
+
11
+ test("server re-export still resolves", async () => {
12
+ const mod = await import("../server/harness-types")
13
+ expect(mod).toBeDefined()
14
+ })
15
+ })
@@ -0,0 +1,21 @@
1
+ import type { AccountInfo, AgentProvider, NormalizedToolCall, TranscriptEntry } from "./types"
2
+
3
+ export interface HarnessEvent {
4
+ type: "transcript" | "session_token" | "rate_limit"
5
+ entry?: TranscriptEntry
6
+ sessionToken?: string
7
+ rateLimit?: { resetAt: number; tz: string }
8
+ }
9
+
10
+ export interface HarnessToolRequest {
11
+ tool: NormalizedToolCall & { toolKind: "ask_user_question" | "exit_plan_mode" }
12
+ }
13
+
14
+ export interface HarnessTurn {
15
+ provider: AgentProvider
16
+ stream: AsyncIterable<HarnessEvent>
17
+ getAccountInfo?: () => Promise<AccountInfo | null>
18
+ getContextUsage?: () => Promise<{ percentage: number; totalTokens: number; maxTokens: number } | null>
19
+ interrupt: () => Promise<void>
20
+ close: () => void
21
+ }