@rryando/arcs 3.10.0 → 4.0.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 (366) 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 -383
  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 +99 -6
  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 +76 -0
  25. package/dist/cli/commands/hooks.d.ts.map +1 -0
  26. package/dist/cli/commands/hooks.js +436 -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 +66 -0
  39. package/dist/cli/commands/web.js.map +1 -0
  40. package/dist/cli/config.d.ts +46 -3
  41. package/dist/cli/config.d.ts.map +1 -1
  42. package/dist/cli/config.js +95 -38
  43. package/dist/cli/config.js.map +1 -1
  44. package/dist/cli/instructions.d.ts +32 -7
  45. package/dist/cli/instructions.d.ts.map +1 -1
  46. package/dist/cli/instructions.js +99 -34
  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 +230 -91
  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/shared/session-vocabulary.d.ts +88 -0
  59. package/dist/shared/session-vocabulary.d.ts.map +1 -0
  60. package/dist/shared/session-vocabulary.js +114 -0
  61. package/dist/shared/session-vocabulary.js.map +1 -0
  62. package/dist/utils/claude-code-hook-install.d.ts +80 -0
  63. package/dist/utils/claude-code-hook-install.d.ts.map +1 -0
  64. package/dist/utils/claude-code-hook-install.js +211 -0
  65. package/dist/utils/claude-code-hook-install.js.map +1 -0
  66. package/dist/utils/claude-transcript.d.ts +206 -0
  67. package/dist/utils/claude-transcript.d.ts.map +1 -0
  68. package/dist/utils/claude-transcript.js +384 -0
  69. package/dist/utils/claude-transcript.js.map +1 -0
  70. package/dist/utils/diagram-generator.d.ts +1 -1
  71. package/dist/utils/diagram-generator.d.ts.map +1 -1
  72. package/dist/utils/diagram-generator.js +3 -2
  73. package/dist/utils/diagram-generator.js.map +1 -1
  74. package/dist/utils/errors.d.ts +6 -2
  75. package/dist/utils/errors.d.ts.map +1 -1
  76. package/dist/utils/errors.js +12 -0
  77. package/dist/utils/errors.js.map +1 -1
  78. package/dist/utils/git.d.ts +21 -0
  79. package/dist/utils/git.d.ts.map +1 -1
  80. package/dist/utils/git.js +65 -1
  81. package/dist/utils/git.js.map +1 -1
  82. package/dist/utils/hook-contract.d.ts +36 -0
  83. package/dist/utils/hook-contract.d.ts.map +1 -0
  84. package/dist/utils/hook-contract.js +35 -0
  85. package/dist/utils/hook-contract.js.map +1 -0
  86. package/dist/utils/hook-token-store.d.ts +61 -0
  87. package/dist/utils/hook-token-store.d.ts.map +1 -0
  88. package/dist/utils/hook-token-store.js +86 -0
  89. package/dist/utils/hook-token-store.js.map +1 -0
  90. package/dist/utils/json-schemas.d.ts +186 -2
  91. package/dist/utils/json-schemas.d.ts.map +1 -1
  92. package/dist/utils/json-schemas.js +48 -4
  93. package/dist/utils/json-schemas.js.map +1 -1
  94. package/dist/utils/knowledge-store.d.ts +7 -1
  95. package/dist/utils/knowledge-store.d.ts.map +1 -1
  96. package/dist/utils/knowledge-store.js +97 -65
  97. package/dist/utils/knowledge-store.js.map +1 -1
  98. package/dist/utils/plan-store.d.ts +8 -0
  99. package/dist/utils/plan-store.d.ts.map +1 -1
  100. package/dist/utils/plan-store.js +98 -59
  101. package/dist/utils/plan-store.js.map +1 -1
  102. package/dist/utils/project-resolver.d.ts +8 -0
  103. package/dist/utils/project-resolver.d.ts.map +1 -1
  104. package/dist/utils/project-resolver.js +7 -2
  105. package/dist/utils/project-resolver.js.map +1 -1
  106. package/dist/utils/session-store.d.ts +339 -0
  107. package/dist/utils/session-store.d.ts.map +1 -0
  108. package/dist/utils/session-store.js +577 -0
  109. package/dist/utils/session-store.js.map +1 -0
  110. package/dist/utils/storage-utils.d.ts +31 -0
  111. package/dist/utils/storage-utils.d.ts.map +1 -1
  112. package/dist/utils/storage-utils.js +116 -5
  113. package/dist/utils/storage-utils.js.map +1 -1
  114. package/dist/utils/task-store.d.ts +7 -0
  115. package/dist/utils/task-store.d.ts.map +1 -1
  116. package/dist/utils/task-store.js +73 -23
  117. package/dist/utils/task-store.js.map +1 -1
  118. package/dist/web-client/assets/GraphCanvas-CTyf_XXQ.js +1 -0
  119. package/dist/web-client/assets/MarkdownEditor-af2vwQOX.js +77 -0
  120. package/dist/web-client/assets/abnfDiagram-VRR7QNED-CdxcKX9t.js +1 -0
  121. package/dist/web-client/assets/arc-Bfaogrm1.js +1 -0
  122. package/dist/web-client/assets/architecture-TIHT7OUA-Bt2-DmfV.js +1 -0
  123. package/dist/web-client/assets/architectureDiagram-ZJ3FMSHR-DOISDv6o.js +36 -0
  124. package/dist/web-client/assets/array-BifhSqXX.js +1 -0
  125. package/dist/web-client/assets/blockDiagram-677ZJIJ3-DKwtbttM.js +132 -0
  126. package/dist/web-client/assets/c4Diagram-LMCZKHZV-CilqK-Mm.js +10 -0
  127. package/dist/web-client/assets/channel-C2mb9np_.js +1 -0
  128. package/dist/web-client/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
  129. package/dist/web-client/assets/chunk-32BRIVSS-C79m1mkG.js +1 -0
  130. package/dist/web-client/assets/chunk-52WLFC77-C6WelGWJ.js +10 -0
  131. package/dist/web-client/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
  132. package/dist/web-client/assets/chunk-7BUUIJ7U-Bb538aSH.js +1 -0
  133. package/dist/web-client/assets/chunk-C7G6YPKG-DLg7ryWI.js +1 -0
  134. package/dist/web-client/assets/chunk-EX3LRPZG-DjWgo4gL.js +231 -0
  135. package/dist/web-client/assets/chunk-FWX5IMBZ-BgS9p_zy.js +2 -0
  136. package/dist/web-client/assets/chunk-HOUHSVGY-DuVR7dZO.js +1 -0
  137. package/dist/web-client/assets/chunk-ICXQ74PX-Y8DlnIJM.js +2 -0
  138. package/dist/web-client/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
  139. package/dist/web-client/assets/chunk-KEIR6QF5-DEvma7oi.js +161 -0
  140. package/dist/web-client/assets/chunk-MOJQB5TN-BEM3QgeD.js +88 -0
  141. package/dist/web-client/assets/chunk-OGEWGWER-DlM8LxGr.js +1 -0
  142. package/dist/web-client/assets/chunk-PUDLZKDR-c6cqNVTx.js +156 -0
  143. package/dist/web-client/assets/chunk-Q4XR5HBZ-C5lNmcka.js +70 -0
  144. package/dist/web-client/assets/chunk-RYQCIY6F-np2RyIY1.js +1 -0
  145. package/dist/web-client/assets/chunk-V7JOEXUC-nSswxvSG.js +206 -0
  146. package/dist/web-client/assets/chunk-VAUOI2AC-CqJkCkT0.js +1 -0
  147. package/dist/web-client/assets/chunk-VR4S4FIN-D3pFchin.js +1 -0
  148. package/dist/web-client/assets/chunk-WYO6CB5R-BI9c-NzI.js +125 -0
  149. package/dist/web-client/assets/chunk-XXDRQBXY-BvKO0v-W.js +1 -0
  150. package/dist/web-client/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
  151. package/dist/web-client/assets/chunk-ZGVPDNZ5-CKTF2kLR.js +62 -0
  152. package/dist/web-client/assets/chunk-ZIRB5QZD-BpeS1aZ7.js +32 -0
  153. package/dist/web-client/assets/classDiagram-OUVF2IWQ-CPd_w3Zr.js +1 -0
  154. package/dist/web-client/assets/classDiagram-v2-EOCWNBFH-CPd_w3Zr.js +1 -0
  155. package/dist/web-client/assets/cose-bilkent-JH36ORCC-BebHqzgp.js +1 -0
  156. package/dist/web-client/assets/cynefin-VYW2F7L2-BrJrnfh1.js +1 -0
  157. package/dist/web-client/assets/cynefinDiagram-TSTJHNR4-9jYzPWJZ.js +62 -0
  158. package/dist/web-client/assets/cytoscape-fcose-peAzqedC.js +1 -0
  159. package/dist/web-client/assets/cytoscape.esm-C3UvhD5t.js +321 -0
  160. package/dist/web-client/assets/dagre-Buvkdvvj.js +1 -0
  161. package/dist/web-client/assets/dagre-VKFMJZFB-B705Djpu.js +4 -0
  162. package/dist/web-client/assets/defaultLocale-BFoDCU3G.js +1 -0
  163. package/dist/web-client/assets/diagram-FQU43EPY-BfQAlUlJ.js +3 -0
  164. package/dist/web-client/assets/diagram-G47NLZAW-s1YDe06A.js +24 -0
  165. package/dist/web-client/assets/diagram-NH7WQ7WH-Dy3z11Hc.js +24 -0
  166. package/dist/web-client/assets/diagram-OA4YK3LP-Bius2xUN.js +30 -0
  167. package/dist/web-client/assets/diagram-WEI45ONY-D7x4VcHM.js +41 -0
  168. package/dist/web-client/assets/dist-B_J_HbC0.js +1 -0
  169. package/dist/web-client/assets/ebnfDiagram-CCIWWBDH-CBg1xrmD.js +1 -0
  170. package/dist/web-client/assets/erDiagram-Q63AITRT-CJRvTFvd.js +85 -0
  171. package/dist/web-client/assets/eventmodeling-45OFAUF4-CTKRC2Yj.js +1 -0
  172. package/dist/web-client/assets/flowDiagram-23GEKE2U-CaZjFyU1.js +1 -0
  173. package/dist/web-client/assets/ganttDiagram-NO4QXBWP-C_LsypZ4.js +292 -0
  174. package/dist/web-client/assets/gitGraph-TEB2WS4Q-Dx2XxdGk.js +1 -0
  175. package/dist/web-client/assets/gitGraphDiagram-IHSO6WYX-DiKWkGWQ.js +106 -0
  176. package/dist/web-client/assets/graphlib-DS17s2tU.js +1 -0
  177. package/dist/web-client/assets/index-CYwhkPtc.js +60 -0
  178. package/dist/web-client/assets/index-wSzUPvml.css +2 -0
  179. package/dist/web-client/assets/info-DKCQHKI2-DORwHenK.js +1 -0
  180. package/dist/web-client/assets/infoDiagram-FWYZ7A6U-CQecXS1E.js +2 -0
  181. package/dist/web-client/assets/init-C-OQMol4.js +1 -0
  182. package/dist/web-client/assets/ishikawaDiagram-FXEZZL3T-CWhj60Zp.js +70 -0
  183. package/dist/web-client/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2 +0 -0
  184. package/dist/web-client/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2 +0 -0
  185. package/dist/web-client/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
  186. package/dist/web-client/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
  187. package/dist/web-client/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2 +0 -0
  188. package/dist/web-client/assets/journeyDiagram-5HDEW3XC-Cj3z2U8u.js +139 -0
  189. package/dist/web-client/assets/kanban-definition-HUTT4EX6-DFmBRenP.js +89 -0
  190. package/dist/web-client/assets/katex-DolUETbr.js +257 -0
  191. package/dist/web-client/assets/line-C_Hxz9xb.js +1 -0
  192. package/dist/web-client/assets/linear-DeUiD2wj.js +1 -0
  193. package/dist/web-client/assets/map-BaFkSB1l.js +1 -0
  194. package/dist/web-client/assets/mermaid-parser.core-E3xRdzPn.js +7 -0
  195. package/dist/web-client/assets/mermaid.core-C2_CcotH.js +11 -0
  196. package/dist/web-client/assets/mindmap-definition-LN4V7U3C-Bs7VxPid.js +96 -0
  197. package/dist/web-client/assets/ordinal-BDEzSJ7C.js +1 -0
  198. package/dist/web-client/assets/packet-7NZHBO7P-D2nqso7i.js +1 -0
  199. package/dist/web-client/assets/path-COt_16Va.js +1 -0
  200. package/dist/web-client/assets/pegDiagram-2B236MQR-Cepo1sIu.js +1 -0
  201. package/dist/web-client/assets/pie-RZYD4A2V-Sx0IGbXt.js +1 -0
  202. package/dist/web-client/assets/pieDiagram-ENE6RG2P-D-PMDNhk.js +39 -0
  203. package/dist/web-client/assets/quadrantDiagram-ABIIQ3AL-BNGC7Fms.js +7 -0
  204. package/dist/web-client/assets/radar-I7S5WNFK-CFf_-2OC.js +1 -0
  205. package/dist/web-client/assets/railroad-3IZDKUUU-BvZeVRGh.js +1 -0
  206. package/dist/web-client/assets/railroad-abnf-AHOZXSZD-DnGh6x2O.js +1 -0
  207. package/dist/web-client/assets/railroad-ebnf-EBAXGLYW-CGfgCoaE.js +1 -0
  208. package/dist/web-client/assets/railroad-peg-LSFZ7HO6-BzQxYdqp.js +1 -0
  209. package/dist/web-client/assets/railroadDiagram-RFXS5EU6-D0iK_k84.js +1 -0
  210. package/dist/web-client/assets/requirementDiagram-TGXJPOKE-BPdsw9tz.js +84 -0
  211. package/dist/web-client/assets/rolldown-runtime-Dd_uD5pT.js +1 -0
  212. package/dist/web-client/assets/rough.esm-By172zw-.js +1 -0
  213. package/dist/web-client/assets/sankeyDiagram-HTMAVEWB-maA6ukOJ.js +40 -0
  214. package/dist/web-client/assets/sequenceDiagram-DBY2YBRQ-DKmAjmgr.js +162 -0
  215. package/dist/web-client/assets/sizeCapture-X5ZJPWSS-B0uUizjq.js +1 -0
  216. package/dist/web-client/assets/src-oBChb5qS.js +1 -0
  217. package/dist/web-client/assets/stateDiagram-2N3HPSRC-esxmzk3w.js +1 -0
  218. package/dist/web-client/assets/stateDiagram-v2-6OUMAXLB-hcBqlOLc.js +1 -0
  219. package/dist/web-client/assets/swimlanes-5IMT3BWC-DFd-wGBv.js +2 -0
  220. package/dist/web-client/assets/swimlanesDiagram-G3AALYLV-DbSrPBYr.js +8 -0
  221. package/dist/web-client/assets/timeline-definition-FHXFAJF6-C7SG8MQH.js +120 -0
  222. package/dist/web-client/assets/treeView-QDETBFTQ-M0rhxbs2.js +1 -0
  223. package/dist/web-client/assets/treemap-6X3UGDF4-BQfkQxSh.js +1 -0
  224. package/dist/web-client/assets/vennDiagram-L72KCM5P-CyIlb8ju.js +34 -0
  225. package/dist/web-client/assets/wardley-OPB4EBWU-EE-7q8M1.js +1 -0
  226. package/dist/web-client/assets/wardleyDiagram-EHGQE667-bY8XdYYS.js +78 -0
  227. package/dist/web-client/assets/xychartDiagram-FW5EYKEG-AhuXJ3de.js +7 -0
  228. package/dist/web-client/index.html +15 -0
  229. package/dist/web-server/app.d.ts +16 -0
  230. package/dist/web-server/app.d.ts.map +1 -0
  231. package/dist/web-server/app.js +77 -0
  232. package/dist/web-server/app.js.map +1 -0
  233. package/dist/web-server/claude-runner.d.ts +188 -0
  234. package/dist/web-server/claude-runner.d.ts.map +1 -0
  235. package/dist/web-server/claude-runner.js +599 -0
  236. package/dist/web-server/claude-runner.js.map +1 -0
  237. package/dist/web-server/hook-auth.d.ts +12 -0
  238. package/dist/web-server/hook-auth.d.ts.map +1 -0
  239. package/dist/web-server/hook-auth.js +36 -0
  240. package/dist/web-server/hook-auth.js.map +1 -0
  241. package/dist/web-server/index.d.ts +23 -0
  242. package/dist/web-server/index.d.ts.map +1 -0
  243. package/dist/web-server/index.js +50 -0
  244. package/dist/web-server/index.js.map +1 -0
  245. package/dist/web-server/opencode-client.d.ts +123 -0
  246. package/dist/web-server/opencode-client.d.ts.map +1 -0
  247. package/dist/web-server/opencode-client.js +514 -0
  248. package/dist/web-server/opencode-client.js.map +1 -0
  249. package/dist/web-server/permission-policy.d.ts +46 -0
  250. package/dist/web-server/permission-policy.d.ts.map +1 -0
  251. package/dist/web-server/permission-policy.js +96 -0
  252. package/dist/web-server/permission-policy.js.map +1 -0
  253. package/dist/web-server/prompt-assembly.d.ts +454 -0
  254. package/dist/web-server/prompt-assembly.d.ts.map +1 -0
  255. package/dist/web-server/prompt-assembly.js +1122 -0
  256. package/dist/web-server/prompt-assembly.js.map +1 -0
  257. package/dist/web-server/respond.d.ts +33 -0
  258. package/dist/web-server/respond.d.ts.map +1 -0
  259. package/dist/web-server/respond.js +79 -0
  260. package/dist/web-server/respond.js.map +1 -0
  261. package/dist/web-server/routes/collections.d.ts +11 -0
  262. package/dist/web-server/routes/collections.d.ts.map +1 -0
  263. package/dist/web-server/routes/collections.js +217 -0
  264. package/dist/web-server/routes/collections.js.map +1 -0
  265. package/dist/web-server/routes/discovery.d.ts +7 -0
  266. package/dist/web-server/routes/discovery.d.ts.map +1 -0
  267. package/dist/web-server/routes/discovery.js +159 -0
  268. package/dist/web-server/routes/discovery.js.map +1 -0
  269. package/dist/web-server/routes/events.d.ts +6 -0
  270. package/dist/web-server/routes/events.d.ts.map +1 -0
  271. package/dist/web-server/routes/events.js +25 -0
  272. package/dist/web-server/routes/events.js.map +1 -0
  273. package/dist/web-server/routes/hook-events.d.ts +44 -0
  274. package/dist/web-server/routes/hook-events.d.ts.map +1 -0
  275. package/dist/web-server/routes/hook-events.js +320 -0
  276. package/dist/web-server/routes/hook-events.js.map +1 -0
  277. package/dist/web-server/routes/projects.d.ts +7 -0
  278. package/dist/web-server/routes/projects.d.ts.map +1 -0
  279. package/dist/web-server/routes/projects.js +272 -0
  280. package/dist/web-server/routes/projects.js.map +1 -0
  281. package/dist/web-server/routes/sessions.d.ts +18 -0
  282. package/dist/web-server/routes/sessions.d.ts.map +1 -0
  283. package/dist/web-server/routes/sessions.js +1298 -0
  284. package/dist/web-server/routes/sessions.js.map +1 -0
  285. package/dist/web-server/routes/workspace.d.ts +27 -0
  286. package/dist/web-server/routes/workspace.d.ts.map +1 -0
  287. package/dist/web-server/routes/workspace.js +280 -0
  288. package/dist/web-server/routes/workspace.js.map +1 -0
  289. package/dist/web-server/run-event-log.d.ts +167 -0
  290. package/dist/web-server/run-event-log.d.ts.map +1 -0
  291. package/dist/web-server/run-event-log.js +468 -0
  292. package/dist/web-server/run-event-log.js.map +1 -0
  293. package/dist/web-server/security.d.ts +7 -0
  294. package/dist/web-server/security.d.ts.map +1 -0
  295. package/dist/web-server/security.js +41 -0
  296. package/dist/web-server/security.js.map +1 -0
  297. package/dist/web-server/session-reconciler.d.ts +162 -0
  298. package/dist/web-server/session-reconciler.d.ts.map +1 -0
  299. package/dist/web-server/session-reconciler.js +363 -0
  300. package/dist/web-server/session-reconciler.js.map +1 -0
  301. package/dist/web-server/static.d.ts +17 -0
  302. package/dist/web-server/static.d.ts.map +1 -0
  303. package/dist/web-server/static.js +79 -0
  304. package/dist/web-server/static.js.map +1 -0
  305. package/dist/web-server/storage.d.ts +17 -0
  306. package/dist/web-server/storage.d.ts.map +1 -0
  307. package/dist/web-server/storage.js +42 -0
  308. package/dist/web-server/storage.js.map +1 -0
  309. package/dist/web-server/watcher.d.ts +37 -0
  310. package/dist/web-server/watcher.d.ts.map +1 -0
  311. package/dist/web-server/watcher.js +181 -0
  312. package/dist/web-server/watcher.js.map +1 -0
  313. package/dist/web-server/web-auth.d.ts +17 -0
  314. package/dist/web-server/web-auth.d.ts.map +1 -0
  315. package/dist/web-server/web-auth.js +33 -0
  316. package/dist/web-server/web-auth.js.map +1 -0
  317. package/dist/web-server/web-token.d.ts +39 -0
  318. package/dist/web-server/web-token.d.ts.map +1 -0
  319. package/dist/web-server/web-token.js +71 -0
  320. package/dist/web-server/web-token.js.map +1 -0
  321. package/opencode/arcs/bundle-runtime.json +5 -13
  322. package/opencode/arcs/manifest.json +215 -151
  323. package/opencode/arcs/prompts/arcs-docs.txt +53 -47
  324. package/opencode/arcs/prompts/arcs-flash.txt +190 -0
  325. package/opencode/arcs/prompts/arcs-orchestrate-caveman.txt +116 -422
  326. package/opencode/arcs/prompts/arcs-orchestrate.txt +114 -341
  327. package/opencode/arcs/prompts/code-reviewer.txt +37 -98
  328. package/opencode/arcs/prompts/devil-advocate.txt +44 -115
  329. package/opencode/arcs/prompts/graph-explorer.txt +31 -179
  330. package/opencode/arcs/prompts/software-engineer.txt +24 -6
  331. package/opencode/arcs/prompts/tech-architect.txt +25 -9
  332. package/opencode/arcs/skills/brainstorming/SKILL.md +65 -105
  333. package/opencode/arcs/skills/deep-pr-review/SKILL.md +5 -5
  334. package/opencode/arcs/skills/deep-pr-review/review-template.md +1 -1
  335. package/opencode/arcs/skills/enriching-codegraph-proposals/SKILL.md +17 -18
  336. package/opencode/arcs/skills/executing-plans/SKILL.md +26 -234
  337. package/opencode/arcs/skills/implementation/SKILL.md +61 -0
  338. package/opencode/arcs/skills/init-project/SKILL.md +16 -15
  339. package/opencode/arcs/skills/install-claude-code-hook/SKILL.md +143 -0
  340. package/opencode/arcs/skills/systematic-debugging/SKILL.md +7 -7
  341. package/opencode/arcs/skills/test-driven-development/SKILL.md +1 -1
  342. package/opencode/arcs/skills/to-diagram/SKILL.md +8 -3
  343. package/opencode/arcs/skills/writing-knowledge/SKILL.md +7 -6
  344. package/opencode/arcs/skills/writing-plans/SKILL.md +80 -130
  345. package/opencode/arcs/skills/writing-plans/plan-document-reviewer-prompt.md +38 -30
  346. package/package.json +14 -6
  347. package/scripts/build-opencode-bundle.mjs +22 -7
  348. package/scripts/claude-code-session-hook.mjs +171 -0
  349. package/scripts/deploy-claudecode-bundle.mjs +206 -132
  350. package/scripts/deploy-opencode-bundle.mjs +181 -5
  351. package/scripts/lib/bundle-helpers.mjs +26 -0
  352. package/scripts/lint-bundle.mjs +123 -3
  353. package/skills/explore-dag.md +5 -3
  354. package/skills/init-project.md +27 -26
  355. package/skills/orchestrate.md +29 -13
  356. package/skills/update-docs.md +8 -13
  357. package/opencode/arcs/prompts/docs-researcher.txt +0 -79
  358. package/opencode/arcs/prompts/oncall-ops.txt +0 -85
  359. package/opencode/arcs/skills/code-agent/SKILL.md +0 -63
  360. package/opencode/arcs/skills/executing-plans/code-quality-reviewer-prompt.md +0 -57
  361. package/opencode/arcs/skills/executing-plans/implementer-prompt.md +0 -152
  362. package/opencode/arcs/skills/executing-plans/spec-reviewer-prompt.md +0 -91
  363. package/opencode/arcs/skills/quick-dev/SKILL.md +0 -52
  364. package/opencode/arcs/skills/requesting-code-review/SKILL.md +0 -59
  365. package/opencode/arcs/skills/requesting-code-review/code-reviewer.md +0 -139
  366. package/opencode/arcs/skills/the-ladder/SKILL.md +0 -54
@@ -0,0 +1,468 @@
1
+ /**
2
+ * Per-run stdout event log — the durable spine of a headless `claude -p` run.
3
+ *
4
+ * Owns `sessions/{normalizedId}.run-{runId}.events.jsonl`: every byte the child
5
+ * writes to stdout lands here VERBATIM, one file line per stdout line, BEFORE
6
+ * anything parses it. That ordering is the whole point — the log is the source
7
+ * of truth and the runner's NDJSON reader is merely its first consumer, so a
8
+ * line the reader cannot parse (drifted wire format, truncated JSON, an event
9
+ * type that did not exist when this shipped) is still on disk, and a process
10
+ * that dies mid-run still leaves behind everything that arrived.
11
+ *
12
+ * Writes are synchronous (`writeSync` against an fd opened with "a") for
13
+ * exactly that reason: an async queue would only ever have *issued* the write
14
+ * before the parse, and a hard kill would lose whatever was still in flight.
15
+ * The chunks are small and few (one per stdout chunk of a single child), so the
16
+ * event-loop cost is a rounding error against a run measured in minutes.
17
+ *
18
+ * The `runId` in the filename is the SAME id the route persists as
19
+ * `currentRunId`, so the log's name and the session record can never disagree
20
+ * about which run produced it.
21
+ *
22
+ * Total by construction, like the reader it feeds: nothing here throws. A log
23
+ * that cannot be opened or written reports itself through `RunEventLogStats`
24
+ * and the run proceeds untouched — a logging failure must never fail a run.
25
+ * Reporting is the whole point: a log that hit its size cap or lost bytes to a
26
+ * short write says so on `truncated`, which rides all the way out to
27
+ * `metadata.run.eventLogTruncated`. A silent fallback here would make an empty
28
+ * log and a capped one look identical to every consumer downstream.
29
+ *
30
+ * At settle the log folds down into the transcript sidecar (assistant text plus
31
+ * one turn per `tool_use`) through `appendSessionTurn`, and older logs for the
32
+ * same session are pruned so the sessions dir cannot grow without limit.
33
+ */
34
+ import { closeSync, mkdirSync, openSync, writeSync } from "node:fs";
35
+ import { readdir, readFile, stat, unlink } from "node:fs/promises";
36
+ import { dirname, join } from "node:path";
37
+ import { appendSessionTurn, readSessionTurns } from "../utils/claude-transcript.js";
38
+ import { normalizeIdentifier } from "../utils/slug.js";
39
+ /**
40
+ * Ceiling on one run's log — a runaway child cannot fill the disk.
41
+ *
42
+ * The finished file is never LARGER than this, terminator included: the writer
43
+ * refuses a chunk that would take it TO the cap (`>=`, not `>`), leaving the one
44
+ * byte `flush()` may still need. The off-by-one that leaves matters because
45
+ * `foldRunEventLog` refuses to read anything past this size — a writer allowed
46
+ * to land on exactly the cap and then add a terminator produces a file its own
47
+ * fold silently discards.
48
+ *
49
+ * Reaching it does not close the log: only the crossing chunk is refused, later
50
+ * chunks that still fit are still written, and `RunEventLogStats.truncated`
51
+ * reports that bytes are missing. The file always ends on a line boundary, so an
52
+ * offset-based tail never reads half a record.
53
+ */
54
+ export const RUN_EVENT_LOG_MAX_BYTES = 32 * 1024 * 1024;
55
+ /**
56
+ * How many event logs a single session keeps. Count-based rather than
57
+ * age-based: a count is a hard bound (N logs per session, at most
58
+ * RUN_EVENT_LOG_MAX_BYTES each), while an age window still admits unbounded
59
+ * growth from a session that runs in a tight loop.
60
+ */
61
+ export const RUN_EVENT_LOG_RETENTION = 5;
62
+ const LOG_SUFFIX = ".events.jsonl";
63
+ const NEWLINE = 0x0a;
64
+ /** The only byte the log ever adds of its own: a line terminator. */
65
+ const TERMINATOR = Buffer.from("\n", "utf-8");
66
+ /**
67
+ * Filename-safe form of a run id. The id reaches a path, so it is sanitized
68
+ * rather than trusted: anything outside `[A-Za-z0-9_-]` (`/`, `.`, `..`) becomes
69
+ * `-` before it can traverse out of the sessions dir.
70
+ */
71
+ export function runEventLogSegment(runId) {
72
+ const safe = runId.replace(/[^A-Za-z0-9_-]/g, "-").slice(0, 64);
73
+ return safe === "" ? "unknown" : safe;
74
+ }
75
+ /**
76
+ * Log path for one run. Keys on the session's canonical `normalizedId` exactly
77
+ * as the transcript sidecar does, so both files for a session sort together and
78
+ * neither can be derived from a raw route id.
79
+ */
80
+ export function runEventLogPath(projectDir, sessionId, runId) {
81
+ const name = `${normalizeIdentifier(sessionId)}.run-${runEventLogSegment(runId)}${LOG_SUFFIX}`;
82
+ return join(projectDir, "sessions", name);
83
+ }
84
+ /** The handle a run with no log target gets — every method is a no-op. */
85
+ const NOOP_HANDLE = {
86
+ path: "",
87
+ push() { },
88
+ flush() { },
89
+ close() {
90
+ return { lines: 0, bytes: 0, truncated: false };
91
+ },
92
+ };
93
+ /**
94
+ * Opens (creating) the run's log and returns a write-through handle.
95
+ *
96
+ * The file is created up front, so a run that produces no stdout at all — a
97
+ * child killed at its deadline before it spoke, an immediate non-zero exit —
98
+ * still leaves the log behind. `undefined` target yields the no-op handle, which
99
+ * is how the runner stays usable without a project dir (tests, and any caller
100
+ * that does not want a log).
101
+ */
102
+ export function openRunEventLog(target) {
103
+ if (target === undefined)
104
+ return NOOP_HANDLE;
105
+ const path = runEventLogPath(target.projectDir, target.sessionId, target.runId);
106
+ let fd = null;
107
+ let lines = 0;
108
+ let bytes = 0;
109
+ let truncated = false;
110
+ let closed = false;
111
+ let endsWithNewline = true;
112
+ /**
113
+ * Bytes were dropped part-way through a record, so the stream now continues
114
+ * INSIDE a line this file does not have. Appending those bytes would splice
115
+ * the tail of a record the log never took onto whatever precedes it and emit
116
+ * a line the child never wrote, so they are dropped until the next newline.
117
+ */
118
+ let resyncing = false;
119
+ let error;
120
+ const note = (err) => {
121
+ if (error === undefined)
122
+ error = String(err);
123
+ };
124
+ try {
125
+ mkdirSync(dirname(path), { recursive: true });
126
+ // "a" — the kernel appends at every write, so nothing here has to track a
127
+ // file position and a concurrent reader (the tail) can never see a hole.
128
+ fd = openSync(path, "a");
129
+ }
130
+ catch (err) {
131
+ note(err);
132
+ }
133
+ const stats = () => ({
134
+ lines,
135
+ bytes,
136
+ truncated,
137
+ ...(error !== undefined && { error }),
138
+ });
139
+ /**
140
+ * Appends `buf` whole, returning how many of its bytes actually landed.
141
+ *
142
+ * `writeSync` may return SHORT — a signal interrupting the syscall (EINTR), a
143
+ * filesystem that ran out of room mid-buffer (ENOSPC) — and its return value
144
+ * is the only place that ever shows. Discarding it emits half a record while
145
+ * counting a whole one, which breaks "always ends on a line boundary" exactly
146
+ * when the disk is full. So the loop keeps writing while the fd makes
147
+ * progress, and reports precisely how far it got. `n <= 0` ends the loop
148
+ * rather than spinning on an fd that has stopped accepting bytes.
149
+ */
150
+ const writeAll = (handle, buf) => {
151
+ let written = 0;
152
+ while (written < buf.length) {
153
+ let n;
154
+ try {
155
+ n = writeSync(handle, buf, written, buf.length - written);
156
+ }
157
+ catch (err) {
158
+ note(err);
159
+ break;
160
+ }
161
+ if (n <= 0)
162
+ break;
163
+ written += n;
164
+ }
165
+ return written;
166
+ };
167
+ /** Counts what landed: bytes, whole lines, and where the file now ends. */
168
+ const account = (buf) => {
169
+ if (buf.length === 0)
170
+ return;
171
+ bytes += buf.length;
172
+ // Native indexOf rather than a per-byte loop: a megabyte chunk must not
173
+ // cost a million iterations on the event loop.
174
+ for (let at = buf.indexOf(NEWLINE); at !== -1; at = buf.indexOf(NEWLINE, at + 1)) {
175
+ lines += 1;
176
+ }
177
+ endsWithNewline = buf[buf.length - 1] === NEWLINE;
178
+ };
179
+ /**
180
+ * Closes a line the child left open. The only byte the log adds of its own,
181
+ * and only when the file would otherwise not end on a line boundary — an
182
+ * offset-based tail would mis-frame the last record without it.
183
+ *
184
+ * Runs at flush() AND the instant a chunk is refused or lands short, not just
185
+ * at close: after a gap in the stream the next accepted chunk must start its
186
+ * own line rather than extend the fragment before the gap.
187
+ *
188
+ * The terminator write can itself fail, and failing SILENTLY is how a
189
+ * fabricated line survives every other guard here: the file is left
190
+ * un-line-closed with `resyncing` unset, so an fd that recovers splices the
191
+ * next chunk onto the open fragment. A terminator that does not land therefore
192
+ * sets BOTH flags — `truncated` because the file is no longer line-framed, and
193
+ * `resyncing` because nothing may extend that fragment ever again.
194
+ */
195
+ const terminate = (handle) => {
196
+ if (endsWithNewline || bytes === 0)
197
+ return;
198
+ if (writeAll(handle, TERMINATOR) !== TERMINATOR.length) {
199
+ truncated = true;
200
+ resyncing = true;
201
+ return;
202
+ }
203
+ account(TERMINATOR);
204
+ };
205
+ return {
206
+ path,
207
+ push(chunk) {
208
+ if (fd === null || closed)
209
+ return;
210
+ let buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf-8");
211
+ if (buf.length === 0)
212
+ return;
213
+ if (resyncing) {
214
+ const at = buf.indexOf(NEWLINE);
215
+ // Still inside the record whose bytes were dropped — all of it belongs
216
+ // to that record, none of it is a line this file may claim to hold.
217
+ if (at === -1)
218
+ return;
219
+ buf = buf.subarray(at + 1);
220
+ resyncing = false;
221
+ // The stream is back at a record start, but the FILE may not be: a
222
+ // terminator that failed AT the gap left an open fragment behind, and
223
+ // knowing where the stream resumed does nothing about it. Close it here,
224
+ // before any of these bytes can land on it — the two questions are
225
+ // different and only this one keeps the next whole record off the
226
+ // fragment. A no-op whenever the file already ends on a boundary.
227
+ terminate(fd);
228
+ // Still open: the fd will not take even one byte, so stay resynced (a
229
+ // failed terminate re-arms it) and drop this record too. A fabricated
230
+ // line is not detectable downstream; a missing one is.
231
+ if (resyncing)
232
+ return;
233
+ if (buf.length === 0)
234
+ return;
235
+ }
236
+ if (bytes + buf.length >= RUN_EVENT_LOG_MAX_BYTES) {
237
+ // The CROSSING chunk is refused whole — never half a record — but the
238
+ // log stays open. Returning early here for the rest of the run turned
239
+ // one oversized chunk into a 0-byte file; now every later chunk that
240
+ // still fits is still kept, and `truncated` is what says the file is no
241
+ // longer the whole stream. `>=` reserves the byte terminate() may add,
242
+ // so the finished file never exceeds the size the fold agrees to read.
243
+ truncated = true;
244
+ // The dropped bytes end mid-record unless the chunk's own last byte was
245
+ // a terminator; only then does the next chunk start a fresh line.
246
+ resyncing = buf[buf.length - 1] !== NEWLINE;
247
+ terminate(fd);
248
+ return;
249
+ }
250
+ const written = writeAll(fd, buf);
251
+ account(buf.subarray(0, written));
252
+ if (written === buf.length)
253
+ return;
254
+ // A short write: this record is on disk in part only and the stream
255
+ // continues from bytes that are gone. Same treatment as the cap — say the
256
+ // file is incomplete, close the half-written line, and skip to the next
257
+ // boundary instead of splicing the next chunk onto a fragment.
258
+ truncated = true;
259
+ // The lost bytes are `buf[written..]`, so the stream stands exactly where
260
+ // it does after a refusal: at `buf`'s last byte. Same rule as the cap,
261
+ // deliberately — hardcoding a resync here is safe in direction but throws
262
+ // away a whole record that begins at a record boundary, for nothing.
263
+ resyncing = buf[buf.length - 1] !== NEWLINE;
264
+ terminate(fd);
265
+ },
266
+ flush() {
267
+ if (fd === null || closed)
268
+ return;
269
+ terminate(fd);
270
+ },
271
+ close() {
272
+ if (fd !== null && !closed) {
273
+ try {
274
+ closeSync(fd);
275
+ }
276
+ catch (err) {
277
+ note(err);
278
+ }
279
+ }
280
+ closed = true;
281
+ return stats();
282
+ },
283
+ };
284
+ }
285
+ const EMPTY_FOLD = {
286
+ appended: 0,
287
+ alreadyFolded: false,
288
+ assistantTextFolded: false,
289
+ };
290
+ function isBlock(value) {
291
+ return typeof value === "object" && value !== null && !Array.isArray(value);
292
+ }
293
+ /**
294
+ * Turns one stream-json `assistant` event yields, in content-block order.
295
+ *
296
+ * Consecutive text blocks coalesce into one turn; every `tool_use` block gets
297
+ * its own turn (unlike the transcript mirror, which keeps only the first) so a
298
+ * message that fans out to three tools reads as three rows. Only completed
299
+ * `assistant` messages are folded: `stream_event` deltas repeat their text and
300
+ * the terminal `result` repeats the final message, so both would duplicate.
301
+ */
302
+ function foldAssistantEvent(event) {
303
+ const message = event.message;
304
+ if (!isBlock(message))
305
+ return [];
306
+ const content = message.content;
307
+ if (typeof content === "string")
308
+ return content === "" ? [] : [{ text: content }];
309
+ if (!Array.isArray(content))
310
+ return [];
311
+ const turns = [];
312
+ let text = "";
313
+ const flushText = () => {
314
+ if (text === "")
315
+ return;
316
+ turns.push({ text });
317
+ text = "";
318
+ };
319
+ for (const block of content) {
320
+ if (!isBlock(block))
321
+ continue;
322
+ if (block.type === "text" && typeof block.text === "string") {
323
+ text += block.text;
324
+ continue;
325
+ }
326
+ if (block.type === "tool_use" && typeof block.name === "string") {
327
+ flushText();
328
+ turns.push({ text: "", tool: { name: block.name } });
329
+ }
330
+ }
331
+ flushText();
332
+ return turns;
333
+ }
334
+ /** Every turn the log implies, in the order the child emitted them. */
335
+ function foldTurns(raw) {
336
+ const turns = [];
337
+ for (const line of raw.split("\n")) {
338
+ const text = (line.endsWith("\r") ? line.slice(0, -1) : line).trim();
339
+ if (text === "")
340
+ continue;
341
+ let value;
342
+ try {
343
+ value = JSON.parse(text);
344
+ }
345
+ catch {
346
+ continue; // unparsable lines stay in the log; they just fold to nothing
347
+ }
348
+ if (!isBlock(value) || value.type !== "assistant")
349
+ continue;
350
+ turns.push(...foldAssistantEvent(value));
351
+ }
352
+ return turns;
353
+ }
354
+ /**
355
+ * Folds a run's event log down into the session's transcript sidecar: assistant
356
+ * text plus one turn per `tool_use`, appended through `appendSessionTurn` in
357
+ * stream order, each tagged with the run id.
358
+ *
359
+ * Idempotence mechanism: the fold's OWN OUTPUT is the marker. Every appended
360
+ * turn carries `run: <runId>`, and a fold refuses as soon as the sidecar holds
361
+ * any turn tagged with that id. This was chosen over a separate marker (a
362
+ * `foldedAt` on the run record, a `.folded` sentinel file) precisely because a
363
+ * separate marker has a window: a crash between "turns appended" and "marker
364
+ * written" would re-fold and duplicate the whole run on the next settle. Here
365
+ * there is no window — the evidence and the mark are the same bytes. The cost
366
+ * is at-most-once rather than exactly-once under a crash MID-fold (the turns
367
+ * already appended are tagged, so the remainder is never completed), which is
368
+ * the safe direction: a short transcript, never a doubled one.
369
+ *
370
+ * Never throws — a fold that cannot read the log or write the sidecar reports
371
+ * an empty result and the settle continues.
372
+ */
373
+ export async function foldRunEventLog(projectDir, sessionId, runId) {
374
+ try {
375
+ const path = runEventLogPath(projectDir, sessionId, runId);
376
+ const info = await stat(path);
377
+ if (!info.isFile() || info.size > RUN_EVENT_LOG_MAX_BYTES)
378
+ return EMPTY_FOLD;
379
+ // The mark IS the data: any turn already tagged with this run id means a
380
+ // previous fold got there first.
381
+ const existing = await readSessionTurns(projectDir, sessionId);
382
+ const tagged = existing.filter((turn) => turn.run === runId);
383
+ if (tagged.length > 0) {
384
+ return {
385
+ appended: 0,
386
+ alreadyFolded: true,
387
+ assistantTextFolded: tagged.some((turn) => turn.type === "assistant" && turn.text !== ""),
388
+ };
389
+ }
390
+ const turns = foldTurns(await readFile(path, "utf-8"));
391
+ if (turns.length === 0)
392
+ return EMPTY_FOLD;
393
+ let appended = 0;
394
+ let assistantTextFolded = false;
395
+ for (const turn of turns) {
396
+ // Sequential on purpose: `appendSessionTurn` mints its negative id from
397
+ // what is already on disk, so concurrent appends would collide.
398
+ await appendSessionTurn(projectDir, sessionId, {
399
+ type: "assistant",
400
+ text: turn.text,
401
+ run: runId,
402
+ ...(turn.tool !== undefined && { tool: turn.tool }),
403
+ });
404
+ appended += 1;
405
+ if (turn.tool === undefined && turn.text !== "")
406
+ assistantTextFolded = true;
407
+ }
408
+ return { appended, alreadyFolded: false, assistantTextFolded };
409
+ }
410
+ catch {
411
+ // Missing log, unreadable sidecar, a full disk — all fold to nothing.
412
+ return EMPTY_FOLD;
413
+ }
414
+ }
415
+ // ---------------------------------------------------------------------------
416
+ // Retention
417
+ // ---------------------------------------------------------------------------
418
+ /**
419
+ * Keeps the newest `keep` event logs for one session and deletes the rest.
420
+ *
421
+ * Called at EVERY settle (after the fold), so the log that just settled is
422
+ * always among the survivors and the sessions dir is bounded at `keep` logs per
423
+ * session no matter how many runs a session accumulates. "Every settle" means
424
+ * the startup orphan sweep too (`settleOrphanedRuns`): a server that dies
425
+ * mid-run never reaches the route's write-back, so without that call site a
426
+ * session whose runs are always interrupted grows one capped log per run
427
+ * forever. `keep: 0` drops them all — what session deletion uses.
428
+ *
429
+ * Never throws; returns how many files it removed.
430
+ */
431
+ export async function pruneRunEventLogs(projectDir, sessionId, keep = RUN_EVENT_LOG_RETENTION) {
432
+ try {
433
+ const sessionsDir = join(projectDir, "sessions");
434
+ const prefix = `${normalizeIdentifier(sessionId)}.run-`;
435
+ const names = (await readdir(sessionsDir)).filter((name) => name.startsWith(prefix) &&
436
+ name.endsWith(LOG_SUFFIX) &&
437
+ name.length > prefix.length + LOG_SUFFIX.length);
438
+ if (names.length <= keep)
439
+ return 0;
440
+ const dated = await Promise.all(names.map(async (name) => {
441
+ try {
442
+ return { name, mtimeMs: (await stat(join(sessionsDir, name))).mtimeMs };
443
+ }
444
+ catch {
445
+ // Vanished under us — sort it to the front so it is dropped first.
446
+ return { name, mtimeMs: 0 };
447
+ }
448
+ }));
449
+ // Newest first; the name breaks mtime ties (same-millisecond runs) so the
450
+ // ordering is total and the prune is deterministic.
451
+ dated.sort((a, b) => b.mtimeMs - a.mtimeMs || (a.name < b.name ? 1 : -1));
452
+ let pruned = 0;
453
+ for (const entry of dated.slice(Math.max(keep, 0))) {
454
+ try {
455
+ await unlink(join(sessionsDir, entry.name));
456
+ pruned += 1;
457
+ }
458
+ catch {
459
+ // Already gone or locked — retention is best-effort.
460
+ }
461
+ }
462
+ return pruned;
463
+ }
464
+ catch {
465
+ return 0;
466
+ }
467
+ }
468
+ //# sourceMappingURL=run-event-log.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-event-log.js","sourceRoot":"","sources":["../../src/web-server/run-event-log.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"}