@rryando/arcs 3.9.2 → 3.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 -373
- 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 +168 -15
- 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 -14
- 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 -412
- package/opencode/arcs/prompts/arcs-orchestrate.txt +114 -331
- 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 +28 -12
- package/opencode/arcs/skills/brainstorming/SKILL.md +65 -105
- package/opencode/arcs/skills/brainstorming/scripts/server.js +37 -10
- package/opencode/arcs/skills/brainstorming/scripts/start-server.sh +20 -3
- package/opencode/arcs/skills/brainstorming/scripts/stop-server.sh +25 -6
- package/opencode/arcs/skills/brainstorming/visual-companion.md +3 -10
- 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 +16 -15
- package/opencode/arcs/skills/test-driven-development/SKILL.md +1 -1
- package/opencode/arcs/skills/to-diagram/SKILL.md +10 -29
- 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 +23 -11
- package/scripts/claude-code-session-hook.mjs +125 -0
- package/scripts/deploy-claudecode-bundle.mjs +185 -132
- package/scripts/deploy-opencode-bundle.mjs +207 -6
- package/scripts/lib/bundle-helpers.mjs +29 -3
- 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/brainstorming/spec-document-reviewer-prompt.md +0 -56
- 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,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Collection routes: knowledge, tasks, plans — full CRUD.
|
|
3
|
+
*
|
|
4
|
+
* All meta mutations go through the same locked, validated store functions the
|
|
5
|
+
* CLI uses (knowledge-store / task-store / plan-store). Body .md files are
|
|
6
|
+
* plain markdown and are read/written directly; meta file paths come from the
|
|
7
|
+
* store indexes, never from client input.
|
|
8
|
+
*/
|
|
9
|
+
import { Hono } from "hono";
|
|
10
|
+
export declare const collectionsRoute: Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
|
|
11
|
+
//# sourceMappingURL=collections.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collections.d.ts","sourceRoot":"","sources":["../../../src/web-server/routes/collections.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAgC5B,eAAO,MAAM,gBAAgB,4EAAa,CAAC"}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Collection routes: knowledge, tasks, plans — full CRUD.
|
|
3
|
+
*
|
|
4
|
+
* All meta mutations go through the same locked, validated store functions the
|
|
5
|
+
* CLI uses (knowledge-store / task-store / plan-store). Body .md files are
|
|
6
|
+
* plain markdown and are read/written directly; meta file paths come from the
|
|
7
|
+
* store indexes, never from client input.
|
|
8
|
+
*/
|
|
9
|
+
import { readFile } from "node:fs/promises";
|
|
10
|
+
import { join } from "node:path";
|
|
11
|
+
import { Hono } from "hono";
|
|
12
|
+
import { z } from "zod";
|
|
13
|
+
import { DagError } from "../../utils/errors.js";
|
|
14
|
+
import { createKnowledgeEntry, deleteKnowledgeEntry, KNOWLEDGE_AUDIENCES, KNOWLEDGE_KINDS, readKnowledgeIndex, updateKnowledgeDocument, } from "../../utils/knowledge-store.js";
|
|
15
|
+
import { createPlan, deletePlan, PLAN_STATUSES, readPlanIndex, updatePlanDocument, } from "../../utils/plan-store.js";
|
|
16
|
+
import { normalizeIdentifier } from "../../utils/slug.js";
|
|
17
|
+
import { createTask, deleteTask, listTasks, TASK_PRIORITIES, TASK_STATUSES, updateTask, } from "../../utils/task-store.js";
|
|
18
|
+
import { toposort } from "../../utils/toposort.js";
|
|
19
|
+
import { parseBody, requireProjectDir, respond } from "../respond.js";
|
|
20
|
+
export const collectionsRoute = new Hono();
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
// Shared zod pieces
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
const fileRefSchema = z.object({ path: z.string(), anchor: z.string().optional() });
|
|
25
|
+
async function readEntryBody(projectDir, file) {
|
|
26
|
+
try {
|
|
27
|
+
return await readFile(join(projectDir, file), "utf-8");
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return "";
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function findById(items, rawId, what) {
|
|
34
|
+
const normalizedId = normalizeIdentifier(rawId);
|
|
35
|
+
const item = items.find((i) => i.normalizedId === normalizedId);
|
|
36
|
+
if (!item) {
|
|
37
|
+
throw new DagError("ENTITY_NOT_FOUND", `${what} "${rawId}" not found`);
|
|
38
|
+
}
|
|
39
|
+
return item;
|
|
40
|
+
}
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
// Knowledge
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
const createKnowledgeSchema = z.object({
|
|
45
|
+
id: z.string().min(1),
|
|
46
|
+
title: z.string().min(1),
|
|
47
|
+
kind: z.enum(KNOWLEDGE_KINDS),
|
|
48
|
+
audience: z.enum(KNOWLEDGE_AUDIENCES).optional(),
|
|
49
|
+
keywords: z.array(z.string()).default([]),
|
|
50
|
+
summary: z.string().optional(),
|
|
51
|
+
content: z.string().optional(),
|
|
52
|
+
sourceFiles: z.array(fileRefSchema).optional(),
|
|
53
|
+
});
|
|
54
|
+
const updateKnowledgeSchema = z.object({
|
|
55
|
+
title: z.string().min(1).optional(),
|
|
56
|
+
kind: z.enum(KNOWLEDGE_KINDS).optional(),
|
|
57
|
+
audience: z.enum(KNOWLEDGE_AUDIENCES).nullable().optional(),
|
|
58
|
+
keywords: z.array(z.string()).optional(),
|
|
59
|
+
summary: z.string().optional(),
|
|
60
|
+
sourceFiles: z.array(fileRefSchema).optional(),
|
|
61
|
+
body: z.string().optional(),
|
|
62
|
+
});
|
|
63
|
+
collectionsRoute.get("/api/p/:slug/knowledge", async (c) => respond(c, async () => {
|
|
64
|
+
const projectDir = requireProjectDir(c.req.param("slug"));
|
|
65
|
+
const index = await readKnowledgeIndex(projectDir);
|
|
66
|
+
return { entries: index.entries };
|
|
67
|
+
}));
|
|
68
|
+
collectionsRoute.post("/api/p/:slug/knowledge", async (c) => respond(c, async () => {
|
|
69
|
+
const projectDir = requireProjectDir(c.req.param("slug"));
|
|
70
|
+
const input = await parseBody(c, createKnowledgeSchema);
|
|
71
|
+
return createKnowledgeEntry(projectDir, input);
|
|
72
|
+
}, 201));
|
|
73
|
+
collectionsRoute.get("/api/p/:slug/knowledge/:id", async (c) => respond(c, async () => {
|
|
74
|
+
const projectDir = requireProjectDir(c.req.param("slug"));
|
|
75
|
+
const index = await readKnowledgeIndex(projectDir);
|
|
76
|
+
const meta = findById(index.entries, c.req.param("id"), "Knowledge entry");
|
|
77
|
+
const body = await readEntryBody(projectDir, meta.file);
|
|
78
|
+
return { meta, body };
|
|
79
|
+
}));
|
|
80
|
+
collectionsRoute.patch("/api/p/:slug/knowledge/:id", async (c) => respond(c, async () => {
|
|
81
|
+
const projectDir = requireProjectDir(c.req.param("slug"));
|
|
82
|
+
const id = c.req.param("id");
|
|
83
|
+
const input = await parseBody(c, updateKnowledgeSchema);
|
|
84
|
+
const { body, audience, ...metaFields } = input;
|
|
85
|
+
return updateKnowledgeDocument(projectDir, {
|
|
86
|
+
id,
|
|
87
|
+
...metaFields,
|
|
88
|
+
...(audience !== undefined && { audience }),
|
|
89
|
+
...(body !== undefined && { content: body }),
|
|
90
|
+
});
|
|
91
|
+
}));
|
|
92
|
+
collectionsRoute.delete("/api/p/:slug/knowledge/:id", async (c) => respond(c, async () => {
|
|
93
|
+
const projectDir = requireProjectDir(c.req.param("slug"));
|
|
94
|
+
await deleteKnowledgeEntry(projectDir, c.req.param("id"));
|
|
95
|
+
return { deleted: true };
|
|
96
|
+
}));
|
|
97
|
+
// ---------------------------------------------------------------------------
|
|
98
|
+
// Tasks
|
|
99
|
+
// ---------------------------------------------------------------------------
|
|
100
|
+
const createTaskSchema = z.object({
|
|
101
|
+
title: z.string().min(1),
|
|
102
|
+
status: z.enum(TASK_STATUSES).optional(),
|
|
103
|
+
priority: z.enum(TASK_PRIORITIES).optional(),
|
|
104
|
+
planId: z.string().optional(),
|
|
105
|
+
dependsOn: z.array(z.string()).optional(),
|
|
106
|
+
sourceFiles: z.array(fileRefSchema).optional(),
|
|
107
|
+
scope: z.string().optional(),
|
|
108
|
+
acceptance: z.string().optional(),
|
|
109
|
+
verify: z.string().optional(),
|
|
110
|
+
skill: z.string().optional(),
|
|
111
|
+
workMode: z.enum(["bounded", "inspect"]).optional(),
|
|
112
|
+
});
|
|
113
|
+
const updateTaskSchema = z.object({
|
|
114
|
+
title: z.string().min(1).optional(),
|
|
115
|
+
status: z.enum(TASK_STATUSES).optional(),
|
|
116
|
+
priority: z.enum(TASK_PRIORITIES).optional(),
|
|
117
|
+
planId: z.string().nullable().optional(),
|
|
118
|
+
dependsOn: z.array(z.string()).nullable().optional(),
|
|
119
|
+
sourceFiles: z.array(fileRefSchema).optional(),
|
|
120
|
+
scope: z.string().nullable().optional(),
|
|
121
|
+
acceptance: z.string().nullable().optional(),
|
|
122
|
+
verify: z.string().nullable().optional(),
|
|
123
|
+
skill: z.string().nullable().optional(),
|
|
124
|
+
workMode: z.enum(["bounded", "inspect"]).nullable().optional(),
|
|
125
|
+
});
|
|
126
|
+
collectionsRoute.get("/api/p/:slug/tasks", async (c) => respond(c, async () => {
|
|
127
|
+
const projectDir = requireProjectDir(c.req.param("slug"));
|
|
128
|
+
const tasks = await listTasks(projectDir);
|
|
129
|
+
let order = null;
|
|
130
|
+
if (c.req.query("order") === "topo") {
|
|
131
|
+
try {
|
|
132
|
+
order = toposort(tasks.map((t) => ({ id: t.normalizedId, dependsOn: t.dependsOn, priority: t.priority })));
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
order = null;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return { tasks, order };
|
|
139
|
+
}));
|
|
140
|
+
collectionsRoute.post("/api/p/:slug/tasks", async (c) => respond(c, async () => {
|
|
141
|
+
const projectDir = requireProjectDir(c.req.param("slug"));
|
|
142
|
+
const input = await parseBody(c, createTaskSchema);
|
|
143
|
+
return createTask(projectDir, input);
|
|
144
|
+
}, 201));
|
|
145
|
+
collectionsRoute.patch("/api/p/:slug/tasks/:id", async (c) => respond(c, async () => {
|
|
146
|
+
const projectDir = requireProjectDir(c.req.param("slug"));
|
|
147
|
+
const input = await parseBody(c, updateTaskSchema);
|
|
148
|
+
return updateTask(projectDir, { id: c.req.param("id"), ...input });
|
|
149
|
+
}));
|
|
150
|
+
collectionsRoute.delete("/api/p/:slug/tasks/:id", async (c) => respond(c, async () => {
|
|
151
|
+
const projectDir = requireProjectDir(c.req.param("slug"));
|
|
152
|
+
await deleteTask(projectDir, c.req.param("id"));
|
|
153
|
+
return { deleted: true };
|
|
154
|
+
}));
|
|
155
|
+
// ---------------------------------------------------------------------------
|
|
156
|
+
// Plans
|
|
157
|
+
// ---------------------------------------------------------------------------
|
|
158
|
+
const createPlanSchema = z.object({
|
|
159
|
+
id: z.string().min(1),
|
|
160
|
+
title: z.string().min(1),
|
|
161
|
+
status: z.enum(PLAN_STATUSES),
|
|
162
|
+
keywords: z.array(z.string()).default([]),
|
|
163
|
+
summary: z.string().optional(),
|
|
164
|
+
content: z.string().optional(),
|
|
165
|
+
sourceFiles: z.array(fileRefSchema).optional(),
|
|
166
|
+
});
|
|
167
|
+
const updatePlanSchema = z.object({
|
|
168
|
+
title: z.string().min(1).optional(),
|
|
169
|
+
status: z.enum(PLAN_STATUSES).optional(),
|
|
170
|
+
keywords: z.array(z.string()).optional(),
|
|
171
|
+
summary: z.string().optional(),
|
|
172
|
+
sourceFiles: z.array(fileRefSchema).optional(),
|
|
173
|
+
body: z.string().optional(),
|
|
174
|
+
diagram: z.string().nullable().optional(),
|
|
175
|
+
});
|
|
176
|
+
collectionsRoute.get("/api/p/:slug/plans", async (c) => respond(c, async () => {
|
|
177
|
+
const projectDir = requireProjectDir(c.req.param("slug"));
|
|
178
|
+
const index = await readPlanIndex(projectDir);
|
|
179
|
+
return { plans: index.plans };
|
|
180
|
+
}));
|
|
181
|
+
collectionsRoute.post("/api/p/:slug/plans", async (c) => respond(c, async () => {
|
|
182
|
+
const projectDir = requireProjectDir(c.req.param("slug"));
|
|
183
|
+
const input = await parseBody(c, createPlanSchema);
|
|
184
|
+
return createPlan(projectDir, input);
|
|
185
|
+
}, 201));
|
|
186
|
+
collectionsRoute.get("/api/p/:slug/plans/:id", async (c) => respond(c, async () => {
|
|
187
|
+
const projectDir = requireProjectDir(c.req.param("slug"));
|
|
188
|
+
const index = await readPlanIndex(projectDir);
|
|
189
|
+
const meta = findById(index.plans, c.req.param("id"), "Plan");
|
|
190
|
+
const body = await readEntryBody(projectDir, meta.file);
|
|
191
|
+
let diagram = null;
|
|
192
|
+
try {
|
|
193
|
+
diagram = await readFile(join(projectDir, "plans", `${meta.normalizedId}.diagram.mmd`), "utf-8");
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
diagram = null;
|
|
197
|
+
}
|
|
198
|
+
return { meta, body, diagram };
|
|
199
|
+
}));
|
|
200
|
+
collectionsRoute.patch("/api/p/:slug/plans/:id", async (c) => respond(c, async () => {
|
|
201
|
+
const projectDir = requireProjectDir(c.req.param("slug"));
|
|
202
|
+
const id = c.req.param("id");
|
|
203
|
+
const input = await parseBody(c, updatePlanSchema);
|
|
204
|
+
const { body, diagram, ...metaFields } = input;
|
|
205
|
+
return updatePlanDocument(projectDir, {
|
|
206
|
+
id,
|
|
207
|
+
...metaFields,
|
|
208
|
+
...(body !== undefined && { content: body }),
|
|
209
|
+
...(diagram !== undefined && { diagram }),
|
|
210
|
+
});
|
|
211
|
+
}));
|
|
212
|
+
collectionsRoute.delete("/api/p/:slug/plans/:id", async (c) => respond(c, async () => {
|
|
213
|
+
const projectDir = requireProjectDir(c.req.param("slug"));
|
|
214
|
+
await deletePlan(projectDir, c.req.param("id"));
|
|
215
|
+
return { deleted: true };
|
|
216
|
+
}));
|
|
217
|
+
//# sourceMappingURL=collections.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collections.js","sourceRoot":"","sources":["../../../src/web-server/routes/collections.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Discovery routes: per-project graph (serialized adjacency index),
|
|
3
|
+
* BM25 cross-project search, and codegraph proposal queue actions.
|
|
4
|
+
*/
|
|
5
|
+
import { Hono } from "hono";
|
|
6
|
+
export declare const discoveryRoute: Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
|
|
7
|
+
//# sourceMappingURL=discovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../../src/web-server/routes/discovery.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAkB5B,eAAO,MAAM,cAAc,4EAAa,CAAC"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Discovery routes: per-project graph (serialized adjacency index),
|
|
3
|
+
* BM25 cross-project search, and codegraph proposal queue actions.
|
|
4
|
+
*/
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
import { Hono } from "hono";
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
import { searchAcrossProjects } from "../../retrieval/cross-project-search.js";
|
|
9
|
+
import { buildAdjacencyIndex } from "../../retrieval/graph-builder.js";
|
|
10
|
+
import { DagError } from "../../utils/errors.js";
|
|
11
|
+
import { withLock } from "../../utils/file-lock.js";
|
|
12
|
+
import { createKnowledgeEntry, deleteKnowledgeEntry, readKnowledgeIndex, } from "../../utils/knowledge-store.js";
|
|
13
|
+
import { readPlanIndex } from "../../utils/plan-store.js";
|
|
14
|
+
import { readProposals, removeProposal } from "../../utils/proposal-store.js";
|
|
15
|
+
import { listTasks } from "../../utils/task-store.js";
|
|
16
|
+
import { parseBody, requireProjectDir, respond } from "../respond.js";
|
|
17
|
+
export const discoveryRoute = new Hono();
|
|
18
|
+
discoveryRoute.get("/api/p/:slug/graph", async (c) => respond(c, async () => {
|
|
19
|
+
const slug = c.req.param("slug");
|
|
20
|
+
const projectDir = requireProjectDir(slug);
|
|
21
|
+
const adjacency = await buildAdjacencyIndex(slug);
|
|
22
|
+
const [knowledge, plans, tasks] = await Promise.all([
|
|
23
|
+
readKnowledgeIndex(projectDir).catch(() => ({ entries: [] })),
|
|
24
|
+
readPlanIndex(projectDir).catch(() => ({ plans: [] })),
|
|
25
|
+
listTasks(projectDir).catch(() => []),
|
|
26
|
+
]);
|
|
27
|
+
const kindByKnowledgeId = new Map(knowledge.entries.map((e) => [e.normalizedId, e.kind]));
|
|
28
|
+
const statusByPlanId = new Map(plans.plans.map((p) => [p.normalizedId, p.status]));
|
|
29
|
+
const taskByNormalizedId = new Map(tasks.map((t) => [t.normalizedId, t]));
|
|
30
|
+
const nodes = [...adjacency.nodes.values()].map((node) => {
|
|
31
|
+
const sep = node.id.indexOf(":");
|
|
32
|
+
const rawId = sep >= 0 ? node.id.slice(sep + 1) : node.id;
|
|
33
|
+
const enriched = { ...node };
|
|
34
|
+
if (node.type === "knowledge") {
|
|
35
|
+
enriched.kind = kindByKnowledgeId.get(rawId);
|
|
36
|
+
}
|
|
37
|
+
else if (node.type === "plan") {
|
|
38
|
+
enriched.status = statusByPlanId.get(rawId);
|
|
39
|
+
}
|
|
40
|
+
else if (node.type === "task") {
|
|
41
|
+
const task = taskByNormalizedId.get(rawId);
|
|
42
|
+
enriched.status = task?.status;
|
|
43
|
+
enriched.priority = task?.priority;
|
|
44
|
+
}
|
|
45
|
+
return enriched;
|
|
46
|
+
});
|
|
47
|
+
const edges = [...adjacency.edges.values()].flat();
|
|
48
|
+
return {
|
|
49
|
+
nodes,
|
|
50
|
+
edges,
|
|
51
|
+
buildTime: adjacency.buildTime,
|
|
52
|
+
sourceHashes: adjacency.sourceHashes,
|
|
53
|
+
};
|
|
54
|
+
}));
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
// GET /api/search?q=... — BM25 search across projects
|
|
57
|
+
// ---------------------------------------------------------------------------
|
|
58
|
+
discoveryRoute.get("/api/search", async (c) => respond(c, async () => {
|
|
59
|
+
const rawQuery = c.req.query("q") ?? "";
|
|
60
|
+
if (rawQuery.length > 256) {
|
|
61
|
+
throw new DagError("INVALID_QUERY", "Search queries must be 256 characters or fewer");
|
|
62
|
+
}
|
|
63
|
+
const q = rawQuery.trim();
|
|
64
|
+
const slug = c.req.query("slug");
|
|
65
|
+
const kind = c.req.query("kind");
|
|
66
|
+
const limitRaw = Number(c.req.query("limit") ?? "20");
|
|
67
|
+
const limit = Number.isFinite(limitRaw) ? Math.min(Math.max(1, limitRaw), 100) : 20;
|
|
68
|
+
if (q.length < 2)
|
|
69
|
+
return { results: [], query: q };
|
|
70
|
+
const results = await searchAcrossProjects({
|
|
71
|
+
query: q,
|
|
72
|
+
limit,
|
|
73
|
+
projectSlugs: slug ? [slug] : undefined,
|
|
74
|
+
includeKnowledge: true,
|
|
75
|
+
includePlans: true,
|
|
76
|
+
kind: kind || undefined,
|
|
77
|
+
});
|
|
78
|
+
return { results, query: q };
|
|
79
|
+
}));
|
|
80
|
+
// ---------------------------------------------------------------------------
|
|
81
|
+
// Proposals — list, drop, promote
|
|
82
|
+
// ---------------------------------------------------------------------------
|
|
83
|
+
discoveryRoute.get("/api/p/:slug/proposals", async (c) => respond(c, async () => {
|
|
84
|
+
const slug = c.req.param("slug");
|
|
85
|
+
requireProjectDir(slug);
|
|
86
|
+
const file = await readProposals(slug);
|
|
87
|
+
return {
|
|
88
|
+
proposals: file?.proposals ?? [],
|
|
89
|
+
generatedAt: file?.generatedAt ?? null,
|
|
90
|
+
graphFingerprint: file?.graphFingerprint ?? null,
|
|
91
|
+
};
|
|
92
|
+
}));
|
|
93
|
+
discoveryRoute.post("/api/p/:slug/proposals/:id/drop", async (c) => respond(c, async () => {
|
|
94
|
+
const slug = c.req.param("slug");
|
|
95
|
+
requireProjectDir(slug);
|
|
96
|
+
const removed = await removeProposal(slug, c.req.param("id"));
|
|
97
|
+
if (!removed) {
|
|
98
|
+
throw new DagError("ENTITY_NOT_FOUND", `Proposal "${c.req.param("id")}" not found`);
|
|
99
|
+
}
|
|
100
|
+
return { removed: true };
|
|
101
|
+
}));
|
|
102
|
+
const promoteSchema = z.object({
|
|
103
|
+
title: z.string().min(1).optional(),
|
|
104
|
+
summary: z.string().optional(),
|
|
105
|
+
keywords: z.array(z.string()).optional(),
|
|
106
|
+
content: z.string().optional(),
|
|
107
|
+
});
|
|
108
|
+
discoveryRoute.post("/api/p/:slug/proposals/:id/promote", async (c) => respond(c, async () => {
|
|
109
|
+
const slug = c.req.param("slug");
|
|
110
|
+
const projectDir = requireProjectDir(slug);
|
|
111
|
+
const proposalId = c.req.param("id");
|
|
112
|
+
const overrides = await parseBody(c, promoteSchema);
|
|
113
|
+
return withLock(join(projectDir, ".proposal-promotion"), async () => {
|
|
114
|
+
const file = await readProposals(slug);
|
|
115
|
+
const proposal = file?.proposals.find((entry) => entry.id === proposalId);
|
|
116
|
+
if (!proposal) {
|
|
117
|
+
throw new DagError("ENTITY_NOT_FOUND", `Proposal "${proposalId}" not found`);
|
|
118
|
+
}
|
|
119
|
+
const defaultContent = [
|
|
120
|
+
`# ${overrides.title ?? proposal.label}`,
|
|
121
|
+
"",
|
|
122
|
+
"## Structural facts",
|
|
123
|
+
"",
|
|
124
|
+
"```json",
|
|
125
|
+
JSON.stringify(proposal.structuralFacts, null, 2),
|
|
126
|
+
"```",
|
|
127
|
+
"",
|
|
128
|
+
"## Source files",
|
|
129
|
+
"",
|
|
130
|
+
...proposal.sourceFiles.map((source) => `- \`${source.path}\`${source.anchor ? ` — ${source.anchor}` : ""}`),
|
|
131
|
+
"",
|
|
132
|
+
].join("\n");
|
|
133
|
+
const created = await createKnowledgeEntry(projectDir, {
|
|
134
|
+
id: proposal.id,
|
|
135
|
+
title: overrides.title ?? proposal.label,
|
|
136
|
+
kind: proposal.kind,
|
|
137
|
+
keywords: overrides.keywords ?? [],
|
|
138
|
+
summary: overrides.summary ?? "",
|
|
139
|
+
content: overrides.content ?? defaultContent,
|
|
140
|
+
sourceFiles: proposal.sourceFiles,
|
|
141
|
+
});
|
|
142
|
+
try {
|
|
143
|
+
const removed = await removeProposal(slug, proposalId);
|
|
144
|
+
if (!removed)
|
|
145
|
+
throw new Error(`Proposal "${proposalId}" disappeared during promotion`);
|
|
146
|
+
}
|
|
147
|
+
catch (error) {
|
|
148
|
+
try {
|
|
149
|
+
await deleteKnowledgeEntry(projectDir, created.normalizedId);
|
|
150
|
+
}
|
|
151
|
+
catch (rollbackError) {
|
|
152
|
+
throw new DagError("PROMOTION_INCOMPLETE", `Proposal promotion created knowledge entry "${created.normalizedId}" but both proposal removal and rollback failed. Delete the knowledge entry or drop the proposal before retrying. Removal error: ${error instanceof Error ? error.message : String(error)}. Rollback error: ${rollbackError instanceof Error ? rollbackError.message : String(rollbackError)}.`);
|
|
153
|
+
}
|
|
154
|
+
throw error;
|
|
155
|
+
}
|
|
156
|
+
return { promoted: true, entry: created };
|
|
157
|
+
});
|
|
158
|
+
}, 201));
|
|
159
|
+
//# sourceMappingURL=discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../../src/web-server/routes/discovery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../../src/web-server/routes/events.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAI5B,eAAO,MAAM,WAAW,4EAAa,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSE route: pushes debounced data-dir change events to connected clients.
|
|
3
|
+
*/
|
|
4
|
+
import { Hono } from "hono";
|
|
5
|
+
import { streamSSE } from "hono/streaming";
|
|
6
|
+
import { onDataChange } from "../watcher.js";
|
|
7
|
+
export const eventsRoute = new Hono();
|
|
8
|
+
const HEARTBEAT_MS = 25_000;
|
|
9
|
+
eventsRoute.get("/api/events", (c) => streamSSE(c, async (stream) => {
|
|
10
|
+
const listener = (event) => {
|
|
11
|
+
void stream.writeSSE({ event: "change", data: JSON.stringify(event) }).catch(() => { });
|
|
12
|
+
};
|
|
13
|
+
const unsubscribe = onDataChange(listener);
|
|
14
|
+
const heartbeat = setInterval(() => {
|
|
15
|
+
void stream.writeSSE({ event: "ping", data: "{}" }).catch(() => { });
|
|
16
|
+
}, HEARTBEAT_MS);
|
|
17
|
+
await new Promise((resolve) => {
|
|
18
|
+
stream.onAbort(() => {
|
|
19
|
+
clearInterval(heartbeat);
|
|
20
|
+
unsubscribe();
|
|
21
|
+
resolve();
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
}));
|
|
25
|
+
//# sourceMappingURL=events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../../src/web-server/routes/events.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAoB,YAAY,EAAE,MAAM,eAAe,CAAC;AAE/D,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC;AAEtC,MAAM,YAAY,GAAG,MAAM,CAAC;AAE5B,WAAW,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,EAAE,CACnC,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;IAC5B,MAAM,QAAQ,GAAG,CAAC,KAAkB,EAAE,EAAE;QACtC,KAAK,MAAM,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACzF,CAAC,CAAC;IACF,MAAM,WAAW,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IAE3C,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE;QACjC,KAAK,MAAM,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACtE,CAAC,EAAE,YAAY,CAAC,CAAC;IAEjB,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;QAClC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE;YAClB,aAAa,CAAC,SAAS,CAAC,CAAC;YACzB,WAAW,EAAE,CAAC;YACd,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CACH,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code session-bridge endpoint.
|
|
3
|
+
*
|
|
4
|
+
* Claude Code has no live-injection channel: hooks are stateless, fire per
|
|
5
|
+
* event, and hold no persistent connection. So the session drives the bridge —
|
|
6
|
+
* it announces itself at `SessionStart`, picks up whatever the web UI queued at
|
|
7
|
+
* every `UserPromptSubmit` checkpoint, closes out at `SessionEnd`, and reports
|
|
8
|
+
* its transcript at `Stop` (the last checkpoint before teardown).
|
|
9
|
+
*
|
|
10
|
+
* The response stays ARCS-shaped (`{sessionId, queuedMessages}`); turning that
|
|
11
|
+
* into Claude Code's `hookSpecificOutput` envelope is the hook script's job, so
|
|
12
|
+
* a change to Claude Code's wire format never reaches the server.
|
|
13
|
+
*
|
|
14
|
+
* Unlike every other route here this one is not browser-facing, so it sits
|
|
15
|
+
* behind `requireHookToken` in addition to the global loopback check.
|
|
16
|
+
*/
|
|
17
|
+
import { Hono } from "hono";
|
|
18
|
+
export declare const hookEventsRoute: Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
|
|
19
|
+
//# sourceMappingURL=hook-events.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hook-events.d.ts","sourceRoot":"","sources":["../../../src/web-server/routes/hook-events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAY5B,eAAO,MAAM,eAAe,4EAAa,CAAC"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code session-bridge endpoint.
|
|
3
|
+
*
|
|
4
|
+
* Claude Code has no live-injection channel: hooks are stateless, fire per
|
|
5
|
+
* event, and hold no persistent connection. So the session drives the bridge —
|
|
6
|
+
* it announces itself at `SessionStart`, picks up whatever the web UI queued at
|
|
7
|
+
* every `UserPromptSubmit` checkpoint, closes out at `SessionEnd`, and reports
|
|
8
|
+
* its transcript at `Stop` (the last checkpoint before teardown).
|
|
9
|
+
*
|
|
10
|
+
* The response stays ARCS-shaped (`{sessionId, queuedMessages}`); turning that
|
|
11
|
+
* into Claude Code's `hookSpecificOutput` envelope is the hook script's job, so
|
|
12
|
+
* a change to Claude Code's wire format never reaches the server.
|
|
13
|
+
*
|
|
14
|
+
* Unlike every other route here this one is not browser-facing, so it sits
|
|
15
|
+
* behind `requireHookToken` in addition to the global loopback check.
|
|
16
|
+
*/
|
|
17
|
+
import { Hono } from "hono";
|
|
18
|
+
import { z } from "zod";
|
|
19
|
+
import { mirrorSessionTranscript } from "../../utils/claude-transcript.js";
|
|
20
|
+
import { drainSessionMessageQueue, getSession, updateSession, upsertSession, } from "../../utils/session-store.js";
|
|
21
|
+
import { parseBody, requireProjectDir, respond } from "../respond.js";
|
|
22
|
+
export const hookEventsRoute = new Hono();
|
|
23
|
+
/**
|
|
24
|
+
* Claude Code's native stdin fields, forwarded verbatim by the hook script.
|
|
25
|
+
* Unknown extra fields are ignored rather than rejected — Claude Code adds
|
|
26
|
+
* fields between releases and a hook must not start failing because of it.
|
|
27
|
+
*/
|
|
28
|
+
const hookEventSchema = z.object({
|
|
29
|
+
hook_event_name: z.enum(["SessionStart", "UserPromptSubmit", "Stop", "SessionEnd"]),
|
|
30
|
+
session_id: z.string().min(1),
|
|
31
|
+
cwd: z.string().optional(),
|
|
32
|
+
source: z.string().optional(),
|
|
33
|
+
prompt: z.string().optional(),
|
|
34
|
+
reason: z.string().optional(),
|
|
35
|
+
transcript_path: z.string().optional(),
|
|
36
|
+
control: z.string().optional(),
|
|
37
|
+
});
|
|
38
|
+
/**
|
|
39
|
+
* Builds the metadata persisted on the session. Claude Code's `cwd` lands under
|
|
40
|
+
* the `directory` key: that is the metadata key the sessions UI and the opencode
|
|
41
|
+
* bridge already read, so both runtimes render their worktree the same way.
|
|
42
|
+
* `transcript_path` is persisted under `transcriptPath` (the sessions UI reads
|
|
43
|
+
* that key) so headless-run write-backs can resolve the transcript without the
|
|
44
|
+
* client resupplying it, and `control` is persisted verbatim — the "arcs-owned"
|
|
45
|
+
* marker that suppresses transcript mirroring for records ARCS wrote itself.
|
|
46
|
+
*/
|
|
47
|
+
function sessionMetadata(event) {
|
|
48
|
+
const metadata = {
|
|
49
|
+
...(event.cwd && { directory: event.cwd }),
|
|
50
|
+
...(event.source && { source: event.source }),
|
|
51
|
+
...(event.control !== undefined && { control: event.control }),
|
|
52
|
+
...(event.transcript_path !== undefined && { transcriptPath: event.transcript_path }),
|
|
53
|
+
};
|
|
54
|
+
return Object.keys(metadata).length > 0 ? metadata : undefined;
|
|
55
|
+
}
|
|
56
|
+
function registerSession(projectDir, event) {
|
|
57
|
+
const metadata = sessionMetadata(event);
|
|
58
|
+
return upsertSession(projectDir, {
|
|
59
|
+
runtimeType: "claude-code",
|
|
60
|
+
runtimeSessionId: event.session_id,
|
|
61
|
+
status: "active",
|
|
62
|
+
...(metadata && { metadata }),
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Merges checkpoint-derived fields (transcriptPath, control, directory…) into
|
|
67
|
+
* the session's metadata. A checkpoint usually arrives for a session registered
|
|
68
|
+
* at SessionStart, so `resolveCheckpointSession` returns it without persisting
|
|
69
|
+
* the checkpoint's own fields — without this merge the transcript path and the
|
|
70
|
+
* arcs-owned marker carried by the checkpoint would be dropped.
|
|
71
|
+
*/
|
|
72
|
+
async function persistCheckpointMetadata(projectDir, session, event) {
|
|
73
|
+
const metadata = sessionMetadata(event);
|
|
74
|
+
if (metadata === undefined)
|
|
75
|
+
return session;
|
|
76
|
+
return updateSession(projectDir, { id: session.normalizedId, metadata });
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Resolves the session behind a checkpoint, registering it if this is the first
|
|
80
|
+
* event ARCS has seen. `resume`/`compact` can deliver a prompt for a session
|
|
81
|
+
* whose SessionStart never reached us, and dropping the checkpoint would strand
|
|
82
|
+
* every message queued for it.
|
|
83
|
+
*/
|
|
84
|
+
async function resolveCheckpointSession(projectDir, event) {
|
|
85
|
+
try {
|
|
86
|
+
return await getSession(projectDir, event.session_id);
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return registerSession(projectDir, event);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
async function handleHookEvent(projectDir, event) {
|
|
93
|
+
if (event.hook_event_name === "SessionStart") {
|
|
94
|
+
const session = await registerSession(projectDir, event);
|
|
95
|
+
return { sessionId: session.normalizedId, queuedMessages: [] };
|
|
96
|
+
}
|
|
97
|
+
if (event.hook_event_name === "UserPromptSubmit") {
|
|
98
|
+
const session = await resolveCheckpointSession(projectDir, event);
|
|
99
|
+
const checkpoint = await persistCheckpointMetadata(projectDir, session, event);
|
|
100
|
+
if (event.transcript_path !== undefined && checkpoint.metadata?.control !== "arcs-owned") {
|
|
101
|
+
await mirrorSessionTranscript(projectDir, checkpoint.normalizedId, event.transcript_path);
|
|
102
|
+
}
|
|
103
|
+
const queuedMessages = await drainSessionMessageQueue(projectDir, checkpoint.normalizedId);
|
|
104
|
+
return { sessionId: checkpoint.normalizedId, queuedMessages };
|
|
105
|
+
}
|
|
106
|
+
if (event.hook_event_name === "Stop") {
|
|
107
|
+
// Stop is a checkpoint like UserPromptSubmit, so an unknown session is
|
|
108
|
+
// auto-registered — but the queue is deliberately NOT drained: a message
|
|
109
|
+
// queued for the session must survive to the next UserPromptSubmit, and
|
|
110
|
+
// Stop can arrive before that checkpoint if the turn ends without one.
|
|
111
|
+
const session = await resolveCheckpointSession(projectDir, event);
|
|
112
|
+
const checkpoint = await persistCheckpointMetadata(projectDir, session, event);
|
|
113
|
+
if (event.transcript_path !== undefined && checkpoint.metadata?.control !== "arcs-owned") {
|
|
114
|
+
await mirrorSessionTranscript(projectDir, checkpoint.normalizedId, event.transcript_path);
|
|
115
|
+
}
|
|
116
|
+
return { sessionId: checkpoint.normalizedId, queuedMessages: [] };
|
|
117
|
+
}
|
|
118
|
+
// SessionEnd. Every documented reason (clear|resume|logout|other) is an
|
|
119
|
+
// ordinary teardown — none of them signals a crash, so none maps to "failed".
|
|
120
|
+
const metadata = sessionMetadata(event);
|
|
121
|
+
const session = await updateSession(projectDir, {
|
|
122
|
+
id: event.session_id,
|
|
123
|
+
status: "completed",
|
|
124
|
+
...(metadata !== undefined && { metadata }),
|
|
125
|
+
});
|
|
126
|
+
if (event.transcript_path !== undefined && session.metadata?.control !== "arcs-owned") {
|
|
127
|
+
await mirrorSessionTranscript(projectDir, session.normalizedId, event.transcript_path);
|
|
128
|
+
}
|
|
129
|
+
return { sessionId: session.normalizedId, queuedMessages: [] };
|
|
130
|
+
}
|
|
131
|
+
hookEventsRoute.post("/api/hook/:slug/event", async (c) => respond(c, async () => {
|
|
132
|
+
const projectDir = requireProjectDir(c.req.param("slug"));
|
|
133
|
+
return handleHookEvent(projectDir, await parseBody(c, hookEventSchema));
|
|
134
|
+
}));
|
|
135
|
+
//# sourceMappingURL=hook-events.js.map
|