@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.
- package/README.md +172 -146
- package/dist/cli/agent-registry.d.ts +12 -0
- package/dist/cli/agent-registry.d.ts.map +1 -0
- package/dist/cli/agent-registry.js +67 -0
- package/dist/cli/agent-registry.js.map +1 -0
- package/dist/cli/arcs-flash.d.ts +2 -0
- package/dist/cli/arcs-flash.d.ts.map +1 -0
- package/dist/cli/arcs-flash.js +68 -0
- package/dist/cli/arcs-flash.js.map +1 -0
- package/dist/cli/arcs-orchestrate-caveman.d.ts +2 -14
- package/dist/cli/arcs-orchestrate-caveman.d.ts.map +1 -1
- package/dist/cli/arcs-orchestrate-caveman.js +6 -97
- package/dist/cli/arcs-orchestrate-caveman.js.map +1 -1
- package/dist/cli/arcs-orchestrate.d.ts +1 -1
- package/dist/cli/arcs-orchestrate.d.ts.map +1 -1
- package/dist/cli/arcs-orchestrate.js +40 -383
- package/dist/cli/arcs-orchestrate.js.map +1 -1
- package/dist/cli/bundle-installer.d.ts +10 -4
- package/dist/cli/bundle-installer.d.ts.map +1 -1
- package/dist/cli/bundle-installer.js +99 -6
- package/dist/cli/bundle-installer.js.map +1 -1
- package/dist/cli/commands/batch.js +4 -0
- package/dist/cli/commands/batch.js.map +1 -1
- package/dist/cli/commands/hooks.d.ts +76 -0
- package/dist/cli/commands/hooks.d.ts.map +1 -0
- package/dist/cli/commands/hooks.js +436 -0
- package/dist/cli/commands/hooks.js.map +1 -0
- package/dist/cli/commands/index.d.ts +2 -0
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/commands/index.js +2 -0
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/project.js +27 -0
- package/dist/cli/commands/project.js.map +1 -1
- package/dist/cli/commands/task.js +16 -1
- package/dist/cli/commands/task.js.map +1 -1
- package/dist/cli/commands/web.d.ts +2 -0
- package/dist/cli/commands/web.d.ts.map +1 -0
- package/dist/cli/commands/web.js +66 -0
- package/dist/cli/commands/web.js.map +1 -0
- package/dist/cli/config.d.ts +46 -3
- package/dist/cli/config.d.ts.map +1 -1
- package/dist/cli/config.js +95 -38
- package/dist/cli/config.js.map +1 -1
- package/dist/cli/instructions.d.ts +32 -7
- package/dist/cli/instructions.d.ts.map +1 -1
- package/dist/cli/instructions.js +99 -34
- package/dist/cli/instructions.js.map +1 -1
- package/dist/cli/orchestrator-shared-blocks.d.ts +31 -0
- package/dist/cli/orchestrator-shared-blocks.d.ts.map +1 -0
- package/dist/cli/orchestrator-shared-blocks.js +148 -0
- package/dist/cli/orchestrator-shared-blocks.js.map +1 -0
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +230 -91
- package/dist/cli/setup.js.map +1 -1
- package/dist/retrieval/index-builder.d.ts.map +1 -1
- package/dist/retrieval/index-builder.js +29 -1
- package/dist/retrieval/index-builder.js.map +1 -1
- package/dist/shared/session-vocabulary.d.ts +88 -0
- package/dist/shared/session-vocabulary.d.ts.map +1 -0
- package/dist/shared/session-vocabulary.js +114 -0
- package/dist/shared/session-vocabulary.js.map +1 -0
- package/dist/utils/claude-code-hook-install.d.ts +80 -0
- package/dist/utils/claude-code-hook-install.d.ts.map +1 -0
- package/dist/utils/claude-code-hook-install.js +211 -0
- package/dist/utils/claude-code-hook-install.js.map +1 -0
- package/dist/utils/claude-transcript.d.ts +206 -0
- package/dist/utils/claude-transcript.d.ts.map +1 -0
- package/dist/utils/claude-transcript.js +384 -0
- package/dist/utils/claude-transcript.js.map +1 -0
- package/dist/utils/diagram-generator.d.ts +1 -1
- package/dist/utils/diagram-generator.d.ts.map +1 -1
- package/dist/utils/diagram-generator.js +3 -2
- package/dist/utils/diagram-generator.js.map +1 -1
- package/dist/utils/errors.d.ts +6 -2
- package/dist/utils/errors.d.ts.map +1 -1
- package/dist/utils/errors.js +12 -0
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/git.d.ts +21 -0
- package/dist/utils/git.d.ts.map +1 -1
- package/dist/utils/git.js +65 -1
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/hook-contract.d.ts +36 -0
- package/dist/utils/hook-contract.d.ts.map +1 -0
- package/dist/utils/hook-contract.js +35 -0
- package/dist/utils/hook-contract.js.map +1 -0
- package/dist/utils/hook-token-store.d.ts +61 -0
- package/dist/utils/hook-token-store.d.ts.map +1 -0
- package/dist/utils/hook-token-store.js +86 -0
- package/dist/utils/hook-token-store.js.map +1 -0
- package/dist/utils/json-schemas.d.ts +186 -2
- package/dist/utils/json-schemas.d.ts.map +1 -1
- package/dist/utils/json-schemas.js +48 -4
- package/dist/utils/json-schemas.js.map +1 -1
- package/dist/utils/knowledge-store.d.ts +7 -1
- package/dist/utils/knowledge-store.d.ts.map +1 -1
- package/dist/utils/knowledge-store.js +97 -65
- package/dist/utils/knowledge-store.js.map +1 -1
- package/dist/utils/plan-store.d.ts +8 -0
- package/dist/utils/plan-store.d.ts.map +1 -1
- package/dist/utils/plan-store.js +98 -59
- package/dist/utils/plan-store.js.map +1 -1
- package/dist/utils/project-resolver.d.ts +8 -0
- package/dist/utils/project-resolver.d.ts.map +1 -1
- package/dist/utils/project-resolver.js +7 -2
- package/dist/utils/project-resolver.js.map +1 -1
- package/dist/utils/session-store.d.ts +339 -0
- package/dist/utils/session-store.d.ts.map +1 -0
- package/dist/utils/session-store.js +577 -0
- package/dist/utils/session-store.js.map +1 -0
- package/dist/utils/storage-utils.d.ts +31 -0
- package/dist/utils/storage-utils.d.ts.map +1 -1
- package/dist/utils/storage-utils.js +116 -5
- package/dist/utils/storage-utils.js.map +1 -1
- package/dist/utils/task-store.d.ts +7 -0
- package/dist/utils/task-store.d.ts.map +1 -1
- package/dist/utils/task-store.js +73 -23
- package/dist/utils/task-store.js.map +1 -1
- package/dist/web-client/assets/GraphCanvas-CTyf_XXQ.js +1 -0
- package/dist/web-client/assets/MarkdownEditor-af2vwQOX.js +77 -0
- package/dist/web-client/assets/abnfDiagram-VRR7QNED-CdxcKX9t.js +1 -0
- package/dist/web-client/assets/arc-Bfaogrm1.js +1 -0
- package/dist/web-client/assets/architecture-TIHT7OUA-Bt2-DmfV.js +1 -0
- package/dist/web-client/assets/architectureDiagram-ZJ3FMSHR-DOISDv6o.js +36 -0
- package/dist/web-client/assets/array-BifhSqXX.js +1 -0
- package/dist/web-client/assets/blockDiagram-677ZJIJ3-DKwtbttM.js +132 -0
- package/dist/web-client/assets/c4Diagram-LMCZKHZV-CilqK-Mm.js +10 -0
- package/dist/web-client/assets/channel-C2mb9np_.js +1 -0
- package/dist/web-client/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
- package/dist/web-client/assets/chunk-32BRIVSS-C79m1mkG.js +1 -0
- package/dist/web-client/assets/chunk-52WLFC77-C6WelGWJ.js +10 -0
- package/dist/web-client/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
- package/dist/web-client/assets/chunk-7BUUIJ7U-Bb538aSH.js +1 -0
- package/dist/web-client/assets/chunk-C7G6YPKG-DLg7ryWI.js +1 -0
- package/dist/web-client/assets/chunk-EX3LRPZG-DjWgo4gL.js +231 -0
- package/dist/web-client/assets/chunk-FWX5IMBZ-BgS9p_zy.js +2 -0
- package/dist/web-client/assets/chunk-HOUHSVGY-DuVR7dZO.js +1 -0
- package/dist/web-client/assets/chunk-ICXQ74PX-Y8DlnIJM.js +2 -0
- package/dist/web-client/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
- package/dist/web-client/assets/chunk-KEIR6QF5-DEvma7oi.js +161 -0
- package/dist/web-client/assets/chunk-MOJQB5TN-BEM3QgeD.js +88 -0
- package/dist/web-client/assets/chunk-OGEWGWER-DlM8LxGr.js +1 -0
- package/dist/web-client/assets/chunk-PUDLZKDR-c6cqNVTx.js +156 -0
- package/dist/web-client/assets/chunk-Q4XR5HBZ-C5lNmcka.js +70 -0
- package/dist/web-client/assets/chunk-RYQCIY6F-np2RyIY1.js +1 -0
- package/dist/web-client/assets/chunk-V7JOEXUC-nSswxvSG.js +206 -0
- package/dist/web-client/assets/chunk-VAUOI2AC-CqJkCkT0.js +1 -0
- package/dist/web-client/assets/chunk-VR4S4FIN-D3pFchin.js +1 -0
- package/dist/web-client/assets/chunk-WYO6CB5R-BI9c-NzI.js +125 -0
- package/dist/web-client/assets/chunk-XXDRQBXY-BvKO0v-W.js +1 -0
- package/dist/web-client/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
- package/dist/web-client/assets/chunk-ZGVPDNZ5-CKTF2kLR.js +62 -0
- package/dist/web-client/assets/chunk-ZIRB5QZD-BpeS1aZ7.js +32 -0
- package/dist/web-client/assets/classDiagram-OUVF2IWQ-CPd_w3Zr.js +1 -0
- package/dist/web-client/assets/classDiagram-v2-EOCWNBFH-CPd_w3Zr.js +1 -0
- package/dist/web-client/assets/cose-bilkent-JH36ORCC-BebHqzgp.js +1 -0
- package/dist/web-client/assets/cynefin-VYW2F7L2-BrJrnfh1.js +1 -0
- package/dist/web-client/assets/cynefinDiagram-TSTJHNR4-9jYzPWJZ.js +62 -0
- package/dist/web-client/assets/cytoscape-fcose-peAzqedC.js +1 -0
- package/dist/web-client/assets/cytoscape.esm-C3UvhD5t.js +321 -0
- package/dist/web-client/assets/dagre-Buvkdvvj.js +1 -0
- package/dist/web-client/assets/dagre-VKFMJZFB-B705Djpu.js +4 -0
- package/dist/web-client/assets/defaultLocale-BFoDCU3G.js +1 -0
- package/dist/web-client/assets/diagram-FQU43EPY-BfQAlUlJ.js +3 -0
- package/dist/web-client/assets/diagram-G47NLZAW-s1YDe06A.js +24 -0
- package/dist/web-client/assets/diagram-NH7WQ7WH-Dy3z11Hc.js +24 -0
- package/dist/web-client/assets/diagram-OA4YK3LP-Bius2xUN.js +30 -0
- package/dist/web-client/assets/diagram-WEI45ONY-D7x4VcHM.js +41 -0
- package/dist/web-client/assets/dist-B_J_HbC0.js +1 -0
- package/dist/web-client/assets/ebnfDiagram-CCIWWBDH-CBg1xrmD.js +1 -0
- package/dist/web-client/assets/erDiagram-Q63AITRT-CJRvTFvd.js +85 -0
- package/dist/web-client/assets/eventmodeling-45OFAUF4-CTKRC2Yj.js +1 -0
- package/dist/web-client/assets/flowDiagram-23GEKE2U-CaZjFyU1.js +1 -0
- package/dist/web-client/assets/ganttDiagram-NO4QXBWP-C_LsypZ4.js +292 -0
- package/dist/web-client/assets/gitGraph-TEB2WS4Q-Dx2XxdGk.js +1 -0
- package/dist/web-client/assets/gitGraphDiagram-IHSO6WYX-DiKWkGWQ.js +106 -0
- package/dist/web-client/assets/graphlib-DS17s2tU.js +1 -0
- package/dist/web-client/assets/index-CYwhkPtc.js +60 -0
- package/dist/web-client/assets/index-wSzUPvml.css +2 -0
- package/dist/web-client/assets/info-DKCQHKI2-DORwHenK.js +1 -0
- package/dist/web-client/assets/infoDiagram-FWYZ7A6U-CQecXS1E.js +2 -0
- package/dist/web-client/assets/init-C-OQMol4.js +1 -0
- package/dist/web-client/assets/ishikawaDiagram-FXEZZL3T-CWhj60Zp.js +70 -0
- package/dist/web-client/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2 +0 -0
- package/dist/web-client/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2 +0 -0
- package/dist/web-client/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
- package/dist/web-client/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
- package/dist/web-client/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2 +0 -0
- package/dist/web-client/assets/journeyDiagram-5HDEW3XC-Cj3z2U8u.js +139 -0
- package/dist/web-client/assets/kanban-definition-HUTT4EX6-DFmBRenP.js +89 -0
- package/dist/web-client/assets/katex-DolUETbr.js +257 -0
- package/dist/web-client/assets/line-C_Hxz9xb.js +1 -0
- package/dist/web-client/assets/linear-DeUiD2wj.js +1 -0
- package/dist/web-client/assets/map-BaFkSB1l.js +1 -0
- package/dist/web-client/assets/mermaid-parser.core-E3xRdzPn.js +7 -0
- package/dist/web-client/assets/mermaid.core-C2_CcotH.js +11 -0
- package/dist/web-client/assets/mindmap-definition-LN4V7U3C-Bs7VxPid.js +96 -0
- package/dist/web-client/assets/ordinal-BDEzSJ7C.js +1 -0
- package/dist/web-client/assets/packet-7NZHBO7P-D2nqso7i.js +1 -0
- package/dist/web-client/assets/path-COt_16Va.js +1 -0
- package/dist/web-client/assets/pegDiagram-2B236MQR-Cepo1sIu.js +1 -0
- package/dist/web-client/assets/pie-RZYD4A2V-Sx0IGbXt.js +1 -0
- package/dist/web-client/assets/pieDiagram-ENE6RG2P-D-PMDNhk.js +39 -0
- package/dist/web-client/assets/quadrantDiagram-ABIIQ3AL-BNGC7Fms.js +7 -0
- package/dist/web-client/assets/radar-I7S5WNFK-CFf_-2OC.js +1 -0
- package/dist/web-client/assets/railroad-3IZDKUUU-BvZeVRGh.js +1 -0
- package/dist/web-client/assets/railroad-abnf-AHOZXSZD-DnGh6x2O.js +1 -0
- package/dist/web-client/assets/railroad-ebnf-EBAXGLYW-CGfgCoaE.js +1 -0
- package/dist/web-client/assets/railroad-peg-LSFZ7HO6-BzQxYdqp.js +1 -0
- package/dist/web-client/assets/railroadDiagram-RFXS5EU6-D0iK_k84.js +1 -0
- package/dist/web-client/assets/requirementDiagram-TGXJPOKE-BPdsw9tz.js +84 -0
- package/dist/web-client/assets/rolldown-runtime-Dd_uD5pT.js +1 -0
- package/dist/web-client/assets/rough.esm-By172zw-.js +1 -0
- package/dist/web-client/assets/sankeyDiagram-HTMAVEWB-maA6ukOJ.js +40 -0
- package/dist/web-client/assets/sequenceDiagram-DBY2YBRQ-DKmAjmgr.js +162 -0
- package/dist/web-client/assets/sizeCapture-X5ZJPWSS-B0uUizjq.js +1 -0
- package/dist/web-client/assets/src-oBChb5qS.js +1 -0
- package/dist/web-client/assets/stateDiagram-2N3HPSRC-esxmzk3w.js +1 -0
- package/dist/web-client/assets/stateDiagram-v2-6OUMAXLB-hcBqlOLc.js +1 -0
- package/dist/web-client/assets/swimlanes-5IMT3BWC-DFd-wGBv.js +2 -0
- package/dist/web-client/assets/swimlanesDiagram-G3AALYLV-DbSrPBYr.js +8 -0
- package/dist/web-client/assets/timeline-definition-FHXFAJF6-C7SG8MQH.js +120 -0
- package/dist/web-client/assets/treeView-QDETBFTQ-M0rhxbs2.js +1 -0
- package/dist/web-client/assets/treemap-6X3UGDF4-BQfkQxSh.js +1 -0
- package/dist/web-client/assets/vennDiagram-L72KCM5P-CyIlb8ju.js +34 -0
- package/dist/web-client/assets/wardley-OPB4EBWU-EE-7q8M1.js +1 -0
- package/dist/web-client/assets/wardleyDiagram-EHGQE667-bY8XdYYS.js +78 -0
- package/dist/web-client/assets/xychartDiagram-FW5EYKEG-AhuXJ3de.js +7 -0
- package/dist/web-client/index.html +15 -0
- package/dist/web-server/app.d.ts +16 -0
- package/dist/web-server/app.d.ts.map +1 -0
- package/dist/web-server/app.js +77 -0
- package/dist/web-server/app.js.map +1 -0
- package/dist/web-server/claude-runner.d.ts +188 -0
- package/dist/web-server/claude-runner.d.ts.map +1 -0
- package/dist/web-server/claude-runner.js +599 -0
- package/dist/web-server/claude-runner.js.map +1 -0
- package/dist/web-server/hook-auth.d.ts +12 -0
- package/dist/web-server/hook-auth.d.ts.map +1 -0
- package/dist/web-server/hook-auth.js +36 -0
- package/dist/web-server/hook-auth.js.map +1 -0
- package/dist/web-server/index.d.ts +23 -0
- package/dist/web-server/index.d.ts.map +1 -0
- package/dist/web-server/index.js +50 -0
- package/dist/web-server/index.js.map +1 -0
- package/dist/web-server/opencode-client.d.ts +123 -0
- package/dist/web-server/opencode-client.d.ts.map +1 -0
- package/dist/web-server/opencode-client.js +514 -0
- package/dist/web-server/opencode-client.js.map +1 -0
- package/dist/web-server/permission-policy.d.ts +46 -0
- package/dist/web-server/permission-policy.d.ts.map +1 -0
- package/dist/web-server/permission-policy.js +96 -0
- package/dist/web-server/permission-policy.js.map +1 -0
- package/dist/web-server/prompt-assembly.d.ts +454 -0
- package/dist/web-server/prompt-assembly.d.ts.map +1 -0
- package/dist/web-server/prompt-assembly.js +1122 -0
- package/dist/web-server/prompt-assembly.js.map +1 -0
- package/dist/web-server/respond.d.ts +33 -0
- package/dist/web-server/respond.d.ts.map +1 -0
- package/dist/web-server/respond.js +79 -0
- package/dist/web-server/respond.js.map +1 -0
- package/dist/web-server/routes/collections.d.ts +11 -0
- package/dist/web-server/routes/collections.d.ts.map +1 -0
- package/dist/web-server/routes/collections.js +217 -0
- package/dist/web-server/routes/collections.js.map +1 -0
- package/dist/web-server/routes/discovery.d.ts +7 -0
- package/dist/web-server/routes/discovery.d.ts.map +1 -0
- package/dist/web-server/routes/discovery.js +159 -0
- package/dist/web-server/routes/discovery.js.map +1 -0
- package/dist/web-server/routes/events.d.ts +6 -0
- package/dist/web-server/routes/events.d.ts.map +1 -0
- package/dist/web-server/routes/events.js +25 -0
- package/dist/web-server/routes/events.js.map +1 -0
- package/dist/web-server/routes/hook-events.d.ts +44 -0
- package/dist/web-server/routes/hook-events.d.ts.map +1 -0
- package/dist/web-server/routes/hook-events.js +320 -0
- package/dist/web-server/routes/hook-events.js.map +1 -0
- package/dist/web-server/routes/projects.d.ts +7 -0
- package/dist/web-server/routes/projects.d.ts.map +1 -0
- package/dist/web-server/routes/projects.js +272 -0
- package/dist/web-server/routes/projects.js.map +1 -0
- package/dist/web-server/routes/sessions.d.ts +18 -0
- package/dist/web-server/routes/sessions.d.ts.map +1 -0
- package/dist/web-server/routes/sessions.js +1298 -0
- package/dist/web-server/routes/sessions.js.map +1 -0
- package/dist/web-server/routes/workspace.d.ts +27 -0
- package/dist/web-server/routes/workspace.d.ts.map +1 -0
- package/dist/web-server/routes/workspace.js +280 -0
- package/dist/web-server/routes/workspace.js.map +1 -0
- package/dist/web-server/run-event-log.d.ts +167 -0
- package/dist/web-server/run-event-log.d.ts.map +1 -0
- package/dist/web-server/run-event-log.js +468 -0
- package/dist/web-server/run-event-log.js.map +1 -0
- package/dist/web-server/security.d.ts +7 -0
- package/dist/web-server/security.d.ts.map +1 -0
- package/dist/web-server/security.js +41 -0
- package/dist/web-server/security.js.map +1 -0
- package/dist/web-server/session-reconciler.d.ts +162 -0
- package/dist/web-server/session-reconciler.d.ts.map +1 -0
- package/dist/web-server/session-reconciler.js +363 -0
- package/dist/web-server/session-reconciler.js.map +1 -0
- package/dist/web-server/static.d.ts +17 -0
- package/dist/web-server/static.d.ts.map +1 -0
- package/dist/web-server/static.js +79 -0
- package/dist/web-server/static.js.map +1 -0
- package/dist/web-server/storage.d.ts +17 -0
- package/dist/web-server/storage.d.ts.map +1 -0
- package/dist/web-server/storage.js +42 -0
- package/dist/web-server/storage.js.map +1 -0
- package/dist/web-server/watcher.d.ts +37 -0
- package/dist/web-server/watcher.d.ts.map +1 -0
- package/dist/web-server/watcher.js +181 -0
- package/dist/web-server/watcher.js.map +1 -0
- package/dist/web-server/web-auth.d.ts +17 -0
- package/dist/web-server/web-auth.d.ts.map +1 -0
- package/dist/web-server/web-auth.js +33 -0
- package/dist/web-server/web-auth.js.map +1 -0
- package/dist/web-server/web-token.d.ts +39 -0
- package/dist/web-server/web-token.d.ts.map +1 -0
- package/dist/web-server/web-token.js +71 -0
- package/dist/web-server/web-token.js.map +1 -0
- package/opencode/arcs/bundle-runtime.json +5 -13
- package/opencode/arcs/manifest.json +215 -151
- package/opencode/arcs/prompts/arcs-docs.txt +53 -47
- package/opencode/arcs/prompts/arcs-flash.txt +190 -0
- package/opencode/arcs/prompts/arcs-orchestrate-caveman.txt +116 -422
- package/opencode/arcs/prompts/arcs-orchestrate.txt +114 -341
- package/opencode/arcs/prompts/code-reviewer.txt +37 -98
- package/opencode/arcs/prompts/devil-advocate.txt +44 -115
- package/opencode/arcs/prompts/graph-explorer.txt +31 -179
- package/opencode/arcs/prompts/software-engineer.txt +24 -6
- package/opencode/arcs/prompts/tech-architect.txt +25 -9
- package/opencode/arcs/skills/brainstorming/SKILL.md +65 -105
- package/opencode/arcs/skills/deep-pr-review/SKILL.md +5 -5
- package/opencode/arcs/skills/deep-pr-review/review-template.md +1 -1
- package/opencode/arcs/skills/enriching-codegraph-proposals/SKILL.md +17 -18
- package/opencode/arcs/skills/executing-plans/SKILL.md +26 -234
- package/opencode/arcs/skills/implementation/SKILL.md +61 -0
- package/opencode/arcs/skills/init-project/SKILL.md +16 -15
- package/opencode/arcs/skills/install-claude-code-hook/SKILL.md +143 -0
- package/opencode/arcs/skills/systematic-debugging/SKILL.md +7 -7
- package/opencode/arcs/skills/test-driven-development/SKILL.md +1 -1
- package/opencode/arcs/skills/to-diagram/SKILL.md +8 -3
- package/opencode/arcs/skills/writing-knowledge/SKILL.md +7 -6
- package/opencode/arcs/skills/writing-plans/SKILL.md +80 -130
- package/opencode/arcs/skills/writing-plans/plan-document-reviewer-prompt.md +38 -30
- package/package.json +14 -6
- package/scripts/build-opencode-bundle.mjs +22 -7
- package/scripts/claude-code-session-hook.mjs +171 -0
- package/scripts/deploy-claudecode-bundle.mjs +206 -132
- package/scripts/deploy-opencode-bundle.mjs +181 -5
- package/scripts/lib/bundle-helpers.mjs +26 -0
- package/scripts/lint-bundle.mjs +123 -3
- package/skills/explore-dag.md +5 -3
- package/skills/init-project.md +27 -26
- package/skills/orchestrate.md +29 -13
- package/skills/update-docs.md +8 -13
- package/opencode/arcs/prompts/docs-researcher.txt +0 -79
- package/opencode/arcs/prompts/oncall-ops.txt +0 -85
- package/opencode/arcs/skills/code-agent/SKILL.md +0 -63
- package/opencode/arcs/skills/executing-plans/code-quality-reviewer-prompt.md +0 -57
- package/opencode/arcs/skills/executing-plans/implementer-prompt.md +0 -152
- package/opencode/arcs/skills/executing-plans/spec-reviewer-prompt.md +0 -91
- package/opencode/arcs/skills/quick-dev/SKILL.md +0 -52
- package/opencode/arcs/skills/requesting-code-review/SKILL.md +0 -59
- package/opencode/arcs/skills/requesting-code-review/code-reviewer.md +0 -139
- package/opencode/arcs/skills/the-ladder/SKILL.md +0 -54
|
@@ -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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/web-server/storage.ts"],"names":[],"mappings":"AAAA,qEAAqE;AAErE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAiB,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE5D,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE5D,sEAAsE;AACtE,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,QAAgB,EAAE,OAAe;IACrE,MAAM,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,eAAe,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;AACrE,CAAC;AAED,sEAAsE;AACtE,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,QAAgB;IACrD,MAAM,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC,CAAC;AACnE,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAI,SAAmB,EAAE,EAAwB;IAClF,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAE/C,MAAM,OAAO,GAAG,KAAK,EAAE,KAAa,EAAc,EAAE;QAClD,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;QAChC,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO,EAAE,EAAE,CAAC;QACxC,OAAO,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;IACtD,CAAC,CAAC;IAEF,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,OAAe,EACf,MAA8C;IAE9C,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IACnD,OAAO,QAAQ,CAAC,YAAY,EAAE,KAAK,IAAI,EAAE;QACvC,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;QAC7C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;QACtC,MAAM,eAAe,CAAC,YAAY,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;QAC9E,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Data-directory watcher for the web server.
|
|
3
|
+
*
|
|
4
|
+
* Emits debounced, classified change events over the ARCS data dir so the web
|
|
5
|
+
* UI can live-refresh when the CLI (or another agent) mutates the DAG.
|
|
6
|
+
* Uses recursive fs.watch when available (Node >= 20 on Linux), falling back
|
|
7
|
+
* to per-directory watchers otherwise.
|
|
8
|
+
*/
|
|
9
|
+
export interface ChangeEvent {
|
|
10
|
+
type: "changed";
|
|
11
|
+
slug: string | null;
|
|
12
|
+
area: "root" | "knowledge" | "tasks" | "plans" | "proposals" | "sessions" | "docs" | "meta" | "other";
|
|
13
|
+
path: string;
|
|
14
|
+
at: string;
|
|
15
|
+
}
|
|
16
|
+
type Listener = (event: ChangeEvent) => void;
|
|
17
|
+
export declare function onDataChange(listener: Listener): () => void;
|
|
18
|
+
/**
|
|
19
|
+
* Classifies a data-dir-relative path into a change area + project slug.
|
|
20
|
+
* Returns null for paths outside the project DAG (e.g. tokens/, config.json).
|
|
21
|
+
*/
|
|
22
|
+
export declare function classifyChange(relativePath: string): {
|
|
23
|
+
slug: string | null;
|
|
24
|
+
area: ChangeEvent["area"];
|
|
25
|
+
} | null;
|
|
26
|
+
/**
|
|
27
|
+
* Starts watching the data dir. Idempotent — safe to call per app instance.
|
|
28
|
+
*/
|
|
29
|
+
export declare function startWatcher(dataDir: string, options?: {
|
|
30
|
+
forceFallback?: boolean;
|
|
31
|
+
}): "recursive" | "fallback";
|
|
32
|
+
/**
|
|
33
|
+
* Stops all watchers (test cleanup).
|
|
34
|
+
*/
|
|
35
|
+
export declare function stopWatcher(): void;
|
|
36
|
+
export {};
|
|
37
|
+
//# sourceMappingURL=watcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watcher.d.ts","sourceRoot":"","sources":["../../src/web-server/watcher.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EACA,MAAM,GACN,WAAW,GACX,OAAO,GACP,OAAO,GACP,WAAW,GACX,UAAU,GACV,MAAM,GACN,MAAM,GACN,OAAO,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,KAAK,QAAQ,GAAG,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;AAY7C,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,IAAI,CAK3D;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,YAAY,EAAE,MAAM,GACnB;IAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;CAAE,GAAG,IAAI,CAkB3D;AAiFD;;GAEG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAA;CAAO,GACxC,WAAW,GAAG,UAAU,CAoB1B;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAgBlC"}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Data-directory watcher for the web server.
|
|
3
|
+
*
|
|
4
|
+
* Emits debounced, classified change events over the ARCS data dir so the web
|
|
5
|
+
* UI can live-refresh when the CLI (or another agent) mutates the DAG.
|
|
6
|
+
* Uses recursive fs.watch when available (Node >= 20 on Linux), falling back
|
|
7
|
+
* to per-directory watchers otherwise.
|
|
8
|
+
*/
|
|
9
|
+
import { existsSync, readdirSync, watch } from "node:fs";
|
|
10
|
+
import { join } from "node:path";
|
|
11
|
+
const listeners = new Set();
|
|
12
|
+
const watchers = [];
|
|
13
|
+
const watchedDirs = new Set();
|
|
14
|
+
const pending = new Map();
|
|
15
|
+
let started = false;
|
|
16
|
+
let mode = null;
|
|
17
|
+
let fallbackDataDir = null;
|
|
18
|
+
let fallbackRescanTimer = null;
|
|
19
|
+
export function onDataChange(listener) {
|
|
20
|
+
listeners.add(listener);
|
|
21
|
+
return () => {
|
|
22
|
+
listeners.delete(listener);
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Classifies a data-dir-relative path into a change area + project slug.
|
|
27
|
+
* Returns null for paths outside the project DAG (e.g. tokens/, config.json).
|
|
28
|
+
*/
|
|
29
|
+
export function classifyChange(relativePath) {
|
|
30
|
+
const rel = relativePath.replace(/\\/g, "/");
|
|
31
|
+
if (rel === "meta.json")
|
|
32
|
+
return { slug: null, area: "root" };
|
|
33
|
+
const match = rel.match(/^projects\/([^/]+)(?:\/(.*))?$/);
|
|
34
|
+
if (!match || !match[1])
|
|
35
|
+
return null;
|
|
36
|
+
const slug = match[1];
|
|
37
|
+
const rest = match[2] ?? "";
|
|
38
|
+
if (rest === "knowledge" || rest.startsWith("knowledge/"))
|
|
39
|
+
return { slug, area: "knowledge" };
|
|
40
|
+
if (rest === "tasks" || rest.startsWith("tasks/") || rest === "tasks.md")
|
|
41
|
+
return { slug, area: "tasks" };
|
|
42
|
+
if (rest === "plans" || rest.startsWith("plans/"))
|
|
43
|
+
return { slug, area: "plans" };
|
|
44
|
+
if (rest === "proposals" || rest.startsWith("proposals/"))
|
|
45
|
+
return { slug, area: "proposals" };
|
|
46
|
+
if (rest === "sessions" || rest.startsWith("sessions/"))
|
|
47
|
+
return { slug, area: "sessions" };
|
|
48
|
+
if (rest === "meta.json")
|
|
49
|
+
return { slug, area: "meta" };
|
|
50
|
+
if (rest.endsWith(".md"))
|
|
51
|
+
return { slug, area: "docs" };
|
|
52
|
+
return { slug, area: "other" };
|
|
53
|
+
}
|
|
54
|
+
function emit(relativePath) {
|
|
55
|
+
const classified = classifyChange(relativePath);
|
|
56
|
+
if (!classified)
|
|
57
|
+
return;
|
|
58
|
+
// Debounce per (slug, area) — a store write touches several files at once.
|
|
59
|
+
const key = `${classified.slug ?? "_"}:${classified.area}`;
|
|
60
|
+
const existing = pending.get(key);
|
|
61
|
+
if (existing)
|
|
62
|
+
clearTimeout(existing);
|
|
63
|
+
pending.set(key, setTimeout(() => {
|
|
64
|
+
pending.delete(key);
|
|
65
|
+
const event = {
|
|
66
|
+
type: "changed",
|
|
67
|
+
slug: classified.slug,
|
|
68
|
+
area: classified.area,
|
|
69
|
+
path: relativePath,
|
|
70
|
+
at: new Date().toISOString(),
|
|
71
|
+
};
|
|
72
|
+
for (const listener of listeners) {
|
|
73
|
+
try {
|
|
74
|
+
listener(event);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
// Listener failures must not break the watcher.
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}, 250));
|
|
81
|
+
}
|
|
82
|
+
function watchDir(absDir, relPrefix) {
|
|
83
|
+
if (!existsSync(absDir) || watchedDirs.has(absDir))
|
|
84
|
+
return;
|
|
85
|
+
try {
|
|
86
|
+
const watcher = watch(absDir, (eventType, filename) => {
|
|
87
|
+
if (!filename)
|
|
88
|
+
return;
|
|
89
|
+
emit(relPrefix ? `${relPrefix}/${filename}` : filename);
|
|
90
|
+
if (eventType === "rename" && fallbackDataDir)
|
|
91
|
+
scheduleFallbackRescan();
|
|
92
|
+
});
|
|
93
|
+
watchedDirs.add(absDir);
|
|
94
|
+
watchers.push(watcher);
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
// Best-effort watching; ignore individual directory failures.
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
function scheduleFallbackRescan() {
|
|
101
|
+
if (!fallbackDataDir)
|
|
102
|
+
return;
|
|
103
|
+
if (fallbackRescanTimer)
|
|
104
|
+
clearTimeout(fallbackRescanTimer);
|
|
105
|
+
fallbackRescanTimer = setTimeout(() => {
|
|
106
|
+
fallbackRescanTimer = null;
|
|
107
|
+
if (fallbackDataDir)
|
|
108
|
+
startFallbackWatchers(fallbackDataDir);
|
|
109
|
+
}, 100);
|
|
110
|
+
}
|
|
111
|
+
function startFallbackWatchers(dataDir) {
|
|
112
|
+
fallbackDataDir = dataDir;
|
|
113
|
+
watchDir(dataDir, "");
|
|
114
|
+
const projectsRoot = join(dataDir, "projects");
|
|
115
|
+
watchDir(projectsRoot, "projects");
|
|
116
|
+
let slugs = [];
|
|
117
|
+
try {
|
|
118
|
+
slugs = readdirSync(projectsRoot, { withFileTypes: true })
|
|
119
|
+
.filter((e) => e.isDirectory())
|
|
120
|
+
.map((e) => e.name);
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
for (const slug of slugs) {
|
|
126
|
+
const projectAbs = join(projectsRoot, slug);
|
|
127
|
+
watchDir(projectAbs, `projects/${slug}`);
|
|
128
|
+
for (const sub of ["knowledge", "tasks", "plans", "proposals", "sessions"]) {
|
|
129
|
+
watchDir(join(projectAbs, sub), `projects/${slug}/${sub}`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Starts watching the data dir. Idempotent — safe to call per app instance.
|
|
135
|
+
*/
|
|
136
|
+
export function startWatcher(dataDir, options = {}) {
|
|
137
|
+
if (started)
|
|
138
|
+
return mode ?? "fallback";
|
|
139
|
+
started = true;
|
|
140
|
+
if (!options.forceFallback) {
|
|
141
|
+
try {
|
|
142
|
+
const watcher = watch(dataDir, { recursive: true }, (_eventType, filename) => {
|
|
143
|
+
if (filename)
|
|
144
|
+
emit(filename);
|
|
145
|
+
});
|
|
146
|
+
watchers.push(watcher);
|
|
147
|
+
mode = "recursive";
|
|
148
|
+
return mode;
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
// Recursive watch unsupported — fall back to per-directory watchers.
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
startFallbackWatchers(dataDir);
|
|
155
|
+
mode = "fallback";
|
|
156
|
+
return mode;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Stops all watchers (test cleanup).
|
|
160
|
+
*/
|
|
161
|
+
export function stopWatcher() {
|
|
162
|
+
for (const watcher of watchers.splice(0)) {
|
|
163
|
+
try {
|
|
164
|
+
watcher.close();
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
// ignore
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
for (const timeout of pending.values())
|
|
171
|
+
clearTimeout(timeout);
|
|
172
|
+
if (fallbackRescanTimer)
|
|
173
|
+
clearTimeout(fallbackRescanTimer);
|
|
174
|
+
pending.clear();
|
|
175
|
+
watchedDirs.clear();
|
|
176
|
+
started = false;
|
|
177
|
+
mode = null;
|
|
178
|
+
fallbackDataDir = null;
|
|
179
|
+
fallbackRescanTimer = null;
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=watcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watcher.js","sourceRoot":"","sources":["../../src/web-server/watcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `X-ARCS-Token` gate for mutating API routes.
|
|
3
|
+
*
|
|
4
|
+
* Layered on top of (never instead of) the global loopback-only
|
|
5
|
+
* `secureLocalRequest`: loopback proves the caller is on this machine, the
|
|
6
|
+
* token proves it is a page this server itself served (see web-token.ts).
|
|
7
|
+
*
|
|
8
|
+
* Deny-by-default across `/api/*` rather than an allowlist of known paths: a
|
|
9
|
+
* mutating route added later is gated the moment it is registered, with exactly
|
|
10
|
+
* one exemption — `/api/hook/*`, whose caller is a Claude Code hook subprocess
|
|
11
|
+
* and not the browser, and which carries its own independent bearer token
|
|
12
|
+
* (hook-auth.ts). Reads are untouched: every GET/HEAD/OPTIONS passes straight
|
|
13
|
+
* through, so `/api/events` and the whole read surface behave exactly as before.
|
|
14
|
+
*/
|
|
15
|
+
import type { MiddlewareHandler } from "hono";
|
|
16
|
+
export declare const requireWebToken: MiddlewareHandler;
|
|
17
|
+
//# sourceMappingURL=web-auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-auth.d.ts","sourceRoot":"","sources":["../../src/web-server/web-auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAc9C,eAAO,MAAM,eAAe,EAAE,iBAW7B,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `X-ARCS-Token` gate for mutating API routes.
|
|
3
|
+
*
|
|
4
|
+
* Layered on top of (never instead of) the global loopback-only
|
|
5
|
+
* `secureLocalRequest`: loopback proves the caller is on this machine, the
|
|
6
|
+
* token proves it is a page this server itself served (see web-token.ts).
|
|
7
|
+
*
|
|
8
|
+
* Deny-by-default across `/api/*` rather than an allowlist of known paths: a
|
|
9
|
+
* mutating route added later is gated the moment it is registered, with exactly
|
|
10
|
+
* one exemption — `/api/hook/*`, whose caller is a Claude Code hook subprocess
|
|
11
|
+
* and not the browser, and which carries its own independent bearer token
|
|
12
|
+
* (hook-auth.ts). Reads are untouched: every GET/HEAD/OPTIONS passes straight
|
|
13
|
+
* through, so `/api/events` and the whole read surface behave exactly as before.
|
|
14
|
+
*/
|
|
15
|
+
import { fail } from "./respond.js";
|
|
16
|
+
import { verifyWebToken } from "./web-token.js";
|
|
17
|
+
/** Mirrors the mutation set in security.ts. */
|
|
18
|
+
const MUTATION_METHODS = new Set(["POST", "PUT", "PATCH", "DELETE"]);
|
|
19
|
+
/** The one prefix that authenticates with its own bearer token instead. */
|
|
20
|
+
const HOOK_PREFIX = "/api/hook/";
|
|
21
|
+
function needsWebToken(method, path) {
|
|
22
|
+
return MUTATION_METHODS.has(method.toUpperCase()) && !path.startsWith(HOOK_PREFIX);
|
|
23
|
+
}
|
|
24
|
+
export const requireWebToken = async (c, next) => {
|
|
25
|
+
if (needsWebToken(c.req.method, c.req.path) &&
|
|
26
|
+
!verifyWebToken(c.req.header("x-arcs-token") ?? "")) {
|
|
27
|
+
// A clean typed refusal, not a throw: respond.ts only maps DagError, and a
|
|
28
|
+
// missing token is an auth answer rather than a DAG failure.
|
|
29
|
+
return c.json(fail("web_unauthorized", "Missing or invalid ARCS web token"), 401);
|
|
30
|
+
}
|
|
31
|
+
await next();
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=web-auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-auth.js","sourceRoot":"","sources":["../../src/web-server/web-auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEhD,+CAA+C;AAC/C,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;AAErE,2EAA2E;AAC3E,MAAM,WAAW,GAAG,YAAY,CAAC;AAEjC,SAAS,aAAa,CAAC,MAAc,EAAE,IAAY;IACjD,OAAO,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AACrF,CAAC;AAED,MAAM,CAAC,MAAM,eAAe,GAAsB,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;IAClE,IACE,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;QACvC,CAAC,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,EACnD,CAAC;QACD,2EAA2E;QAC3E,6DAA6D;QAC7D,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,mCAAmC,CAAC,EAAE,GAAG,CAAC,CAAC;IACpF,CAAC;IAED,MAAM,IAAI,EAAE,CAAC;AACf,CAAC,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-server auth token for the browser-facing mutating API.
|
|
3
|
+
*
|
|
4
|
+
* The loopback + Origin checks in security.ts stop remote and cross-site
|
|
5
|
+
* callers, but they authenticate a NETWORK LOCATION, not a process: every other
|
|
6
|
+
* program on this machine shares localhost, and the mutating routes now spawn
|
|
7
|
+
* `claude` subprocesses. This token proves the caller is a page THIS server
|
|
8
|
+
* served — it is minted fresh at every server start and injected into the
|
|
9
|
+
* served index.html (see static.ts), so the SPA holds it from first paint and
|
|
10
|
+
* no other local process can guess it.
|
|
11
|
+
*
|
|
12
|
+
* Deliberately per-SERVER, not per-project (unlike hook-token-store, which
|
|
13
|
+
* authenticates a per-project hook install): it authenticates the browser tab,
|
|
14
|
+
* and one tab drives every project. Verification always reads the in-memory
|
|
15
|
+
* value, never the file, so a second server started against the same data dir
|
|
16
|
+
* cannot authorize requests to this one — it only replaces the on-disk copy.
|
|
17
|
+
* Exactly one token is live per PROCESS: a second createApp in the same process
|
|
18
|
+
* rotates it and every app then verifies against the newest value. ARCS runs
|
|
19
|
+
* one server per process, so that is a test-only nuance.
|
|
20
|
+
*
|
|
21
|
+
* The file exists for out-of-band consumers (scripts, tests) and is written
|
|
22
|
+
* 0o600: the token is never passed on an argv or in an env var a `ps` can read.
|
|
23
|
+
*/
|
|
24
|
+
export declare function webTokenPath(): string;
|
|
25
|
+
/**
|
|
26
|
+
* Mints this server's token, replacing any previous one, and persists it 0o600.
|
|
27
|
+
* Called once from createApp, before any route can be served: the middleware
|
|
28
|
+
* and the index.html transform both read the value it installs.
|
|
29
|
+
*/
|
|
30
|
+
export declare function mintWebToken(): string;
|
|
31
|
+
/** This server's live token, or undefined before mintWebToken() has run. */
|
|
32
|
+
export declare function currentWebToken(): string | undefined;
|
|
33
|
+
/**
|
|
34
|
+
* Constant-time token comparison. Returns false when no token has been minted
|
|
35
|
+
* yet, so a request that arrives before startup finished cannot be authorized
|
|
36
|
+
* by an empty header.
|
|
37
|
+
*/
|
|
38
|
+
export declare function verifyWebToken(candidate: string): boolean;
|
|
39
|
+
//# sourceMappingURL=web-token.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-token.d.ts","sourceRoot":"","sources":["../../src/web-server/web-token.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAkBH,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED;;;;GAIG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAerC;AAED,4EAA4E;AAC5E,wBAAgB,eAAe,IAAI,MAAM,GAAG,SAAS,CAEpD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAOzD"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-server auth token for the browser-facing mutating API.
|
|
3
|
+
*
|
|
4
|
+
* The loopback + Origin checks in security.ts stop remote and cross-site
|
|
5
|
+
* callers, but they authenticate a NETWORK LOCATION, not a process: every other
|
|
6
|
+
* program on this machine shares localhost, and the mutating routes now spawn
|
|
7
|
+
* `claude` subprocesses. This token proves the caller is a page THIS server
|
|
8
|
+
* served — it is minted fresh at every server start and injected into the
|
|
9
|
+
* served index.html (see static.ts), so the SPA holds it from first paint and
|
|
10
|
+
* no other local process can guess it.
|
|
11
|
+
*
|
|
12
|
+
* Deliberately per-SERVER, not per-project (unlike hook-token-store, which
|
|
13
|
+
* authenticates a per-project hook install): it authenticates the browser tab,
|
|
14
|
+
* and one tab drives every project. Verification always reads the in-memory
|
|
15
|
+
* value, never the file, so a second server started against the same data dir
|
|
16
|
+
* cannot authorize requests to this one — it only replaces the on-disk copy.
|
|
17
|
+
* Exactly one token is live per PROCESS: a second createApp in the same process
|
|
18
|
+
* rotates it and every app then verifies against the newest value. ARCS runs
|
|
19
|
+
* one server per process, so that is a test-only nuance.
|
|
20
|
+
*
|
|
21
|
+
* The file exists for out-of-band consumers (scripts, tests) and is written
|
|
22
|
+
* 0o600: the token is never passed on an argv or in an env var a `ps` can read.
|
|
23
|
+
*/
|
|
24
|
+
import { randomBytes, timingSafeEqual } from "node:crypto";
|
|
25
|
+
import { chmodSync, mkdirSync, writeFileSync } from "node:fs";
|
|
26
|
+
import { dirname, join } from "node:path";
|
|
27
|
+
import { getDataDir } from "../utils/paths.js";
|
|
28
|
+
import { nowISO } from "../utils/storage-utils.js";
|
|
29
|
+
const TOKEN_BYTES = 32;
|
|
30
|
+
let currentToken;
|
|
31
|
+
export function webTokenPath() {
|
|
32
|
+
return join(getDataDir(), "web-token.json");
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Mints this server's token, replacing any previous one, and persists it 0o600.
|
|
36
|
+
* Called once from createApp, before any route can be served: the middleware
|
|
37
|
+
* and the index.html transform both read the value it installs.
|
|
38
|
+
*/
|
|
39
|
+
export function mintWebToken() {
|
|
40
|
+
const token = randomBytes(TOKEN_BYTES).toString("hex");
|
|
41
|
+
const file = { token, createdAt: nowISO() };
|
|
42
|
+
const path = webTokenPath();
|
|
43
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
44
|
+
// The `mode` option only applies when writeFileSync CREATES the file, so an
|
|
45
|
+
// existing token file keeps whatever mode it had — chmod unconditionally.
|
|
46
|
+
// A world-readable token file is the exact failure this whole module exists
|
|
47
|
+
// to avoid.
|
|
48
|
+
writeFileSync(path, `${JSON.stringify(file, null, 2)}\n`, { encoding: "utf-8", mode: 0o600 });
|
|
49
|
+
chmodSync(path, 0o600);
|
|
50
|
+
currentToken = token;
|
|
51
|
+
return token;
|
|
52
|
+
}
|
|
53
|
+
/** This server's live token, or undefined before mintWebToken() has run. */
|
|
54
|
+
export function currentWebToken() {
|
|
55
|
+
return currentToken;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Constant-time token comparison. Returns false when no token has been minted
|
|
59
|
+
* yet, so a request that arrives before startup finished cannot be authorized
|
|
60
|
+
* by an empty header.
|
|
61
|
+
*/
|
|
62
|
+
export function verifyWebToken(candidate) {
|
|
63
|
+
if (!currentToken || !candidate)
|
|
64
|
+
return false;
|
|
65
|
+
const expected = Buffer.from(currentToken, "utf-8");
|
|
66
|
+
const actual = Buffer.from(candidate, "utf-8");
|
|
67
|
+
if (expected.length !== actual.length)
|
|
68
|
+
return false;
|
|
69
|
+
return timingSafeEqual(expected, actual);
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=web-token.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-token.js","sourceRoot":"","sources":["../../src/web-server/web-token.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AAQnD,MAAM,WAAW,GAAG,EAAE,CAAC;AAEvB,IAAI,YAAgC,CAAC;AAErC,MAAM,UAAU,YAAY;IAC1B,OAAO,IAAI,CAAC,UAAU,EAAE,EAAE,gBAAgB,CAAC,CAAC;AAC9C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY;IAC1B,MAAM,KAAK,GAAG,WAAW,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACvD,MAAM,IAAI,GAAiB,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,CAAC;IAC1D,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;IAE5B,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,4EAA4E;IAC5E,0EAA0E;IAC1E,4EAA4E;IAC5E,YAAY;IACZ,aAAa,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC9F,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAEvB,YAAY,GAAG,KAAK,CAAC;IACrB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,eAAe;IAC7B,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,SAAiB;IAC9C,IAAI,CAAC,YAAY,IAAI,CAAC,SAAS;QAAE,OAAO,KAAK,CAAC;IAE9C,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IACpD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAC/C,IAAI,QAAQ,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IACpD,OAAO,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AAC3C,CAAC"}
|
|
@@ -9,9 +9,6 @@
|
|
|
9
9
|
"scripts/start-server.sh",
|
|
10
10
|
"scripts/stop-server.sh"
|
|
11
11
|
],
|
|
12
|
-
"code-agent": [
|
|
13
|
-
"SKILL.md"
|
|
14
|
-
],
|
|
15
12
|
"deep-pr-review": [
|
|
16
13
|
"SKILL.md",
|
|
17
14
|
"review-template.md",
|
|
@@ -21,17 +18,13 @@
|
|
|
21
18
|
"SKILL.md"
|
|
22
19
|
],
|
|
23
20
|
"executing-plans": [
|
|
24
|
-
"SKILL.md"
|
|
25
|
-
"code-quality-reviewer-prompt.md",
|
|
26
|
-
"implementer-prompt.md",
|
|
27
|
-
"spec-reviewer-prompt.md"
|
|
21
|
+
"SKILL.md"
|
|
28
22
|
],
|
|
29
|
-
"
|
|
23
|
+
"implementation": [
|
|
30
24
|
"SKILL.md"
|
|
31
25
|
],
|
|
32
|
-
"
|
|
33
|
-
"SKILL.md"
|
|
34
|
-
"code-reviewer.md"
|
|
26
|
+
"install-claude-code-hook": [
|
|
27
|
+
"SKILL.md"
|
|
35
28
|
],
|
|
36
29
|
"systematic-debugging": [
|
|
37
30
|
"SKILL.md",
|
|
@@ -66,8 +59,7 @@
|
|
|
66
59
|
"bundle-runtime.json",
|
|
67
60
|
".opencode/plugins/arcs.js",
|
|
68
61
|
"skills/caveman-commit/SKILL.md",
|
|
69
|
-
"skills/init-project/SKILL.md"
|
|
70
|
-
"skills/the-ladder/SKILL.md"
|
|
62
|
+
"skills/init-project/SKILL.md"
|
|
71
63
|
],
|
|
72
64
|
"excludePatterns": [
|
|
73
65
|
"**/references/**",
|