@rryando/arcs 3.9.2 → 3.11.0

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 (331) hide show
  1. package/README.md +172 -146
  2. package/dist/cli/agent-registry.d.ts +12 -0
  3. package/dist/cli/agent-registry.d.ts.map +1 -0
  4. package/dist/cli/agent-registry.js +67 -0
  5. package/dist/cli/agent-registry.js.map +1 -0
  6. package/dist/cli/arcs-flash.d.ts +2 -0
  7. package/dist/cli/arcs-flash.d.ts.map +1 -0
  8. package/dist/cli/arcs-flash.js +68 -0
  9. package/dist/cli/arcs-flash.js.map +1 -0
  10. package/dist/cli/arcs-orchestrate-caveman.d.ts +2 -14
  11. package/dist/cli/arcs-orchestrate-caveman.d.ts.map +1 -1
  12. package/dist/cli/arcs-orchestrate-caveman.js +6 -97
  13. package/dist/cli/arcs-orchestrate-caveman.js.map +1 -1
  14. package/dist/cli/arcs-orchestrate.d.ts +1 -1
  15. package/dist/cli/arcs-orchestrate.d.ts.map +1 -1
  16. package/dist/cli/arcs-orchestrate.js +40 -373
  17. package/dist/cli/arcs-orchestrate.js.map +1 -1
  18. package/dist/cli/bundle-installer.d.ts +10 -4
  19. package/dist/cli/bundle-installer.d.ts.map +1 -1
  20. package/dist/cli/bundle-installer.js +168 -15
  21. package/dist/cli/bundle-installer.js.map +1 -1
  22. package/dist/cli/commands/batch.js +4 -0
  23. package/dist/cli/commands/batch.js.map +1 -1
  24. package/dist/cli/commands/hooks.d.ts +36 -0
  25. package/dist/cli/commands/hooks.d.ts.map +1 -0
  26. package/dist/cli/commands/hooks.js +298 -0
  27. package/dist/cli/commands/hooks.js.map +1 -0
  28. package/dist/cli/commands/index.d.ts +2 -0
  29. package/dist/cli/commands/index.d.ts.map +1 -1
  30. package/dist/cli/commands/index.js +2 -0
  31. package/dist/cli/commands/index.js.map +1 -1
  32. package/dist/cli/commands/project.js +27 -0
  33. package/dist/cli/commands/project.js.map +1 -1
  34. package/dist/cli/commands/task.js +16 -1
  35. package/dist/cli/commands/task.js.map +1 -1
  36. package/dist/cli/commands/web.d.ts +2 -0
  37. package/dist/cli/commands/web.d.ts.map +1 -0
  38. package/dist/cli/commands/web.js +56 -0
  39. package/dist/cli/commands/web.js.map +1 -0
  40. package/dist/cli/config.d.ts +32 -0
  41. package/dist/cli/config.d.ts.map +1 -1
  42. package/dist/cli/config.js +56 -0
  43. package/dist/cli/config.js.map +1 -1
  44. package/dist/cli/instructions.d.ts +19 -6
  45. package/dist/cli/instructions.d.ts.map +1 -1
  46. package/dist/cli/instructions.js +62 -32
  47. package/dist/cli/instructions.js.map +1 -1
  48. package/dist/cli/orchestrator-shared-blocks.d.ts +31 -0
  49. package/dist/cli/orchestrator-shared-blocks.d.ts.map +1 -0
  50. package/dist/cli/orchestrator-shared-blocks.js +148 -0
  51. package/dist/cli/orchestrator-shared-blocks.js.map +1 -0
  52. package/dist/cli/setup.d.ts.map +1 -1
  53. package/dist/cli/setup.js +159 -85
  54. package/dist/cli/setup.js.map +1 -1
  55. package/dist/retrieval/index-builder.d.ts.map +1 -1
  56. package/dist/retrieval/index-builder.js +29 -1
  57. package/dist/retrieval/index-builder.js.map +1 -1
  58. package/dist/utils/claude-code-hook-install.d.ts +80 -0
  59. package/dist/utils/claude-code-hook-install.d.ts.map +1 -0
  60. package/dist/utils/claude-code-hook-install.js +146 -0
  61. package/dist/utils/claude-code-hook-install.js.map +1 -0
  62. package/dist/utils/claude-transcript.d.ts +127 -0
  63. package/dist/utils/claude-transcript.d.ts.map +1 -0
  64. package/dist/utils/claude-transcript.js +353 -0
  65. package/dist/utils/claude-transcript.js.map +1 -0
  66. package/dist/utils/diagram-generator.d.ts +1 -1
  67. package/dist/utils/diagram-generator.d.ts.map +1 -1
  68. package/dist/utils/diagram-generator.js +3 -2
  69. package/dist/utils/diagram-generator.js.map +1 -1
  70. package/dist/utils/errors.d.ts +6 -2
  71. package/dist/utils/errors.d.ts.map +1 -1
  72. package/dist/utils/errors.js +12 -0
  73. package/dist/utils/errors.js.map +1 -1
  74. package/dist/utils/hook-token-store.d.ts +22 -0
  75. package/dist/utils/hook-token-store.d.ts.map +1 -0
  76. package/dist/utils/hook-token-store.js +43 -0
  77. package/dist/utils/hook-token-store.js.map +1 -0
  78. package/dist/utils/json-schemas.d.ts +186 -2
  79. package/dist/utils/json-schemas.d.ts.map +1 -1
  80. package/dist/utils/json-schemas.js +48 -4
  81. package/dist/utils/json-schemas.js.map +1 -1
  82. package/dist/utils/knowledge-store.d.ts +7 -1
  83. package/dist/utils/knowledge-store.d.ts.map +1 -1
  84. package/dist/utils/knowledge-store.js +97 -65
  85. package/dist/utils/knowledge-store.js.map +1 -1
  86. package/dist/utils/plan-store.d.ts +8 -0
  87. package/dist/utils/plan-store.d.ts.map +1 -1
  88. package/dist/utils/plan-store.js +98 -59
  89. package/dist/utils/plan-store.js.map +1 -1
  90. package/dist/utils/project-resolver.d.ts +8 -0
  91. package/dist/utils/project-resolver.d.ts.map +1 -1
  92. package/dist/utils/project-resolver.js +7 -2
  93. package/dist/utils/project-resolver.js.map +1 -1
  94. package/dist/utils/session-store.d.ts +113 -0
  95. package/dist/utils/session-store.d.ts.map +1 -0
  96. package/dist/utils/session-store.js +312 -0
  97. package/dist/utils/session-store.js.map +1 -0
  98. package/dist/utils/storage-utils.d.ts +31 -0
  99. package/dist/utils/storage-utils.d.ts.map +1 -1
  100. package/dist/utils/storage-utils.js +116 -5
  101. package/dist/utils/storage-utils.js.map +1 -1
  102. package/dist/utils/task-store.d.ts +7 -0
  103. package/dist/utils/task-store.d.ts.map +1 -1
  104. package/dist/utils/task-store.js +73 -23
  105. package/dist/utils/task-store.js.map +1 -1
  106. package/dist/web-client/assets/GraphCanvas-dNyZ458L.js +1 -0
  107. package/dist/web-client/assets/MarkdownEditor-BmU9mdkN.js +77 -0
  108. package/dist/web-client/assets/abnfDiagram-VRR7QNED-D1BFBoeF.js +1 -0
  109. package/dist/web-client/assets/arc-Bfaogrm1.js +1 -0
  110. package/dist/web-client/assets/architecture-TIHT7OUA-CJqI5wNI.js +1 -0
  111. package/dist/web-client/assets/architectureDiagram-ZJ3FMSHR-CA8hTWUK.js +36 -0
  112. package/dist/web-client/assets/array-BifhSqXX.js +1 -0
  113. package/dist/web-client/assets/blockDiagram-677ZJIJ3-CQpb_KwX.js +132 -0
  114. package/dist/web-client/assets/c4Diagram-LMCZKHZV-BhpHX84V.js +10 -0
  115. package/dist/web-client/assets/channel-C8DlmyVe.js +1 -0
  116. package/dist/web-client/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
  117. package/dist/web-client/assets/chunk-32BRIVSS-BUusQQa_.js +1 -0
  118. package/dist/web-client/assets/chunk-52WLFC77-nNYwlftl.js +10 -0
  119. package/dist/web-client/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
  120. package/dist/web-client/assets/chunk-7BUUIJ7U-Bb538aSH.js +1 -0
  121. package/dist/web-client/assets/chunk-C7G6YPKG-D0a-yqnK.js +1 -0
  122. package/dist/web-client/assets/chunk-EX3LRPZG-IDuRMN-4.js +231 -0
  123. package/dist/web-client/assets/chunk-FWX5IMBZ-D_spTcqi.js +2 -0
  124. package/dist/web-client/assets/chunk-HOUHSVGY-C-bcxwZS.js +1 -0
  125. package/dist/web-client/assets/chunk-ICXQ74PX-CjmK2bAM.js +2 -0
  126. package/dist/web-client/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
  127. package/dist/web-client/assets/chunk-KEIR6QF5-DEvma7oi.js +161 -0
  128. package/dist/web-client/assets/chunk-MOJQB5TN-Bkc08KWY.js +88 -0
  129. package/dist/web-client/assets/chunk-OGEWGWER-BAAYYvG9.js +1 -0
  130. package/dist/web-client/assets/chunk-PUDLZKDR-WXbPY7NM.js +156 -0
  131. package/dist/web-client/assets/chunk-Q4XR5HBZ-DcbnjxQE.js +70 -0
  132. package/dist/web-client/assets/chunk-RYQCIY6F-np2RyIY1.js +1 -0
  133. package/dist/web-client/assets/chunk-V7JOEXUC-C6t75PAp.js +206 -0
  134. package/dist/web-client/assets/chunk-VAUOI2AC-DVrJ0Ic7.js +1 -0
  135. package/dist/web-client/assets/chunk-VR4S4FIN-MOOFvGS0.js +1 -0
  136. package/dist/web-client/assets/chunk-WYO6CB5R-sK7Y2NZD.js +125 -0
  137. package/dist/web-client/assets/chunk-XXDRQBXY-BvKO0v-W.js +1 -0
  138. package/dist/web-client/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
  139. package/dist/web-client/assets/chunk-ZGVPDNZ5-a13RQsku.js +62 -0
  140. package/dist/web-client/assets/chunk-ZIRB5QZD-BpeS1aZ7.js +32 -0
  141. package/dist/web-client/assets/classDiagram-OUVF2IWQ-p32N1P_G.js +1 -0
  142. package/dist/web-client/assets/classDiagram-v2-EOCWNBFH-p32N1P_G.js +1 -0
  143. package/dist/web-client/assets/cose-bilkent-JH36ORCC-BebHqzgp.js +1 -0
  144. package/dist/web-client/assets/cynefin-VYW2F7L2-D8xaH-wO.js +1 -0
  145. package/dist/web-client/assets/cynefinDiagram-TSTJHNR4-Bt__EqJW.js +62 -0
  146. package/dist/web-client/assets/cytoscape-fcose-peAzqedC.js +1 -0
  147. package/dist/web-client/assets/cytoscape.esm-C3UvhD5t.js +321 -0
  148. package/dist/web-client/assets/dagre-Buvkdvvj.js +1 -0
  149. package/dist/web-client/assets/dagre-VKFMJZFB-Bwgjwflz.js +4 -0
  150. package/dist/web-client/assets/defaultLocale-BFoDCU3G.js +1 -0
  151. package/dist/web-client/assets/diagram-FQU43EPY-CaPDVUq2.js +3 -0
  152. package/dist/web-client/assets/diagram-G47NLZAW-BQLB9YYA.js +24 -0
  153. package/dist/web-client/assets/diagram-NH7WQ7WH-BWo84w8Y.js +24 -0
  154. package/dist/web-client/assets/diagram-OA4YK3LP-bKn6Pz5s.js +30 -0
  155. package/dist/web-client/assets/diagram-WEI45ONY-BRqV5Oy6.js +41 -0
  156. package/dist/web-client/assets/dist-B_J_HbC0.js +1 -0
  157. package/dist/web-client/assets/ebnfDiagram-CCIWWBDH-DhUXL1-7.js +1 -0
  158. package/dist/web-client/assets/erDiagram-Q63AITRT-HXAQQ-_F.js +85 -0
  159. package/dist/web-client/assets/eventmodeling-45OFAUF4-Bj5P8mZJ.js +1 -0
  160. package/dist/web-client/assets/flowDiagram-23GEKE2U-37BztFri.js +1 -0
  161. package/dist/web-client/assets/ganttDiagram-NO4QXBWP-D-Ddf_Ii.js +292 -0
  162. package/dist/web-client/assets/gitGraph-TEB2WS4Q-BmHzs0uF.js +1 -0
  163. package/dist/web-client/assets/gitGraphDiagram-IHSO6WYX-YnQWrlh_.js +106 -0
  164. package/dist/web-client/assets/graphlib-DS17s2tU.js +1 -0
  165. package/dist/web-client/assets/index-3mNPVkix.css +2 -0
  166. package/dist/web-client/assets/index-DCWxuIeQ.js +58 -0
  167. package/dist/web-client/assets/info-DKCQHKI2-DCT_B7RN.js +1 -0
  168. package/dist/web-client/assets/infoDiagram-FWYZ7A6U-D-le1Zhq.js +2 -0
  169. package/dist/web-client/assets/init-C-OQMol4.js +1 -0
  170. package/dist/web-client/assets/ishikawaDiagram-FXEZZL3T-Jr1x2VJB.js +70 -0
  171. package/dist/web-client/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2 +0 -0
  172. package/dist/web-client/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2 +0 -0
  173. package/dist/web-client/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
  174. package/dist/web-client/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
  175. package/dist/web-client/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2 +0 -0
  176. package/dist/web-client/assets/journeyDiagram-5HDEW3XC-BF9ELxj-.js +139 -0
  177. package/dist/web-client/assets/kanban-definition-HUTT4EX6-C4fJqAxu.js +89 -0
  178. package/dist/web-client/assets/katex-DolUETbr.js +257 -0
  179. package/dist/web-client/assets/line-7N7ikFxa.js +1 -0
  180. package/dist/web-client/assets/linear-DeUiD2wj.js +1 -0
  181. package/dist/web-client/assets/map-BaFkSB1l.js +1 -0
  182. package/dist/web-client/assets/mermaid-parser.core-QbC1icPt.js +7 -0
  183. package/dist/web-client/assets/mermaid.core-C26d_UJm.js +11 -0
  184. package/dist/web-client/assets/mindmap-definition-LN4V7U3C-D6TV1JDf.js +96 -0
  185. package/dist/web-client/assets/ordinal-BDEzSJ7C.js +1 -0
  186. package/dist/web-client/assets/packet-7NZHBO7P-CR1vrGj3.js +1 -0
  187. package/dist/web-client/assets/path-COt_16Va.js +1 -0
  188. package/dist/web-client/assets/pegDiagram-2B236MQR-xOMBBtfV.js +1 -0
  189. package/dist/web-client/assets/pie-RZYD4A2V-BbWuhjwy.js +1 -0
  190. package/dist/web-client/assets/pieDiagram-ENE6RG2P-MsfnsqgW.js +39 -0
  191. package/dist/web-client/assets/quadrantDiagram-ABIIQ3AL-BoI7zKXF.js +7 -0
  192. package/dist/web-client/assets/radar-I7S5WNFK-CbYXKToJ.js +1 -0
  193. package/dist/web-client/assets/railroad-3IZDKUUU-6LxHDkLe.js +1 -0
  194. package/dist/web-client/assets/railroad-abnf-AHOZXSZD-2Dg9wu0J.js +1 -0
  195. package/dist/web-client/assets/railroad-ebnf-EBAXGLYW-C_E2ot0R.js +1 -0
  196. package/dist/web-client/assets/railroad-peg-LSFZ7HO6-Bs9UQR1b.js +1 -0
  197. package/dist/web-client/assets/railroadDiagram-RFXS5EU6-D6RUoUki.js +1 -0
  198. package/dist/web-client/assets/requirementDiagram-TGXJPOKE-B6k4BDpE.js +84 -0
  199. package/dist/web-client/assets/rolldown-runtime-Dd_uD5pT.js +1 -0
  200. package/dist/web-client/assets/rough.esm-By172zw-.js +1 -0
  201. package/dist/web-client/assets/sankeyDiagram-HTMAVEWB-BUDF-UFr.js +40 -0
  202. package/dist/web-client/assets/sequenceDiagram-DBY2YBRQ-D6GqcsUi.js +162 -0
  203. package/dist/web-client/assets/sizeCapture-X5ZJPWSS-B0uUizjq.js +1 -0
  204. package/dist/web-client/assets/src-oBChb5qS.js +1 -0
  205. package/dist/web-client/assets/stateDiagram-2N3HPSRC-WfJCQAK5.js +1 -0
  206. package/dist/web-client/assets/stateDiagram-v2-6OUMAXLB-BCMWGnsJ.js +1 -0
  207. package/dist/web-client/assets/swimlanes-5IMT3BWC-BtMo82mC.js +2 -0
  208. package/dist/web-client/assets/swimlanesDiagram-G3AALYLV-DmudmLcK.js +8 -0
  209. package/dist/web-client/assets/timeline-definition-FHXFAJF6-CoAmv2Sn.js +120 -0
  210. package/dist/web-client/assets/treeView-QDETBFTQ-BWsKzE1s.js +1 -0
  211. package/dist/web-client/assets/treemap-6X3UGDF4-i_qGtB3o.js +1 -0
  212. package/dist/web-client/assets/vennDiagram-L72KCM5P-DYkiLe-P.js +34 -0
  213. package/dist/web-client/assets/wardley-OPB4EBWU-Daaqr1Vp.js +1 -0
  214. package/dist/web-client/assets/wardleyDiagram-EHGQE667-Bofbsg3J.js +78 -0
  215. package/dist/web-client/assets/xychartDiagram-FW5EYKEG-KNF4VTfL.js +7 -0
  216. package/dist/web-client/index.html +15 -0
  217. package/dist/web-server/app.d.ts +13 -0
  218. package/dist/web-server/app.d.ts.map +1 -0
  219. package/dist/web-server/app.js +58 -0
  220. package/dist/web-server/app.js.map +1 -0
  221. package/dist/web-server/claude-runner.d.ts +86 -0
  222. package/dist/web-server/claude-runner.d.ts.map +1 -0
  223. package/dist/web-server/claude-runner.js +320 -0
  224. package/dist/web-server/claude-runner.js.map +1 -0
  225. package/dist/web-server/hook-auth.d.ts +12 -0
  226. package/dist/web-server/hook-auth.d.ts.map +1 -0
  227. package/dist/web-server/hook-auth.js +36 -0
  228. package/dist/web-server/hook-auth.js.map +1 -0
  229. package/dist/web-server/index.d.ts +23 -0
  230. package/dist/web-server/index.d.ts.map +1 -0
  231. package/dist/web-server/index.js +49 -0
  232. package/dist/web-server/index.js.map +1 -0
  233. package/dist/web-server/opencode-client.d.ts +123 -0
  234. package/dist/web-server/opencode-client.d.ts.map +1 -0
  235. package/dist/web-server/opencode-client.js +514 -0
  236. package/dist/web-server/opencode-client.js.map +1 -0
  237. package/dist/web-server/respond.d.ts +33 -0
  238. package/dist/web-server/respond.d.ts.map +1 -0
  239. package/dist/web-server/respond.js +79 -0
  240. package/dist/web-server/respond.js.map +1 -0
  241. package/dist/web-server/routes/collections.d.ts +11 -0
  242. package/dist/web-server/routes/collections.d.ts.map +1 -0
  243. package/dist/web-server/routes/collections.js +217 -0
  244. package/dist/web-server/routes/collections.js.map +1 -0
  245. package/dist/web-server/routes/discovery.d.ts +7 -0
  246. package/dist/web-server/routes/discovery.d.ts.map +1 -0
  247. package/dist/web-server/routes/discovery.js +159 -0
  248. package/dist/web-server/routes/discovery.js.map +1 -0
  249. package/dist/web-server/routes/events.d.ts +6 -0
  250. package/dist/web-server/routes/events.d.ts.map +1 -0
  251. package/dist/web-server/routes/events.js +25 -0
  252. package/dist/web-server/routes/events.js.map +1 -0
  253. package/dist/web-server/routes/hook-events.d.ts +19 -0
  254. package/dist/web-server/routes/hook-events.d.ts.map +1 -0
  255. package/dist/web-server/routes/hook-events.js +135 -0
  256. package/dist/web-server/routes/hook-events.js.map +1 -0
  257. package/dist/web-server/routes/projects.d.ts +7 -0
  258. package/dist/web-server/routes/projects.d.ts.map +1 -0
  259. package/dist/web-server/routes/projects.js +272 -0
  260. package/dist/web-server/routes/projects.js.map +1 -0
  261. package/dist/web-server/routes/sessions.d.ts +16 -0
  262. package/dist/web-server/routes/sessions.d.ts.map +1 -0
  263. package/dist/web-server/routes/sessions.js +442 -0
  264. package/dist/web-server/routes/sessions.js.map +1 -0
  265. package/dist/web-server/security.d.ts +7 -0
  266. package/dist/web-server/security.d.ts.map +1 -0
  267. package/dist/web-server/security.js +41 -0
  268. package/dist/web-server/security.js.map +1 -0
  269. package/dist/web-server/static.d.ts +10 -0
  270. package/dist/web-server/static.d.ts.map +1 -0
  271. package/dist/web-server/static.js +36 -0
  272. package/dist/web-server/static.js.map +1 -0
  273. package/dist/web-server/storage.d.ts +17 -0
  274. package/dist/web-server/storage.d.ts.map +1 -0
  275. package/dist/web-server/storage.js +42 -0
  276. package/dist/web-server/storage.js.map +1 -0
  277. package/dist/web-server/watcher.d.ts +37 -0
  278. package/dist/web-server/watcher.d.ts.map +1 -0
  279. package/dist/web-server/watcher.js +181 -0
  280. package/dist/web-server/watcher.js.map +1 -0
  281. package/opencode/arcs/bundle-runtime.json +5 -14
  282. package/opencode/arcs/manifest.json +213 -149
  283. package/opencode/arcs/prompts/arcs-docs.txt +53 -47
  284. package/opencode/arcs/prompts/arcs-flash.txt +190 -0
  285. package/opencode/arcs/prompts/arcs-orchestrate-caveman.txt +116 -412
  286. package/opencode/arcs/prompts/arcs-orchestrate.txt +114 -331
  287. package/opencode/arcs/prompts/code-reviewer.txt +37 -98
  288. package/opencode/arcs/prompts/devil-advocate.txt +44 -115
  289. package/opencode/arcs/prompts/graph-explorer.txt +31 -179
  290. package/opencode/arcs/prompts/software-engineer.txt +24 -6
  291. package/opencode/arcs/prompts/tech-architect.txt +28 -12
  292. package/opencode/arcs/skills/brainstorming/SKILL.md +65 -105
  293. package/opencode/arcs/skills/brainstorming/scripts/server.js +37 -10
  294. package/opencode/arcs/skills/brainstorming/scripts/start-server.sh +20 -3
  295. package/opencode/arcs/skills/brainstorming/scripts/stop-server.sh +25 -6
  296. package/opencode/arcs/skills/brainstorming/visual-companion.md +3 -10
  297. package/opencode/arcs/skills/deep-pr-review/SKILL.md +5 -5
  298. package/opencode/arcs/skills/deep-pr-review/review-template.md +1 -1
  299. package/opencode/arcs/skills/enriching-codegraph-proposals/SKILL.md +17 -18
  300. package/opencode/arcs/skills/executing-plans/SKILL.md +26 -234
  301. package/opencode/arcs/skills/implementation/SKILL.md +61 -0
  302. package/opencode/arcs/skills/init-project/SKILL.md +16 -15
  303. package/opencode/arcs/skills/install-claude-code-hook/SKILL.md +143 -0
  304. package/opencode/arcs/skills/systematic-debugging/SKILL.md +16 -15
  305. package/opencode/arcs/skills/test-driven-development/SKILL.md +1 -1
  306. package/opencode/arcs/skills/to-diagram/SKILL.md +10 -29
  307. package/opencode/arcs/skills/writing-knowledge/SKILL.md +7 -6
  308. package/opencode/arcs/skills/writing-plans/SKILL.md +80 -130
  309. package/opencode/arcs/skills/writing-plans/plan-document-reviewer-prompt.md +38 -30
  310. package/package.json +14 -6
  311. package/scripts/build-opencode-bundle.mjs +23 -11
  312. package/scripts/claude-code-session-hook.mjs +125 -0
  313. package/scripts/deploy-claudecode-bundle.mjs +185 -132
  314. package/scripts/deploy-opencode-bundle.mjs +207 -6
  315. package/scripts/lib/bundle-helpers.mjs +29 -3
  316. package/scripts/lint-bundle.mjs +123 -3
  317. package/skills/explore-dag.md +5 -3
  318. package/skills/init-project.md +27 -26
  319. package/skills/orchestrate.md +29 -13
  320. package/skills/update-docs.md +8 -13
  321. package/opencode/arcs/prompts/docs-researcher.txt +0 -79
  322. package/opencode/arcs/prompts/oncall-ops.txt +0 -85
  323. package/opencode/arcs/skills/brainstorming/spec-document-reviewer-prompt.md +0 -56
  324. package/opencode/arcs/skills/code-agent/SKILL.md +0 -63
  325. package/opencode/arcs/skills/executing-plans/code-quality-reviewer-prompt.md +0 -57
  326. package/opencode/arcs/skills/executing-plans/implementer-prompt.md +0 -152
  327. package/opencode/arcs/skills/executing-plans/spec-reviewer-prompt.md +0 -91
  328. package/opencode/arcs/skills/quick-dev/SKILL.md +0 -52
  329. package/opencode/arcs/skills/requesting-code-review/SKILL.md +0 -59
  330. package/opencode/arcs/skills/requesting-code-review/code-reviewer.md +0 -139
  331. package/opencode/arcs/skills/the-ladder/SKILL.md +0 -54
@@ -0,0 +1,320 @@
1
+ /**
2
+ * Headless `claude -p` run lifecycle (T001 of the session-panel async-runs plan).
3
+ *
4
+ * Owns everything between "the web route decided to run a job" and a finished
5
+ * run record: spawn, output capture with caps, timeout escalation, `--output-
6
+ * format json` parsing, exit mapping, per-write-target concurrency serialization
7
+ * and ARCS_HOOK_* env scrubbing. The module is argv-agnostic — the calling route
8
+ * supplies argv/cwd; this module never decides what the child does. The route's
9
+ * post-run write-back (transcript mirror + metadata.run finalization) plugs in
10
+ * as the per-job `onSettled` callback, invoked after the child fully exits.
11
+ *
12
+ * Injectable `spawnImpl` + `binary` keep tests free of real children; the
13
+ * default impl is plain node child_process `spawn` with `stdio:
14
+ * ["ignore","pipe","pipe"]`. Every child-side failure resolves to an outcome
15
+ * record — this module never throws on spawn/exit/timeout paths.
16
+ */
17
+ import { spawn } from "node:child_process";
18
+ const DEFAULT_TIMEOUT_MS = 10 * 60 * 1000; // 10 min
19
+ const DEFAULT_KILL_GRACE_MS = 5_000;
20
+ export const STDOUT_CAP = 1024 * 1024; // 1 MB
21
+ export const STDERR_CAP = 4 * 1024; // 4 KB
22
+ /** Keys never forwarded to the child env — the hook handshake must not leak. */
23
+ const ENV_SCRUB_KEYS = ["ARCS_HOOK_TOKEN", "ARCS_HOOK_SLUG", "ARCS_HOOK_URL"];
24
+ /** writeTargetKey → live child. Module-level: shared across all web routes. */
25
+ const liveRuns = new Map();
26
+ /**
27
+ * Atomically claims the slot for a write-target key. Returns a typed refusal
28
+ * when a live run already holds it. Synchronous and called immediately after
29
+ * spawn (no await in between), so two overlapping requests cannot both win.
30
+ */
31
+ export function beginRun(writeTargetKey, child) {
32
+ if (liveRuns.has(writeTargetKey)) {
33
+ return {
34
+ ok: false,
35
+ reason: "ALREADY_RUNNING",
36
+ message: `a claude run for "${writeTargetKey}" is already in progress`,
37
+ };
38
+ }
39
+ const startedAt = Date.now();
40
+ liveRuns.set(writeTargetKey, { child, startedAt });
41
+ return { ok: true, startedAt };
42
+ }
43
+ /** Releases the slot for a write-target key (idempotent). */
44
+ export function endRun(writeTargetKey) {
45
+ liveRuns.delete(writeTargetKey);
46
+ }
47
+ /** Read-only liveness probe for the same slot (routes / UI status). */
48
+ export function isRunLive(writeTargetKey) {
49
+ return liveRuns.has(writeTargetKey);
50
+ }
51
+ // ---------------------------------------------------------------------------
52
+ // runClaudeJob
53
+ // ---------------------------------------------------------------------------
54
+ export async function runClaudeJob(input, options = {}) {
55
+ const { argv, cwd, writeTargetKey } = input;
56
+ const spawnImpl = options.spawnImpl ?? spawn;
57
+ const binary = options.binary ?? "claude";
58
+ const killGraceMs = options.killGraceMs ?? DEFAULT_KILL_GRACE_MS;
59
+ const env = input.env ?? process.env;
60
+ const timeoutMs = resolveTimeoutMs(input.timeoutMs, env);
61
+ const startedAt = Date.now();
62
+ const fail = (outcome, error) => ({
63
+ pid: null,
64
+ startedAt,
65
+ endedAt: Date.now(),
66
+ outcome,
67
+ error,
68
+ });
69
+ let child;
70
+ try {
71
+ child = spawnImpl(binary, argv, { cwd, env: scrubEnv(env), stdio: ["ignore", "pipe", "pipe"] });
72
+ }
73
+ catch (err) {
74
+ // Some spawn failures surface synchronously (fake impls, odd platforms).
75
+ return writeBack(input, fail("error", spawnErrorMessage(err, binary)));
76
+ }
77
+ const begin = beginRun(writeTargetKey, child);
78
+ if (!begin.ok) {
79
+ // A live run holds the slot — drop the freshly spawned child immediately.
80
+ // Attach a no-op error listener first: the refused child has no other
81
+ // listeners, so a spawn failure surfacing on it would otherwise crash.
82
+ child.on("error", () => { });
83
+ safeKill(child, "SIGKILL");
84
+ return writeBack(input, fail("error", begin.message));
85
+ }
86
+ const record = { pid: child.pid ?? null, startedAt, outcome: "success" };
87
+ try {
88
+ const settled = await settleRun(child, { timeoutMs, killGraceMs, binary });
89
+ record.endedAt = settled.endedAt;
90
+ record.outcome = settled.outcome;
91
+ if (settled.error !== undefined)
92
+ record.error = settled.error;
93
+ if (settled.replyText !== undefined) {
94
+ record.replyText = settled.replyText;
95
+ record.replyChars = settled.replyText.length;
96
+ }
97
+ }
98
+ catch (err) {
99
+ // Never throw on child-side failures — every path resolves to a record.
100
+ record.outcome = "error";
101
+ record.error = `runner failed: ${String(err)}`;
102
+ }
103
+ finally {
104
+ endRun(writeTargetKey);
105
+ }
106
+ return writeBack(input, record);
107
+ }
108
+ /**
109
+ * Fires the route-registered write-back (onSettled) against the settled record.
110
+ * Runs after endRun so the concurrency slot frees before the write-back's store
111
+ * work begins. Every record-producing path funnels through here — including
112
+ * sync spawn failures and refused overlaps — so the route can mirror the
113
+ * runtime transcript and finalize metadata.run regardless of outcome. Callback
114
+ * errors are swallowed: the write-back is best-effort and never changes the
115
+ * returned record.
116
+ */
117
+ async function writeBack(input, record) {
118
+ if (input.onSettled === undefined)
119
+ return record;
120
+ try {
121
+ await input.onSettled(record);
122
+ }
123
+ catch {
124
+ // Write-back failure is a swallowed no-op — the run itself already settled.
125
+ }
126
+ return record;
127
+ }
128
+ function settleRun(child, ctx) {
129
+ return new Promise((resolve) => {
130
+ const stdout = makeTailBuffer(STDOUT_CAP);
131
+ const stderr = makeTailBuffer(STDERR_CAP);
132
+ let settled = false;
133
+ let timedOut = false;
134
+ let termTimer = null;
135
+ let killTimer = null;
136
+ const clearTimers = () => {
137
+ if (termTimer)
138
+ clearTimeout(termTimer);
139
+ if (killTimer)
140
+ clearTimeout(killTimer);
141
+ termTimer = null;
142
+ killTimer = null;
143
+ };
144
+ const settle = (result) => {
145
+ if (settled)
146
+ return;
147
+ settled = true;
148
+ clearTimers();
149
+ child.removeAllListeners();
150
+ child.stdout?.removeAllListeners();
151
+ child.stderr?.removeAllListeners();
152
+ resolve(result);
153
+ };
154
+ termTimer = setTimeout(() => {
155
+ timedOut = true;
156
+ safeKill(child, "SIGTERM");
157
+ killTimer = setTimeout(() => {
158
+ safeKill(child, "SIGKILL");
159
+ }, ctx.killGraceMs);
160
+ }, ctx.timeoutMs);
161
+ child.stdout?.on("data", (chunk) => stdout.push(String(chunk)));
162
+ child.stderr?.on("data", (chunk) => stderr.push(String(chunk)));
163
+ child.on("error", (err) => {
164
+ settle({
165
+ endedAt: Date.now(),
166
+ outcome: "error",
167
+ error: spawnErrorMessage(err, ctx.binary),
168
+ });
169
+ });
170
+ // Resolve on `close` (after stdio drained) rather than `exit` so the caps
171
+ // see the complete output. `close` also fires after a failed spawn.
172
+ child.on("close", (code, signal) => {
173
+ settle(mapExit({
174
+ code,
175
+ signal: signal ?? null,
176
+ timedOut,
177
+ stdout,
178
+ stderr,
179
+ timeoutMs: ctx.timeoutMs,
180
+ }));
181
+ });
182
+ });
183
+ }
184
+ function mapExit(input) {
185
+ const endedAt = Date.now();
186
+ if (input.timedOut) {
187
+ return {
188
+ endedAt,
189
+ outcome: "timeout",
190
+ error: `claude run timed out after ${input.timeoutMs}ms (SIGTERM, then SIGKILL)`,
191
+ };
192
+ }
193
+ if (input.code === 0) {
194
+ const parsed = parseClaudeJson(input.stdout.text());
195
+ if (parsed) {
196
+ if (parsed.is_error) {
197
+ return {
198
+ endedAt,
199
+ outcome: "error",
200
+ error: parsed.result?.trim() || "claude reported an error (is_error)",
201
+ };
202
+ }
203
+ // `result` is optional — fall back to the trimmed raw stdout when absent.
204
+ const replyText = typeof parsed.result === "string" ? parsed.result : input.stdout.text().trim();
205
+ return { endedAt, outcome: "success", replyText };
206
+ }
207
+ // Unparsable stdout on exit 0 — treat the trimmed raw stdout as the reply.
208
+ return { endedAt, outcome: "success", replyText: input.stdout.text().trim() };
209
+ }
210
+ if (input.signal) {
211
+ return {
212
+ endedAt,
213
+ outcome: "error",
214
+ error: `claude run was terminated by signal ${input.signal}`,
215
+ };
216
+ }
217
+ const stderrTail = input.stderr.text().trim();
218
+ return {
219
+ endedAt,
220
+ outcome: "error",
221
+ error: stderrTail || `claude exited with status ${input.code}`,
222
+ };
223
+ }
224
+ /**
225
+ * Parses `claude --output-format json` stdout. Returns null when the output is
226
+ * not a JSON object carrying the is_error/result envelope, so the caller can
227
+ * fall back to raw stdout. Never throws.
228
+ */
229
+ function parseClaudeJson(stdout) {
230
+ const text = stdout.trim();
231
+ if (!text)
232
+ return null;
233
+ let value;
234
+ try {
235
+ value = JSON.parse(text);
236
+ }
237
+ catch {
238
+ return null;
239
+ }
240
+ if (typeof value !== "object" || value === null)
241
+ return null;
242
+ const candidate = value;
243
+ if (typeof candidate.is_error !== "boolean" && typeof candidate.result !== "string") {
244
+ return null;
245
+ }
246
+ return candidate;
247
+ }
248
+ function resolveTimeoutMs(timeoutMs, env) {
249
+ if (typeof timeoutMs === "number" && Number.isFinite(timeoutMs) && timeoutMs > 0) {
250
+ return timeoutMs;
251
+ }
252
+ const raw = env.ARCS_CLAUDE_RUN_TIMEOUT_MS;
253
+ if (raw) {
254
+ const parsed = Number.parseInt(raw, 10);
255
+ if (Number.isInteger(parsed) && parsed > 0)
256
+ return parsed;
257
+ }
258
+ return DEFAULT_TIMEOUT_MS;
259
+ }
260
+ /** process.env minus the ARCS_HOOK_* handshake keys (the explicit 3-key
261
+ * denylist above — not a prefix wildcard scrub). */
262
+ function scrubEnv(env) {
263
+ const childEnv = {};
264
+ for (const [key, value] of Object.entries(env)) {
265
+ if (value === undefined)
266
+ continue;
267
+ if (ENV_SCRUB_KEYS.includes(key))
268
+ continue;
269
+ childEnv[key] = value;
270
+ }
271
+ return childEnv;
272
+ }
273
+ function spawnErrorMessage(err, binary) {
274
+ const code = err?.code;
275
+ if (code === "ENOENT")
276
+ return "claude not found on PATH";
277
+ return `failed to spawn ${binary}: ${String(err)}`;
278
+ }
279
+ function safeKill(child, signal) {
280
+ try {
281
+ child.kill(signal);
282
+ }
283
+ catch {
284
+ // Child already exited — nothing to signal.
285
+ }
286
+ }
287
+ /**
288
+ * Accumulates output keeping only the most recent `limit` characters, dropping
289
+ * overflow from the head. Used so a runaway child cannot balloon memory while
290
+ * the important (tail) output survives.
291
+ *
292
+ * SHORTCUT: caps count UTF-16 code units, not bytes; upgrade to
293
+ * Buffer.byteLength accounting when non-ASCII payloads sit at the cap boundary.
294
+ */
295
+ function makeTailBuffer(limit) {
296
+ const chunks = [];
297
+ let size = 0;
298
+ return {
299
+ push(chunk) {
300
+ if (chunk.length === 0)
301
+ return;
302
+ chunks.push(chunk);
303
+ size += chunk.length;
304
+ while (size > limit && chunks.length > 1) {
305
+ size -= chunks[0].length;
306
+ chunks.shift();
307
+ }
308
+ if (size > limit) {
309
+ // Single chunk larger than the cap — keep its tail.
310
+ const overflow = size - limit;
311
+ chunks[0] = chunks[0].slice(overflow);
312
+ size -= overflow;
313
+ }
314
+ },
315
+ text() {
316
+ return chunks.join("");
317
+ },
318
+ };
319
+ }
320
+ //# sourceMappingURL=claude-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-runner.js","sourceRoot":"","sources":["../../src/web-server/claude-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Bearer-token gate for `/api/hook/*`.
3
+ *
4
+ * Layered on top of (never instead of) the global loopback-only
5
+ * `secureLocalRequest`: loopback proves the caller is on this machine, the
6
+ * token proves it is this project's installed hook script. Browser-facing
7
+ * routes stay token-free — only the hook endpoint carries a shared secret,
8
+ * because only it is called by something that is not the ARCS web UI.
9
+ */
10
+ import type { MiddlewareHandler } from "hono";
11
+ export declare const requireHookToken: MiddlewareHandler;
12
+ //# sourceMappingURL=hook-auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook-auth.d.ts","sourceRoot":"","sources":["../../src/web-server/hook-auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAY9C,eAAO,MAAM,gBAAgB,EAAE,iBAmB9B,CAAC"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Bearer-token gate for `/api/hook/*`.
3
+ *
4
+ * Layered on top of (never instead of) the global loopback-only
5
+ * `secureLocalRequest`: loopback proves the caller is on this machine, the
6
+ * token proves it is this project's installed hook script. Browser-facing
7
+ * routes stay token-free — only the hook endpoint carries a shared secret,
8
+ * because only it is called by something that is not the ARCS web UI.
9
+ */
10
+ import { verifyHookToken } from "../utils/hook-token-store.js";
11
+ import { fail, requireProjectDir } from "./respond.js";
12
+ const BEARER = /^Bearer\s+(\S+)$/i;
13
+ /** `/api/hook/:slug/...` → the slug segment, or "" when the shape is wrong. */
14
+ function slugFromPath(url) {
15
+ const segments = new URL(url).pathname.split("/");
16
+ return segments[1] === "api" && segments[2] === "hook" ? (segments[3] ?? "") : "";
17
+ }
18
+ export const requireHookToken = async (c, next) => {
19
+ const unauthorized = () => c.json(fail("hook_unauthorized", "Missing or invalid ARCS hook token"), 401);
20
+ const match = BEARER.exec((c.req.header("authorization") ?? "").trim());
21
+ if (!match)
22
+ return unauthorized();
23
+ let projectDir;
24
+ try {
25
+ projectDir = requireProjectDir(slugFromPath(c.req.url));
26
+ }
27
+ catch {
28
+ // Deliberately 401, not 404: an unauthenticated caller must not be able to
29
+ // probe which project slugs exist on this machine.
30
+ return unauthorized();
31
+ }
32
+ if (!(await verifyHookToken(projectDir, match[1])))
33
+ return unauthorized();
34
+ await next();
35
+ };
36
+ //# sourceMappingURL=hook-auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook-auth.js","sourceRoot":"","sources":["../../src/web-server/hook-auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEvD,MAAM,MAAM,GAAG,mBAAmB,CAAC;AAEnC,+EAA+E;AAC/E,SAAS,YAAY,CAAC,GAAW;IAC/B,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAClD,OAAO,QAAQ,CAAC,CAAC,CAAC,KAAK,KAAK,IAAI,QAAQ,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACpF,CAAC;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAsB,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;IACnE,MAAM,YAAY,GAAG,GAAG,EAAE,CACxB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,oCAAoC,CAAC,EAAE,GAAG,CAAC,CAAC;IAE/E,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACxE,IAAI,CAAC,KAAK;QAAE,OAAO,YAAY,EAAE,CAAC;IAElC,IAAI,UAAkB,CAAC;IACvB,IAAI,CAAC;QACH,UAAU,GAAG,iBAAiB,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1D,CAAC;IAAC,MAAM,CAAC;QACP,2EAA2E;QAC3E,mDAAmD;QACnD,OAAO,YAAY,EAAE,CAAC;IACxB,CAAC;IAED,IAAI,CAAC,CAAC,MAAM,eAAe,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAAE,OAAO,YAAY,EAAE,CAAC;IAE1E,MAAM,IAAI,EAAE,CAAC;AACf,CAAC,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Web server entry — starts the HTTP server for the ARCS web UI.
3
+ */
4
+ export interface StartWebServerOptions {
5
+ /** Port to listen on (default 4173). Pass 0 for an ephemeral port. */
6
+ port?: number;
7
+ /** Interface to bind (default 127.0.0.1). */
8
+ host?: string;
9
+ /** Auto-open the browser (default false here; the CLI command defaults true). */
10
+ open?: boolean;
11
+ /** Override the static client root. */
12
+ staticRoot?: string;
13
+ /** Disable the data-dir watcher (tests). */
14
+ watch?: boolean;
15
+ }
16
+ export interface WebServerHandle {
17
+ url: string;
18
+ port: number;
19
+ host: string;
20
+ close: () => Promise<void>;
21
+ }
22
+ export declare function startWebServer(options?: StartWebServerOptions): Promise<WebServerHandle>;
23
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/web-server/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,MAAM,WAAW,qBAAqB;IACpC,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iFAAiF;IACjF,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,uCAAuC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B;AAeD,wBAAsB,cAAc,CAClC,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,eAAe,CAAC,CA8B1B"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Web server entry — starts the HTTP server for the ARCS web UI.
3
+ */
4
+ import { spawn } from "node:child_process";
5
+ import { serve } from "@hono/node-server";
6
+ import { createApp } from "./app.js";
7
+ import { isLoopbackHost } from "./security.js";
8
+ function openBrowser(url) {
9
+ try {
10
+ const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "cmd" : "xdg-open";
11
+ const args = process.platform === "win32" ? ["/c", "start", "", url] : [url];
12
+ const child = spawn(cmd, args, { detached: true, stdio: "ignore" });
13
+ child.on("error", () => { });
14
+ child.unref();
15
+ }
16
+ catch {
17
+ // No browser available — the URL is printed either way.
18
+ }
19
+ }
20
+ export async function startWebServer(options = {}) {
21
+ const host = options.host ?? "127.0.0.1";
22
+ const requestedPort = options.port ?? 4173;
23
+ if (!isLoopbackHost(host)) {
24
+ throw new Error(`ARCS web only binds to loopback addresses; refusing non-loopback host "${host}".`);
25
+ }
26
+ const app = createApp({ staticRoot: options.staticRoot, watch: options.watch });
27
+ return new Promise((resolvePromise, rejectPromise) => {
28
+ try {
29
+ const server = serve({ fetch: app.fetch, port: requestedPort, hostname: host }, (info) => {
30
+ const url = `http://${host}:${info.port}`;
31
+ if (options.open)
32
+ openBrowser(url);
33
+ resolvePromise({
34
+ url,
35
+ port: info.port,
36
+ host,
37
+ close: () => new Promise((res) => {
38
+ server.close(() => res());
39
+ }),
40
+ });
41
+ });
42
+ server.on("error", rejectPromise);
43
+ }
44
+ catch (err) {
45
+ rejectPromise(err);
46
+ }
47
+ });
48
+ }
49
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/web-server/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAsB/C,SAAS,WAAW,CAAC,GAAW;IAC9B,IAAI,CAAC;QACH,MAAM,GAAG,GACP,OAAO,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC;QAC7F,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAC7E,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QACpE,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAC5B,KAAK,CAAC,KAAK,EAAE,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACP,wDAAwD;IAC1D,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,UAAiC,EAAE;IAEnC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,WAAW,CAAC;IACzC,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC;IAC3C,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CACb,0EAA0E,IAAI,IAAI,CACnF,CAAC;IACJ,CAAC;IACD,MAAM,GAAG,GAAG,SAAS,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IAEhF,OAAO,IAAI,OAAO,CAAC,CAAC,cAAc,EAAE,aAAa,EAAE,EAAE;QACnD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,KAAK,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE;gBACvF,MAAM,GAAG,GAAG,UAAU,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBAC1C,IAAI,OAAO,CAAC,IAAI;oBAAE,WAAW,CAAC,GAAG,CAAC,CAAC;gBACnC,cAAc,CAAC;oBACb,GAAG;oBACH,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,IAAI;oBACJ,KAAK,EAAE,GAAG,EAAE,CACV,IAAI,OAAO,CAAO,CAAC,GAAG,EAAE,EAAE;wBACxB,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;oBAC5B,CAAC,CAAC;iBACL,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;QACpC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,aAAa,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,123 @@
1
+ /**
2
+ * opencode session discovery bridge (Phase 1 — observability only).
3
+ *
4
+ * ARCS never spawns or manages an opencode server; it attaches to an already
5
+ * running `opencode serve` instance as a thin client, subscribes to the
6
+ * cross-instance `/global/event` SSE stream, and mirrors what it sees into the
7
+ * per-project session store. Everything here is best-effort: if opencode is
8
+ * not configured, not running, or speaks a different dialect, the ARCS web
9
+ * server keeps working and the sessions list is simply empty or stale.
10
+ *
11
+ * Verified against opencode 0.0.0-main-202607110203:
12
+ * - `opencode serve` defaults to port 0 (ephemeral), so a port/URL must be
13
+ * supplied explicitly via env — there is no safe default to guess.
14
+ * - `OPENCODE_SERVER_PASSWORD` is enforced as HTTP Basic auth with the literal
15
+ * username "opencode"; any other username is rejected with 401.
16
+ * - `/event` is scoped to one instance (`?directory=`); `/global/event` is the
17
+ * cross-directory stream and wraps each event as `{ directory, project,
18
+ * payload }`. Frames carry no `event:` field, only `data:`.
19
+ */
20
+ import { type SessionStatus } from "../utils/session-store.js";
21
+ export interface OpencodeConfig {
22
+ baseUrl: string;
23
+ password?: string;
24
+ }
25
+ /**
26
+ * Reads bridge configuration from the environment. Returns null (discovery
27
+ * disabled) when no opencode endpoint is configured.
28
+ */
29
+ export declare function readOpencodeConfig(env?: NodeJS.ProcessEnv): OpencodeConfig | null;
30
+ export interface OpencodeMessageTarget {
31
+ /** opencode-native session id ("ses_…") — never the ARCS normalized id. */
32
+ runtimeSessionId: string;
33
+ /** Worktree the session belongs to, when known — scopes opencode's lookup. */
34
+ directory?: string;
35
+ }
36
+ /**
37
+ * Injects a user message into a live opencode session.
38
+ *
39
+ * Unlike the rest of this module (best-effort observability) this is a user
40
+ * mutation, so failures throw a typed DagError the web routes can surface.
41
+ *
42
+ * Verified against opencode 1.0.0 (`GET /doc`) plus a live server:
43
+ * - `POST /session/:sessionID/prompt_async` acks with 204 and runs the turn in
44
+ * the background. `POST /session/:sessionID/message` takes the same body but
45
+ * only responds once the assistant has finished its whole turn — minutes, for
46
+ * a browser request — so async delivery is the one that fits a web form.
47
+ * - the body requires `parts`; a text part is `{ type: "text", text }`.
48
+ * - `?directory=` is optional (an unscoped send still lands) but is passed when
49
+ * known so the lookup is unambiguous across worktrees.
50
+ */
51
+ export declare function sendOpencodeMessage(config: OpencodeConfig, target: OpencodeMessageTarget, text: string): Promise<void>;
52
+ export interface CreateOpencodeSessionInput {
53
+ /** Worktree the session runs in — required, see the directory note below. */
54
+ directory: string;
55
+ title?: string;
56
+ }
57
+ /** Only what ARCS needs to mirror the session; the SSE stream fills in the rest. */
58
+ export interface CreatedOpencodeSession {
59
+ runtimeSessionId: string;
60
+ title?: string;
61
+ }
62
+ /**
63
+ * Creates a live opencode session bound to a worktree.
64
+ *
65
+ * Verified against opencode 0.0.0-main-202607110203 (`GET /doc`, operationId
66
+ * `session.create`) plus a live server:
67
+ * - the route is `POST /session` — NOT `/api/session`. opencode serves its own
68
+ * web UI from the same port and answers every unknown path with a 200
69
+ * text/html SPA shell, so a wrong path looks like a success until the body is
70
+ * read. That is why the id is checked below rather than trusting `res.ok`.
71
+ * - `directory` is a *query* parameter and never a body field. Omitting it does
72
+ * not fail; opencode silently creates the session in its own working
73
+ * directory, so the caller must always pass the worktree explicitly.
74
+ * - `title` is the only body field ARCS sets; the response is a full session
75
+ * object (`{ id, slug, directory, title, time }`).
76
+ * - `DELETE /session/:sessionID` exists, so nothing created here is permanent.
77
+ */
78
+ export declare function createOpencodeSession(config: OpencodeConfig, input: CreateOpencodeSessionInput): Promise<CreatedOpencodeSession>;
79
+ interface OpencodeSessionInfo {
80
+ id?: string;
81
+ slug?: string;
82
+ title?: string;
83
+ directory?: string;
84
+ projectID?: string;
85
+ time?: {
86
+ created?: number;
87
+ updated?: number;
88
+ };
89
+ project?: {
90
+ worktree?: string;
91
+ };
92
+ }
93
+ interface OpencodeEvent {
94
+ type?: string;
95
+ properties?: {
96
+ sessionID?: string;
97
+ info?: OpencodeSessionInfo;
98
+ status?: {
99
+ type?: string;
100
+ };
101
+ };
102
+ }
103
+ /**
104
+ * Maps an opencode event type to the ARCS session status it implies.
105
+ * Returns null for events that carry no status transition (the record is
106
+ * refreshed but its status is left alone).
107
+ */
108
+ export declare function statusForOpencodeEvent(event: OpencodeEvent): SessionStatus | null;
109
+ export interface OpencodeDiscoveryState {
110
+ enabled: boolean;
111
+ connected: boolean;
112
+ baseUrl: string | null;
113
+ }
114
+ export declare function opencodeDiscoveryState(): OpencodeDiscoveryState;
115
+ /**
116
+ * Starts the discovery loop if an opencode endpoint is configured. Idempotent;
117
+ * returns false when discovery is disabled (no configuration present).
118
+ */
119
+ export declare function startOpencodeDiscovery(config?: OpencodeConfig | null): boolean;
120
+ /** Stops the discovery loop (test cleanup / server shutdown). */
121
+ export declare function stopOpencodeDiscovery(): Promise<void>;
122
+ export {};
123
+ //# sourceMappingURL=opencode-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opencode-client.d.ts","sourceRoot":"","sources":["../../src/web-server/opencode-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAOH,OAAO,EAEL,KAAK,aAAa,EAGnB,MAAM,2BAA2B,CAAC;AAanC,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,cAAc,GAAG,IAAI,CAc9F;AAYD,MAAM,WAAW,qBAAqB;IACpC,2EAA2E;IAC3E,gBAAgB,EAAE,MAAM,CAAC;IACzB,8EAA8E;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,qBAAqB,EAC7B,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAiCf;AAMD,MAAM,WAAW,0BAA0B;IACzC,6EAA6E;IAC7E,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,oFAAoF;AACpF,MAAM,WAAW,sBAAsB;IACrC,gBAAgB,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,cAAc,EACtB,KAAK,EAAE,0BAA0B,GAChC,OAAO,CAAC,sBAAsB,CAAC,CAyCjC;AAeD,UAAU,mBAAmB;IAC3B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9C,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACjC;AAED,UAAU,aAAa;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE;QACX,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,IAAI,CAAC,EAAE,mBAAmB,CAAC;QAC3B,MAAM,CAAC,EAAE;YAAE,IAAI,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;KAC5B,CAAC;CACH;AAQD;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,aAAa,GAAG,aAAa,GAAG,IAAI,CAuBjF;AA2DD,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,wBAAgB,sBAAsB,IAAI,sBAAsB,CAE/D;AAoQD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,wBAAuB,GAAG,OAAO,CAW7E;AAED,iEAAiE;AACjE,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAa3D"}