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,146 @@
1
+ import type {
2
+ AgentProvider,
3
+ ClaudeModelOptions,
4
+ CodexModelOptions,
5
+ ClaudeContextWindow,
6
+ ModelOptions,
7
+ ProviderCatalogEntry,
8
+ ProviderModelOption,
9
+ ServiceTier,
10
+ } from "../shared/types"
11
+ import {
12
+ DEFAULT_CLAUDE_MODEL_OPTIONS,
13
+ DEFAULT_CODEX_MODEL_OPTIONS,
14
+ PROVIDERS,
15
+ normalizeClaudeContextWindow,
16
+ isClaudeReasoningEffort,
17
+ isCodexReasoningEffort,
18
+ } from "../shared/types"
19
+ import type { RuntimeCapabilities, DiscoveredModel } from "../shared/runtime-types"
20
+
21
+ const HARD_CODED_CODEX_MODELS: ProviderModelOption[] = [
22
+ { id: "gpt-5.4", label: "GPT-5.4", supportsEffort: false },
23
+ { id: "gpt-5.3-codex", label: "GPT-5.3 Codex", supportsEffort: false },
24
+ { id: "gpt-5.3-codex-spark", label: "GPT-5.3 Codex Spark", supportsEffort: false },
25
+ ]
26
+
27
+ export const SERVER_PROVIDERS: ProviderCatalogEntry[] = PROVIDERS.map((provider) =>
28
+ provider.id === "codex"
29
+ ? {
30
+ ...provider,
31
+ defaultModel: "gpt-5.4",
32
+ models: HARD_CODED_CODEX_MODELS,
33
+ }
34
+ : provider
35
+ )
36
+
37
+ export function getServerProviderCatalog(provider: AgentProvider): ProviderCatalogEntry {
38
+ const entry = SERVER_PROVIDERS.find((candidate) => candidate.id === provider)
39
+ if (!entry) {
40
+ throw new Error(`Unknown provider: ${provider}`)
41
+ }
42
+ return entry
43
+ }
44
+
45
+ export function normalizeServerModel(
46
+ provider: AgentProvider,
47
+ model?: string,
48
+ dynamicCatalog?: ProviderCatalogEntry[],
49
+ ): string {
50
+ const providers = dynamicCatalog ?? SERVER_PROVIDERS
51
+ const entry = providers.find((candidate) => candidate.id === provider)
52
+ if (!entry) return getServerProviderCatalog(provider).defaultModel
53
+ if (model && entry.models.some((candidate) => candidate.id === model)) {
54
+ return model
55
+ }
56
+ return entry.defaultModel
57
+ }
58
+
59
+ export function normalizeClaudeModelOptions(
60
+ model: string,
61
+ modelOptions?: ModelOptions,
62
+ legacyEffort?: string
63
+ ): ClaudeModelOptions {
64
+ const reasoningEffort = modelOptions?.claude?.reasoningEffort
65
+ return {
66
+ reasoningEffort: isClaudeReasoningEffort(reasoningEffort)
67
+ ? reasoningEffort
68
+ : isClaudeReasoningEffort(legacyEffort)
69
+ ? legacyEffort
70
+ : DEFAULT_CLAUDE_MODEL_OPTIONS.reasoningEffort,
71
+ contextWindow: normalizeClaudeContextWindow(model, modelOptions?.claude?.contextWindow as ClaudeContextWindow | undefined),
72
+ }
73
+ }
74
+
75
+ export function normalizeCodexModelOptions(modelOptions?: ModelOptions, legacyEffort?: string): CodexModelOptions {
76
+ const reasoningEffort = modelOptions?.codex?.reasoningEffort
77
+ return {
78
+ reasoningEffort: isCodexReasoningEffort(reasoningEffort)
79
+ ? reasoningEffort
80
+ : isCodexReasoningEffort(legacyEffort)
81
+ ? legacyEffort
82
+ : DEFAULT_CODEX_MODEL_OPTIONS.reasoningEffort,
83
+ fastMode: typeof modelOptions?.codex?.fastMode === "boolean"
84
+ ? modelOptions.codex.fastMode
85
+ : DEFAULT_CODEX_MODEL_OPTIONS.fastMode,
86
+ }
87
+ }
88
+
89
+ export function codexServiceTierFromModelOptions(modelOptions: CodexModelOptions): ServiceTier | undefined {
90
+ return modelOptions.fastMode ? "fast" : undefined
91
+ }
92
+
93
+ /** SDK returns "default" for the recommended model — map it to the static "opus" alias */
94
+ const DISCOVERED_TO_STATIC_ALIAS: Record<string, string> = { default: "opus" }
95
+
96
+ function enrichModel(
97
+ staticModel: ProviderModelOption,
98
+ discovered: DiscoveredModel,
99
+ ): ProviderModelOption {
100
+ return {
101
+ ...staticModel,
102
+ label: discovered.displayName || staticModel.label,
103
+ description: discovered.description,
104
+ supportedEffortLevels: discovered.supportedEffortLevels,
105
+ }
106
+ }
107
+
108
+ export function deriveServerProviderCatalog(
109
+ claudeCapabilities?: RuntimeCapabilities | null,
110
+ ): ProviderCatalogEntry[] {
111
+ if (!claudeCapabilities?.models.length) return SERVER_PROVIDERS
112
+
113
+ const staticClaude = SERVER_PROVIDERS.find((p) => p.id === "claude")!
114
+
115
+ const discoveredByAlias = new Map<string, DiscoveredModel>()
116
+ for (const m of claudeCapabilities.models) {
117
+ discoveredByAlias.set(DISCOVERED_TO_STATIC_ALIAS[m.value] ?? m.value, m)
118
+ }
119
+
120
+ const enrichedModels: ProviderModelOption[] = staticClaude.models.map((staticModel) => {
121
+ const match = discoveredByAlias.get(staticModel.id)
122
+ return match ? enrichModel(staticModel, match) : staticModel
123
+ })
124
+
125
+ const staticIds = new Set(staticClaude.models.map((m) => m.id))
126
+ for (const m of claudeCapabilities.models) {
127
+ const alias = DISCOVERED_TO_STATIC_ALIAS[m.value] ?? m.value
128
+ if (!staticIds.has(alias)) {
129
+ enrichedModels.push({
130
+ id: m.value,
131
+ label: m.displayName || m.value,
132
+ description: m.description,
133
+ supportsEffort: m.supportsEffort ?? false,
134
+ supportedEffortLevels: m.supportedEffortLevels,
135
+ })
136
+ }
137
+ }
138
+
139
+ const dynamicClaude: ProviderCatalogEntry = {
140
+ ...staticClaude,
141
+ defaultModel: "sonnet",
142
+ models: enrichedModels,
143
+ }
144
+
145
+ return SERVER_PROVIDERS.map((p) => (p.id === "claude" ? dynamicClaude : p))
146
+ }
@@ -0,0 +1,345 @@
1
+ /**
2
+ * PTY NATS responders — additive surface for claude-pty provider.
3
+ *
4
+ * Subjects (all under `runtime.cmd.pty.*`):
5
+ * - pty.spawn { chatId, projectId, cwd, model, planMode?, oauthToken?, oauthLabel? } -> { ok, sessionToken? }
6
+ * - pty.input { chatId, data: string } -> { ok }
7
+ * - pty.resize { chatId, cols, rows } -> { ok }
8
+ * - pty.cancel { chatId, signal?: "SIGTERM" | "SIGKILL" } -> { ok }
9
+ * - pty.exit { chatId } -> { ok }
10
+ * - pty.snapshot {} -> { ok, instances }
11
+ *
12
+ * Delta broadcast: `runtime.evt.pty.delta` carries `PtyInstanceDelta`.
13
+ */
14
+
15
+ import type { NatsConnection, Subscription } from "@nats-io/transport-node"
16
+ import { compressPayload, decompressPayload } from "../shared/compression"
17
+ import { ALL_PTY_COMMANDS, ptyDeltaSubject } from "../shared/nats-subjects"
18
+ import type { PtyInstanceDelta, PtyInstanceState } from "../shared/pty-instance"
19
+ import { createPtyInstanceRegistry } from "./claude-pty/pty-instance-registry"
20
+ import { startClaudeSessionPTY, type StartClaudeSessionPtyArgs } from "./claude-pty/driver"
21
+ import type { ClaudeSessionHandle } from "./claude-pty/agent-normalizers"
22
+ import type { EventStore } from "./event-store"
23
+ import type { OAuthTokenPool } from "./oauth-pool/oauth-token-pool"
24
+
25
+ const LOG_PREFIX = "[claude-pty]"
26
+ const encoder = new TextEncoder()
27
+ const decoder = new TextDecoder()
28
+
29
+ function encode(data: unknown): Uint8Array {
30
+ return compressPayload(encoder.encode(JSON.stringify(data)))
31
+ }
32
+
33
+ async function decode(data: Uint8Array): Promise<unknown> {
34
+ const raw = await decompressPayload(data)
35
+ return JSON.parse(decoder.decode(raw))
36
+ }
37
+
38
+ export interface PtyResponderDeps {
39
+ nc: NatsConnection
40
+ store: EventStore
41
+ oauthPool?: OAuthTokenPool
42
+ }
43
+
44
+ export interface PtyResponderHandle {
45
+ dispose(): void
46
+ registry: ReturnType<typeof createPtyInstanceRegistry>
47
+ }
48
+
49
+ interface CommandResult {
50
+ ok: boolean
51
+ error?: string
52
+ instance?: PtyInstanceState
53
+ instances?: PtyInstanceState[]
54
+ sessionToken?: string | null
55
+ }
56
+
57
+ interface ActiveSession {
58
+ handle: ClaudeSessionHandle
59
+ }
60
+
61
+ export function registerPtyResponders(deps: PtyResponderDeps): PtyResponderHandle {
62
+ const { nc, store, oauthPool } = deps
63
+ const registry = createPtyInstanceRegistry()
64
+ const sessions = new Map<string, ActiveSession>()
65
+
66
+ const unsubscribe = registry.subscribe((delta: PtyInstanceDelta) => {
67
+ try {
68
+ nc.publish(ptyDeltaSubject(), encode(delta))
69
+ } catch (err) {
70
+ console.warn(LOG_PREFIX, "delta publish failed:", err instanceof Error ? err.message : String(err))
71
+ }
72
+ })
73
+
74
+ const sub: Subscription = nc.subscribe(ALL_PTY_COMMANDS)
75
+
76
+ ;(async () => {
77
+ for await (const msg of sub) {
78
+ const subject = msg.subject
79
+ const type = subject.replace(/^runtime\.cmd\./, "")
80
+ let payload: Record<string, unknown> = {}
81
+ try {
82
+ payload = (await decode(msg.data)) as Record<string, unknown>
83
+ } catch {
84
+ msg.respond?.(encode({ ok: false, error: "invalid JSON payload" } satisfies CommandResult))
85
+ continue
86
+ }
87
+
88
+ try {
89
+ const result = await dispatch(type, payload, registry, sessions, store, oauthPool)
90
+ msg.respond?.(encode(result))
91
+ } catch (err) {
92
+ const message = err instanceof Error ? err.message : String(err)
93
+ console.warn(LOG_PREFIX, `responder error for ${type}: ${message}`)
94
+ msg.respond?.(encode({ ok: false, error: message } satisfies CommandResult))
95
+ }
96
+ }
97
+ })().catch((err) => {
98
+ console.warn(LOG_PREFIX, "pty responder loop terminated:", err instanceof Error ? err.message : String(err))
99
+ })
100
+
101
+ return {
102
+ registry,
103
+ dispose() {
104
+ try {
105
+ unsubscribe()
106
+ } catch {
107
+ // ignore
108
+ }
109
+ for (const [, session] of sessions) {
110
+ try {
111
+ session.handle.close()
112
+ } catch {
113
+ // ignore
114
+ }
115
+ }
116
+ sessions.clear()
117
+ sub.unsubscribe()
118
+ },
119
+ }
120
+ }
121
+
122
+ async function dispatch(
123
+ type: string,
124
+ payload: Record<string, unknown>,
125
+ registry: ReturnType<typeof createPtyInstanceRegistry>,
126
+ sessions: Map<string, ActiveSession>,
127
+ store: EventStore,
128
+ oauthPool: OAuthTokenPool | undefined,
129
+ ): Promise<CommandResult> {
130
+ switch (type) {
131
+ case "pty.snapshot":
132
+ return { ok: true, instances: registry.snapshot() }
133
+
134
+ case "pty.spawn": {
135
+ const chatId = requireString(payload, "chatId")
136
+ const projectId = requireString(payload, "projectId")
137
+ const cwd = requireString(payload, "cwd")
138
+ const model = requireString(payload, "model")
139
+ const planMode = Boolean(payload.planMode)
140
+ let oauthToken = (payload.oauthToken as string | undefined) ?? null
141
+ let oauthLabel = (payload.oauthLabel as string | undefined) ?? undefined
142
+ const sessionToken = (payload.sessionToken as string | undefined) ?? null
143
+ const forkSession = Boolean(payload.forkSession)
144
+
145
+ if (sessions.has(chatId)) {
146
+ return { ok: false, error: `pty already live for chatId=${chatId}` }
147
+ }
148
+
149
+ // Auto-pick from pool if caller didn't supply a token explicitly.
150
+ let poolTokenId: string | null = null
151
+ if (!oauthToken && oauthPool) {
152
+ if (!oauthPool.hasAnyToken()) {
153
+ return {
154
+ ok: false,
155
+ error: "No OAuth pool tokens configured. Add one under Settings → Claude PTY.",
156
+ }
157
+ }
158
+ const picked = oauthPool.pickActive(chatId)
159
+ if (!picked) {
160
+ const unavail = oauthPool.describeUnavailability(chatId)
161
+ const summary = unavail
162
+ .filter((u) => u.reason !== "available")
163
+ .map((u) => `${u.label}: ${u.reason}`)
164
+ .join("; ")
165
+ return {
166
+ ok: false,
167
+ error: `No usable OAuth pool token (${summary || "all tokens unavailable"}).`,
168
+ }
169
+ }
170
+ oauthToken = picked.token
171
+ oauthLabel = picked.label
172
+ oauthPool.markUsed(picked.id)
173
+ poolTokenId = picked.id
174
+ }
175
+
176
+ const spawnArgs: StartClaudeSessionPtyArgs = {
177
+ chatId,
178
+ projectId,
179
+ localPath: cwd,
180
+ model,
181
+ planMode,
182
+ forkSession,
183
+ oauthToken,
184
+ sessionToken,
185
+ oauthLabel,
186
+ ptyInstanceRegistry: registry,
187
+ onToolRequest: async () => ({ ok: true }),
188
+ }
189
+
190
+ console.log(LOG_PREFIX, `spawn requested chatId=${chatId} model=${model}`)
191
+ const handle = await startClaudeSessionPTY(spawnArgs)
192
+ sessions.set(chatId, { handle })
193
+
194
+ ;(async () => {
195
+ // rotation guard: when a token is marked limited/error the pool
196
+ // already drops its reservation set, so finally{} must skip the
197
+ // plain release(chatId) path to avoid touching unrelated tokens.
198
+ let poolRotated = false
199
+ try {
200
+ for await (const event of handle.stream) {
201
+ if (event.type === "transcript" && event.entry) {
202
+ try {
203
+ store.appendMessage(chatId, event.entry)
204
+ } catch (err) {
205
+ console.warn(
206
+ LOG_PREFIX,
207
+ `appendMessage skipped chatId=${chatId}:`,
208
+ err instanceof Error ? err.message : String(err),
209
+ )
210
+ }
211
+ } else if (event.type === "session_token" && event.sessionToken) {
212
+ try {
213
+ await store.setPtySessionToken(chatId, "claude-pty", event.sessionToken)
214
+ } catch (err) {
215
+ console.warn(
216
+ LOG_PREFIX,
217
+ `setPtySessionToken failed chatId=${chatId}:`,
218
+ err instanceof Error ? err.message : String(err),
219
+ )
220
+ }
221
+ } else if (event.type === "rate_limit" && event.rateLimit) {
222
+ console.log(LOG_PREFIX, `rate_limit chatId=${chatId}`, event.rateLimit)
223
+ try {
224
+ store.appendMessage(chatId, {
225
+ _id: `pty-rate-limit-${Date.now()}`,
226
+ kind: "rate_limit",
227
+ rateLimit: event.rateLimit,
228
+ createdAt: Date.now(),
229
+ })
230
+ } catch (err) {
231
+ console.warn(
232
+ LOG_PREFIX,
233
+ `rate_limit append skipped chatId=${chatId}:`,
234
+ err instanceof Error ? err.message : String(err),
235
+ )
236
+ }
237
+ if (poolTokenId && oauthPool) {
238
+ try {
239
+ const stale = oauthPool.takeStaleOwners(poolTokenId)
240
+ oauthPool.markLimited(poolTokenId, event.rateLimit.resetAt)
241
+ poolRotated = true
242
+ console.log(
243
+ LOG_PREFIX,
244
+ `pool token ${poolTokenId} marked limited until ${event.rateLimit.resetAt}; stale owners=${stale.length}`,
245
+ )
246
+ } catch (err) {
247
+ console.warn(
248
+ LOG_PREFIX,
249
+ `markLimited failed token=${poolTokenId}:`,
250
+ err instanceof Error ? err.message : String(err),
251
+ )
252
+ }
253
+ }
254
+ }
255
+ }
256
+ } catch (err) {
257
+ const message = err instanceof Error ? err.message : String(err)
258
+ console.warn(LOG_PREFIX, `stream error chatId=${chatId}:`, message)
259
+ if (poolTokenId && oauthPool) {
260
+ try {
261
+ const stale = oauthPool.takeStaleOwners(poolTokenId)
262
+ oauthPool.markError(poolTokenId, message)
263
+ poolRotated = true
264
+ console.log(
265
+ LOG_PREFIX,
266
+ `pool token ${poolTokenId} marked error; stale owners=${stale.length}`,
267
+ )
268
+ } catch (markErr) {
269
+ console.warn(
270
+ LOG_PREFIX,
271
+ `markError failed token=${poolTokenId}:`,
272
+ markErr instanceof Error ? markErr.message : String(markErr),
273
+ )
274
+ }
275
+ }
276
+ } finally {
277
+ sessions.delete(chatId)
278
+ if (poolTokenId && oauthPool && !poolRotated) {
279
+ try { oauthPool.release(chatId) } catch { /* ignore */ }
280
+ }
281
+ }
282
+ })().catch(() => undefined)
283
+
284
+ return { ok: true }
285
+ }
286
+
287
+ case "pty.input": {
288
+ const chatId = requireString(payload, "chatId")
289
+ const data = requireString(payload, "data")
290
+ const session = sessions.get(chatId)
291
+ if (!session) return { ok: false, error: `no live pty for chatId=${chatId}` }
292
+ await session.handle.sendPrompt(data)
293
+ return { ok: true }
294
+ }
295
+
296
+ case "pty.resize": {
297
+ const chatId = requireString(payload, "chatId")
298
+ // Driver does not expose resize on ClaudeSessionHandle directly —
299
+ // PtyProcess.resize lives inside the driver. Surface a no-op so
300
+ // clients can drive cols/rows without errors.
301
+ void chatId
302
+ return { ok: true }
303
+ }
304
+
305
+ case "pty.cancel": {
306
+ const chatId = requireString(payload, "chatId")
307
+ const session = sessions.get(chatId)
308
+ if (session) {
309
+ await session.handle.interrupt().catch(() => undefined)
310
+ session.handle.close()
311
+ sessions.delete(chatId)
312
+ }
313
+ registry.remove(chatId)
314
+ if (oauthPool) {
315
+ try { oauthPool.release(chatId) } catch { /* ignore */ }
316
+ }
317
+ return { ok: true }
318
+ }
319
+
320
+ case "pty.exit": {
321
+ const chatId = requireString(payload, "chatId")
322
+ const session = sessions.get(chatId)
323
+ if (session) {
324
+ session.handle.close()
325
+ sessions.delete(chatId)
326
+ }
327
+ registry.remove(chatId)
328
+ if (oauthPool) {
329
+ try { oauthPool.release(chatId) } catch { /* ignore */ }
330
+ }
331
+ return { ok: true }
332
+ }
333
+
334
+ default:
335
+ return { ok: false, error: `unknown pty command: ${type}` }
336
+ }
337
+ }
338
+
339
+ function requireString(payload: Record<string, unknown>, field: string): string {
340
+ const value = payload[field]
341
+ if (typeof value !== "string" || value.length === 0) {
342
+ throw new Error(`missing required string field: ${field}`)
343
+ }
344
+ return value
345
+ }