@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,442 @@
1
+ /**
2
+ * Session routes — full CRUD over the per-project session index.
3
+ *
4
+ * Sessions are runtime records for agent sessions (opencode, claude-code)
5
+ * attached to a project. All mutations go through the locked session-store,
6
+ * so the opencode discovery bridge and the web UI cannot clobber each other.
7
+ *
8
+ * `POST /sessions/:id/message` is the one route that reaches outside the store:
9
+ * it proxies a prompt into the live runtime (opencode) or queues it for the
10
+ * session to collect itself (claude-code). Every route here is browser-facing
11
+ * and therefore already behind the global loopback-only `secureLocalRequest`
12
+ * middleware — no per-route auth.
13
+ */
14
+ import { randomUUID } from "node:crypto";
15
+ import { stat, unlink } from "node:fs/promises";
16
+ import { resolve } from "node:path";
17
+ import { Hono } from "hono";
18
+ import { z } from "zod";
19
+ import { appendReferenceTurn, appendSessionTurn, mirrorSessionTranscript, readSessionTurns, sessionTranscriptPath, } from "../../utils/claude-transcript.js";
20
+ import { DagError } from "../../utils/errors.js";
21
+ import { readJsonSafe } from "../../utils/json.js";
22
+ import { createSession, deleteSession, enqueueSessionMessage, getSession, listSessions, SESSION_LINKED_NODE_TYPES, SESSION_RUNTIME_TYPES, SESSION_STATUSES, updateSession, upsertSession, } from "../../utils/session-store.js";
23
+ import { isRunLive, runClaudeJob } from "../claude-runner.js";
24
+ import { createOpencodeSession, readOpencodeConfig, sendOpencodeMessage, } from "../opencode-client.js";
25
+ import { parseBody, requireProjectDir, respond } from "../respond.js";
26
+ export const sessionsRoute = new Hono();
27
+ const createSessionSchema = z.object({
28
+ runtimeType: z.enum(SESSION_RUNTIME_TYPES),
29
+ runtimeSessionId: z.string().min(1),
30
+ status: z.enum(SESSION_STATUSES).optional(),
31
+ startedAt: z.string().optional(),
32
+ lastMessageAt: z.string().optional(),
33
+ userEmail: z.string().optional(),
34
+ metadata: z.record(z.unknown()).optional(),
35
+ });
36
+ const updateSessionSchema = z.object({
37
+ status: z.enum(SESSION_STATUSES).optional(),
38
+ lastMessageAt: z.string().nullable().optional(),
39
+ userEmail: z.string().nullable().optional(),
40
+ metadata: z.record(z.unknown()).nullable().optional(),
41
+ /** `null` on either linkage field unlinks the session entirely. */
42
+ linkedNodeType: z.enum(SESSION_LINKED_NODE_TYPES).nullable().optional(),
43
+ linkedNodeId: z.string().nullable().optional(),
44
+ });
45
+ /** A document section the caller is pointing the session at. When present, the
46
+ * delivery call is followed by an ARCS-authored reference turn in the session's
47
+ * transcript sidecar (see appendReferenceTurn). Shared by POST /message and
48
+ * POST /run so both routes accept byte-identical reference payloads. */
49
+ const sessionReferenceSchema = z.object({
50
+ section: z.object({
51
+ depth: z.number(),
52
+ text: z.string(),
53
+ id: z.string(),
54
+ startOffset: z.number(),
55
+ endOffset: z.number(),
56
+ }),
57
+ text: z.string(),
58
+ source: z.object({
59
+ kind: z.enum(["overview", "knowledge", "plan"]),
60
+ label: z.string(),
61
+ doc: z.string().optional(),
62
+ id: z.string().optional(),
63
+ }),
64
+ });
65
+ const sendMessageSchema = z.object({
66
+ message: z.string().min(1),
67
+ reference: sessionReferenceSchema.optional(),
68
+ });
69
+ /** Payload for POST /sessions/:id/run — a headless `claude -p` targeting mode.
70
+ * `threadId` is the stable-mode thread to reuse; when absent (and the
71
+ * referenced session is not itself an ARCS-owned thread) one is minted. */
72
+ const runClaudeMessageSchema = z.object({
73
+ mode: z.enum(["resume", "oneshot", "stable"]),
74
+ message: z.string().min(1),
75
+ threadId: z.string().optional(),
76
+ reference: sessionReferenceSchema.optional(),
77
+ });
78
+ const createOpencodeSessionSchema = z.object({
79
+ title: z.string().min(1).optional(),
80
+ });
81
+ function sessionDirectory(session) {
82
+ const directory = session.metadata?.directory;
83
+ return typeof directory === "string" && directory ? directory : undefined;
84
+ }
85
+ function requireOpencodeConfig() {
86
+ const config = readOpencodeConfig();
87
+ if (!config) {
88
+ throw new DagError("OPENCODE_NOT_CONFIGURED", "No opencode endpoint configured — set OPENCODE_PORT (or ARCS_OPENCODE_URL) " +
89
+ "so ARCS can reach a running `opencode serve`.");
90
+ }
91
+ return config;
92
+ }
93
+ /**
94
+ * The worktree a newly created session should run in.
95
+ *
96
+ * Guessing is not an option: opencode happily creates a session in its own
97
+ * working directory when no directory is supplied, which would silently point
98
+ * the agent at the wrong repository. An unregistered project is an error.
99
+ */
100
+ async function primaryWorkspacePath(projectDir, slug) {
101
+ const meta = await readJsonSafe(resolve(projectDir, "meta.json"));
102
+ const directory = meta?.workspacePaths?.[0];
103
+ if (!directory) {
104
+ throw new DagError("PROJECT_WORKSPACE_UNSET", `Project "${slug}" has no registered workspace path, so there is no directory to ` +
105
+ `create a session in — run \`arcs project update-paths ${slug} --add <path>\` first.`);
106
+ }
107
+ return directory;
108
+ }
109
+ function parseFilters(status, runtimeType) {
110
+ const filters = {};
111
+ if (status && SESSION_STATUSES.includes(status)) {
112
+ filters.status = status;
113
+ }
114
+ if (runtimeType && SESSION_RUNTIME_TYPES.includes(runtimeType)) {
115
+ filters.runtimeType = runtimeType;
116
+ }
117
+ return filters;
118
+ }
119
+ /**
120
+ * Mode-1 write-back (T005): the callback the route registers on runClaudeJob,
121
+ * invoked by the runner after the headless child fully exits — on every outcome
122
+ * (success/error/timeout/killed).
123
+ *
124
+ * - resume: mirrors the resumed session's runtime transcript into its sidecar
125
+ * via the persisted metadata.transcriptPath (hook-events T004 persists it at
126
+ * its checkpoints). The path is re-read fresh from the store — it may have
127
+ * been updated between the 202 and the run's exit. An absent path is a no-op;
128
+ * mirrorSessionTranscript is offset-idempotent and never throws, so repeated
129
+ * write-backs never duplicate and failures are inert.
130
+ * - oneshot/stable: never mirror — their sidecars are appendSessionTurn-owned.
131
+ * On a success outcome the captured reply is appended as an assistant turn
132
+ * (every reply lands in the sidecar); error/timeout outcomes append nothing.
133
+ *
134
+ * Every path finalizes metadata.run with the settled record (pid/startedAt/
135
+ * mode plus endedAt/outcome/error/replyChars) so the panel shows the true
136
+ * result. Best-effort by contract: the runner swallows any error thrown here,
137
+ * so a failed write-back never surfaces on the accepted 202.
138
+ */
139
+ async function writeBackRun(projectDir, ctx, record) {
140
+ if (ctx.mode === "resume") {
141
+ let target = ctx.writeTarget;
142
+ try {
143
+ target = await getSession(projectDir, ctx.writeTarget.normalizedId);
144
+ }
145
+ catch {
146
+ // Session deleted mid-run — fall back to the write-target captured at 202.
147
+ }
148
+ const transcriptPath = target.metadata?.transcriptPath;
149
+ if (typeof transcriptPath === "string" && transcriptPath !== "") {
150
+ await mirrorSessionTranscript(projectDir, ctx.writeTarget.normalizedId, transcriptPath);
151
+ }
152
+ }
153
+ else if (record.outcome === "success" && record.replyText !== undefined) {
154
+ // Modes 2/3 on success: the captured reply lands in the sidecar as an
155
+ // assistant turn (minted in the shared negative id space after the user
156
+ // turn and any reference). Error/timeout outcomes append nothing.
157
+ await appendSessionTurn(projectDir, ctx.writeTarget.normalizedId, {
158
+ type: "assistant",
159
+ text: record.replyText,
160
+ });
161
+ }
162
+ const run = {
163
+ pid: record.pid,
164
+ startedAt: record.startedAt,
165
+ mode: ctx.mode,
166
+ ...(record.endedAt !== undefined && { endedAt: record.endedAt }),
167
+ outcome: record.outcome,
168
+ ...(record.error !== undefined && { error: record.error }),
169
+ ...(record.replyChars !== undefined && { replyChars: record.replyChars }),
170
+ };
171
+ const runMetadata = { run };
172
+ if (ctx.mode === "stable" && ctx.firstStableSpawn && record.outcome === "success") {
173
+ runMetadata.threadInitialized = true;
174
+ }
175
+ await updateSession(projectDir, {
176
+ id: ctx.writeTarget.normalizedId,
177
+ metadata: runMetadata,
178
+ });
179
+ }
180
+ sessionsRoute.get("/api/p/:slug/sessions", async (c) => respond(c, async () => {
181
+ const projectDir = requireProjectDir(c.req.param("slug"));
182
+ const sessions = await listSessions(projectDir, parseFilters(c.req.query("status"), c.req.query("runtimeType")));
183
+ return { sessions };
184
+ }));
185
+ sessionsRoute.post("/api/p/:slug/sessions", async (c) => respond(c, async () => {
186
+ const projectDir = requireProjectDir(c.req.param("slug"));
187
+ const input = await parseBody(c, createSessionSchema);
188
+ return createSession(projectDir, input);
189
+ }, 201));
190
+ /**
191
+ * Creates a live opencode session in the project's primary workspace.
192
+ *
193
+ * The new session is mirrored into the index straight away rather than waiting
194
+ * for the discovery stream to notice it, so the caller can select and message
195
+ * it immediately. The stream's own `session.created` event lands moments later
196
+ * and merges into the same record.
197
+ *
198
+ * There is deliberately no claude-code counterpart: a Claude Code session only
199
+ * exists once a user runs `claude` in a linked directory, so there is nothing
200
+ * for ARCS to create remotely.
201
+ */
202
+ sessionsRoute.post("/api/p/:slug/sessions/opencode/new", async (c) => respond(c, async () => {
203
+ const slug = c.req.param("slug");
204
+ const projectDir = requireProjectDir(slug);
205
+ const { title } = await parseBody(c, createOpencodeSessionSchema);
206
+ const directory = await primaryWorkspacePath(projectDir, slug);
207
+ const config = requireOpencodeConfig();
208
+ const created = await createOpencodeSession(config, {
209
+ directory,
210
+ ...(title && { title }),
211
+ });
212
+ return upsertSession(projectDir, {
213
+ runtimeType: "opencode",
214
+ runtimeSessionId: created.runtimeSessionId,
215
+ status: "active",
216
+ metadata: { directory, ...(created.title && { title: created.title }) },
217
+ });
218
+ }, 201));
219
+ sessionsRoute.get("/api/p/:slug/sessions/:id", async (c) => respond(c, async () => {
220
+ const projectDir = requireProjectDir(c.req.param("slug"));
221
+ return getSession(projectDir, c.req.param("id"));
222
+ }));
223
+ sessionsRoute.patch("/api/p/:slug/sessions/:id", async (c) => respond(c, async () => {
224
+ const projectDir = requireProjectDir(c.req.param("slug"));
225
+ const input = await parseBody(c, updateSessionSchema);
226
+ return updateSession(projectDir, { id: c.req.param("id"), ...input });
227
+ }));
228
+ /**
229
+ * Sends a message to the runtime behind a session.
230
+ *
231
+ * Delivery is asymmetric by runtime, and deliberately so: opencode sessions get
232
+ * live injection (the running agent picks the prompt up mid-turn), while Claude
233
+ * Code sessions get queued delivery (the session itself drains the queue at its
234
+ * next hook checkpoint — Claude Code exposes no live channel to inject into).
235
+ * Both answer with the updated session, so the caller can tell them apart by
236
+ * `messageQueue` rather than by branching on `runtimeType` itself.
237
+ *
238
+ * A `reference` body field appends an ARCS-authored reference turn to the
239
+ * session's transcript sidecar, but only after delivery has succeeded — a
240
+ * failed send must never leave a dangling reference behind. The append is a
241
+ * swallowed no-op on failure (the message itself was already delivered).
242
+ */
243
+ sessionsRoute.post("/api/p/:slug/sessions/:id/message", async (c) => respond(c, async () => {
244
+ const projectDir = requireProjectDir(c.req.param("slug"));
245
+ const { message, reference } = await parseBody(c, sendMessageSchema);
246
+ const session = await getSession(projectDir, c.req.param("id"));
247
+ let updated;
248
+ if (session.runtimeType === "claude-code") {
249
+ // Queued, not sent: `lastMessageAt` stays untouched until the session
250
+ // actually drains this at a checkpoint.
251
+ updated = await enqueueSessionMessage(projectDir, session.normalizedId, message);
252
+ }
253
+ else {
254
+ await sendOpencodeMessage(requireOpencodeConfig(), {
255
+ runtimeSessionId: session.runtimeSessionId,
256
+ ...(sessionDirectory(session) && { directory: sessionDirectory(session) }),
257
+ }, message);
258
+ updated = await updateSession(projectDir, {
259
+ id: session.normalizedId,
260
+ lastMessageAt: new Date().toISOString(),
261
+ });
262
+ }
263
+ // Delivery succeeded (or was accepted into the queue) — record the
264
+ // reference turn against the session's transcript sidecar, carrying the
265
+ // section/source payload verbatim so the web UI can render click-through.
266
+ if (reference !== undefined) {
267
+ await appendReferenceTurn(projectDir, session.normalizedId, {
268
+ text: reference.text,
269
+ ts: new Date().toISOString(),
270
+ section: reference.section,
271
+ source: reference.source,
272
+ });
273
+ }
274
+ return updated;
275
+ }));
276
+ /**
277
+ * Starts a headless `claude -p` job in one of three targeting modes and answers
278
+ * 202 with the write-target session — the record the run's transcript and reply
279
+ * land on. The 202 is the acceptance: the run proceeds out-of-band in the
280
+ * runner, whose exit-time write-back (T005) then settles the run — finalizing
281
+ * `metadata.run` with the outcome on every path and, for resume mode, mirroring
282
+ * the resumed session's transcript into its sidecar.
283
+ *
284
+ * - resume: the referenced session must be a claude-code session that is not
285
+ * currently active; the run resumes its runtime thread in the session's own
286
+ * directory.
287
+ * - oneshot: the run targets a deterministic ARCS-owned session
288
+ * (`arcs-oneshot-<slug>`) recreated idempotently on every call, in the
289
+ * project's primary workspace.
290
+ * - stable: the run targets a persistent ARCS-owned thread (`arcs-thread-<slug>-
291
+ * <uuid4>` minted once then reused) so a conversation accumulates in one
292
+ * sidecar; the first successful spawn seeds the thread (`--session-id`),
293
+ * later spawns resume it (`--resume` + `--session-id`).
294
+ *
295
+ * Modes 2/3 append the user turn (and optional reference) to the write-target
296
+ * sidecar immediately — the panel shows the prompt before the run ends, with
297
+ * delivery-first ordering (user turn before reference). Mode 1 never appends:
298
+ * its transcript write-back happens at exit (T005).
299
+ *
300
+ * Concurrency: one live run per write-target. The runner's beginRun is the
301
+ * atomic claim; the read-only isRunLive probe here answers the common
302
+ * overlapping case with a proper 409 before anything is appended or spawned
303
+ * (a rare race between probe and claim is still refused by the runner itself).
304
+ */
305
+ sessionsRoute.post("/api/p/:slug/sessions/:id/run", async (c) => respond(c, async () => {
306
+ const slug = c.req.param("slug");
307
+ const projectDir = requireProjectDir(slug);
308
+ const { mode, message, threadId, reference } = await parseBody(c, runClaudeMessageSchema);
309
+ const session = await getSession(projectDir, c.req.param("id"));
310
+ let writeTarget;
311
+ let dir;
312
+ let runThreadId;
313
+ let firstStableSpawn = false;
314
+ if (mode === "resume") {
315
+ if (session.runtimeType !== "claude-code") {
316
+ throw new DagError("CLAUDE_RUN_TARGET_INVALID", `cannot resume session "${session.normalizedId}": only claude-code sessions can be run headlessly`);
317
+ }
318
+ if (session.status === "active") {
319
+ throw new DagError("CLAUDE_SESSION_ACTIVE", `cannot resume session "${session.normalizedId}": the session is still active`);
320
+ }
321
+ writeTarget = session;
322
+ dir = sessionDirectory(session) ?? (await primaryWorkspacePath(projectDir, slug));
323
+ }
324
+ else {
325
+ dir = await primaryWorkspacePath(projectDir, slug);
326
+ if (mode === "oneshot") {
327
+ writeTarget = await upsertSession(projectDir, {
328
+ runtimeType: "claude-code",
329
+ runtimeSessionId: `arcs-oneshot-${slug}`,
330
+ metadata: { control: "arcs-owned", directory: dir },
331
+ });
332
+ }
333
+ else {
334
+ // stable — reuse the referenced session's own thread when ARCS owns
335
+ // it, otherwise take the payload threadId or mint a fresh one.
336
+ const thread = (session.metadata?.control === "arcs-owned" && session.runtimeSessionId) ||
337
+ threadId ||
338
+ `arcs-thread-${slug}-${randomUUID()}`;
339
+ runThreadId = thread;
340
+ writeTarget = await upsertSession(projectDir, {
341
+ runtimeType: "claude-code",
342
+ runtimeSessionId: thread,
343
+ metadata: { control: "arcs-owned", directory: dir },
344
+ });
345
+ firstStableSpawn = writeTarget.metadata?.threadInitialized !== true;
346
+ }
347
+ }
348
+ // One live run per write-target — refuse before appending anything.
349
+ if (isRunLive(writeTarget.normalizedId)) {
350
+ throw new DagError("CLAUDE_RUN_IN_PROGRESS", `a claude run for "${writeTarget.normalizedId}" is already in progress`);
351
+ }
352
+ if (mode !== "resume") {
353
+ await appendSessionTurn(projectDir, writeTarget.normalizedId, {
354
+ type: "user",
355
+ text: message,
356
+ });
357
+ if (reference !== undefined) {
358
+ await appendReferenceTurn(projectDir, writeTarget.normalizedId, {
359
+ text: reference.text,
360
+ ts: new Date().toISOString(),
361
+ section: reference.section,
362
+ source: reference.source,
363
+ });
364
+ }
365
+ }
366
+ // NOTE: no "--cwd" flag — claude >= 2.x rejects it ("error: unknown
367
+ // option '--cwd'"), settling every headless run as outcome:error. The
368
+ // spawn applies the working directory via options.cwd below instead.
369
+ let argv;
370
+ if (mode === "resume") {
371
+ argv = ["-p", message, "--resume", session.runtimeSessionId, "--output-format", "json"];
372
+ }
373
+ else if (mode === "oneshot") {
374
+ argv = ["-p", message, "--output-format", "json"];
375
+ }
376
+ else {
377
+ const thread = runThreadId;
378
+ argv = firstStableSpawn
379
+ ? ["-p", message, "--session-id", thread, "--output-format", "json"]
380
+ : ["-p", message, "--resume", thread, "--session-id", thread, "--output-format", "json"];
381
+ }
382
+ // Fire-and-forget: the run proceeds out-of-band. The runner invokes the
383
+ // registered write-back after the child fully exits (it resolves on
384
+ // `close`) on every outcome path; write-back failures are swallowed by
385
+ // the runner, so a failed mirror/finalize never surfaces on the accepted
386
+ // 202. The trailing catch is defensive — the runner never rejects.
387
+ runClaudeJob({
388
+ argv,
389
+ cwd: dir,
390
+ writeTargetKey: writeTarget.normalizedId,
391
+ onSettled: (record) => writeBackRun(projectDir, { mode, writeTarget, firstStableSpawn }, record),
392
+ }).catch(() => {
393
+ // Best-effort — the write-back lives inside the runner's onSettled.
394
+ });
395
+ return {
396
+ session: writeTarget,
397
+ run: {
398
+ accepted: true,
399
+ mode,
400
+ ...(mode === "stable" && { threadId: runThreadId }),
401
+ },
402
+ };
403
+ }, 202));
404
+ sessionsRoute.delete("/api/p/:slug/sessions/:id", async (c) => respond(c, async () => {
405
+ const projectDir = requireProjectDir(c.req.param("slug"));
406
+ // Resolve through the index first: the sidecar filename keys on the
407
+ // session's canonical normalizedId, so a non-slugified route id must not
408
+ // re-derive the filename (deleteSession alone would orphan the sidecar).
409
+ const session = await getSession(projectDir, c.req.param("id"));
410
+ await deleteSession(projectDir, session.normalizedId);
411
+ try {
412
+ await unlink(sessionTranscriptPath(projectDir, session.normalizedId));
413
+ }
414
+ catch {
415
+ // Sidecar may not exist — a failed unlink is a swallowed no-op.
416
+ }
417
+ return { deleted: true };
418
+ }));
419
+ /**
420
+ * Reads the session's transcript sidecar (mirrored Claude Code lines plus
421
+ * ARCS-authored reference turns) into the read-model the web UI renders.
422
+ * An absent sidecar answers an empty transcript with `mirroredAt: null`; once
423
+ * the sidecar exists, `mirroredAt` is the file mtime so the UI can show how
424
+ * fresh the mirror is.
425
+ */
426
+ sessionsRoute.get("/api/p/:slug/sessions/:id/transcript", async (c) => respond(c, async () => {
427
+ const projectDir = requireProjectDir(c.req.param("slug"));
428
+ const session = await getSession(projectDir, c.req.param("id"));
429
+ let mirroredAt = null;
430
+ try {
431
+ const info = await stat(sessionTranscriptPath(projectDir, session.normalizedId));
432
+ if (info.isFile())
433
+ mirroredAt = info.mtime.toISOString();
434
+ }
435
+ catch {
436
+ // No sidecar yet — empty transcript, nothing mirrored.
437
+ }
438
+ if (mirroredAt === null)
439
+ return { turns: [], mirroredAt: null };
440
+ return { turns: await readSessionTurns(projectDir, session.normalizedId), mirroredAt };
441
+ }));
442
+ //# sourceMappingURL=sessions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../../src/web-server/routes/sessions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { MiddlewareHandler } from "hono";
2
+ export declare function isLoopbackHost(host: string): boolean;
3
+ /**
4
+ * Local-server hardening against DNS rebinding and browser CSRF.
5
+ */
6
+ export declare const secureLocalRequest: MiddlewareHandler;
7
+ //# sourceMappingURL=security.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../../src/web-server/security.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAK9C,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAKpD;AAOD;;GAEG;AACH,eAAO,MAAM,kBAAkB,EAAE,iBA8BhC,CAAC"}
@@ -0,0 +1,41 @@
1
+ import { fail } from "./respond.js";
2
+ const MUTATION_METHODS = new Set(["POST", "PUT", "PATCH", "DELETE"]);
3
+ export function isLoopbackHost(host) {
4
+ const normalized = host.toLowerCase().replace(/^\[|\]$/g, "");
5
+ return (normalized === "localhost" || normalized === "::1" || /^127(?:\.\d{1,3}){3}$/.test(normalized));
6
+ }
7
+ function hostnameFromHostHeader(value) {
8
+ if (value.startsWith("["))
9
+ return value.slice(1, value.indexOf("]"));
10
+ return value.split(":", 1)[0] ?? "";
11
+ }
12
+ /**
13
+ * Local-server hardening against DNS rebinding and browser CSRF.
14
+ */
15
+ export const secureLocalRequest = async (c, next) => {
16
+ const host = hostnameFromHostHeader(c.req.header("host") ?? "");
17
+ if (!isLoopbackHost(host)) {
18
+ return c.json(fail("forbidden_host", "ARCS web only accepts loopback requests"), 403);
19
+ }
20
+ const origin = c.req.header("origin");
21
+ if (origin) {
22
+ let originHost = "";
23
+ try {
24
+ originHost = new URL(origin).hostname;
25
+ }
26
+ catch {
27
+ return c.json(fail("forbidden_origin", "Invalid request origin"), 403);
28
+ }
29
+ if (!isLoopbackHost(originHost)) {
30
+ return c.json(fail("forbidden_origin", "Cross-site mutations are not allowed"), 403);
31
+ }
32
+ }
33
+ if (MUTATION_METHODS.has(c.req.method)) {
34
+ const contentType = c.req.header("content-type") ?? "";
35
+ if (!contentType.toLowerCase().startsWith("application/json")) {
36
+ return c.json(fail("unsupported_media_type", "Mutations require Content-Type: application/json"), 415);
37
+ }
38
+ }
39
+ await next();
40
+ };
41
+ //# sourceMappingURL=security.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.js","sourceRoot":"","sources":["../../src/web-server/security.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEpC,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;AAErE,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAC9D,OAAO,CACL,UAAU,KAAK,WAAW,IAAI,UAAU,KAAK,KAAK,IAAI,uBAAuB,CAAC,IAAI,CAAC,UAAU,CAAC,CAC/F,CAAC;AACJ,CAAC;AAED,SAAS,sBAAsB,CAAC,KAAa;IAC3C,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;IACrE,OAAO,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;AACtC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAsB,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;IACrE,MAAM,IAAI,GAAG,sBAAsB,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IAChE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,yCAAyC,CAAC,EAAE,GAAG,CAAC,CAAC;IACxF,CAAC;IAED,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACtC,IAAI,MAAM,EAAE,CAAC;QACX,IAAI,UAAU,GAAG,EAAE,CAAC;QACpB,IAAI,CAAC;YACH,UAAU,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC;QACxC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,wBAAwB,CAAC,EAAE,GAAG,CAAC,CAAC;QACzE,CAAC;QACD,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,EAAE,CAAC;YAChC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,sCAAsC,CAAC,EAAE,GAAG,CAAC,CAAC;QACvF,CAAC;IACH,CAAC;IAED,IAAI,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QACvC,MAAM,WAAW,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;QACvD,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,kBAAkB,CAAC,EAAE,CAAC;YAC9D,OAAO,CAAC,CAAC,IAAI,CACX,IAAI,CAAC,wBAAwB,EAAE,kDAAkD,CAAC,EAClF,GAAG,CACJ,CAAC;QACJ,CAAC;IACH,CAAC;IAED,MAAM,IAAI,EAAE,CAAC;AACf,CAAC,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Static client bundle serving with SPA fallback.
3
+ *
4
+ * The Vite build output lives at dist/web-client (resolved by the caller).
5
+ * If the bundle is missing, the server runs API-only and explains how to
6
+ * build the client.
7
+ */
8
+ import type { Hono } from "hono";
9
+ export declare function registerStaticServing(app: Hono, root: string): void;
10
+ //# sourceMappingURL=static.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"static.d.ts","sourceRoot":"","sources":["../../src/web-server/static.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAMjC,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAuBnE"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Static client bundle serving with SPA fallback.
3
+ *
4
+ * The Vite build output lives at dist/web-client (resolved by the caller).
5
+ * If the bundle is missing, the server runs API-only and explains how to
6
+ * build the client.
7
+ */
8
+ import { existsSync } from "node:fs";
9
+ import { join } from "node:path";
10
+ import { serveStatic } from "@hono/node-server/serve-static";
11
+ import { fail } from "./respond.js";
12
+ const NOT_BUILT_HINT = "ARCS web client is not built. Run `npm run build:web` in the arcs repo (or reinstall @rryando/arcs).";
13
+ export function registerStaticServing(app, root) {
14
+ if (!existsSync(join(root, "index.html"))) {
15
+ app.notFound((c) => {
16
+ if (c.req.path.startsWith("/api/")) {
17
+ return c.json(fail("not_found", `No route: ${c.req.method} ${c.req.path}`), 404);
18
+ }
19
+ return c.text(NOT_BUILT_HINT, 404);
20
+ });
21
+ return;
22
+ }
23
+ app.use("*", async (c, next) => {
24
+ if (c.req.path.startsWith("/api/"))
25
+ return next();
26
+ return serveStatic({ root })(c, next);
27
+ });
28
+ app.notFound((c) => {
29
+ if (c.req.path.startsWith("/api/")) {
30
+ return c.json(fail("not_found", `No route: ${c.req.method} ${c.req.path}`), 404);
31
+ }
32
+ // SPA fallback — client-side routing takes over.
33
+ return serveStatic({ path: join(root, "index.html") })(c, async () => { });
34
+ });
35
+ }
36
+ //# sourceMappingURL=static.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"static.js","sourceRoot":"","sources":["../../src/web-server/static.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAE7D,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEpC,MAAM,cAAc,GAClB,sGAAsG,CAAC;AAEzG,MAAM,UAAU,qBAAqB,CAAC,GAAS,EAAE,IAAY;IAC3D,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC;QAC1C,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE;YACjB,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBACnC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;YACnF,CAAC;YACD,OAAO,CAAC,CAAC,IAAI,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IAED,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;QAC7B,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;YAAE,OAAO,IAAI,EAAE,CAAC;QAClD,OAAO,WAAW,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE;QACjB,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACnC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;QACnF,CAAC;QACD,iDAAiD;QACjD,OAAO,WAAW,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC,CAAsB,CAAC;IACjG,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,17 @@
1
+ /** Lock-safe, atomic filesystem mutations used by the web server. */
2
+ import { type RootMeta } from "../utils/dag.js";
3
+ export { writeTextAtomic } from "../utils/storage-utils.js";
4
+ /** Atomically replace a text file while holding its advisory lock. */
5
+ export declare function writeTextLocked(filePath: string, content: string): Promise<void>;
6
+ /** Remove a file while holding the same advisory lock writers use. */
7
+ export declare function removeFileLocked(filePath: string): Promise<void>;
8
+ /**
9
+ * Acquire several file locks in deterministic lexical order to avoid deadlock.
10
+ */
11
+ export declare function withFileLocks<T>(filePaths: string[], fn: () => T | Promise<T>): Promise<T>;
12
+ /**
13
+ * Read-modify-write root meta.json while holding one lock for the whole
14
+ * validation and mutation transaction.
15
+ */
16
+ export declare function mutateRootMetaLocked<T>(dataDir: string, mutate: (rootMeta: RootMeta) => T | Promise<T>): Promise<T>;
17
+ //# sourceMappingURL=storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/web-server/storage.ts"],"names":[],"mappings":"AAAA,qEAAqE;AAIrE,OAAO,EAAE,KAAK,QAAQ,EAAgB,MAAM,iBAAiB,CAAC;AAI9D,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE5D,sEAAsE;AACtE,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEtF;AAED,sEAAsE;AACtE,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEtE;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAUhG;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,CAAC,EAC1C,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAC7C,OAAO,CAAC,CAAC,CAAC,CAQZ"}
@@ -0,0 +1,42 @@
1
+ /** Lock-safe, atomic filesystem mutations used by the web server. */
2
+ import { unlink } from "node:fs/promises";
3
+ import { resolve } from "node:path";
4
+ import { readRootMeta } from "../utils/dag.js";
5
+ import { withLock } from "../utils/file-lock.js";
6
+ import { writeTextAtomic } from "../utils/storage-utils.js";
7
+ export { writeTextAtomic } from "../utils/storage-utils.js";
8
+ /** Atomically replace a text file while holding its advisory lock. */
9
+ export async function writeTextLocked(filePath, content) {
10
+ await withLock(filePath, () => writeTextAtomic(filePath, content));
11
+ }
12
+ /** Remove a file while holding the same advisory lock writers use. */
13
+ export async function removeFileLocked(filePath) {
14
+ await withLock(filePath, () => unlink(filePath).catch(() => { }));
15
+ }
16
+ /**
17
+ * Acquire several file locks in deterministic lexical order to avoid deadlock.
18
+ */
19
+ export async function withFileLocks(filePaths, fn) {
20
+ const ordered = [...new Set(filePaths)].sort();
21
+ const acquire = async (index) => {
22
+ const filePath = ordered[index];
23
+ if (filePath === undefined)
24
+ return fn();
25
+ return withLock(filePath, () => acquire(index + 1));
26
+ };
27
+ return acquire(0);
28
+ }
29
+ /**
30
+ * Read-modify-write root meta.json while holding one lock for the whole
31
+ * validation and mutation transaction.
32
+ */
33
+ export async function mutateRootMetaLocked(dataDir, mutate) {
34
+ const rootMetaPath = resolve(dataDir, "meta.json");
35
+ return withLock(rootMetaPath, async () => {
36
+ const rootMeta = await readRootMeta(dataDir);
37
+ const result = await mutate(rootMeta);
38
+ await writeTextAtomic(rootMetaPath, `${JSON.stringify(rootMeta, null, 2)}\n`);
39
+ return result;
40
+ });
41
+ }
42
+ //# sourceMappingURL=storage.js.map