@rryando/arcs 3.10.0 → 3.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +36 -0
- package/dist/cli/commands/hooks.d.ts.map +1 -0
- package/dist/cli/commands/hooks.js +298 -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 +56 -0
- package/dist/cli/commands/web.js.map +1 -0
- package/dist/cli/config.d.ts +32 -0
- package/dist/cli/config.d.ts.map +1 -1
- package/dist/cli/config.js +56 -0
- package/dist/cli/config.js.map +1 -1
- package/dist/cli/instructions.d.ts +19 -6
- package/dist/cli/instructions.d.ts.map +1 -1
- package/dist/cli/instructions.js +62 -32
- 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 +159 -85
- 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/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 +146 -0
- package/dist/utils/claude-code-hook-install.js.map +1 -0
- package/dist/utils/claude-transcript.d.ts +127 -0
- package/dist/utils/claude-transcript.d.ts.map +1 -0
- package/dist/utils/claude-transcript.js +353 -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/hook-token-store.d.ts +22 -0
- package/dist/utils/hook-token-store.d.ts.map +1 -0
- package/dist/utils/hook-token-store.js +43 -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 +113 -0
- package/dist/utils/session-store.d.ts.map +1 -0
- package/dist/utils/session-store.js +312 -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-dNyZ458L.js +1 -0
- package/dist/web-client/assets/MarkdownEditor-BmU9mdkN.js +77 -0
- package/dist/web-client/assets/abnfDiagram-VRR7QNED-D1BFBoeF.js +1 -0
- package/dist/web-client/assets/arc-Bfaogrm1.js +1 -0
- package/dist/web-client/assets/architecture-TIHT7OUA-CJqI5wNI.js +1 -0
- package/dist/web-client/assets/architectureDiagram-ZJ3FMSHR-CA8hTWUK.js +36 -0
- package/dist/web-client/assets/array-BifhSqXX.js +1 -0
- package/dist/web-client/assets/blockDiagram-677ZJIJ3-CQpb_KwX.js +132 -0
- package/dist/web-client/assets/c4Diagram-LMCZKHZV-BhpHX84V.js +10 -0
- package/dist/web-client/assets/channel-C8DlmyVe.js +1 -0
- package/dist/web-client/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
- package/dist/web-client/assets/chunk-32BRIVSS-BUusQQa_.js +1 -0
- package/dist/web-client/assets/chunk-52WLFC77-nNYwlftl.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-D0a-yqnK.js +1 -0
- package/dist/web-client/assets/chunk-EX3LRPZG-IDuRMN-4.js +231 -0
- package/dist/web-client/assets/chunk-FWX5IMBZ-D_spTcqi.js +2 -0
- package/dist/web-client/assets/chunk-HOUHSVGY-C-bcxwZS.js +1 -0
- package/dist/web-client/assets/chunk-ICXQ74PX-CjmK2bAM.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-Bkc08KWY.js +88 -0
- package/dist/web-client/assets/chunk-OGEWGWER-BAAYYvG9.js +1 -0
- package/dist/web-client/assets/chunk-PUDLZKDR-WXbPY7NM.js +156 -0
- package/dist/web-client/assets/chunk-Q4XR5HBZ-DcbnjxQE.js +70 -0
- package/dist/web-client/assets/chunk-RYQCIY6F-np2RyIY1.js +1 -0
- package/dist/web-client/assets/chunk-V7JOEXUC-C6t75PAp.js +206 -0
- package/dist/web-client/assets/chunk-VAUOI2AC-DVrJ0Ic7.js +1 -0
- package/dist/web-client/assets/chunk-VR4S4FIN-MOOFvGS0.js +1 -0
- package/dist/web-client/assets/chunk-WYO6CB5R-sK7Y2NZD.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-a13RQsku.js +62 -0
- package/dist/web-client/assets/chunk-ZIRB5QZD-BpeS1aZ7.js +32 -0
- package/dist/web-client/assets/classDiagram-OUVF2IWQ-p32N1P_G.js +1 -0
- package/dist/web-client/assets/classDiagram-v2-EOCWNBFH-p32N1P_G.js +1 -0
- package/dist/web-client/assets/cose-bilkent-JH36ORCC-BebHqzgp.js +1 -0
- package/dist/web-client/assets/cynefin-VYW2F7L2-D8xaH-wO.js +1 -0
- package/dist/web-client/assets/cynefinDiagram-TSTJHNR4-Bt__EqJW.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-Bwgjwflz.js +4 -0
- package/dist/web-client/assets/defaultLocale-BFoDCU3G.js +1 -0
- package/dist/web-client/assets/diagram-FQU43EPY-CaPDVUq2.js +3 -0
- package/dist/web-client/assets/diagram-G47NLZAW-BQLB9YYA.js +24 -0
- package/dist/web-client/assets/diagram-NH7WQ7WH-BWo84w8Y.js +24 -0
- package/dist/web-client/assets/diagram-OA4YK3LP-bKn6Pz5s.js +30 -0
- package/dist/web-client/assets/diagram-WEI45ONY-BRqV5Oy6.js +41 -0
- package/dist/web-client/assets/dist-B_J_HbC0.js +1 -0
- package/dist/web-client/assets/ebnfDiagram-CCIWWBDH-DhUXL1-7.js +1 -0
- package/dist/web-client/assets/erDiagram-Q63AITRT-HXAQQ-_F.js +85 -0
- package/dist/web-client/assets/eventmodeling-45OFAUF4-Bj5P8mZJ.js +1 -0
- package/dist/web-client/assets/flowDiagram-23GEKE2U-37BztFri.js +1 -0
- package/dist/web-client/assets/ganttDiagram-NO4QXBWP-D-Ddf_Ii.js +292 -0
- package/dist/web-client/assets/gitGraph-TEB2WS4Q-BmHzs0uF.js +1 -0
- package/dist/web-client/assets/gitGraphDiagram-IHSO6WYX-YnQWrlh_.js +106 -0
- package/dist/web-client/assets/graphlib-DS17s2tU.js +1 -0
- package/dist/web-client/assets/index-3mNPVkix.css +2 -0
- package/dist/web-client/assets/index-DCWxuIeQ.js +58 -0
- package/dist/web-client/assets/info-DKCQHKI2-DCT_B7RN.js +1 -0
- package/dist/web-client/assets/infoDiagram-FWYZ7A6U-D-le1Zhq.js +2 -0
- package/dist/web-client/assets/init-C-OQMol4.js +1 -0
- package/dist/web-client/assets/ishikawaDiagram-FXEZZL3T-Jr1x2VJB.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-BF9ELxj-.js +139 -0
- package/dist/web-client/assets/kanban-definition-HUTT4EX6-C4fJqAxu.js +89 -0
- package/dist/web-client/assets/katex-DolUETbr.js +257 -0
- package/dist/web-client/assets/line-7N7ikFxa.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-QbC1icPt.js +7 -0
- package/dist/web-client/assets/mermaid.core-C26d_UJm.js +11 -0
- package/dist/web-client/assets/mindmap-definition-LN4V7U3C-D6TV1JDf.js +96 -0
- package/dist/web-client/assets/ordinal-BDEzSJ7C.js +1 -0
- package/dist/web-client/assets/packet-7NZHBO7P-CR1vrGj3.js +1 -0
- package/dist/web-client/assets/path-COt_16Va.js +1 -0
- package/dist/web-client/assets/pegDiagram-2B236MQR-xOMBBtfV.js +1 -0
- package/dist/web-client/assets/pie-RZYD4A2V-BbWuhjwy.js +1 -0
- package/dist/web-client/assets/pieDiagram-ENE6RG2P-MsfnsqgW.js +39 -0
- package/dist/web-client/assets/quadrantDiagram-ABIIQ3AL-BoI7zKXF.js +7 -0
- package/dist/web-client/assets/radar-I7S5WNFK-CbYXKToJ.js +1 -0
- package/dist/web-client/assets/railroad-3IZDKUUU-6LxHDkLe.js +1 -0
- package/dist/web-client/assets/railroad-abnf-AHOZXSZD-2Dg9wu0J.js +1 -0
- package/dist/web-client/assets/railroad-ebnf-EBAXGLYW-C_E2ot0R.js +1 -0
- package/dist/web-client/assets/railroad-peg-LSFZ7HO6-Bs9UQR1b.js +1 -0
- package/dist/web-client/assets/railroadDiagram-RFXS5EU6-D6RUoUki.js +1 -0
- package/dist/web-client/assets/requirementDiagram-TGXJPOKE-B6k4BDpE.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-BUDF-UFr.js +40 -0
- package/dist/web-client/assets/sequenceDiagram-DBY2YBRQ-D6GqcsUi.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-WfJCQAK5.js +1 -0
- package/dist/web-client/assets/stateDiagram-v2-6OUMAXLB-BCMWGnsJ.js +1 -0
- package/dist/web-client/assets/swimlanes-5IMT3BWC-BtMo82mC.js +2 -0
- package/dist/web-client/assets/swimlanesDiagram-G3AALYLV-DmudmLcK.js +8 -0
- package/dist/web-client/assets/timeline-definition-FHXFAJF6-CoAmv2Sn.js +120 -0
- package/dist/web-client/assets/treeView-QDETBFTQ-BWsKzE1s.js +1 -0
- package/dist/web-client/assets/treemap-6X3UGDF4-i_qGtB3o.js +1 -0
- package/dist/web-client/assets/vennDiagram-L72KCM5P-DYkiLe-P.js +34 -0
- package/dist/web-client/assets/wardley-OPB4EBWU-Daaqr1Vp.js +1 -0
- package/dist/web-client/assets/wardleyDiagram-EHGQE667-Bofbsg3J.js +78 -0
- package/dist/web-client/assets/xychartDiagram-FW5EYKEG-KNF4VTfL.js +7 -0
- package/dist/web-client/index.html +15 -0
- package/dist/web-server/app.d.ts +13 -0
- package/dist/web-server/app.d.ts.map +1 -0
- package/dist/web-server/app.js +58 -0
- package/dist/web-server/app.js.map +1 -0
- package/dist/web-server/claude-runner.d.ts +86 -0
- package/dist/web-server/claude-runner.d.ts.map +1 -0
- package/dist/web-server/claude-runner.js +320 -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 +49 -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/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 +19 -0
- package/dist/web-server/routes/hook-events.d.ts.map +1 -0
- package/dist/web-server/routes/hook-events.js +135 -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 +16 -0
- package/dist/web-server/routes/sessions.d.ts.map +1 -0
- package/dist/web-server/routes/sessions.js +442 -0
- package/dist/web-server/routes/sessions.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/static.d.ts +10 -0
- package/dist/web-server/static.d.ts.map +1 -0
- package/dist/web-server/static.js +36 -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/opencode/arcs/bundle-runtime.json +5 -13
- package/opencode/arcs/manifest.json +213 -149
- 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 +125 -0
- package/scripts/deploy-claudecode-bundle.mjs +185 -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
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
|
|
2
3
|
// Deploy opencode ARCS bundle bundle from repo to user config.
|
|
3
4
|
//
|
|
4
5
|
// Direction: repo → config ONLY. Never writes config → repo.
|
|
@@ -11,6 +12,7 @@
|
|
|
11
12
|
// Outputs JSON to stdout: DeployResult
|
|
12
13
|
// Exit code: 0 on success, 1 on error.
|
|
13
14
|
|
|
15
|
+
import { createHash } from "node:crypto";
|
|
14
16
|
import {
|
|
15
17
|
copyFileSync,
|
|
16
18
|
existsSync,
|
|
@@ -27,6 +29,9 @@ import { fileURLToPath } from "node:url";
|
|
|
27
29
|
import {
|
|
28
30
|
assertNoReservedPathSegments,
|
|
29
31
|
assertPathWithinCategoryRoot,
|
|
32
|
+
isActiveAgentForMode,
|
|
33
|
+
isRetiredAgentForMode,
|
|
34
|
+
validateRetirementReplacements,
|
|
30
35
|
wireCodegraphMcp,
|
|
31
36
|
wireRtk,
|
|
32
37
|
} from "./lib/bundle-helpers.mjs";
|
|
@@ -59,6 +64,42 @@ function ensureParentDir(filePath) {
|
|
|
59
64
|
mkdirSync(dirname(filePath), { recursive: true });
|
|
60
65
|
}
|
|
61
66
|
|
|
67
|
+
function sha256(content) {
|
|
68
|
+
return createHash("sha256").update(content).digest("hex");
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function readInstalledManifest() {
|
|
72
|
+
const path = resolve(configRoot, ".arcs-bundle.json");
|
|
73
|
+
if (!existsSync(path)) return null;
|
|
74
|
+
try {
|
|
75
|
+
const value = JSON.parse(readFileSync(path, "utf-8"));
|
|
76
|
+
return value?.bundleId === "arcs-opencode-bundle" ? value : null;
|
|
77
|
+
} catch {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function configOwnershipHash(value) {
|
|
83
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
84
|
+
return sha256(JSON.stringify(value));
|
|
85
|
+
}
|
|
86
|
+
const withoutModel = { ...value };
|
|
87
|
+
delete withoutModel.model;
|
|
88
|
+
return sha256(JSON.stringify(withoutModel));
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function agentDefaultModel(manifest, id) {
|
|
92
|
+
const merge = (manifest.config?.requiredMerges ?? []).find(
|
|
93
|
+
(candidate) =>
|
|
94
|
+
candidate.path?.length === 2 &&
|
|
95
|
+
candidate.path[0] === "agent" &&
|
|
96
|
+
candidate.path[1] === id &&
|
|
97
|
+
candidate.value &&
|
|
98
|
+
typeof candidate.value === "object",
|
|
99
|
+
);
|
|
100
|
+
return merge?.value?.model;
|
|
101
|
+
}
|
|
102
|
+
|
|
62
103
|
function validateManifestPaths(manifest) {
|
|
63
104
|
assertPathWithinCategoryRoot(manifest.skills.source, "skills");
|
|
64
105
|
assertPathWithinCategoryRoot(manifest.skills.destination, "skills");
|
|
@@ -78,6 +119,43 @@ function validateManifestPaths(manifest) {
|
|
|
78
119
|
}
|
|
79
120
|
}
|
|
80
121
|
|
|
122
|
+
function validateAgentRegistry(agents) {
|
|
123
|
+
if (!Array.isArray(agents)) throw new Error("Invalid agent registry: agents must be an array");
|
|
124
|
+
const byId = new Map();
|
|
125
|
+
const sources = new Set();
|
|
126
|
+
const destinations = new Set();
|
|
127
|
+
for (const agent of agents ?? []) {
|
|
128
|
+
if (!agent || typeof agent.id !== "string" || !/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(agent.id)) {
|
|
129
|
+
throw new Error("Invalid agent registry: every agent requires a valid id");
|
|
130
|
+
}
|
|
131
|
+
if (agent.status !== "active" && agent.status !== "retired") {
|
|
132
|
+
throw new Error(`Invalid agent registry status for ${agent.id}`);
|
|
133
|
+
}
|
|
134
|
+
if (agent.kind !== "primary" && agent.kind !== "subagent") {
|
|
135
|
+
throw new Error(`Invalid agent registry kind for ${agent.id}`);
|
|
136
|
+
}
|
|
137
|
+
if (
|
|
138
|
+
!Array.isArray(agent.modes) ||
|
|
139
|
+
agent.modes.length === 0 ||
|
|
140
|
+
agent.modes.some((mode) => mode !== "opencode" && mode !== "claudecode")
|
|
141
|
+
) {
|
|
142
|
+
throw new Error(`Invalid agent registry modes for ${agent.id}`);
|
|
143
|
+
}
|
|
144
|
+
if (byId.has(agent.id)) throw new Error(`Invalid agent registry: duplicate id ${agent.id}`);
|
|
145
|
+
if (sources.has(agent.source)) {
|
|
146
|
+
throw new Error(`Invalid agent registry: duplicate source ${agent.source}`);
|
|
147
|
+
}
|
|
148
|
+
if (destinations.has(agent.destination)) {
|
|
149
|
+
throw new Error(`Invalid agent registry: duplicate destination ${agent.destination}`);
|
|
150
|
+
}
|
|
151
|
+
byId.set(agent.id, agent);
|
|
152
|
+
sources.add(agent.source);
|
|
153
|
+
destinations.add(agent.destination);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
validateRetirementReplacements(agents);
|
|
157
|
+
}
|
|
158
|
+
|
|
81
159
|
async function main() {
|
|
82
160
|
const manifestPath = resolve(bundleRoot, "manifest.json");
|
|
83
161
|
if (!existsSync(manifestPath)) {
|
|
@@ -86,6 +164,8 @@ async function main() {
|
|
|
86
164
|
|
|
87
165
|
const manifest = JSON.parse(readFileSync(manifestPath, "utf-8"));
|
|
88
166
|
validateManifestPaths(manifest);
|
|
167
|
+
validateAgentRegistry(manifest.agents);
|
|
168
|
+
const previousManifest = readInstalledManifest();
|
|
89
169
|
|
|
90
170
|
// Build mapping: config-relative path → bundle-absolute path
|
|
91
171
|
const deployMap = new Map();
|
|
@@ -102,7 +182,7 @@ async function main() {
|
|
|
102
182
|
}
|
|
103
183
|
|
|
104
184
|
// Plugin
|
|
105
|
-
if (manifest.plugin
|
|
185
|
+
if (manifest.plugin?.source) {
|
|
106
186
|
const pluginSource = resolve(bundleRoot, manifest.plugin.source);
|
|
107
187
|
if (existsSync(pluginSource)) {
|
|
108
188
|
deployMap.set(manifest.plugin.destination, pluginSource);
|
|
@@ -110,7 +190,9 @@ async function main() {
|
|
|
110
190
|
}
|
|
111
191
|
|
|
112
192
|
// Agents (sub-agent prompts) — bundle prompts/<file> → config prompts/<file>
|
|
113
|
-
for (const agent of manifest.agents ?? [])
|
|
193
|
+
for (const agent of (manifest.agents ?? []).filter((record) =>
|
|
194
|
+
isActiveAgentForMode(record, "opencode"),
|
|
195
|
+
)) {
|
|
114
196
|
const agentSource = resolve(bundleRoot, agent.source);
|
|
115
197
|
if (existsSync(agentSource)) {
|
|
116
198
|
deployMap.set(agent.destination, agentSource);
|
|
@@ -128,8 +210,7 @@ async function main() {
|
|
|
128
210
|
const sourceContent = readFileSync(bundleAbsolute, "utf-8");
|
|
129
211
|
|
|
130
212
|
const isNew = !existsSync(configAbsolute);
|
|
131
|
-
const isChanged =
|
|
132
|
-
!isNew && readFileSync(configAbsolute, "utf-8") !== sourceContent;
|
|
213
|
+
const isChanged = !isNew && readFileSync(configAbsolute, "utf-8") !== sourceContent;
|
|
133
214
|
|
|
134
215
|
if (isNew) {
|
|
135
216
|
filesAdded.push(configRelative);
|
|
@@ -168,6 +249,54 @@ async function main() {
|
|
|
168
249
|
}
|
|
169
250
|
}
|
|
170
251
|
|
|
252
|
+
const retiredById = new Map(
|
|
253
|
+
(manifest.agents ?? [])
|
|
254
|
+
.filter((agent) => isRetiredAgentForMode(agent, "opencode"))
|
|
255
|
+
.map((agent) => [agent.id, agent]),
|
|
256
|
+
);
|
|
257
|
+
let config = null;
|
|
258
|
+
let configChanged = false;
|
|
259
|
+
const configPath = resolve(configRoot, "opencode.json");
|
|
260
|
+
if (existsSync(configPath)) {
|
|
261
|
+
try {
|
|
262
|
+
config = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
263
|
+
} catch {
|
|
264
|
+
config = null;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
const configAgents =
|
|
268
|
+
config?.agent && typeof config.agent === "object" && !Array.isArray(config.agent)
|
|
269
|
+
? config.agent
|
|
270
|
+
: null;
|
|
271
|
+
|
|
272
|
+
for (const ownership of previousManifest?.agents ?? []) {
|
|
273
|
+
const retired = retiredById.get(ownership.id);
|
|
274
|
+
if (!retired || retired.destination !== ownership.promptDestination) continue;
|
|
275
|
+
const promptPath = resolve(configRoot, ownership.promptDestination);
|
|
276
|
+
if (existsSync(promptPath) && sha256(readFileSync(promptPath)) === ownership.sourceHash) {
|
|
277
|
+
filesRemoved.push(ownership.promptDestination);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
if (!configAgents || !ownership.configKey || !ownership.configHash) continue;
|
|
281
|
+
const current = configAgents[ownership.configKey];
|
|
282
|
+
if (current === undefined || configOwnershipHash(current) !== ownership.configHash) continue;
|
|
283
|
+
const replacement = retired.replacementId ? configAgents[retired.replacementId] : null;
|
|
284
|
+
const retiredDefault = agentDefaultModel(manifest, ownership.id);
|
|
285
|
+
if (
|
|
286
|
+
replacement &&
|
|
287
|
+
typeof replacement === "object" &&
|
|
288
|
+
current?.model !== undefined &&
|
|
289
|
+
current.model !== retiredDefault
|
|
290
|
+
) {
|
|
291
|
+
const replacementDefault = agentDefaultModel(manifest, retired.replacementId);
|
|
292
|
+
if (replacement.model === undefined || replacement.model === replacementDefault) {
|
|
293
|
+
replacement.model = current.model;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
delete configAgents[ownership.configKey];
|
|
297
|
+
configChanged = true;
|
|
298
|
+
}
|
|
299
|
+
|
|
171
300
|
// Pass 2: Apply writes (only when not dry-run)
|
|
172
301
|
if (!dryRun) {
|
|
173
302
|
// Clean-delete the skills directory before copying to guarantee a fresh install.
|
|
@@ -189,6 +318,53 @@ async function main() {
|
|
|
189
318
|
for (const fileToRemove of filesRemoved) {
|
|
190
319
|
rmSync(resolve(configRoot, fileToRemove), { force: true });
|
|
191
320
|
}
|
|
321
|
+
|
|
322
|
+
if (configChanged) {
|
|
323
|
+
writeFileSync(configPath, `${JSON.stringify(config, null, 2)}\n`, "utf-8");
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
const activeAgents = (manifest.agents ?? []).filter((agent) =>
|
|
327
|
+
isActiveAgentForMode(agent, "opencode"),
|
|
328
|
+
);
|
|
329
|
+
const previousAgents = new Map(
|
|
330
|
+
(previousManifest?.agents ?? []).map((ownership) => [ownership.id, ownership]),
|
|
331
|
+
);
|
|
332
|
+
const installedAgents = activeAgents
|
|
333
|
+
.filter((agent) => deployMap.has(agent.destination))
|
|
334
|
+
.map((agent) => {
|
|
335
|
+
const previous = previousAgents.get(agent.id);
|
|
336
|
+
const currentConfig = configAgents?.[agent.id];
|
|
337
|
+
const configStillOwned =
|
|
338
|
+
previous?.configKey &&
|
|
339
|
+
previous?.configHash &&
|
|
340
|
+
currentConfig !== undefined &&
|
|
341
|
+
configOwnershipHash(currentConfig) === previous.configHash;
|
|
342
|
+
return {
|
|
343
|
+
id: agent.id,
|
|
344
|
+
promptDestination: agent.destination,
|
|
345
|
+
sourceHash: sha256(readFileSync(resolve(configRoot, agent.destination))),
|
|
346
|
+
...(configStillOwned
|
|
347
|
+
? { configKey: previous.configKey, configHash: previous.configHash }
|
|
348
|
+
: {}),
|
|
349
|
+
};
|
|
350
|
+
});
|
|
351
|
+
writeFileSync(
|
|
352
|
+
resolve(configRoot, ".arcs-bundle.json"),
|
|
353
|
+
`${JSON.stringify(
|
|
354
|
+
{
|
|
355
|
+
bundleId: manifest.bundleId,
|
|
356
|
+
installMode: manifest.installMode,
|
|
357
|
+
sourceBundleVersion: "deploy-script",
|
|
358
|
+
sourceBundleHash: sha256(readFileSync(manifestPath)),
|
|
359
|
+
installedAt: new Date().toISOString(),
|
|
360
|
+
ownedPaths: manifest.ownedPaths ?? [],
|
|
361
|
+
agents: installedAgents,
|
|
362
|
+
},
|
|
363
|
+
null,
|
|
364
|
+
2,
|
|
365
|
+
)}\n`,
|
|
366
|
+
"utf-8",
|
|
367
|
+
);
|
|
192
368
|
}
|
|
193
369
|
|
|
194
370
|
// After successful deploy, ensure arcs CLI is globally registered
|
|
@@ -227,7 +403,7 @@ async function main() {
|
|
|
227
403
|
}),
|
|
228
404
|
};
|
|
229
405
|
|
|
230
|
-
process.stdout.write(JSON.stringify(result, null, 2)
|
|
406
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
231
407
|
}
|
|
232
408
|
|
|
233
409
|
try {
|
|
@@ -1,6 +1,32 @@
|
|
|
1
1
|
import { spawnSync } from "node:child_process";
|
|
2
2
|
import { isAbsolute, relative, resolve } from "node:path";
|
|
3
3
|
|
|
4
|
+
export function isActiveAgentForMode(agent, mode) {
|
|
5
|
+
return agent.status === "active" && agent.modes.includes(mode);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function isRetiredAgentForMode(agent, mode) {
|
|
9
|
+
return agent.status === "retired" && agent.modes.includes(mode);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function validateRetirementReplacements(agents) {
|
|
13
|
+
const byId = new Map(agents.map((agent) => [agent.id, agent]));
|
|
14
|
+
for (const agent of agents) {
|
|
15
|
+
if (agent.status !== "retired") continue;
|
|
16
|
+
const replacement = agent.replacementId ? byId.get(agent.replacementId) : undefined;
|
|
17
|
+
if (
|
|
18
|
+
!replacement ||
|
|
19
|
+
replacement.status !== "active" ||
|
|
20
|
+
replacement.kind !== agent.kind ||
|
|
21
|
+
agent.modes.some((mode) => !replacement.modes.includes(mode))
|
|
22
|
+
) {
|
|
23
|
+
throw new Error(
|
|
24
|
+
`Retired agent ${agent.id} must name an active compatible replacement covering kind and modes`,
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
4
30
|
export function normalizeRelativePath(filePath) {
|
|
5
31
|
return filePath.replace(/\\/g, "/");
|
|
6
32
|
}
|
package/scripts/lint-bundle.mjs
CHANGED
|
@@ -21,7 +21,8 @@ const bundleRoot = process.env.BUNDLE_LINT_BUNDLE_ROOT
|
|
|
21
21
|
? resolve(repoRoot, process.env.BUNDLE_LINT_BUNDLE_ROOT)
|
|
22
22
|
: defaultBundleRoot;
|
|
23
23
|
|
|
24
|
-
/** @type {Array<{severity: 'error'|'warning', kind: string, message: string, file?: string, repair?: string}>} */const issues =
|
|
24
|
+
/** @type {Array<{severity: 'error'|'warning', kind: string, message: string, file?: string, repair?: string}>} */ const issues =
|
|
25
|
+
[];
|
|
25
26
|
|
|
26
27
|
function addIssue(severity, kind, message, file, repair) {
|
|
27
28
|
const issue = { severity, kind, message };
|
|
@@ -55,6 +56,114 @@ if (!existsSync(sourceManifestPath)) {
|
|
|
55
56
|
}
|
|
56
57
|
const sourceManifest = JSON.parse(readFileSync(sourceManifestPath, "utf-8"));
|
|
57
58
|
|
|
59
|
+
function isPromptPath(value) {
|
|
60
|
+
if (typeof value !== "string" || value.includes("\\")) return false;
|
|
61
|
+
const segments = value.split("/");
|
|
62
|
+
return (
|
|
63
|
+
segments.length >= 2 &&
|
|
64
|
+
segments[0] === "prompts" &&
|
|
65
|
+
segments.slice(1).every((segment) => segment !== "" && segment !== "." && segment !== "..") &&
|
|
66
|
+
segments.at(-1).endsWith(".txt")
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function isAgentRegistryRecord(agent) {
|
|
71
|
+
return (
|
|
72
|
+
agent &&
|
|
73
|
+
typeof agent.id === "string" &&
|
|
74
|
+
/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(agent.id) &&
|
|
75
|
+
["active", "retired"].includes(agent.status) &&
|
|
76
|
+
["primary", "subagent"].includes(agent.kind) &&
|
|
77
|
+
["heavy", "standard", "light"].includes(agent.tier) &&
|
|
78
|
+
Array.isArray(agent.modes) &&
|
|
79
|
+
agent.modes.length > 0 &&
|
|
80
|
+
agent.modes.every((mode) => ["opencode", "claudecode"].includes(mode)) &&
|
|
81
|
+
isPromptPath(agent.source) &&
|
|
82
|
+
isPromptPath(agent.destination) &&
|
|
83
|
+
typeof agent.description === "string" &&
|
|
84
|
+
agent.description.length > 0 &&
|
|
85
|
+
agent.permissions &&
|
|
86
|
+
["edit", "bash", "webfetch", "mcp", "task"].every((permission) =>
|
|
87
|
+
["allow", "deny"].includes(agent.permissions[permission]),
|
|
88
|
+
)
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (!Array.isArray(sourceManifest.agents)) {
|
|
93
|
+
addIssue(
|
|
94
|
+
"error",
|
|
95
|
+
"invalid-agent-registry",
|
|
96
|
+
`Source manifest agents must be an array`,
|
|
97
|
+
"manifest.json",
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
const registryAgents = Array.isArray(sourceManifest.agents) ? sourceManifest.agents : [];
|
|
101
|
+
const registryIds = new Set();
|
|
102
|
+
const registrySources = new Set();
|
|
103
|
+
const registryDestinations = new Set();
|
|
104
|
+
for (const agent of registryAgents) {
|
|
105
|
+
if (!isAgentRegistryRecord(agent)) {
|
|
106
|
+
addIssue(
|
|
107
|
+
"error",
|
|
108
|
+
"invalid-agent-registry",
|
|
109
|
+
`Source manifest contains an invalid agent registry record`,
|
|
110
|
+
"manifest.json",
|
|
111
|
+
);
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
if (registryIds.has(agent.id)) {
|
|
115
|
+
addIssue(
|
|
116
|
+
"error",
|
|
117
|
+
"invalid-agent-registry",
|
|
118
|
+
`Source manifest contains duplicate agent id ${agent.id}`,
|
|
119
|
+
"manifest.json",
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
registryIds.add(agent.id);
|
|
123
|
+
if (registrySources.has(agent.source)) {
|
|
124
|
+
addIssue(
|
|
125
|
+
"error",
|
|
126
|
+
"invalid-agent-registry",
|
|
127
|
+
`Source manifest contains duplicate agent source ${agent.source}`,
|
|
128
|
+
"manifest.json",
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
registrySources.add(agent.source);
|
|
132
|
+
if (registryDestinations.has(agent.destination)) {
|
|
133
|
+
addIssue(
|
|
134
|
+
"error",
|
|
135
|
+
"invalid-agent-registry",
|
|
136
|
+
`Source manifest contains duplicate agent destination ${agent.destination}`,
|
|
137
|
+
"manifest.json",
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
registryDestinations.add(agent.destination);
|
|
141
|
+
|
|
142
|
+
if (agent.status === "active" && agent.kind === "subagent" && agent.modes.includes("opencode")) {
|
|
143
|
+
const merge = sourceManifest.config?.requiredMerges?.find(
|
|
144
|
+
(entry) =>
|
|
145
|
+
entry.path?.length === 2 && entry.path[0] === "agent" && entry.path[1] === agent.id,
|
|
146
|
+
);
|
|
147
|
+
const value = merge?.value;
|
|
148
|
+
if (
|
|
149
|
+
!value ||
|
|
150
|
+
value.description !== agent.description ||
|
|
151
|
+
value.mode !== agent.kind ||
|
|
152
|
+
value.prompt !== `{file:./${agent.destination}}` ||
|
|
153
|
+
["edit", "bash", "webfetch", "mcp"].some(
|
|
154
|
+
(permission) => value.permission?.[permission] !== agent.permissions[permission],
|
|
155
|
+
)
|
|
156
|
+
) {
|
|
157
|
+
addIssue(
|
|
158
|
+
"error",
|
|
159
|
+
"agent-config-drift",
|
|
160
|
+
`OpenCode config for ${agent.id} does not match its registry record`,
|
|
161
|
+
"manifest.json",
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
58
167
|
// --- Check 1: Every manifest-declared bundled file exists ---
|
|
59
168
|
const declaredFiles = new Set();
|
|
60
169
|
|
|
@@ -77,18 +186,29 @@ for (const [skillName, skillFiles] of Object.entries(manifest.skills ?? {})) {
|
|
|
77
186
|
for (const agentFile of manifest.agents ?? []) {
|
|
78
187
|
declaredFiles.add(agentFile);
|
|
79
188
|
if (!existsSync(resolve(bundleRoot, agentFile))) {
|
|
80
|
-
addIssue(
|
|
189
|
+
addIssue(
|
|
190
|
+
"error",
|
|
191
|
+
"missing-declared-file",
|
|
192
|
+
`Manifest declares ${agentFile} but file is missing`,
|
|
193
|
+
agentFile,
|
|
194
|
+
);
|
|
81
195
|
}
|
|
82
196
|
}
|
|
83
197
|
|
|
84
198
|
for (const pluginFile of manifest.plugin ?? []) {
|
|
85
199
|
declaredFiles.add(pluginFile);
|
|
86
200
|
if (!existsSync(resolve(bundleRoot, pluginFile))) {
|
|
87
|
-
addIssue(
|
|
201
|
+
addIssue(
|
|
202
|
+
"error",
|
|
203
|
+
"missing-declared-file",
|
|
204
|
+
`Manifest declares ${pluginFile} but file is missing`,
|
|
205
|
+
pluginFile,
|
|
206
|
+
);
|
|
88
207
|
}
|
|
89
208
|
}
|
|
90
209
|
|
|
91
210
|
for (const agent of sourceManifest.agents ?? []) {
|
|
211
|
+
if (agent.status !== "active" || !isPromptPath(agent.source)) continue;
|
|
92
212
|
declaredFiles.add(agent.source);
|
|
93
213
|
if (!existsSync(resolve(bundleRoot, agent.source))) {
|
|
94
214
|
addIssue(
|
package/skills/explore-dag.md
CHANGED
|
@@ -17,9 +17,9 @@ flowchart TD
|
|
|
17
17
|
|
|
18
18
|
A[arcs project list → big picture] --> B{Question answered by DAG?}
|
|
19
19
|
B -->|yes| C[Report from DAG data]
|
|
20
|
-
B -->|no| D[Dispatch graph-explorer
|
|
21
|
-
D --> E{Durable discovery?}
|
|
22
|
-
E -->|yes| F[
|
|
20
|
+
B -->|no| D[Dispatch graph-explorer: codegraph then bounded source fallback]:::sub
|
|
21
|
+
D --> E{Durable discovery proposed?}
|
|
22
|
+
E -->|yes| F[Gate proposal before orchestrator persistence]
|
|
23
23
|
E -->|no| C
|
|
24
24
|
F --> C
|
|
25
25
|
```
|
|
@@ -49,6 +49,8 @@ Discovery: `arcs --commands --json`
|
|
|
49
49
|
3. `arcs project get <slug> --json` per dependency for meta/docs
|
|
50
50
|
4. Build dependency chain
|
|
51
51
|
|
|
52
|
+
For repository questions, use DAG-first search (`arcs search`, `arcs related`, and indexed bodies). When DAG evidence is insufficient, `graph-explorer` uses codegraph if available, then bounded source fallback. Exploration remains read-only; durable findings are proposals until their owning phase passes.
|
|
53
|
+
|
|
52
54
|
## Tips
|
|
53
55
|
|
|
54
56
|
- Start with `arcs project list` for the big picture
|
package/skills/init-project.md
CHANGED
|
@@ -15,18 +15,16 @@ User wants to track a new project, bootstrap documentation, or connect a repo to
|
|
|
15
15
|
flowchart TD
|
|
16
16
|
classDef sub fill:#8b5cf6,color:#fff
|
|
17
17
|
|
|
18
|
-
A[Gather
|
|
19
|
-
B --> C[Present
|
|
20
|
-
C
|
|
21
|
-
D
|
|
22
|
-
E
|
|
23
|
-
F
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
I --> J[Collect proposals → dedup → arcs knowledge create × N]
|
|
29
|
-
J --> K[Done]
|
|
18
|
+
A[Gather identity and exact requested artifacts] --> B[Read-only analyses, max four per round]:::sub
|
|
19
|
+
B --> C[Present exact project and docs artifact set]
|
|
20
|
+
C --> D[devil-advocate INIT gate]
|
|
21
|
+
D -->|PASS| E[Request current-turn exact authorization]
|
|
22
|
+
E -->|authorized| F[Orchestrator: arcs project init + approved docs]
|
|
23
|
+
F --> G{pending_enrichment?}
|
|
24
|
+
G -->|yes| H[Read-only enrichment proposals]:::sub
|
|
25
|
+
H --> I[Gate proposals, then orchestrator persists]
|
|
26
|
+
G -->|no| J[Validate and report]
|
|
27
|
+
I --> J
|
|
30
28
|
```
|
|
31
29
|
|
|
32
30
|
## CLI Primer
|
|
@@ -38,14 +36,17 @@ Discovery: `arcs --commands --json`
|
|
|
38
36
|
|
|
39
37
|
## Constraints
|
|
40
38
|
|
|
41
|
-
-
|
|
39
|
+
- Gather project identity and requested artifact scope from the user; repository analysis supplies evidence, not authority
|
|
42
40
|
- Verify `dependsOn` targets exist via `arcs project list --json`
|
|
43
41
|
- Init creates empty plans/ and knowledge/ indexes
|
|
44
|
-
- Repo analysis is
|
|
42
|
+
- Repo analysis is read-only fan-out across typed agents, with at most four disjoint analyses per round
|
|
43
|
+
- No durable write occurs before the INIT gate passes and the user authorizes the exact artifact set in the current turn
|
|
44
|
+
- Plans, tasks, and diagrams use the separate HITL design pipeline: `brainstorming` design approval, then `writing-plans` as sole author, gate, and exact-revision authorization
|
|
45
|
+
- No automatic git actions; add, commit, and push require an explicit current-turn user request
|
|
45
46
|
|
|
46
47
|
## Codegraph Sub-Flow (DEFAULT: ON when binary present)
|
|
47
48
|
|
|
48
|
-
|
|
49
|
+
`arcs project init` uses codegraph when available and degrades cleanly when it is absent. Ingestion creates structural **proposals**, not accepted knowledge. If init reports `pending_enrichment: true`, the orchestrator dispatches the read-only `enriching-codegraph-proposals` skill and persists only proposals that pass their owning gate.
|
|
49
50
|
|
|
50
51
|
1. **Detect:** `detectCodegraph()` from `src/utils/codegraph.ts`. If unavailable, skip cleanly — never block INIT on codegraph.
|
|
51
52
|
2. **Trust the gitignore guarantee:** `runIndex()` already auto-appends `.codegraph/` to `.gitignore` (`ensureGitignoreEntry`). Don't redundantly check or modify `.gitignore` from agents — running the index is sufficient.
|
|
@@ -58,14 +59,14 @@ The orchestrator runs codegraph directly during INIT to produce structural **pro
|
|
|
58
59
|
- 8 god nodes (`kind=module`, ranked by callers+callees / impact)
|
|
59
60
|
- 8 architecture clusters (`kind=architecture`, synthesized pseudo-communities by directory prefix)
|
|
60
61
|
- 5 cross-module couplings (`kind=gotcha`, high-degree links across top-level dirs)
|
|
61
|
-
5. **Enrich** with the `enriching-codegraph-proposals` skill — read `arcs proposal list <slug> --json
|
|
62
|
+
5. **Enrich read-only** with the `enriching-codegraph-proposals` skill — read `arcs proposal list <slug> --json` and return exact keep / merge / drop proposed mutations. Sub-agents may run read-only codegraph MCP queries for evidence:
|
|
62
63
|
- `codegraph_search "entry points and main commands"` → seeds for "key files" reference entries
|
|
63
64
|
- `codegraph_explore` on core modules → seeds for "core modules" entries
|
|
64
65
|
- `codegraph_node "<godNodeLabel>"` → structural summary for module entry bodies
|
|
65
66
|
- `codegraph_impact "<critical-symbol>"` → reverse-impact map for high-risk modules
|
|
66
67
|
- `codegraph_callers` / `codegraph_callees "<symbol>"` → dependency paths for architecture entries
|
|
67
|
-
6. **
|
|
68
|
-
7. **
|
|
68
|
+
6. **Gate:** `devil-advocate` reviews the exact enrichment proposal.
|
|
69
|
+
7. **Persist after PASS:** the orchestrator applies only the gated proposal operations. Workers never write knowledge directly.
|
|
69
70
|
|
|
70
71
|
If codegraph is missing, log "codegraph not on PATH; proceeding without graph signal" and skip steps 3–5. Sub-agents still run; they just lack the graph priors.
|
|
71
72
|
|
|
@@ -82,23 +83,23 @@ If codegraph is missing, log "codegraph not on PATH; proceeding without graph si
|
|
|
82
83
|
|
|
83
84
|
| Sub-agent | Owns | Knowledge kinds it produces |
|
|
84
85
|
|-----------|------|----------------------------|
|
|
85
|
-
| `tech-architect` | Module boundaries, clusters, dependency direction, cross-module couplings, structural gotchas, lessons | `architecture`, `module`, `gotcha`, `lesson` |
|
|
86
|
-
| `
|
|
86
|
+
| `tech-architect` (`AGENT_MODE: architecture`) | Module boundaries, clusters, dependency direction, cross-module couplings, structural gotchas, lessons | `architecture`, `module`, `gotcha`, `lesson` |
|
|
87
|
+
| `tech-architect` (`AGENT_MODE: research`) | Tech stack, third-party libraries, key files, features | `reference`, `feature` |
|
|
87
88
|
| `code-reviewer` (audit mode, optional) | Coding-style + convention scan from existing code | `pattern` |
|
|
88
89
|
|
|
89
|
-
Dispatch
|
|
90
|
+
Dispatch only disjoint read-only analyses in parallel, with a maximum of four agents per round. Each agent receives relevant graph evidence and returns proposals; persistence remains with the orchestrator after the owning gate passes.
|
|
90
91
|
|
|
91
92
|
## Knowledge Categories for Analysis Sub-Agents
|
|
92
93
|
|
|
93
94
|
| Category | Kind | What to discover | Primary agent |
|
|
94
95
|
|----------|------|------------------|---------------|
|
|
95
|
-
| tech stack | `architecture` | Languages, frameworks, runtimes, build tools, versions | `
|
|
96
|
-
| key files | `reference` | Entry points, config files, main modules, purposes | `
|
|
96
|
+
| tech stack | `architecture` | Languages, frameworks, runtimes, build tools, versions | `tech-architect` (`AGENT_MODE: research`) |
|
|
97
|
+
| key files | `reference` | Entry points, config files, main modules, purposes | `tech-architect` (`AGENT_MODE: research`; codegraph_search "entry points") |
|
|
97
98
|
| code patterns | `pattern` | Recurring design patterns, abstractions, error handling | `code-reviewer` (audit mode) or `tech-architect` |
|
|
98
99
|
| coding style | `pattern` | Formatting, linting, import ordering, file organization | `code-reviewer` (audit mode) |
|
|
99
100
|
| core modules | `module` | Core modules/shared functions — what, where, interconnections | `tech-architect` (god nodes from codegraph) |
|
|
100
|
-
| external services | `module` | APIs, databases, message queues the project interacts with | `
|
|
101
|
-
| third-party libraries | `reference` | Key dependencies and why they are used | `
|
|
102
|
-
| features | `feature` | Major user-facing or system-facing features | `
|
|
101
|
+
| external services | `module` | APIs, databases, message queues the project interacts with | `tech-architect` (`AGENT_MODE: research`) |
|
|
102
|
+
| third-party libraries | `reference` | Key dependencies and why they are used | `tech-architect` (`AGENT_MODE: research`) |
|
|
103
|
+
| features | `feature` | Major user-facing or system-facing features | `tech-architect` (`AGENT_MODE: research`) |
|
|
103
104
|
| cross-module couplings | `gotcha` | Hot edges between modules surfaced by codegraph | `tech-architect` (auto from `ingestGraph`) |
|
|
104
105
|
| architecture clusters | `architecture` | Pseudo-community/directory groupings from codegraph | `tech-architect` (auto from `ingestGraph`) |
|
package/skills/orchestrate.md
CHANGED
|
@@ -8,7 +8,7 @@ description: Classify intent and route work across all ARCS workflows
|
|
|
8
8
|
|
|
9
9
|
## When
|
|
10
10
|
|
|
11
|
-
User request
|
|
11
|
+
User request needs routing through INIT, DESIGN, EXECUTE, SYNC, EXPLORE, REVIEW, or MULTI.
|
|
12
12
|
|
|
13
13
|
## Flow
|
|
14
14
|
|
|
@@ -17,12 +17,13 @@ flowchart TD
|
|
|
17
17
|
A[User Request] --> B[T0: arcs brief --lean --json]
|
|
18
18
|
B --> C[Classify Intent]
|
|
19
19
|
C -->|new project| INIT[INIT]
|
|
20
|
-
C -->|plan
|
|
20
|
+
C -->|design/plan| DESIGN[DESIGN]
|
|
21
21
|
C -->|do work| EXECUTE[EXECUTE]
|
|
22
22
|
C -->|reconcile| SYNC[SYNC]
|
|
23
|
-
C -->|discover
|
|
23
|
+
C -->|discover| EXPLORE[EXPLORE]
|
|
24
|
+
C -->|review/audit| REVIEW[REVIEW]
|
|
24
25
|
C -->|compound| MULTI[MULTI]
|
|
25
|
-
INIT &
|
|
26
|
+
INIT & DESIGN & EXECUTE & SYNC & EXPLORE & REVIEW & MULTI --> DONE[Completion gate and terminal state]
|
|
26
27
|
```
|
|
27
28
|
|
|
28
29
|
## Context Tiers
|
|
@@ -58,7 +59,7 @@ flowchart TD
|
|
|
58
59
|
|
|
59
60
|
Use `recommendedSurface` to pick the routing branch:
|
|
60
61
|
- `QUEUE` → execute the active task (EXECUTE workflow)
|
|
61
|
-
- `PLAN` →
|
|
62
|
+
- `PLAN` → design or plan work (DESIGN workflow)
|
|
62
63
|
- `MEMORY` → no active work; review knowledge or propose a new plan
|
|
63
64
|
|
|
64
65
|
## CLI Primer
|
|
@@ -69,14 +70,29 @@ arcs <command> --json
|
|
|
69
70
|
```
|
|
70
71
|
Discovery: `arcs --commands --json`
|
|
71
72
|
|
|
72
|
-
## Skill
|
|
73
|
+
## Agent and Skill Routes
|
|
73
74
|
|
|
74
|
-
|
|
|
75
|
-
|
|
76
|
-
|
|
|
77
|
-
|
|
|
78
|
-
|
|
|
79
|
-
|
|
|
75
|
+
| Agent | AGENT_MODE | Route |
|
|
76
|
+
|-------|------------|-------|
|
|
77
|
+
| `software-engineer` | `default` | Implementation with orchestrator-selected `WORK_MODE: bounded` or `inspect`; load `implementation` |
|
|
78
|
+
| `software-engineer` | `incident` | Diagnosis-first work; add mandatory `systematic-debugging` |
|
|
79
|
+
| `tech-architect` | `architecture` | Read-only design with `brainstorming`, then `writing-plans` only after design approval |
|
|
80
|
+
| `tech-architect` | `research` | DAG-first cited research; use `writing-knowledge` for substantive proposals |
|
|
81
|
+
| `graph-explorer` | `default` | DAG-first repository facts, dependencies, and bounded source questions |
|
|
82
|
+
| `code-reviewer` | `review` / `audit` | Reactive diff/PR review or proactive scope/architecture audit |
|
|
83
|
+
| `devil-advocate` | phase name | Mandatory phase and completion gates |
|
|
84
|
+
| `arcs-docs` | `audit` / `apply` | Two-pass SYNC only |
|
|
85
|
+
|
|
86
|
+
The twelve skills are `implementation`, `test-driven-development`, `executing-plans`, `systematic-debugging`, `brainstorming`, `writing-plans`, `to-diagram`, `writing-knowledge`, `init-project`, `enriching-codegraph-proposals`, `deep-pr-review`, and `caveman-commit`.
|
|
87
|
+
|
|
88
|
+
`WORK_MODE: bounded` means no repository exploration or user questions. `WORK_MODE: inspect` permits limited inspection to resolve at most one material decision. Add `test-driven-development` for new behavior or bug fixes, and add `executing-plans` only for one approved plan node.
|
|
89
|
+
|
|
90
|
+
## Workflow Contracts
|
|
91
|
+
|
|
92
|
+
- **DESIGN:** `brainstorming` produces a read-only design. After the user approves it, `writing-plans` is the sole author of the complete exact plan, task, dependency, verification, and diagram draft. `devil-advocate` gates that draft before exact current-turn authorization and persistence.
|
|
93
|
+
- **SYNC:** exactly two-pass — `arcs-docs` `audit` returns exact proposed mutations; `devil-advocate` gates them; only then may `arcs-docs` `apply` the approved mutations and validate the DAG.
|
|
94
|
+
- **EXPLORE:** use DAG-first retrieval. If the DAG cannot answer, dispatch `graph-explorer` for codegraph or bounded source fallback.
|
|
95
|
+
- **Git:** no automatic git actions. Run add, commit, or push only after an explicit current-turn user request naming the action.
|
|
80
96
|
|
|
81
97
|
## Loop Tools
|
|
82
98
|
|
|
@@ -90,7 +106,7 @@ Use these `arcs loop` session commands only when iterative execution is explicit
|
|
|
90
106
|
|
|
91
107
|
- Sub-agents run ONLY the scoped VERIFY command from their dispatch (tests/lint on files they touched) — never the full suite.
|
|
92
108
|
- The orchestrator never verifies: no tests, lint, builds, or `tsc`.
|
|
93
|
-
- `devil-advocate` PHASE: completion is the session's single full-project pass (
|
|
109
|
+
- `devil-advocate` PHASE: completion is the session's single full-project pass (`npm test`, `npm run typecheck`, and `npm run lint`); on BLOCK, re-dispatch scoped fixes from its FAILURES attribution and re-gate. Two consecutive BLOCKs → stop, report.
|
|
94
110
|
|
|
95
111
|
## Completion
|
|
96
112
|
|