@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.
Files changed (331) hide show
  1. package/README.md +172 -146
  2. package/dist/cli/agent-registry.d.ts +12 -0
  3. package/dist/cli/agent-registry.d.ts.map +1 -0
  4. package/dist/cli/agent-registry.js +67 -0
  5. package/dist/cli/agent-registry.js.map +1 -0
  6. package/dist/cli/arcs-flash.d.ts +2 -0
  7. package/dist/cli/arcs-flash.d.ts.map +1 -0
  8. package/dist/cli/arcs-flash.js +68 -0
  9. package/dist/cli/arcs-flash.js.map +1 -0
  10. package/dist/cli/arcs-orchestrate-caveman.d.ts +2 -14
  11. package/dist/cli/arcs-orchestrate-caveman.d.ts.map +1 -1
  12. package/dist/cli/arcs-orchestrate-caveman.js +6 -97
  13. package/dist/cli/arcs-orchestrate-caveman.js.map +1 -1
  14. package/dist/cli/arcs-orchestrate.d.ts +1 -1
  15. package/dist/cli/arcs-orchestrate.d.ts.map +1 -1
  16. package/dist/cli/arcs-orchestrate.js +40 -373
  17. package/dist/cli/arcs-orchestrate.js.map +1 -1
  18. package/dist/cli/bundle-installer.d.ts +10 -4
  19. package/dist/cli/bundle-installer.d.ts.map +1 -1
  20. package/dist/cli/bundle-installer.js +168 -15
  21. package/dist/cli/bundle-installer.js.map +1 -1
  22. package/dist/cli/commands/batch.js +4 -0
  23. package/dist/cli/commands/batch.js.map +1 -1
  24. package/dist/cli/commands/hooks.d.ts +36 -0
  25. package/dist/cli/commands/hooks.d.ts.map +1 -0
  26. package/dist/cli/commands/hooks.js +298 -0
  27. package/dist/cli/commands/hooks.js.map +1 -0
  28. package/dist/cli/commands/index.d.ts +2 -0
  29. package/dist/cli/commands/index.d.ts.map +1 -1
  30. package/dist/cli/commands/index.js +2 -0
  31. package/dist/cli/commands/index.js.map +1 -1
  32. package/dist/cli/commands/project.js +27 -0
  33. package/dist/cli/commands/project.js.map +1 -1
  34. package/dist/cli/commands/task.js +16 -1
  35. package/dist/cli/commands/task.js.map +1 -1
  36. package/dist/cli/commands/web.d.ts +2 -0
  37. package/dist/cli/commands/web.d.ts.map +1 -0
  38. package/dist/cli/commands/web.js +56 -0
  39. package/dist/cli/commands/web.js.map +1 -0
  40. package/dist/cli/config.d.ts +32 -0
  41. package/dist/cli/config.d.ts.map +1 -1
  42. package/dist/cli/config.js +56 -0
  43. package/dist/cli/config.js.map +1 -1
  44. package/dist/cli/instructions.d.ts +19 -6
  45. package/dist/cli/instructions.d.ts.map +1 -1
  46. package/dist/cli/instructions.js +62 -32
  47. package/dist/cli/instructions.js.map +1 -1
  48. package/dist/cli/orchestrator-shared-blocks.d.ts +31 -0
  49. package/dist/cli/orchestrator-shared-blocks.d.ts.map +1 -0
  50. package/dist/cli/orchestrator-shared-blocks.js +148 -0
  51. package/dist/cli/orchestrator-shared-blocks.js.map +1 -0
  52. package/dist/cli/setup.d.ts.map +1 -1
  53. package/dist/cli/setup.js +159 -85
  54. package/dist/cli/setup.js.map +1 -1
  55. package/dist/retrieval/index-builder.d.ts.map +1 -1
  56. package/dist/retrieval/index-builder.js +29 -1
  57. package/dist/retrieval/index-builder.js.map +1 -1
  58. package/dist/utils/claude-code-hook-install.d.ts +80 -0
  59. package/dist/utils/claude-code-hook-install.d.ts.map +1 -0
  60. package/dist/utils/claude-code-hook-install.js +146 -0
  61. package/dist/utils/claude-code-hook-install.js.map +1 -0
  62. package/dist/utils/claude-transcript.d.ts +127 -0
  63. package/dist/utils/claude-transcript.d.ts.map +1 -0
  64. package/dist/utils/claude-transcript.js +353 -0
  65. package/dist/utils/claude-transcript.js.map +1 -0
  66. package/dist/utils/diagram-generator.d.ts +1 -1
  67. package/dist/utils/diagram-generator.d.ts.map +1 -1
  68. package/dist/utils/diagram-generator.js +3 -2
  69. package/dist/utils/diagram-generator.js.map +1 -1
  70. package/dist/utils/errors.d.ts +6 -2
  71. package/dist/utils/errors.d.ts.map +1 -1
  72. package/dist/utils/errors.js +12 -0
  73. package/dist/utils/errors.js.map +1 -1
  74. package/dist/utils/hook-token-store.d.ts +22 -0
  75. package/dist/utils/hook-token-store.d.ts.map +1 -0
  76. package/dist/utils/hook-token-store.js +43 -0
  77. package/dist/utils/hook-token-store.js.map +1 -0
  78. package/dist/utils/json-schemas.d.ts +186 -2
  79. package/dist/utils/json-schemas.d.ts.map +1 -1
  80. package/dist/utils/json-schemas.js +48 -4
  81. package/dist/utils/json-schemas.js.map +1 -1
  82. package/dist/utils/knowledge-store.d.ts +7 -1
  83. package/dist/utils/knowledge-store.d.ts.map +1 -1
  84. package/dist/utils/knowledge-store.js +97 -65
  85. package/dist/utils/knowledge-store.js.map +1 -1
  86. package/dist/utils/plan-store.d.ts +8 -0
  87. package/dist/utils/plan-store.d.ts.map +1 -1
  88. package/dist/utils/plan-store.js +98 -59
  89. package/dist/utils/plan-store.js.map +1 -1
  90. package/dist/utils/project-resolver.d.ts +8 -0
  91. package/dist/utils/project-resolver.d.ts.map +1 -1
  92. package/dist/utils/project-resolver.js +7 -2
  93. package/dist/utils/project-resolver.js.map +1 -1
  94. package/dist/utils/session-store.d.ts +113 -0
  95. package/dist/utils/session-store.d.ts.map +1 -0
  96. package/dist/utils/session-store.js +312 -0
  97. package/dist/utils/session-store.js.map +1 -0
  98. package/dist/utils/storage-utils.d.ts +31 -0
  99. package/dist/utils/storage-utils.d.ts.map +1 -1
  100. package/dist/utils/storage-utils.js +116 -5
  101. package/dist/utils/storage-utils.js.map +1 -1
  102. package/dist/utils/task-store.d.ts +7 -0
  103. package/dist/utils/task-store.d.ts.map +1 -1
  104. package/dist/utils/task-store.js +73 -23
  105. package/dist/utils/task-store.js.map +1 -1
  106. package/dist/web-client/assets/GraphCanvas-dNyZ458L.js +1 -0
  107. package/dist/web-client/assets/MarkdownEditor-BmU9mdkN.js +77 -0
  108. package/dist/web-client/assets/abnfDiagram-VRR7QNED-D1BFBoeF.js +1 -0
  109. package/dist/web-client/assets/arc-Bfaogrm1.js +1 -0
  110. package/dist/web-client/assets/architecture-TIHT7OUA-CJqI5wNI.js +1 -0
  111. package/dist/web-client/assets/architectureDiagram-ZJ3FMSHR-CA8hTWUK.js +36 -0
  112. package/dist/web-client/assets/array-BifhSqXX.js +1 -0
  113. package/dist/web-client/assets/blockDiagram-677ZJIJ3-CQpb_KwX.js +132 -0
  114. package/dist/web-client/assets/c4Diagram-LMCZKHZV-BhpHX84V.js +10 -0
  115. package/dist/web-client/assets/channel-C8DlmyVe.js +1 -0
  116. package/dist/web-client/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
  117. package/dist/web-client/assets/chunk-32BRIVSS-BUusQQa_.js +1 -0
  118. package/dist/web-client/assets/chunk-52WLFC77-nNYwlftl.js +10 -0
  119. package/dist/web-client/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
  120. package/dist/web-client/assets/chunk-7BUUIJ7U-Bb538aSH.js +1 -0
  121. package/dist/web-client/assets/chunk-C7G6YPKG-D0a-yqnK.js +1 -0
  122. package/dist/web-client/assets/chunk-EX3LRPZG-IDuRMN-4.js +231 -0
  123. package/dist/web-client/assets/chunk-FWX5IMBZ-D_spTcqi.js +2 -0
  124. package/dist/web-client/assets/chunk-HOUHSVGY-C-bcxwZS.js +1 -0
  125. package/dist/web-client/assets/chunk-ICXQ74PX-CjmK2bAM.js +2 -0
  126. package/dist/web-client/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
  127. package/dist/web-client/assets/chunk-KEIR6QF5-DEvma7oi.js +161 -0
  128. package/dist/web-client/assets/chunk-MOJQB5TN-Bkc08KWY.js +88 -0
  129. package/dist/web-client/assets/chunk-OGEWGWER-BAAYYvG9.js +1 -0
  130. package/dist/web-client/assets/chunk-PUDLZKDR-WXbPY7NM.js +156 -0
  131. package/dist/web-client/assets/chunk-Q4XR5HBZ-DcbnjxQE.js +70 -0
  132. package/dist/web-client/assets/chunk-RYQCIY6F-np2RyIY1.js +1 -0
  133. package/dist/web-client/assets/chunk-V7JOEXUC-C6t75PAp.js +206 -0
  134. package/dist/web-client/assets/chunk-VAUOI2AC-DVrJ0Ic7.js +1 -0
  135. package/dist/web-client/assets/chunk-VR4S4FIN-MOOFvGS0.js +1 -0
  136. package/dist/web-client/assets/chunk-WYO6CB5R-sK7Y2NZD.js +125 -0
  137. package/dist/web-client/assets/chunk-XXDRQBXY-BvKO0v-W.js +1 -0
  138. package/dist/web-client/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
  139. package/dist/web-client/assets/chunk-ZGVPDNZ5-a13RQsku.js +62 -0
  140. package/dist/web-client/assets/chunk-ZIRB5QZD-BpeS1aZ7.js +32 -0
  141. package/dist/web-client/assets/classDiagram-OUVF2IWQ-p32N1P_G.js +1 -0
  142. package/dist/web-client/assets/classDiagram-v2-EOCWNBFH-p32N1P_G.js +1 -0
  143. package/dist/web-client/assets/cose-bilkent-JH36ORCC-BebHqzgp.js +1 -0
  144. package/dist/web-client/assets/cynefin-VYW2F7L2-D8xaH-wO.js +1 -0
  145. package/dist/web-client/assets/cynefinDiagram-TSTJHNR4-Bt__EqJW.js +62 -0
  146. package/dist/web-client/assets/cytoscape-fcose-peAzqedC.js +1 -0
  147. package/dist/web-client/assets/cytoscape.esm-C3UvhD5t.js +321 -0
  148. package/dist/web-client/assets/dagre-Buvkdvvj.js +1 -0
  149. package/dist/web-client/assets/dagre-VKFMJZFB-Bwgjwflz.js +4 -0
  150. package/dist/web-client/assets/defaultLocale-BFoDCU3G.js +1 -0
  151. package/dist/web-client/assets/diagram-FQU43EPY-CaPDVUq2.js +3 -0
  152. package/dist/web-client/assets/diagram-G47NLZAW-BQLB9YYA.js +24 -0
  153. package/dist/web-client/assets/diagram-NH7WQ7WH-BWo84w8Y.js +24 -0
  154. package/dist/web-client/assets/diagram-OA4YK3LP-bKn6Pz5s.js +30 -0
  155. package/dist/web-client/assets/diagram-WEI45ONY-BRqV5Oy6.js +41 -0
  156. package/dist/web-client/assets/dist-B_J_HbC0.js +1 -0
  157. package/dist/web-client/assets/ebnfDiagram-CCIWWBDH-DhUXL1-7.js +1 -0
  158. package/dist/web-client/assets/erDiagram-Q63AITRT-HXAQQ-_F.js +85 -0
  159. package/dist/web-client/assets/eventmodeling-45OFAUF4-Bj5P8mZJ.js +1 -0
  160. package/dist/web-client/assets/flowDiagram-23GEKE2U-37BztFri.js +1 -0
  161. package/dist/web-client/assets/ganttDiagram-NO4QXBWP-D-Ddf_Ii.js +292 -0
  162. package/dist/web-client/assets/gitGraph-TEB2WS4Q-BmHzs0uF.js +1 -0
  163. package/dist/web-client/assets/gitGraphDiagram-IHSO6WYX-YnQWrlh_.js +106 -0
  164. package/dist/web-client/assets/graphlib-DS17s2tU.js +1 -0
  165. package/dist/web-client/assets/index-3mNPVkix.css +2 -0
  166. package/dist/web-client/assets/index-DCWxuIeQ.js +58 -0
  167. package/dist/web-client/assets/info-DKCQHKI2-DCT_B7RN.js +1 -0
  168. package/dist/web-client/assets/infoDiagram-FWYZ7A6U-D-le1Zhq.js +2 -0
  169. package/dist/web-client/assets/init-C-OQMol4.js +1 -0
  170. package/dist/web-client/assets/ishikawaDiagram-FXEZZL3T-Jr1x2VJB.js +70 -0
  171. package/dist/web-client/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2 +0 -0
  172. package/dist/web-client/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2 +0 -0
  173. package/dist/web-client/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
  174. package/dist/web-client/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
  175. package/dist/web-client/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2 +0 -0
  176. package/dist/web-client/assets/journeyDiagram-5HDEW3XC-BF9ELxj-.js +139 -0
  177. package/dist/web-client/assets/kanban-definition-HUTT4EX6-C4fJqAxu.js +89 -0
  178. package/dist/web-client/assets/katex-DolUETbr.js +257 -0
  179. package/dist/web-client/assets/line-7N7ikFxa.js +1 -0
  180. package/dist/web-client/assets/linear-DeUiD2wj.js +1 -0
  181. package/dist/web-client/assets/map-BaFkSB1l.js +1 -0
  182. package/dist/web-client/assets/mermaid-parser.core-QbC1icPt.js +7 -0
  183. package/dist/web-client/assets/mermaid.core-C26d_UJm.js +11 -0
  184. package/dist/web-client/assets/mindmap-definition-LN4V7U3C-D6TV1JDf.js +96 -0
  185. package/dist/web-client/assets/ordinal-BDEzSJ7C.js +1 -0
  186. package/dist/web-client/assets/packet-7NZHBO7P-CR1vrGj3.js +1 -0
  187. package/dist/web-client/assets/path-COt_16Va.js +1 -0
  188. package/dist/web-client/assets/pegDiagram-2B236MQR-xOMBBtfV.js +1 -0
  189. package/dist/web-client/assets/pie-RZYD4A2V-BbWuhjwy.js +1 -0
  190. package/dist/web-client/assets/pieDiagram-ENE6RG2P-MsfnsqgW.js +39 -0
  191. package/dist/web-client/assets/quadrantDiagram-ABIIQ3AL-BoI7zKXF.js +7 -0
  192. package/dist/web-client/assets/radar-I7S5WNFK-CbYXKToJ.js +1 -0
  193. package/dist/web-client/assets/railroad-3IZDKUUU-6LxHDkLe.js +1 -0
  194. package/dist/web-client/assets/railroad-abnf-AHOZXSZD-2Dg9wu0J.js +1 -0
  195. package/dist/web-client/assets/railroad-ebnf-EBAXGLYW-C_E2ot0R.js +1 -0
  196. package/dist/web-client/assets/railroad-peg-LSFZ7HO6-Bs9UQR1b.js +1 -0
  197. package/dist/web-client/assets/railroadDiagram-RFXS5EU6-D6RUoUki.js +1 -0
  198. package/dist/web-client/assets/requirementDiagram-TGXJPOKE-B6k4BDpE.js +84 -0
  199. package/dist/web-client/assets/rolldown-runtime-Dd_uD5pT.js +1 -0
  200. package/dist/web-client/assets/rough.esm-By172zw-.js +1 -0
  201. package/dist/web-client/assets/sankeyDiagram-HTMAVEWB-BUDF-UFr.js +40 -0
  202. package/dist/web-client/assets/sequenceDiagram-DBY2YBRQ-D6GqcsUi.js +162 -0
  203. package/dist/web-client/assets/sizeCapture-X5ZJPWSS-B0uUizjq.js +1 -0
  204. package/dist/web-client/assets/src-oBChb5qS.js +1 -0
  205. package/dist/web-client/assets/stateDiagram-2N3HPSRC-WfJCQAK5.js +1 -0
  206. package/dist/web-client/assets/stateDiagram-v2-6OUMAXLB-BCMWGnsJ.js +1 -0
  207. package/dist/web-client/assets/swimlanes-5IMT3BWC-BtMo82mC.js +2 -0
  208. package/dist/web-client/assets/swimlanesDiagram-G3AALYLV-DmudmLcK.js +8 -0
  209. package/dist/web-client/assets/timeline-definition-FHXFAJF6-CoAmv2Sn.js +120 -0
  210. package/dist/web-client/assets/treeView-QDETBFTQ-BWsKzE1s.js +1 -0
  211. package/dist/web-client/assets/treemap-6X3UGDF4-i_qGtB3o.js +1 -0
  212. package/dist/web-client/assets/vennDiagram-L72KCM5P-DYkiLe-P.js +34 -0
  213. package/dist/web-client/assets/wardley-OPB4EBWU-Daaqr1Vp.js +1 -0
  214. package/dist/web-client/assets/wardleyDiagram-EHGQE667-Bofbsg3J.js +78 -0
  215. package/dist/web-client/assets/xychartDiagram-FW5EYKEG-KNF4VTfL.js +7 -0
  216. package/dist/web-client/index.html +15 -0
  217. package/dist/web-server/app.d.ts +13 -0
  218. package/dist/web-server/app.d.ts.map +1 -0
  219. package/dist/web-server/app.js +58 -0
  220. package/dist/web-server/app.js.map +1 -0
  221. package/dist/web-server/claude-runner.d.ts +86 -0
  222. package/dist/web-server/claude-runner.d.ts.map +1 -0
  223. package/dist/web-server/claude-runner.js +320 -0
  224. package/dist/web-server/claude-runner.js.map +1 -0
  225. package/dist/web-server/hook-auth.d.ts +12 -0
  226. package/dist/web-server/hook-auth.d.ts.map +1 -0
  227. package/dist/web-server/hook-auth.js +36 -0
  228. package/dist/web-server/hook-auth.js.map +1 -0
  229. package/dist/web-server/index.d.ts +23 -0
  230. package/dist/web-server/index.d.ts.map +1 -0
  231. package/dist/web-server/index.js +49 -0
  232. package/dist/web-server/index.js.map +1 -0
  233. package/dist/web-server/opencode-client.d.ts +123 -0
  234. package/dist/web-server/opencode-client.d.ts.map +1 -0
  235. package/dist/web-server/opencode-client.js +514 -0
  236. package/dist/web-server/opencode-client.js.map +1 -0
  237. package/dist/web-server/respond.d.ts +33 -0
  238. package/dist/web-server/respond.d.ts.map +1 -0
  239. package/dist/web-server/respond.js +79 -0
  240. package/dist/web-server/respond.js.map +1 -0
  241. package/dist/web-server/routes/collections.d.ts +11 -0
  242. package/dist/web-server/routes/collections.d.ts.map +1 -0
  243. package/dist/web-server/routes/collections.js +217 -0
  244. package/dist/web-server/routes/collections.js.map +1 -0
  245. package/dist/web-server/routes/discovery.d.ts +7 -0
  246. package/dist/web-server/routes/discovery.d.ts.map +1 -0
  247. package/dist/web-server/routes/discovery.js +159 -0
  248. package/dist/web-server/routes/discovery.js.map +1 -0
  249. package/dist/web-server/routes/events.d.ts +6 -0
  250. package/dist/web-server/routes/events.d.ts.map +1 -0
  251. package/dist/web-server/routes/events.js +25 -0
  252. package/dist/web-server/routes/events.js.map +1 -0
  253. package/dist/web-server/routes/hook-events.d.ts +19 -0
  254. package/dist/web-server/routes/hook-events.d.ts.map +1 -0
  255. package/dist/web-server/routes/hook-events.js +135 -0
  256. package/dist/web-server/routes/hook-events.js.map +1 -0
  257. package/dist/web-server/routes/projects.d.ts +7 -0
  258. package/dist/web-server/routes/projects.d.ts.map +1 -0
  259. package/dist/web-server/routes/projects.js +272 -0
  260. package/dist/web-server/routes/projects.js.map +1 -0
  261. package/dist/web-server/routes/sessions.d.ts +16 -0
  262. package/dist/web-server/routes/sessions.d.ts.map +1 -0
  263. package/dist/web-server/routes/sessions.js +442 -0
  264. package/dist/web-server/routes/sessions.js.map +1 -0
  265. package/dist/web-server/security.d.ts +7 -0
  266. package/dist/web-server/security.d.ts.map +1 -0
  267. package/dist/web-server/security.js +41 -0
  268. package/dist/web-server/security.js.map +1 -0
  269. package/dist/web-server/static.d.ts +10 -0
  270. package/dist/web-server/static.d.ts.map +1 -0
  271. package/dist/web-server/static.js +36 -0
  272. package/dist/web-server/static.js.map +1 -0
  273. package/dist/web-server/storage.d.ts +17 -0
  274. package/dist/web-server/storage.d.ts.map +1 -0
  275. package/dist/web-server/storage.js +42 -0
  276. package/dist/web-server/storage.js.map +1 -0
  277. package/dist/web-server/watcher.d.ts +37 -0
  278. package/dist/web-server/watcher.d.ts.map +1 -0
  279. package/dist/web-server/watcher.js +181 -0
  280. package/dist/web-server/watcher.js.map +1 -0
  281. package/opencode/arcs/bundle-runtime.json +5 -14
  282. package/opencode/arcs/manifest.json +213 -149
  283. package/opencode/arcs/prompts/arcs-docs.txt +53 -47
  284. package/opencode/arcs/prompts/arcs-flash.txt +190 -0
  285. package/opencode/arcs/prompts/arcs-orchestrate-caveman.txt +116 -412
  286. package/opencode/arcs/prompts/arcs-orchestrate.txt +114 -331
  287. package/opencode/arcs/prompts/code-reviewer.txt +37 -98
  288. package/opencode/arcs/prompts/devil-advocate.txt +44 -115
  289. package/opencode/arcs/prompts/graph-explorer.txt +31 -179
  290. package/opencode/arcs/prompts/software-engineer.txt +24 -6
  291. package/opencode/arcs/prompts/tech-architect.txt +28 -12
  292. package/opencode/arcs/skills/brainstorming/SKILL.md +65 -105
  293. package/opencode/arcs/skills/brainstorming/scripts/server.js +37 -10
  294. package/opencode/arcs/skills/brainstorming/scripts/start-server.sh +20 -3
  295. package/opencode/arcs/skills/brainstorming/scripts/stop-server.sh +25 -6
  296. package/opencode/arcs/skills/brainstorming/visual-companion.md +3 -10
  297. package/opencode/arcs/skills/deep-pr-review/SKILL.md +5 -5
  298. package/opencode/arcs/skills/deep-pr-review/review-template.md +1 -1
  299. package/opencode/arcs/skills/enriching-codegraph-proposals/SKILL.md +17 -18
  300. package/opencode/arcs/skills/executing-plans/SKILL.md +26 -234
  301. package/opencode/arcs/skills/implementation/SKILL.md +61 -0
  302. package/opencode/arcs/skills/init-project/SKILL.md +16 -15
  303. package/opencode/arcs/skills/install-claude-code-hook/SKILL.md +143 -0
  304. package/opencode/arcs/skills/systematic-debugging/SKILL.md +16 -15
  305. package/opencode/arcs/skills/test-driven-development/SKILL.md +1 -1
  306. package/opencode/arcs/skills/to-diagram/SKILL.md +10 -29
  307. package/opencode/arcs/skills/writing-knowledge/SKILL.md +7 -6
  308. package/opencode/arcs/skills/writing-plans/SKILL.md +80 -130
  309. package/opencode/arcs/skills/writing-plans/plan-document-reviewer-prompt.md +38 -30
  310. package/package.json +14 -6
  311. package/scripts/build-opencode-bundle.mjs +23 -11
  312. package/scripts/claude-code-session-hook.mjs +125 -0
  313. package/scripts/deploy-claudecode-bundle.mjs +185 -132
  314. package/scripts/deploy-opencode-bundle.mjs +207 -6
  315. package/scripts/lib/bundle-helpers.mjs +29 -3
  316. package/scripts/lint-bundle.mjs +123 -3
  317. package/skills/explore-dag.md +5 -3
  318. package/skills/init-project.md +27 -26
  319. package/skills/orchestrate.md +29 -13
  320. package/skills/update-docs.md +8 -13
  321. package/opencode/arcs/prompts/docs-researcher.txt +0 -79
  322. package/opencode/arcs/prompts/oncall-ops.txt +0 -85
  323. package/opencode/arcs/skills/brainstorming/spec-document-reviewer-prompt.md +0 -56
  324. package/opencode/arcs/skills/code-agent/SKILL.md +0 -63
  325. package/opencode/arcs/skills/executing-plans/code-quality-reviewer-prompt.md +0 -57
  326. package/opencode/arcs/skills/executing-plans/implementer-prompt.md +0 -152
  327. package/opencode/arcs/skills/executing-plans/spec-reviewer-prompt.md +0 -91
  328. package/opencode/arcs/skills/quick-dev/SKILL.md +0 -52
  329. package/opencode/arcs/skills/requesting-code-review/SKILL.md +0 -59
  330. package/opencode/arcs/skills/requesting-code-review/code-reviewer.md +0 -139
  331. 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,
@@ -24,7 +26,15 @@ import {
24
26
  import { homedir } from "node:os";
25
27
  import { dirname, relative, resolve } from "node:path";
26
28
  import { fileURLToPath } from "node:url";
27
- import { wireCodegraphMcp, wireRtk } from "./lib/bundle-helpers.mjs";
29
+ import {
30
+ assertNoReservedPathSegments,
31
+ assertPathWithinCategoryRoot,
32
+ isActiveAgentForMode,
33
+ isRetiredAgentForMode,
34
+ validateRetirementReplacements,
35
+ wireCodegraphMcp,
36
+ wireRtk,
37
+ } from "./lib/bundle-helpers.mjs";
28
38
 
29
39
  const scriptDir = dirname(fileURLToPath(import.meta.url));
30
40
  const repoRoot = resolve(scriptDir, "..");
@@ -54,6 +64,98 @@ function ensureParentDir(filePath) {
54
64
  mkdirSync(dirname(filePath), { recursive: true });
55
65
  }
56
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
+
103
+ function validateManifestPaths(manifest) {
104
+ assertPathWithinCategoryRoot(manifest.skills.source, "skills");
105
+ assertPathWithinCategoryRoot(manifest.skills.destination, "skills");
106
+
107
+ for (const ownedPath of manifest.ownedPaths ?? []) {
108
+ assertNoReservedPathSegments(ownedPath);
109
+ }
110
+
111
+ if (manifest.plugin?.source) {
112
+ assertPathWithinCategoryRoot(manifest.plugin.source, ".opencode/plugins");
113
+ assertPathWithinCategoryRoot(manifest.plugin.destination, "plugins");
114
+ }
115
+
116
+ for (const agent of manifest.agents ?? []) {
117
+ assertPathWithinCategoryRoot(agent.source, "prompts");
118
+ assertPathWithinCategoryRoot(agent.destination, "prompts");
119
+ }
120
+ }
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
+
57
159
  async function main() {
58
160
  const manifestPath = resolve(bundleRoot, "manifest.json");
59
161
  if (!existsSync(manifestPath)) {
@@ -61,6 +163,9 @@ async function main() {
61
163
  }
62
164
 
63
165
  const manifest = JSON.parse(readFileSync(manifestPath, "utf-8"));
166
+ validateManifestPaths(manifest);
167
+ validateAgentRegistry(manifest.agents);
168
+ const previousManifest = readInstalledManifest();
64
169
 
65
170
  // Build mapping: config-relative path → bundle-absolute path
66
171
  const deployMap = new Map();
@@ -77,7 +182,7 @@ async function main() {
77
182
  }
78
183
 
79
184
  // Plugin
80
- if (manifest.plugin && manifest.plugin.source) {
185
+ if (manifest.plugin?.source) {
81
186
  const pluginSource = resolve(bundleRoot, manifest.plugin.source);
82
187
  if (existsSync(pluginSource)) {
83
188
  deployMap.set(manifest.plugin.destination, pluginSource);
@@ -85,7 +190,9 @@ async function main() {
85
190
  }
86
191
 
87
192
  // Agents (sub-agent prompts) — bundle prompts/<file> → config prompts/<file>
88
- for (const agent of manifest.agents ?? []) {
193
+ for (const agent of (manifest.agents ?? []).filter((record) =>
194
+ isActiveAgentForMode(record, "opencode"),
195
+ )) {
89
196
  const agentSource = resolve(bundleRoot, agent.source);
90
197
  if (existsSync(agentSource)) {
91
198
  deployMap.set(agent.destination, agentSource);
@@ -103,8 +210,7 @@ async function main() {
103
210
  const sourceContent = readFileSync(bundleAbsolute, "utf-8");
104
211
 
105
212
  const isNew = !existsSync(configAbsolute);
106
- const isChanged =
107
- !isNew && readFileSync(configAbsolute, "utf-8") !== sourceContent;
213
+ const isChanged = !isNew && readFileSync(configAbsolute, "utf-8") !== sourceContent;
108
214
 
109
215
  if (isNew) {
110
216
  filesAdded.push(configRelative);
@@ -143,6 +249,54 @@ async function main() {
143
249
  }
144
250
  }
145
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
+
146
300
  // Pass 2: Apply writes (only when not dry-run)
147
301
  if (!dryRun) {
148
302
  // Clean-delete the skills directory before copying to guarantee a fresh install.
@@ -164,6 +318,53 @@ async function main() {
164
318
  for (const fileToRemove of filesRemoved) {
165
319
  rmSync(resolve(configRoot, fileToRemove), { force: true });
166
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
+ );
167
368
  }
168
369
 
169
370
  // After successful deploy, ensure arcs CLI is globally registered
@@ -202,7 +403,7 @@ async function main() {
202
403
  }),
203
404
  };
204
405
 
205
- process.stdout.write(JSON.stringify(result, null, 2) + "\n");
406
+ process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
206
407
  }
207
408
 
208
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
  }
@@ -44,7 +70,7 @@ export function assertSafeOutputPath(candidatePath, reportedPath = candidatePath
44
70
  }
45
71
 
46
72
  export function assertPathWithinCategoryRoot(candidatePath, categoryRoot, reportedPath = candidatePath) {
47
- const normalizedPath = assertSafeOutputPath(candidatePath, reportedPath);
73
+ const normalizedPath = assertNoReservedPathSegments(candidatePath, reportedPath);
48
74
  const normalizedCategoryRoot = assertNoReservedPathSegments(categoryRoot, reportedPath);
49
75
  const categoryRelativePath = normalizeRelativePath(
50
76
  relative(normalizedCategoryRoot, normalizedPath),
@@ -151,8 +177,8 @@ export function assertSourceParity(runtimeManifest, sourceRoot, arcsNativeSkillN
151
177
  }
152
178
 
153
179
  export function validateDeclaredPath(relativePath, outputRoot, validationRoot) {
154
- const normalizedPath = assertSafeOutputPath(relativePath);
155
- const normalizedValidationRoot = assertSafeOutputPath(validationRoot, relativePath);
180
+ const normalizedPath = assertNoReservedPathSegments(relativePath);
181
+ const normalizedValidationRoot = assertNoReservedPathSegments(validationRoot, relativePath);
156
182
 
157
183
  const outputPath = resolve(outputRoot, normalizedPath);
158
184
  const outputRelativePath = normalizeRelativePath(relative(outputRoot, outputPath));
@@ -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("error", "missing-declared-file", `Manifest declares ${agentFile} but file is missing`, agentFile);
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("error", "missing-declared-file", `Manifest declares ${pluginFile} but file is missing`, pluginFile);
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(
@@ -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 sub-agent]:::sub
21
- D --> E{Durable discovery?}
22
- E -->|yes| F[arcs knowledge upsert]
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
@@ -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: name, description, repoUrl?, dependsOn?] --> B[arcs project list conflict check]
19
- B --> C[Present summary to user]
20
- C -->|confirmed| D[arcs project init]
21
- D --> E[arcs project update-doc × 4]
22
- E --> F{codegraph on PATH?}
23
- F -->|yes| G[codegraph index --force --quiet]
24
- F -->|no| H[Skip graph step, log gap]
25
- G --> G2[ingestGraph ≤20 proposals]
26
- G2 --> G3[codegraph MCP explore / impact for enrichment]:::sub
27
- H & G3 --> I[Fan out: tech-architect + docs-researcher]:::sub
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
- - Do NOT read repo to infer name/description gather from user
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 **fan-out across typed agents**, not a generic "analysis sub-agent" (see Agent Dispatch table below)
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
- The orchestrator runs codegraph directly during INIT to produce structural **proposals** before any sub-agent reads code. Proposals land on the proposal-store ledger (`pending_enrichment: true`); agents enrich them into knowledge entries via the `enriching-codegraph-proposals` skill.
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`, decide per-proposal verdicts (keep / merge / drop), persist via `arcs proposal promote` and `arcs proposal drop`. Sub-agents may run read-only codegraph MCP queries for evidence (the MCP server auto-syncs via its own file watcher):
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. **Hand to typed agents:** the proposals + query results go to the sub-agents listed in **Agent Dispatch** below; they merge graph evidence with code reading and return finalized knowledge entries.
68
- 7. **Write** the entries directly via `arcs batch --file=ops.json` (one batch invocation for all knowledge entries) or `arcs knowledge create` per entry.
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
- | `docs-researcher` | Tech stack, third-party libraries, key files, features | `reference`, `feature` |
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 in parallel. Each agent receives the relevant `KnowledgeProposal` records from `ingestGraph` plus targeted codegraph MCP queries for evidence. Each agent returns finalized proposals (title, kind, summary, keywords, sourceFiles, body) for the orchestrator to write directly via `arcs knowledge create` (or `arcs batch`).
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 | `docs-researcher` |
96
- | key files | `reference` | Entry points, config files, main modules, purposes | `docs-researcher` (codegraph_search "entry points") |
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 | `docs-researcher` |
101
- | third-party libraries | `reference` | Key dependencies and why they are used | `docs-researcher` |
102
- | features | `feature` | Major user-facing or system-facing features | `docs-researcher` |
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`) |