@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,171 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* ARCS ↔ Claude Code session-bridge hook.
|
|
4
|
+
*
|
|
5
|
+
* Registered four times in settings.json (SessionStart, UserPromptSubmit,
|
|
6
|
+
* SessionEnd, Stop) and dispatches internally on the `hook_event_name` field
|
|
7
|
+
* Claude Code writes to stdin. Install with `arcs hooks install-claude-code
|
|
8
|
+
* <slug>`, which generates the token and prints the snippet to paste.
|
|
9
|
+
*
|
|
10
|
+
* Two of the four can put text in front of the model: SessionStart mirrors
|
|
11
|
+
* ARCS's staged environment (project, workspace, DAG position) into the new
|
|
12
|
+
* session, and UserPromptSubmit delivers messages queued from the web UI. Both
|
|
13
|
+
* emit Claude Code's `hookSpecificOutput` envelope on stdout; the other two
|
|
14
|
+
* print nothing.
|
|
15
|
+
*
|
|
16
|
+
* HARD RULE: this script never blocks the session. Any failure — ARCS not
|
|
17
|
+
* running, token rejected, timeout, malformed JSON — is swallowed, nothing is
|
|
18
|
+
* printed, and the exit code stays 0. Exit code 2 (the "block" signal) is never
|
|
19
|
+
* produced. A broken bridge must be invisible, never an obstacle to the user's
|
|
20
|
+
* actual Claude Code session.
|
|
21
|
+
*
|
|
22
|
+
* Config comes from the environment, assigned inline in the settings.json
|
|
23
|
+
* command string:
|
|
24
|
+
* ARCS_HOOK_TOKEN per-project token (required)
|
|
25
|
+
* ARCS_HOOK_SLUG ARCS project slug (required)
|
|
26
|
+
* ARCS_HOOK_URL ARCS web server URL (default http://127.0.0.1:4173)
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
// DEFAULT_URL and EVENTS are literals on purpose: this file runs standalone out
|
|
30
|
+
// of the user's settings.json and importing ARCS would give the HARD RULE above
|
|
31
|
+
// a way to fail. `src/utils/hook-contract.ts` owns the same two values for the
|
|
32
|
+
// TypeScript side, and `test/hook-contract-parity.test.ts` parses THIS source
|
|
33
|
+
// and fails if the two ever diverge — so keep the shapes greppable: a
|
|
34
|
+
// double-quoted DEFAULT_URL, and a flat `new Set([...])` of string literals.
|
|
35
|
+
const DEFAULT_URL = "http://127.0.0.1:4173";
|
|
36
|
+
/** Short by design: a hung ARCS server must not stall prompt submission. */
|
|
37
|
+
const TIMEOUT_MS = 1500;
|
|
38
|
+
const EVENTS = new Set(["SessionStart", "UserPromptSubmit", "SessionEnd", "Stop"]);
|
|
39
|
+
/**
|
|
40
|
+
* Refusal bound on a context block the server sends, in characters.
|
|
41
|
+
*
|
|
42
|
+
* The server caps the SessionStart block at 2500 (`SESSION_START_STAGE_CAP` in
|
|
43
|
+
* `src/web-server/routes/hook-events.ts`); this is the CLIENT's own limit, so a
|
|
44
|
+
* misbehaving, mismatched or hostile ARCS cannot shove an unbounded body into
|
|
45
|
+
* the head of the user's live session. Over the bound the block is dropped
|
|
46
|
+
* whole rather than clipped — a clip would sever a wrapper's closing delimiter.
|
|
47
|
+
* `test/claude-code-hook-script.test.ts` parses this literal and fails if the
|
|
48
|
+
* server's cap ever climbs above it, so the two cannot silently cross.
|
|
49
|
+
*/
|
|
50
|
+
const MAX_CONTEXT_CHARS = 4000;
|
|
51
|
+
|
|
52
|
+
/** Never rejects: an unreadable stdin yields "" and the run turns into a no-op. */
|
|
53
|
+
function readStdin() {
|
|
54
|
+
return new Promise((resolveStdin) => {
|
|
55
|
+
let raw = "";
|
|
56
|
+
let settled = false;
|
|
57
|
+
const finish = () => {
|
|
58
|
+
if (settled) return;
|
|
59
|
+
settled = true;
|
|
60
|
+
clearTimeout(timer);
|
|
61
|
+
process.stdin.destroy();
|
|
62
|
+
resolveStdin(raw);
|
|
63
|
+
};
|
|
64
|
+
const timer = setTimeout(finish, TIMEOUT_MS);
|
|
65
|
+
|
|
66
|
+
process.stdin.setEncoding("utf-8");
|
|
67
|
+
process.stdin.on("data", (chunk) => {
|
|
68
|
+
raw += chunk;
|
|
69
|
+
});
|
|
70
|
+
process.stdin.on("end", finish);
|
|
71
|
+
process.stdin.on("error", finish);
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Labelled and separated so the agent can tell queued out-of-band instructions
|
|
77
|
+
* from the prompt the user just typed.
|
|
78
|
+
*/
|
|
79
|
+
function formatQueued(messages) {
|
|
80
|
+
const body = messages.map((m, i) => `[${i + 1}] ${String(m).trim()}`).join("\n\n");
|
|
81
|
+
return `Messages queued from the ARCS web UI, delivered at this checkpoint:\n\n${body}`;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async function main() {
|
|
85
|
+
const raw = await readStdin();
|
|
86
|
+
if (!raw.trim()) return;
|
|
87
|
+
|
|
88
|
+
const event = JSON.parse(raw);
|
|
89
|
+
const eventName = event?.hook_event_name;
|
|
90
|
+
const sessionId = event?.session_id;
|
|
91
|
+
if (!EVENTS.has(eventName) || typeof sessionId !== "string" || !sessionId) return;
|
|
92
|
+
|
|
93
|
+
const token = process.env.ARCS_HOOK_TOKEN;
|
|
94
|
+
const slug = process.env.ARCS_HOOK_SLUG;
|
|
95
|
+
if (!token || !slug) return;
|
|
96
|
+
const baseUrl = (process.env.ARCS_HOOK_URL || DEFAULT_URL).replace(/\/+$/, "");
|
|
97
|
+
|
|
98
|
+
const response = await fetch(`${baseUrl}/api/hook/${encodeURIComponent(slug)}/event`, {
|
|
99
|
+
method: "POST",
|
|
100
|
+
headers: {
|
|
101
|
+
"content-type": "application/json",
|
|
102
|
+
authorization: `Bearer ${token}`,
|
|
103
|
+
},
|
|
104
|
+
body: JSON.stringify({
|
|
105
|
+
hook_event_name: eventName,
|
|
106
|
+
session_id: sessionId,
|
|
107
|
+
...(typeof event.cwd === "string" && { cwd: event.cwd }),
|
|
108
|
+
...(typeof event.source === "string" && { source: event.source }),
|
|
109
|
+
...(typeof event.reason === "string" && { reason: event.reason }),
|
|
110
|
+
...(typeof event.transcript_path === "string" && { transcript_path: event.transcript_path }),
|
|
111
|
+
}),
|
|
112
|
+
signal: AbortSignal.timeout(TIMEOUT_MS),
|
|
113
|
+
});
|
|
114
|
+
if (!response.ok) return;
|
|
115
|
+
|
|
116
|
+
// Two events can inject context: SessionStart mirrors ARCS's staged
|
|
117
|
+
// environment into the fresh session, UserPromptSubmit delivers whatever the
|
|
118
|
+
// web UI queued. SessionEnd and Stop are pure notifications and answer with
|
|
119
|
+
// empty stdout.
|
|
120
|
+
if (eventName !== "SessionStart" && eventName !== "UserPromptSubmit") return;
|
|
121
|
+
|
|
122
|
+
const envelope = await response.json();
|
|
123
|
+
|
|
124
|
+
if (eventName === "SessionStart") {
|
|
125
|
+
const staged = envelope?.data?.stagedContext;
|
|
126
|
+
// Every rejection here is a silent no-op, never a repair: an absent field,
|
|
127
|
+
// a non-string, an empty string and an oversized body all mean "ARCS has
|
|
128
|
+
// nothing usable to stage", and the session proceeds exactly as if the
|
|
129
|
+
// bridge were not installed.
|
|
130
|
+
if (typeof staged !== "string" || staged === "" || staged.length > MAX_CONTEXT_CHARS) return;
|
|
131
|
+
|
|
132
|
+
process.stdout.write(
|
|
133
|
+
JSON.stringify({
|
|
134
|
+
hookSpecificOutput: {
|
|
135
|
+
hookEventName: "SessionStart",
|
|
136
|
+
additionalContext: staged,
|
|
137
|
+
},
|
|
138
|
+
}),
|
|
139
|
+
);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const messages = envelope?.data?.queuedMessages;
|
|
144
|
+
if (!Array.isArray(messages) || messages.length === 0) return;
|
|
145
|
+
|
|
146
|
+
process.stdout.write(
|
|
147
|
+
JSON.stringify({
|
|
148
|
+
hookSpecificOutput: {
|
|
149
|
+
hookEventName: "UserPromptSubmit",
|
|
150
|
+
additionalContext: formatQueued(messages),
|
|
151
|
+
},
|
|
152
|
+
}),
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Belt and braces around the hard rule: even a bug in this file (or a stray
|
|
157
|
+
// async rejection) must not surface as a non-zero exit for the user.
|
|
158
|
+
process.on("uncaughtException", () => {
|
|
159
|
+
process.exitCode = 0;
|
|
160
|
+
});
|
|
161
|
+
process.on("unhandledRejection", () => {
|
|
162
|
+
process.exitCode = 0;
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
// No process.exit(): letting the event loop drain guarantees stdout is flushed
|
|
166
|
+
// before the process ends, and the default exit code is already 0.
|
|
167
|
+
main()
|
|
168
|
+
.catch(() => {})
|
|
169
|
+
.finally(() => {
|
|
170
|
+
process.exitCode = 0;
|
|
171
|
+
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
|
|
2
3
|
// Deploy claudecode ARCS bundle from repo to Claude Code config.
|
|
3
4
|
//
|
|
4
5
|
// Direction: repo → config ONLY. Never writes config → repo.
|
|
@@ -8,7 +9,9 @@
|
|
|
8
9
|
// 2. Skills tree → <destination>/skills/arcs-<name>/...
|
|
9
10
|
// (Claude Code skills must be flat under skills/; we use the `arcs-`
|
|
10
11
|
// prefix as a namespace so orphan pruning never touches user skills.)
|
|
11
|
-
// 3. Default agent → settings.json `agent` field
|
|
12
|
+
// 3. Default agent → settings.json `agent` field, resolved from an
|
|
13
|
+
// explicit DEPLOY_PRIMARY_AGENT selection, else through the
|
|
14
|
+
// DEFAULT_AGENT_PRECEDENCE list (default: "arcs-orchestrate")
|
|
12
15
|
//
|
|
13
16
|
// Env vars:
|
|
14
17
|
// DEPLOY_BUNDLE_ROOT — override bundle root (default: opencode/arcs)
|
|
@@ -16,10 +19,13 @@
|
|
|
16
19
|
// DEPLOY_PROJECT_ROOT — override project root (default: repository root)
|
|
17
20
|
// DEPLOY_SCOPE — `global` or `project` (default: `global`)
|
|
18
21
|
// DEPLOY_DRY_RUN — "false" to actually write; anything else = dry-run (default: dry-run)
|
|
22
|
+
// DEPLOY_PRIMARY_AGENT — user-selected default primary agent id; empty/unset falls
|
|
23
|
+
// back to DEFAULT_AGENT_PRECEDENCE
|
|
19
24
|
//
|
|
20
25
|
// Outputs JSON to stdout: DeployResult
|
|
21
26
|
// Exit code: 0 on success, 1 on error.
|
|
22
27
|
|
|
28
|
+
import { createHash } from "node:crypto";
|
|
23
29
|
import {
|
|
24
30
|
existsSync,
|
|
25
31
|
mkdirSync,
|
|
@@ -32,7 +38,13 @@ import {
|
|
|
32
38
|
import { homedir } from "node:os";
|
|
33
39
|
import { dirname, relative, resolve } from "node:path";
|
|
34
40
|
import { fileURLToPath } from "node:url";
|
|
35
|
-
import {
|
|
41
|
+
import {
|
|
42
|
+
isActiveAgentForMode,
|
|
43
|
+
isRetiredAgentForMode,
|
|
44
|
+
validateRetirementReplacements,
|
|
45
|
+
wireCodegraphMcp,
|
|
46
|
+
wireRtk,
|
|
47
|
+
} from "./lib/bundle-helpers.mjs";
|
|
36
48
|
|
|
37
49
|
const scriptDir = dirname(fileURLToPath(import.meta.url));
|
|
38
50
|
const repoRoot = resolve(scriptDir, "..");
|
|
@@ -67,9 +79,30 @@ const dryRun = process.env.DEPLOY_DRY_RUN !== "false";
|
|
|
67
79
|
|
|
68
80
|
const destination = scope === "project" ? projectRoot : configRoot;
|
|
69
81
|
|
|
70
|
-
const DEFAULT_AGENT = "arcs-orchestrate";
|
|
71
82
|
const SKILL_PREFIX = "arcs-";
|
|
72
83
|
|
|
84
|
+
function isPromptPath(value) {
|
|
85
|
+
if (typeof value !== "string" || value.includes("\\")) return false;
|
|
86
|
+
const segments = value.split("/");
|
|
87
|
+
return (
|
|
88
|
+
segments.length >= 2 &&
|
|
89
|
+
segments[0] === "prompts" &&
|
|
90
|
+
segments.slice(1).every((segment) => segment !== "" && segment !== "." && segment !== "..") &&
|
|
91
|
+
segments.at(-1).endsWith(".txt")
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function resolveBundlePromptPath(value) {
|
|
96
|
+
if (!isPromptPath(value)) throw new Error(`Invalid bundle prompt path: ${value}`);
|
|
97
|
+
const promptsRoot = resolve(bundleRoot, "prompts");
|
|
98
|
+
const resolvedPath = resolve(promptsRoot, ...value.split("/").slice(1));
|
|
99
|
+
const relativePath = relative(promptsRoot, resolvedPath);
|
|
100
|
+
if (relativePath.split(/[\\/]/).includes("..")) {
|
|
101
|
+
throw new Error(`Bundle prompt path escapes prompts/: ${value}`);
|
|
102
|
+
}
|
|
103
|
+
return resolvedPath;
|
|
104
|
+
}
|
|
105
|
+
|
|
73
106
|
// ---------------------------------------------------------------------------
|
|
74
107
|
// Model tier configuration
|
|
75
108
|
// ---------------------------------------------------------------------------
|
|
@@ -81,102 +114,80 @@ const tierModels = {
|
|
|
81
114
|
light: process.env.DEPLOY_MODEL_LIGHT || "inherit",
|
|
82
115
|
};
|
|
83
116
|
|
|
84
|
-
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
"
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
117
|
+
function readAgentRegistry() {
|
|
118
|
+
const manifestPath = resolve(bundleRoot, "manifest.json");
|
|
119
|
+
if (!existsSync(manifestPath)) throw new Error(`Agent registry not found at ${manifestPath}`);
|
|
120
|
+
const manifest = JSON.parse(readFileSync(manifestPath, "utf-8"));
|
|
121
|
+
if (!Array.isArray(manifest.agents))
|
|
122
|
+
throw new Error("Invalid agent registry: agents must be an array");
|
|
123
|
+
|
|
124
|
+
const ids = new Set();
|
|
125
|
+
const sources = new Set();
|
|
126
|
+
const destinations = new Set();
|
|
127
|
+
for (const agent of manifest.agents) {
|
|
128
|
+
const valid =
|
|
129
|
+
agent &&
|
|
130
|
+
typeof agent.id === "string" &&
|
|
131
|
+
/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(agent.id) &&
|
|
132
|
+
["active", "retired"].includes(agent.status) &&
|
|
133
|
+
["primary", "subagent"].includes(agent.kind) &&
|
|
134
|
+
["heavy", "standard", "light"].includes(agent.tier) &&
|
|
135
|
+
Array.isArray(agent.modes) &&
|
|
136
|
+
agent.modes.length > 0 &&
|
|
137
|
+
agent.modes.every((mode) => ["opencode", "claudecode"].includes(mode)) &&
|
|
138
|
+
isPromptPath(agent.source) &&
|
|
139
|
+
isPromptPath(agent.destination) &&
|
|
140
|
+
typeof agent.description === "string" &&
|
|
141
|
+
agent.description.length > 0 &&
|
|
142
|
+
agent.permissions &&
|
|
143
|
+
["allow", "deny"].includes(agent.permissions.edit) &&
|
|
144
|
+
["allow", "deny"].includes(agent.permissions.bash) &&
|
|
145
|
+
["allow", "deny"].includes(agent.permissions.webfetch) &&
|
|
146
|
+
["allow", "deny"].includes(agent.permissions.mcp) &&
|
|
147
|
+
["allow", "deny"].includes(agent.permissions.task);
|
|
148
|
+
if (!valid) throw new Error(`Invalid agent registry record: ${JSON.stringify(agent)}`);
|
|
149
|
+
if (ids.has(agent.id)) throw new Error(`Duplicate agent registry id: ${agent.id}`);
|
|
150
|
+
if (sources.has(agent.source))
|
|
151
|
+
throw new Error(`Duplicate agent registry source: ${agent.source}`);
|
|
152
|
+
if (destinations.has(agent.destination))
|
|
153
|
+
throw new Error(`Duplicate agent registry destination: ${agent.destination}`);
|
|
154
|
+
ids.add(agent.id);
|
|
155
|
+
sources.add(agent.source);
|
|
156
|
+
destinations.add(agent.destination);
|
|
157
|
+
}
|
|
158
|
+
validateRetirementReplacements(manifest.agents);
|
|
159
|
+
return manifest.agents;
|
|
160
|
+
}
|
|
97
161
|
|
|
98
|
-
|
|
99
|
-
const
|
|
100
|
-
"
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
"devil-advocate": {
|
|
108
|
-
name: "Devil's Advocate",
|
|
109
|
-
description:
|
|
110
|
-
"Adversarial phase-gate agent. Checks work at phase boundaries using KISS/YAGNI/DRY principles. Runs tests, reads diffs, delivers pass/block verdicts. Cannot edit code.",
|
|
111
|
-
tools: "Read, Glob, Grep, Bash",
|
|
112
|
-
model: "inherit",
|
|
113
|
-
},
|
|
114
|
-
"graph-explorer": {
|
|
115
|
-
name: "Graph Explorer",
|
|
116
|
-
description:
|
|
117
|
-
"DAG-first codebase and knowledge exploration specialist. Queries arcs search, related, and context first, then codegraph MCP code-intelligence tools, before falling back to raw file-system tools. Replaces vanilla explore for ARCS projects.",
|
|
118
|
-
tools: "Read, Glob, Grep, Bash",
|
|
119
|
-
model: "inherit",
|
|
120
|
-
},
|
|
121
|
-
"tech-architect": {
|
|
122
|
-
name: "Technical Architect",
|
|
123
|
-
description:
|
|
124
|
-
"Architecture and analysis specialist. Deep structural reasoning, refactor guidance, trade-off evaluation, and root cause analysis without making hasty edits.",
|
|
125
|
-
tools: "Read, Glob, Grep, Bash",
|
|
126
|
-
model: "inherit",
|
|
127
|
-
},
|
|
128
|
-
"code-reviewer": {
|
|
129
|
-
name: "Code Reviewer",
|
|
130
|
-
description:
|
|
131
|
-
"Reviews code changes for production readiness and catches correctness, maintainability, and testing issues.",
|
|
132
|
-
tools: "Read, Glob, Grep, Bash",
|
|
133
|
-
model: "inherit",
|
|
134
|
-
},
|
|
135
|
-
"arcs-docs": {
|
|
136
|
-
name: "ARCS Docs Specialist",
|
|
137
|
-
description:
|
|
138
|
-
"ARCS documentation specialist. Manages plans, knowledge entries, diagrams, and DAG health. Knows ARCS structure intimately.",
|
|
139
|
-
tools: "Read, Write, Edit, Glob, Grep, Bash",
|
|
140
|
-
model: "inherit",
|
|
141
|
-
},
|
|
142
|
-
"docs-researcher": {
|
|
143
|
-
name: "Docs Researcher",
|
|
144
|
-
description:
|
|
145
|
-
"Handles documentation writing, research synthesis, OCR-adjacent extraction, and document-heavy analysis tasks.",
|
|
146
|
-
tools: "Read, Write, Edit, Glob, Grep, Bash",
|
|
147
|
-
model: "inherit",
|
|
148
|
-
},
|
|
149
|
-
"oncall-ops": {
|
|
150
|
-
name: "On-Call Ops",
|
|
151
|
-
description:
|
|
152
|
-
"Debugging and diagnosis specialist. Finds root causes through systematic investigation, log triage, bisect, and performance profiling.",
|
|
153
|
-
tools: "Read, Write, Edit, Glob, Grep, Bash",
|
|
154
|
-
model: "inherit",
|
|
155
|
-
},
|
|
156
|
-
"arcs-orchestrate": {
|
|
157
|
-
name: "ARCS Orchestrator",
|
|
158
|
-
description:
|
|
159
|
-
"The central coordinator for executing plans, managing agent dispatch, and handling DAG workflows.",
|
|
160
|
-
// Task is required: orchestrators dispatch sub-agents. Omitting it leaves
|
|
161
|
-
// the delegator with no way to delegate.
|
|
162
|
-
tools: "Task, Read, Write, Edit, Glob, Grep, Bash",
|
|
163
|
-
model: "inherit",
|
|
164
|
-
},
|
|
165
|
-
"arcs-orchestrate-caveman": {
|
|
166
|
-
name: "ARCS Orchestrator (Caveman)",
|
|
167
|
-
description:
|
|
168
|
-
"A terse, high-efficiency orchestrator that drives tasks without extra commentary.",
|
|
169
|
-
// Task is required: orchestrators dispatch sub-agents. Omitting it leaves
|
|
170
|
-
// the delegator with no way to delegate.
|
|
171
|
-
tools: "Task, Read, Write, Edit, Glob, Grep, Bash",
|
|
172
|
-
model: "inherit",
|
|
173
|
-
},
|
|
174
|
-
};
|
|
162
|
+
function claudeTools(agent) {
|
|
163
|
+
const tools = [];
|
|
164
|
+
if (agent.permissions.task === "allow") tools.push("Task");
|
|
165
|
+
tools.push("Read");
|
|
166
|
+
if (agent.permissions.edit === "allow") tools.push("Write", "Edit");
|
|
167
|
+
tools.push("Glob", "Grep");
|
|
168
|
+
if (agent.permissions.bash === "allow") tools.push("Bash");
|
|
169
|
+
return tools.join(", ");
|
|
170
|
+
}
|
|
175
171
|
|
|
176
172
|
function ensureParentDir(filePath) {
|
|
177
173
|
mkdirSync(dirname(filePath), { recursive: true });
|
|
178
174
|
}
|
|
179
175
|
|
|
176
|
+
function sha256(content) {
|
|
177
|
+
return createHash("sha256").update(content).digest("hex");
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function readInstalledManifest() {
|
|
181
|
+
const manifestPath = resolve(destination, configRelativePath(".arcs-bundle.json"));
|
|
182
|
+
if (!existsSync(manifestPath)) return null;
|
|
183
|
+
try {
|
|
184
|
+
const value = JSON.parse(readFileSync(manifestPath, "utf-8"));
|
|
185
|
+
return value?.bundleId === "arcs-claudecode-bundle" ? value : null;
|
|
186
|
+
} catch {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
180
191
|
function configRelativePath(suffix) {
|
|
181
192
|
return scope === "project" ? `.claude/${suffix}` : suffix;
|
|
182
193
|
}
|
|
@@ -204,26 +215,23 @@ function buildAgentSources() {
|
|
|
204
215
|
throw new Error(`Prompts directory not found at ${promptsDir}`);
|
|
205
216
|
}
|
|
206
217
|
|
|
207
|
-
const
|
|
208
|
-
const
|
|
209
|
-
|
|
218
|
+
const registry = readAgentRegistry();
|
|
219
|
+
const registeredSources = new Set(registry.map((agent) => agent.source));
|
|
220
|
+
const promptFiles = readdirSync(promptsDir).filter((file) => file.endsWith(".txt"));
|
|
210
221
|
for (const file of promptFiles) {
|
|
211
|
-
const
|
|
212
|
-
|
|
213
|
-
|
|
222
|
+
const source = `prompts/${file}`;
|
|
223
|
+
if (!registeredSources.has(source)) throw new Error(`Unregistered prompt file: ${source}`);
|
|
224
|
+
}
|
|
214
225
|
|
|
215
|
-
|
|
216
|
-
name: stem
|
|
217
|
-
.split("-")
|
|
218
|
-
.map((w) => w.charAt(0).toUpperCase() + w.slice(1))
|
|
219
|
-
.join(" "),
|
|
220
|
-
description: `ARCS ${stem} agent.`,
|
|
221
|
-
tools: "Read, Write, Edit, Glob, Grep, Bash",
|
|
222
|
-
model: "inherit",
|
|
223
|
-
};
|
|
226
|
+
const sources = [];
|
|
224
227
|
|
|
225
|
-
|
|
226
|
-
const
|
|
228
|
+
for (const agent of registry.filter((record) => isActiveAgentForMode(record, "claudecode"))) {
|
|
229
|
+
const stem = agent.id;
|
|
230
|
+
const sourcePath = resolveBundlePromptPath(agent.source);
|
|
231
|
+
if (!existsSync(sourcePath))
|
|
232
|
+
throw new Error(`Registered agent prompt not found: ${agent.source}`);
|
|
233
|
+
const promptContent = readFileSync(sourcePath, "utf-8");
|
|
234
|
+
const model = tierModels[agent.tier];
|
|
227
235
|
|
|
228
236
|
// Claude Code requires `name` to be a kebab-case identifier (lowercase
|
|
229
237
|
// letters + hyphens). The filename stem already satisfies this and is
|
|
@@ -231,17 +239,12 @@ function buildAgentSources() {
|
|
|
231
239
|
// `description`. The default-agent setting (DEFAULT_AGENT) references this
|
|
232
240
|
// same stem, so it resolves. Display names with spaces/parens/apostrophes
|
|
233
241
|
// (meta.name) are invalid here and caused intermittent init failures.
|
|
234
|
-
const toolsCsv = meta.tools
|
|
235
|
-
.split(",")
|
|
236
|
-
.map((t) => t.trim())
|
|
237
|
-
.join(", ");
|
|
238
|
-
|
|
239
242
|
const compiledContent = [
|
|
240
243
|
"---",
|
|
241
244
|
`name: ${stem}`,
|
|
242
|
-
`description: ${
|
|
245
|
+
`description: ${agent.description}`,
|
|
243
246
|
`model: ${model}`,
|
|
244
|
-
`tools: ${
|
|
247
|
+
`tools: ${claudeTools(agent)}`,
|
|
245
248
|
"---",
|
|
246
249
|
"",
|
|
247
250
|
promptContent,
|
|
@@ -289,7 +292,47 @@ function buildSkillSources() {
|
|
|
289
292
|
// 3. settings.json merge — set default agent
|
|
290
293
|
// ---------------------------------------------------------------------------
|
|
291
294
|
|
|
295
|
+
// Which primary becomes the deployed default is an explicit, ordered policy —
|
|
296
|
+
// never "whichever active primary happens to come first in manifest.json".
|
|
297
|
+
// Registry array order must not be able to promote an agent: a new primary
|
|
298
|
+
// (e.g. the speed-optimized arcs-flash) becomes eligible only by being listed
|
|
299
|
+
// here, and only at the rank it is listed at. Earlier entries always win, so a
|
|
300
|
+
// lower-ranked primary is a fallback, never a silent replacement.
|
|
301
|
+
const DEFAULT_AGENT_PRECEDENCE = ["arcs-orchestrate", "arcs-orchestrate-caveman", "arcs-flash"];
|
|
302
|
+
|
|
303
|
+
function isSelectablePrimary(agent) {
|
|
304
|
+
return Boolean(agent) && agent.kind === "primary" && isActiveAgentForMode(agent, "claudecode");
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
function selectDefaultAgent(registry) {
|
|
308
|
+
// An explicit user selection outranks the pinned precedence — but only when it
|
|
309
|
+
// names a real Claude-Code-active primary. A user who asked for X must never
|
|
310
|
+
// silently get Y, so an unusable selection hard-fails instead of degrading
|
|
311
|
+
// into the precedence walk.
|
|
312
|
+
const requestedId = (process.env.DEPLOY_PRIMARY_AGENT ?? "").trim();
|
|
313
|
+
if (requestedId !== "") {
|
|
314
|
+
const requested = registry.find((record) => record.id === requestedId);
|
|
315
|
+
if (isSelectablePrimary(requested)) return requested;
|
|
316
|
+
const selectable = registry.filter(isSelectablePrimary).map((record) => record.id);
|
|
317
|
+
throw new Error(
|
|
318
|
+
`DEPLOY_PRIMARY_AGENT "${requestedId}" is not an active Claude Code primary agent. Selectable: ${selectable.join(", ") || "(none)"}`,
|
|
319
|
+
);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
for (const id of DEFAULT_AGENT_PRECEDENCE) {
|
|
323
|
+
const agent = registry.find((record) => record.id === id);
|
|
324
|
+
if (isSelectablePrimary(agent)) {
|
|
325
|
+
return agent;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
throw new Error(
|
|
329
|
+
`No active Claude Code primary agent in default precedence: ${DEFAULT_AGENT_PRECEDENCE.join(", ")}`,
|
|
330
|
+
);
|
|
331
|
+
}
|
|
332
|
+
|
|
292
333
|
function planSettingsUpdate() {
|
|
334
|
+
const defaultAgent = selectDefaultAgent(readAgentRegistry());
|
|
335
|
+
|
|
293
336
|
const settingsConfigRelative = configRelativePath("settings.json");
|
|
294
337
|
const settingsAbsolute = resolve(destination, settingsConfigRelative);
|
|
295
338
|
|
|
@@ -308,7 +351,7 @@ function planSettingsUpdate() {
|
|
|
308
351
|
}
|
|
309
352
|
}
|
|
310
353
|
|
|
311
|
-
const merged = { ...parsed, agent:
|
|
354
|
+
const merged = { ...parsed, agent: defaultAgent.id };
|
|
312
355
|
const serialized = `${JSON.stringify(merged, null, 2)}\n`;
|
|
313
356
|
|
|
314
357
|
let status;
|
|
@@ -328,6 +371,8 @@ function planSettingsUpdate() {
|
|
|
328
371
|
// ---------------------------------------------------------------------------
|
|
329
372
|
|
|
330
373
|
function main() {
|
|
374
|
+
const registry = readAgentRegistry();
|
|
375
|
+
const previousManifest = readInstalledManifest();
|
|
331
376
|
const agentSources = buildAgentSources();
|
|
332
377
|
const skillSources = buildSkillSources();
|
|
333
378
|
const settingsPlan = planSettingsUpdate();
|
|
@@ -375,20 +420,6 @@ function main() {
|
|
|
375
420
|
// Orphans
|
|
376
421
|
const filesRemoved = [];
|
|
377
422
|
|
|
378
|
-
// Agent orphans — only `.md` files whose stem we recognize from agentMetadata
|
|
379
|
-
const agentsTargetDir = resolve(destination, configRelativePath("agents"));
|
|
380
|
-
const activeAgentStems = new Set(agentSources.map((f) => f.stem));
|
|
381
|
-
if (existsSync(agentsTargetDir)) {
|
|
382
|
-
for (const entry of readdirSync(agentsTargetDir, { withFileTypes: true })) {
|
|
383
|
-
if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
384
|
-
const stem = entry.name.slice(0, -3);
|
|
385
|
-
if (agentMetadata[stem] && !activeAgentStems.has(stem)) {
|
|
386
|
-
filesRemoved.push(configRelativePath(`agents/${entry.name}`));
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
|
|
392
423
|
// Skill orphans — only `arcs-*/` directories that aren't in current source.
|
|
393
424
|
// The prefix gives us a safe namespace; foreign user skills are never touched.
|
|
394
425
|
const skillsTargetDir = resolve(destination, configRelativePath("skills"));
|
|
@@ -405,6 +436,22 @@ function main() {
|
|
|
405
436
|
}
|
|
406
437
|
}
|
|
407
438
|
|
|
439
|
+
const retiredById = new Map(
|
|
440
|
+
registry
|
|
441
|
+
.filter((agent) => isRetiredAgentForMode(agent, "claudecode"))
|
|
442
|
+
.map((agent) => [agent.id, agent]),
|
|
443
|
+
);
|
|
444
|
+
for (const ownership of previousManifest?.agents ?? []) {
|
|
445
|
+
const retired = retiredById.get(ownership.id);
|
|
446
|
+
if (!retired) continue;
|
|
447
|
+
const expectedDestination = configRelativePath(`agents/${retired.id}.md`);
|
|
448
|
+
if (ownership.promptDestination !== expectedDestination) continue;
|
|
449
|
+
const installedPath = resolve(destination, ownership.promptDestination);
|
|
450
|
+
if (existsSync(installedPath) && sha256(readFileSync(installedPath)) === ownership.sourceHash) {
|
|
451
|
+
filesRemoved.push(ownership.promptDestination);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
408
455
|
// Pass 2: Write if not dry-run
|
|
409
456
|
if (!dryRun) {
|
|
410
457
|
for (const { compiledContent, configRelative } of agentSources) {
|
|
@@ -432,6 +479,33 @@ function main() {
|
|
|
432
479
|
rmSync(abs, { recursive: isDir, force: true });
|
|
433
480
|
}
|
|
434
481
|
}
|
|
482
|
+
|
|
483
|
+
const installedManifestPath = resolve(destination, configRelativePath(".arcs-bundle.json"));
|
|
484
|
+
ensureParentDir(installedManifestPath);
|
|
485
|
+
writeFileSync(
|
|
486
|
+
installedManifestPath,
|
|
487
|
+
`${JSON.stringify(
|
|
488
|
+
{
|
|
489
|
+
bundleId: "arcs-claudecode-bundle",
|
|
490
|
+
installMode: `claudecode-${scope}`,
|
|
491
|
+
sourceBundleVersion: "deploy-script",
|
|
492
|
+
sourceBundleHash: sha256(readFileSync(resolve(bundleRoot, "manifest.json"))),
|
|
493
|
+
installedAt: new Date().toISOString(),
|
|
494
|
+
// Persisted so a later `arcs init` can reuse the previous tier
|
|
495
|
+
// selection instead of re-prompting for it.
|
|
496
|
+
tierModels,
|
|
497
|
+
ownedPaths: [],
|
|
498
|
+
agents: agentSources.map((agent) => ({
|
|
499
|
+
id: agent.stem,
|
|
500
|
+
promptDestination: agent.configRelative,
|
|
501
|
+
sourceHash: sha256(agent.compiledContent),
|
|
502
|
+
})),
|
|
503
|
+
},
|
|
504
|
+
null,
|
|
505
|
+
2,
|
|
506
|
+
)}\n`,
|
|
507
|
+
"utf-8",
|
|
508
|
+
);
|
|
435
509
|
}
|
|
436
510
|
|
|
437
511
|
// Best-effort: wire the codegraph MCP server. Skipped on dry-run; never fatal.
|