@iowarp/clio-coder 0.4.2 → 0.4.4

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 (523) hide show
  1. package/CHANGELOG.md +98 -0
  2. package/CONTRIBUTING.md +86 -19
  3. package/README.md +35 -6
  4. package/dist/{acp-TMDQZDIG.js → acp-WNAYYF4F.js} +12 -13
  5. package/dist/{agents-5N5NG3XG.js → agents-3OKXHLOI.js} +60 -57
  6. package/dist/assets/codewiki.json +1 -1
  7. package/dist/{auth-Z5CCBXKQ.js → auth-VKNNMGPU.js} +21 -19
  8. package/dist/{builtins-K6TNDT24.js → builtins-WGALA46I.js} +9 -4
  9. package/dist/{chunk-XE3PCIXH.js → chunk-23L32XTI.js} +12 -9
  10. package/dist/{chunk-I64IFBLB.js → chunk-25QBEXRS.js} +18 -11
  11. package/dist/{chunk-CDNVLKUX.js → chunk-26QSH3EJ.js} +13 -7
  12. package/dist/{chunk-QQLGQY2A.js → chunk-2ASED4PZ.js} +22 -22
  13. package/dist/{chunk-MCEPRMZW.js → chunk-2CU2H6KE.js} +2 -2
  14. package/dist/chunk-2DSOYNFC.js +108 -0
  15. package/dist/{chunk-72GZI5EV.js → chunk-2JH2WHGE.js} +2 -2
  16. package/dist/{chunk-I66EAJFY.js → chunk-2WZ546HR.js} +267 -232
  17. package/dist/{chunk-O3YUNJZ2.js → chunk-2ZSONWVL.js} +82 -25
  18. package/dist/{chunk-2NHR3NAY.js → chunk-36CT5VVL.js} +331 -42
  19. package/dist/{chunk-2X4RYJTJ.js → chunk-3GY4F45V.js} +3 -3
  20. package/dist/{chunk-ZW55JB7N.js → chunk-3ODX73FK.js} +4 -6
  21. package/dist/{chunk-PBP4B7XR.js → chunk-3UNOLWNZ.js} +3 -3
  22. package/dist/{chunk-4JDLP6ZS.js → chunk-3UUXNFEX.js} +14 -10
  23. package/dist/{chunk-RKSR6VSF.js → chunk-4IUZQIJ3.js} +29 -1
  24. package/dist/{chunk-ZW4HH5JJ.js → chunk-4M6Z5QVF.js} +6 -6
  25. package/dist/{chunk-K6BSR66V.js → chunk-4NSRCOYP.js} +4 -1
  26. package/dist/{chunk-M2DAX4F6.js → chunk-4WR7VSYB.js} +2 -2
  27. package/dist/{chunk-FSP7CMNU.js → chunk-54X7T7DK.js} +61 -6
  28. package/dist/{chunk-54ODD65L.js → chunk-5636DCO5.js} +4 -4
  29. package/dist/chunk-57XXR6DR.js +3763 -0
  30. package/dist/{chunk-3KIPBMUA.js → chunk-5ICU3EUH.js} +2 -2
  31. package/dist/{chunk-77QIVUZB.js → chunk-5MEZN6CB.js} +4 -4
  32. package/dist/{chunk-O42A54GG.js → chunk-5OIVVPHF.js} +2 -2
  33. package/dist/{chunk-YJISEZKC.js → chunk-5TUB6SLS.js} +6 -6
  34. package/dist/{chunk-IMXMHHMQ.js → chunk-6OSVSQL5.js} +341 -57
  35. package/dist/{chunk-Q4XWMHX6.js → chunk-6PAZTBPA.js} +14 -2
  36. package/dist/{chunk-FVDGR2ZL.js → chunk-6Q3CYFD3.js} +112 -39
  37. package/dist/{chunk-IDNA72AH.js → chunk-6QOTUPRG.js} +155 -36
  38. package/dist/{chunk-X7IARSHT.js → chunk-6UINWWS6.js} +16 -10
  39. package/dist/{chunk-CYZW7JHJ.js → chunk-72YIHOZQ.js} +9 -9
  40. package/dist/{chunk-IKSLQ4XV.js → chunk-75W7L2E2.js} +752 -861
  41. package/dist/{chunk-CRFOIAX3.js → chunk-7UGL4MB5.js} +6 -6
  42. package/dist/{chunk-HIICAHCJ.js → chunk-AUPNRN7C.js} +2 -2
  43. package/dist/{chunk-7BHIY2MW.js → chunk-BJVFZO5U.js} +8 -50
  44. package/dist/{chunk-B74PXLU7.js → chunk-CUSRQKPU.js} +65 -3
  45. package/dist/chunk-DQOVN6KV.js +386 -0
  46. package/dist/{chunk-E7GT7O5N.js → chunk-DT3LWJOB.js} +7 -4
  47. package/dist/chunk-DXKJURES.js +671 -0
  48. package/dist/{chunk-JBCS7CRR.js → chunk-EL24TAU4.js} +10 -10
  49. package/dist/{chunk-TPEQIQIE.js → chunk-ELWDPP3Y.js} +8 -8
  50. package/dist/{chunk-NDINPTJ4.js → chunk-ELZVTCGV.js} +5 -4
  51. package/dist/chunk-EXLD33WO.js +381 -0
  52. package/dist/chunk-FEAXX7B6.js +101 -0
  53. package/dist/{chunk-RLYRBIYQ.js → chunk-FFUPXJC4.js} +90 -331
  54. package/dist/{chunk-5PFYMY2V.js → chunk-FTMGRKEF.js} +2 -2
  55. package/dist/{chunk-34BHNEE3.js → chunk-GHS5EBTQ.js} +58 -7
  56. package/dist/{chunk-DYHAXKHD.js → chunk-GWZNEVM2.js} +12 -8
  57. package/dist/chunk-GX5WYQO4.js +59 -0
  58. package/dist/chunk-GYV6VZOC.js +26 -0
  59. package/dist/{chunk-MQXIVJ35.js → chunk-HAXOFFRH.js} +5 -5
  60. package/dist/chunk-I2DWJ4GM.js +390 -0
  61. package/dist/{chunk-TXOTCRLG.js → chunk-I5FWO7L5.js} +5 -5
  62. package/dist/{chunk-WNP7O5WZ.js → chunk-ID64D7PE.js} +4 -4
  63. package/dist/{chunk-XQRY4DTA.js → chunk-IGLP3ODT.js} +10 -10
  64. package/dist/chunk-IRXAATOX.js +539 -0
  65. package/dist/chunk-IXIY2H4R.js +44 -0
  66. package/dist/{chunk-SSEYRH53.js → chunk-IZXGRF7P.js} +92 -147
  67. package/dist/{chunk-5TSRNF4G.js → chunk-JCI2ROMZ.js} +164 -6
  68. package/dist/{chunk-JWJGP5DQ.js → chunk-JEIYHLOR.js} +7 -7
  69. package/dist/{chunk-F2I26BDK.js → chunk-JQLNNIKT.js} +4 -4
  70. package/dist/{chunk-BYMNWQ7O.js → chunk-JSD46VO2.js} +315 -63
  71. package/dist/{chunk-AK5XEFVZ.js → chunk-JT2RFCC5.js} +64 -14
  72. package/dist/{chunk-MCMZMDAC.js → chunk-K6T2ZAMZ.js} +168 -6
  73. package/dist/{chunk-PGF63K6I.js → chunk-KFV5L5SK.js} +73 -4
  74. package/dist/{chunk-IHXBNWMM.js → chunk-KXDSS5WJ.js} +7 -3
  75. package/dist/{chunk-PJX3WQUQ.js → chunk-LLXSDWXS.js} +3 -3
  76. package/dist/{chunk-DZAW46HP.js → chunk-LTIKRKFL.js} +3 -3
  77. package/dist/{chunk-DZEK6CJN.js → chunk-N56KALIC.js} +21 -21
  78. package/dist/{chunk-B7HM5Z7T.js → chunk-NAI6ZFCY.js} +9 -5
  79. package/dist/{chunk-I66ZTYNP.js → chunk-NRO2BJRH.js} +2656 -2213
  80. package/dist/{chunk-ZGNYYXQ6.js → chunk-NXIMQY5W.js} +3 -3
  81. package/dist/{chunk-IKOZFYBN.js → chunk-NXYCB2VD.js} +149 -106
  82. package/dist/{chunk-CWVRRIEI.js → chunk-NZMNUPZZ.js} +2 -2
  83. package/dist/{chunk-462T4EGZ.js → chunk-O5CVSAG5.js} +2 -2
  84. package/dist/chunk-ODGTEFFI.js +50 -0
  85. package/dist/{chunk-3F7VUY77.js → chunk-OEJSLEPW.js} +2 -2
  86. package/dist/{chunk-KKOJXO6R.js → chunk-OMQNJVKW.js} +4 -2
  87. package/dist/{chunk-5KW52TEP.js → chunk-Q4WO54TA.js} +132 -77
  88. package/dist/{chunk-W6NIE6OW.js → chunk-QUFRYSWI.js} +13 -7
  89. package/dist/{chunk-42FMPA75.js → chunk-QZWQA4DE.js} +2 -2
  90. package/dist/chunk-R6Q67RJH.js +134 -0
  91. package/dist/{chunk-W4YEMFBX.js → chunk-RAY4OVGZ.js} +3 -3
  92. package/dist/{chunk-ZNT2M6TG.js → chunk-RQCKCSRL.js} +17 -17
  93. package/dist/{chunk-LJID3DYZ.js → chunk-RXTN6AKH.js} +3 -3
  94. package/dist/{chunk-P75RZCJW.js → chunk-RZDWV63N.js} +3 -3
  95. package/dist/{chunk-UH632ZYL.js → chunk-S6PYF2XF.js} +2 -2
  96. package/dist/{chunk-HJWWJ6IL.js → chunk-TOIVGRUX.js} +17 -5
  97. package/dist/{chunk-HLAFFSEK.js → chunk-TQAHXW6Y.js} +2 -2
  98. package/dist/{chunk-JIEGK6UF.js → chunk-U6TMQNSI.js} +48 -4
  99. package/dist/{chunk-2HFQNRV3.js → chunk-UEPWCCTY.js} +12 -12
  100. package/dist/chunk-UOIZ7DA4.js +41 -0
  101. package/dist/{chunk-UH347SHR.js → chunk-USR47QNF.js} +11 -11
  102. package/dist/{chunk-AZ4WMN4W.js → chunk-V6HJFQZE.js} +2 -2
  103. package/dist/chunk-V76WTFTW.js +318 -0
  104. package/dist/{chunk-NMJXSHBJ.js → chunk-W54I7H25.js} +2 -2
  105. package/dist/{chunk-KPXDY6QF.js → chunk-XRZT5WY5.js} +2 -2
  106. package/dist/{chunk-UBRFI4HS.js → chunk-XULDXHTN.js} +142 -50
  107. package/dist/chunk-XXYSBZIQ.js +283 -0
  108. package/dist/{chunk-HKMD33FO.js → chunk-Y55JBDO5.js} +405 -122
  109. package/dist/{chunk-XOXV5GKE.js → chunk-YD5GIKET.js} +17 -8
  110. package/dist/{chunk-XGDPUNND.js → chunk-YECAMM3D.js} +2 -2
  111. package/dist/{chunk-BO7Y52RY.js → chunk-YNFKXPEC.js} +7 -7
  112. package/dist/{chunk-VXMFAE2W.js → chunk-YPC6ZR5L.js} +19 -6
  113. package/dist/{chunk-M2WXEHER.js → chunk-ZA4VCIGV.js} +2 -2
  114. package/dist/cli/index.js +42 -40
  115. package/dist/{clio-7VB377CC.js → clio-QLICPCF5.js} +7 -7
  116. package/dist/{code-nav-YVLCYA7V.js → code-nav-IJR2DBPR.js} +9 -9
  117. package/dist/{components-UBWCQSRW.js → components-2TGAI2RC.js} +5 -6
  118. package/dist/{config-4HVOS65E.js → config-IUA6OYNS.js} +88 -81
  119. package/dist/{configure-PIWO7B24.js → configure-VEPX4NMX.js} +26 -25
  120. package/dist/{context-KQYIWPWT.js → context-2DKHWH2T.js} +60 -45
  121. package/dist/{context-IYEHL3WQ.js → context-4MPR7WKB.js} +78 -69
  122. package/dist/{context-N6ZE3LGJ.js → context-BOYF5EJM.js} +15 -11
  123. package/dist/{context-clear-G4OGZJDS.js → context-clear-S4ZJCQUX.js} +73 -65
  124. package/dist/context-map-COB37XXN.js +505 -0
  125. package/dist/{context-working-set-BWLF6LJP.js → context-working-set-3I3FYX6Y.js} +18 -17
  126. package/dist/detail-A7JAVSIG.js +98 -0
  127. package/dist/{dispatch-runner-2QQAITS3.js → dispatch-runner-RJ5I2F2O.js} +99 -75
  128. package/dist/{docs-PD3EXDKU.js → docs-SPOV3BAN.js} +3 -5
  129. package/dist/{doctor-LHBD36VU.js → doctor-DKICC2SN.js} +71 -48
  130. package/dist/{eval-C45FYRJ6.js → eval-OQOQUDHK.js} +308 -146
  131. package/dist/{eval-inventory-6DEJPLBF.js → eval-inventory-Y6QRFOH5.js} +4 -4
  132. package/dist/{evidence-6SHONYAF.js → evidence-4DQ25GUQ.js} +79 -175
  133. package/dist/evidence-4F5USFKH.js +208 -0
  134. package/dist/{evolve-KRKMV72X.js → evolve-GSS52E5J.js} +71 -67
  135. package/dist/{extensions-KPZ2UHBB.js → extensions-G7MFLYHT.js} +8 -9
  136. package/dist/{fleet-IVTCKDHT.js → fleet-Q37YHHAQ.js} +126 -118
  137. package/dist/{fleet-commands-EDWL3IT7.js → fleet-commands-G7E4N7SM.js} +16 -13
  138. package/dist/{fleet-decisions-YP3YEFGK.js → fleet-decisions-O7M6QBA2.js} +9 -8
  139. package/dist/{fleet-graph-ZFWKHY2M.js → fleet-graph-TOUBW6OW.js} +21 -20
  140. package/dist/{fleet-inspect-FVUNCBML.js → fleet-inspect-SW33JJNI.js} +65 -60
  141. package/dist/{fleet-preflight-UN5XED4R.js → fleet-preflight-CV2655TW.js} +4 -5
  142. package/dist/{fleet-validate-XOWC4HSX.js → fleet-validate-KESZX2YH.js} +25 -24
  143. package/dist/{fleet-verify-UN3SODEL.js → fleet-verify-UQPMTVE3.js} +66 -61
  144. package/dist/{fleet-view-TWHJKCN6.js → fleet-view-MN2VG4MR.js} +65 -60
  145. package/dist/{init-T2QORQ3Y.js → init-PXEXQSBF.js} +90 -82
  146. package/dist/{interop-IN5I2A66.js → interop-ZG5T62U3.js} +12 -13
  147. package/dist/inventory-C26CFDRR.js +101 -0
  148. package/dist/{library-LSCATDLZ.js → library-B2W4N74O.js} +29 -29
  149. package/dist/{memory-HYOKAGGJ.js → memory-YCANYS5A.js} +73 -69
  150. package/dist/{models-2GPMFYCM.js → models-GERTU3YI.js} +51 -47
  151. package/dist/{monitor-E4ASVUJH.js → monitor-CPNIUULB.js} +74 -67
  152. package/dist/{orchestrator-DDMPR3PY.js → orchestrator-J4BSH4WQ.js} +1288 -1606
  153. package/dist/{panes-E3RUXOW5.js → panes-BOHAEGYC.js} +4 -4
  154. package/dist/{panes-IXKLOKA2.js → panes-NXSLDQZ2.js} +10 -11
  155. package/dist/{paths-L7LGY6RN.js → paths-VSUWNC22.js} +6 -7
  156. package/dist/reset-TNWTB5LU.js +343 -0
  157. package/dist/{resources-OTRSN34L.js → resources-4PXNMD5G.js} +29 -22
  158. package/dist/{run-5DEYH5QK.js → run-D6XJ34CN.js} +132 -132
  159. package/dist/{share-IHWTLO3M.js → share-2NWMJJEE.js} +27 -27
  160. package/dist/{skills-IYMXMKW4.js → skills-KR7WON5G.js} +40 -33
  161. package/dist/{skills-eval-DROHSJAR.js → skills-eval-O2ZNOLDS.js} +81 -77
  162. package/dist/{skills-inventory-D7X4L4ZX.js → skills-inventory-ZZOUBK7O.js} +23 -22
  163. package/dist/{slash-commands-QBM7UZ3B.js → slash-commands-ZXPJD64J.js} +47 -37
  164. package/dist/{steer-Z5DO23FJ.js → steer-XA25PSCS.js} +4 -4
  165. package/dist/{support-U7QOWY26.js → support-7EMVWYG2.js} +6 -6
  166. package/dist/{targets-P2FUC4IL.js → targets-OMH2XCSN.js} +50 -49
  167. package/dist/tasks-IPAGMEIX.js +36 -0
  168. package/dist/{terminal-lease-YREJ3JX2.js → terminal-lease-C2J3JYRE.js} +4 -4
  169. package/dist/{tools-5B7RO6MV.js → tools-EFFEAIDP.js} +8 -9
  170. package/dist/{trace-YMGMUM6A.js → trace-FXMXUZUF.js} +7 -7
  171. package/dist/uninstall-HALS6BLF.js +407 -0
  172. package/dist/upgrade-MS72RJEP.js +306 -0
  173. package/dist/{usage-ME5MPXGX.js → usage-NHG6MCJM.js} +162 -108
  174. package/dist/{verifiers-BVZ7IWOO.js → verifiers-7AUNVXDY.js} +155 -22
  175. package/dist/{verify-5K7ZKQFC.js → verify-FWYGPKMR.js} +14 -12
  176. package/dist/{web-fetch-MPARV2K7.js → web-fetch-V4FKSDAV.js} +4 -4
  177. package/dist/{wiki-generate-F5W5QTYY.js → wiki-generate-743CIGJW.js} +99 -90
  178. package/dist/{with-panes-BYOJCLAM.js → with-panes-BDQEWBRT.js} +10 -10
  179. package/dist/worker/entry.js +72 -68
  180. package/docs/README.md +3 -2
  181. package/docs/architecture/acp.md +17 -0
  182. package/docs/architecture/artifact-placement.md +1 -0
  183. package/docs/architecture/artifact-versions.md +2 -2
  184. package/docs/architecture/context-engine.md +4 -0
  185. package/docs/architecture/dispatch-typed-intent.md +1 -1
  186. package/docs/architecture/evidence-and-memory.md +1 -1
  187. package/docs/architecture/middleware-and-components.md +1 -1
  188. package/docs/architecture/model-catalog.md +21 -10
  189. package/docs/architecture/observability.md +19 -2
  190. package/docs/architecture/prompt-envelope-and-tools.md +17 -5
  191. package/docs/architecture/provider-adapter-cookbook.md +63 -0
  192. package/docs/architecture/safety-model.md +25 -22
  193. package/docs/architecture/tui-design.md +1 -1
  194. package/docs/guide/built-in-agents.md +25 -11
  195. package/docs/guide/commands-and-modes.md +18 -3
  196. package/docs/guide/configuration-and-targets.md +100 -10
  197. package/docs/guide/configuration-reference.md +17 -7
  198. package/docs/guide/environment-variables.md +4 -2
  199. package/docs/guide/installation-and-lifecycle.md +37 -4
  200. package/docs/guide/proactive-memory.md +66 -55
  201. package/docs/guide/skills-marketplace.md +18 -0
  202. package/docs/guide/tool-usage.md +78 -3
  203. package/docs/history/config-knobs-audit.md +2 -2
  204. package/docs/process/development-pipeline.md +40 -2
  205. package/docs/process/eval-runner.md +67 -3
  206. package/docs/process/git-commit-provenance.md +15 -0
  207. package/docs/process/release-cut-checklist.md +207 -0
  208. package/docs/process/scientific-validation.md +18 -17
  209. package/evals/behavioral-machinery-support.ts +1 -0
  210. package/evals/behavioral-machinery.yaml +1 -1
  211. package/evals/behavioral-model.yaml +3 -2
  212. package/package.json +2 -2
  213. package/skills/README.md +7 -5
  214. package/skills/coding/ast-grep/SKILL.md +101 -30
  215. package/skills/coding/ast-grep/evals.md +26 -0
  216. package/skills/coding/coding-standards/SKILL.md +47 -2
  217. package/skills/coding/coding-standards/evals.md +23 -0
  218. package/skills/coding/prototype/SKILL.md +87 -28
  219. package/skills/coding/prototype/evals.md +19 -0
  220. package/skills/coding/tdd/SKILL.md +80 -53
  221. package/skills/coding/tdd/evals.md +20 -0
  222. package/skills/context/context-handoff/SKILL.md +43 -2
  223. package/skills/context/context-handoff/evals.md +44 -0
  224. package/skills/context/context-prime/SKILL.md +45 -15
  225. package/skills/context/context-prime/evals.md +45 -0
  226. package/skills/git/branch-closeout/SKILL.md +132 -0
  227. package/skills/git/branch-closeout/evals.md +133 -0
  228. package/skills/git/branch-closeout/references/closeout-checklist.md +81 -0
  229. package/skills/git/file-ticket/SKILL.md +77 -63
  230. package/skills/git/file-ticket/assets/issue-template.md +22 -0
  231. package/skills/git/file-ticket/evals.md +31 -26
  232. package/skills/git/file-ticket/references/issue-discovery.md +49 -0
  233. package/skills/git/fix-issue/SKILL.md +87 -64
  234. package/skills/git/fix-issue/evals.md +35 -31
  235. package/skills/git/fix-issue/references/diagnosis-and-rca.md +46 -0
  236. package/skills/git/resolve-merge-conflicts/SKILL.md +100 -51
  237. package/skills/git/resolve-merge-conflicts/evals.md +52 -25
  238. package/skills/git/resolve-merge-conflicts/references/conflict-matrix.md +126 -0
  239. package/skills/git/ship/SKILL.md +103 -67
  240. package/skills/git/ship/assets/pr-template.md +21 -0
  241. package/skills/git/ship/evals.md +44 -28
  242. package/skills/git/ship/references/remote-and-branch-policy.md +62 -0
  243. package/skills/git/worktree-create/SKILL.md +80 -50
  244. package/skills/git/worktree-create/evals.md +40 -33
  245. package/skills/git/worktree-create/references/worktree-setup.md +62 -66
  246. package/skills/git/worktree-merge/SKILL.md +112 -65
  247. package/skills/git/worktree-merge/evals.md +42 -34
  248. package/skills/git/worktree-merge/references/merge-strategies.md +52 -0
  249. package/skills/planning/archify/SKILL.md +196 -0
  250. package/skills/planning/archify/evals.md +65 -0
  251. package/skills/planning/architecture/SKILL.md +61 -12
  252. package/skills/planning/architecture/evals.md +65 -0
  253. package/skills/planning/backlog/SKILL.md +130 -14
  254. package/skills/planning/backlog/evals.md +142 -0
  255. package/skills/planning/prd/SKILL.md +47 -6
  256. package/skills/planning/prd/evals.md +54 -0
  257. package/skills/planning/product-intent/SKILL.md +57 -2
  258. package/skills/planning/product-intent/evals.md +70 -0
  259. package/skills/planning/tech-spec/SKILL.md +53 -2
  260. package/skills/planning/tech-spec/evals.md +73 -0
  261. package/skills/registry.yaml +58 -50
  262. package/skills/remote.yaml +13 -0
  263. package/skills/research/arxiv-literature/SKILL.md +76 -18
  264. package/skills/research/arxiv-literature/evals.md +50 -0
  265. package/skills/research/experiment-protocol/SKILL.md +20 -1
  266. package/skills/research/experiment-protocol/evals.md +23 -0
  267. package/skills/research/scientific-debugging/SKILL.md +24 -1
  268. package/skills/research/scientific-debugging/evals.md +18 -0
  269. package/skills/research/scientific-modernization/SKILL.md +26 -1
  270. package/skills/research/scientific-modernization/evals.md +27 -0
  271. package/skills/skill-marketplace.json +63 -28
  272. package/skills/workflow/cut-it/SKILL.md +64 -5
  273. package/skills/workflow/cut-it/evals.md +101 -0
  274. package/skills/workflow/design-council/SKILL.md +112 -27
  275. package/skills/workflow/design-council/evals.md +161 -0
  276. package/skills/workflow/grill-me/SKILL.md +85 -10
  277. package/skills/workflow/grill-me/evals.md +153 -0
  278. package/skills/workflow/workflow-distiller/SKILL.md +76 -17
  279. package/skills/workflow/workflow-distiller/evals.md +118 -0
  280. package/src/cli/args.ts +0 -8
  281. package/src/cli/configure-interop.ts +105 -13
  282. package/src/cli/configure-oauth.ts +57 -0
  283. package/src/cli/configure-onboarding.ts +980 -0
  284. package/src/cli/configure-target.ts +594 -0
  285. package/src/cli/configure.ts +1084 -529
  286. package/src/cli/context-map.ts +114 -0
  287. package/src/cli/context.ts +4 -0
  288. package/src/cli/doctor-state-size.ts +1 -12
  289. package/src/cli/doctor-validation-contract.ts +28 -0
  290. package/src/cli/doctor.ts +5 -0
  291. package/src/cli/evidence-detail.ts +1 -75
  292. package/src/cli/evidence-inventory.ts +1 -167
  293. package/src/cli/index.ts +3 -0
  294. package/src/cli/lifecycle-presenter.ts +436 -0
  295. package/src/cli/models.ts +10 -2
  296. package/src/cli/modes/print.ts +5 -1
  297. package/src/cli/reset.ts +228 -106
  298. package/src/cli/run.ts +7 -4
  299. package/src/cli/select.ts +664 -0
  300. package/src/cli/skills.ts +9 -2
  301. package/src/cli/targets.ts +3 -0
  302. package/src/cli/tasks.ts +84 -0
  303. package/src/cli/uninstall.ts +233 -165
  304. package/src/cli/upgrade.ts +210 -150
  305. package/src/cli/usage.ts +92 -27
  306. package/src/cli/validate-model.ts +3 -3
  307. package/src/cli/verifiers.ts +147 -1
  308. package/src/cli/wiki-generate.ts +1 -0
  309. package/src/core/commit-attribution.ts +41 -1
  310. package/src/core/config.ts +56 -0
  311. package/src/core/external-diagnostic.ts +44 -0
  312. package/src/core/gateway-routing.ts +157 -0
  313. package/src/core/git-commit-attribution.ts +46 -3
  314. package/src/core/run-overrides.ts +0 -5
  315. package/src/core/safe-exec.ts +17 -2
  316. package/src/core/skill-activation.ts +92 -2
  317. package/src/core/tool-names.ts +5 -2
  318. package/src/domains/agents/builtins/architect.md +1 -1
  319. package/src/domains/agents/builtins/coder.md +1 -1
  320. package/src/domains/agents/builtins/documenter.md +1 -1
  321. package/src/domains/agents/builtins/git-master.md +1 -1
  322. package/src/domains/agents/builtins/provenance.md +7 -7
  323. package/src/domains/agents/builtins/tester.md +1 -1
  324. package/src/domains/agents/builtins/verifier.md +2 -2
  325. package/src/domains/agents/builtins/wiki-writer.md +4 -3
  326. package/src/domains/agents/builtins/world-knowledge.md +31 -0
  327. package/src/domains/agents/catalog.ts +1 -1
  328. package/src/domains/agents/result-contract.ts +70 -0
  329. package/src/domains/context/extension.ts +31 -7
  330. package/src/domains/context/refresh.ts +3 -0
  331. package/src/domains/context/wiki/frontmatter.ts +5 -2
  332. package/src/domains/context/wiki/generate.ts +6 -0
  333. package/src/domains/context/wiki/map-seed.ts +589 -0
  334. package/src/domains/context/wiki/plan.ts +2 -2
  335. package/src/domains/context/wiki/prompts.ts +43 -0
  336. package/src/domains/dispatch/active-route-planner.ts +4 -0
  337. package/src/domains/dispatch/admission.ts +29 -0
  338. package/src/domains/dispatch/agent-candidates.ts +10 -0
  339. package/src/domains/dispatch/budget-envelope.ts +86 -1
  340. package/src/domains/dispatch/capability-match.ts +1 -0
  341. package/src/domains/dispatch/capacity-lease.ts +17 -0
  342. package/src/domains/dispatch/code-step.ts +11 -4
  343. package/src/domains/dispatch/contract.ts +42 -8
  344. package/src/domains/dispatch/execution-scheduler.ts +2 -0
  345. package/src/domains/dispatch/extension.ts +184 -56
  346. package/src/domains/dispatch/fleet-commit-attribution.ts +5 -0
  347. package/src/domains/dispatch/fleet-run.ts +1 -0
  348. package/src/domains/dispatch/host-verification.ts +114 -13
  349. package/src/domains/dispatch/intent.ts +28 -18
  350. package/src/domains/dispatch/orphan-recovery.ts +2 -0
  351. package/src/domains/dispatch/receipt-integrity.ts +4 -0
  352. package/src/domains/dispatch/reservation-store.ts +5 -3
  353. package/src/domains/dispatch/state.ts +15 -2
  354. package/src/domains/dispatch/types.ts +20 -2
  355. package/src/domains/dispatch/worker-model-metadata.ts +38 -0
  356. package/src/domains/eval/metrics/call-ledger-stream.ts +34 -11
  357. package/src/domains/eval/metrics/token-stream.ts +201 -31
  358. package/src/domains/eval/metrics/tracked.ts +40 -4
  359. package/src/domains/eval/runners/clio-run.ts +17 -11
  360. package/src/domains/eval/runners/context-index.ts +2 -7
  361. package/src/domains/eval/runners/context-init.ts +3 -6
  362. package/src/domains/eval/runners/external-command.ts +29 -11
  363. package/src/domains/eval/schema/suite.ts +28 -0
  364. package/src/domains/eval/schema/verdict.ts +2 -2
  365. package/src/domains/eval/suites/resolve.ts +13 -1
  366. package/src/domains/eval/suites/run.ts +24 -3
  367. package/src/domains/evidence/build.ts +102 -15
  368. package/src/domains/evidence/detail.ts +69 -0
  369. package/src/domains/evidence/eval.ts +13 -1
  370. package/src/domains/evidence/finish-contract-map.ts +5 -1
  371. package/src/domains/evidence/inventory.ts +167 -0
  372. package/src/domains/evidence/store.ts +16 -0
  373. package/src/domains/evidence/types.ts +12 -0
  374. package/src/domains/extensions/resources.ts +7 -0
  375. package/src/domains/interop/registry.ts +6 -2
  376. package/src/domains/interop/types.ts +4 -0
  377. package/src/domains/lifecycle/migrations/index.ts +4 -0
  378. package/src/domains/memory/task-memory-policy.ts +70 -26
  379. package/src/domains/memory/task-memory-telemetry.ts +1 -0
  380. package/src/domains/middleware/index.ts +0 -1
  381. package/src/domains/middleware/marketplace-offer.ts +22 -35
  382. package/src/domains/middleware/memory-intervention.ts +127 -32
  383. package/src/domains/middleware/memory-step-endpoint.ts +3 -2
  384. package/src/domains/middleware/runtime.ts +7 -3
  385. package/src/domains/middleware/skills-reminder.ts +31 -2
  386. package/src/domains/mux/detect.ts +3 -6
  387. package/src/domains/observability/accountability.ts +15 -1
  388. package/src/domains/observability/compaction-usage.ts +118 -0
  389. package/src/domains/observability/contract.ts +52 -7
  390. package/src/domains/observability/cost.ts +1 -1
  391. package/src/domains/observability/evidence-index.ts +10 -0
  392. package/src/domains/observability/extension.ts +15 -6
  393. package/src/domains/observability/out-of-turn-usage.ts +52 -21
  394. package/src/domains/observability/projection.ts +394 -45
  395. package/src/{interactive → domains/observability}/worker-progress.ts +3 -3
  396. package/src/domains/prompts/fragments/operating/contract.md +2 -0
  397. package/src/domains/prompts/fragments/wiki/page.md +8 -0
  398. package/src/domains/providers/contract.ts +4 -1
  399. package/src/domains/providers/extension.ts +40 -9
  400. package/src/domains/providers/model-capabilities.ts +9 -0
  401. package/src/domains/providers/model-discovery.ts +3 -4
  402. package/src/domains/providers/model-runtime-capabilities.ts +15 -5
  403. package/src/domains/providers/models/local-models/clio-coder-local-coding-targets.yaml +48 -26
  404. package/src/domains/providers/runtimes/antigravity/antigravity-code.ts +225 -45
  405. package/src/domains/providers/runtimes/claude/claude-code.ts +9 -0
  406. package/src/domains/providers/runtimes/common/lmstudio-http.ts +6 -2
  407. package/src/domains/providers/runtimes/common/local-synth.ts +2 -0
  408. package/src/domains/providers/runtimes/protocol/litellm.ts +119 -29
  409. package/src/domains/providers/support.ts +11 -5
  410. package/src/domains/providers/target-model-cache.ts +25 -2
  411. package/src/domains/providers/types/capability-flags.ts +2 -0
  412. package/src/domains/providers/types/runtime-descriptor.ts +20 -1
  413. package/src/domains/providers/types/target-descriptor.ts +19 -0
  414. package/src/domains/resources/index.ts +3 -0
  415. package/src/domains/resources/skills/install.ts +72 -7
  416. package/src/domains/resources/skills/loader.ts +7 -0
  417. package/src/domains/resources/skills/marketplace.ts +63 -11
  418. package/src/domains/safety/action-classifier.ts +7 -0
  419. package/src/domains/safety/autonomy.ts +15 -0
  420. package/src/domains/safety/default-path-policy.ts +2 -0
  421. package/src/domains/safety/finish-contract-registration.ts +29 -14
  422. package/src/domains/safety/finish-contract.ts +252 -40
  423. package/src/domains/safety/index.ts +21 -1
  424. package/src/domains/safety/path-policy.ts +1 -1
  425. package/src/domains/safety/policy-engine.ts +60 -17
  426. package/src/domains/safety/protected-artifacts.ts +191 -88
  427. package/src/domains/safety/rigor.ts +53 -39
  428. package/src/domains/safety/run-effects.ts +2 -22
  429. package/src/domains/safety/skill-authority.ts +55 -0
  430. package/src/domains/safety/validation-contract.ts +388 -0
  431. package/src/domains/session/archive-readers.ts +10 -1
  432. package/src/domains/session/compaction/compact.ts +72 -22
  433. package/src/domains/session/decision-board.ts +101 -2
  434. package/src/domains/session/entries.ts +50 -7
  435. package/src/domains/session/extension.ts +4 -4
  436. package/src/domains/session/handoff.ts +2 -1
  437. package/src/domains/session/manager.ts +2 -3
  438. package/src/domains/session/task-board.ts +14 -1
  439. package/src/domains/session/tree/fork.ts +1 -2
  440. package/src/domains/session/tree/navigator.ts +1 -1
  441. package/src/domains/session/usage.ts +3 -3
  442. package/src/domains/user-tasks/acceptance.ts +56 -0
  443. package/src/domains/user-tasks/active-acceptance.ts +40 -0
  444. package/src/domains/user-tasks/store.ts +34 -3
  445. package/src/engine/acp/adapter.ts +24 -6
  446. package/src/engine/acp/server.ts +21 -4
  447. package/src/engine/acp/transport.ts +53 -8
  448. package/src/engine/acp/types.ts +4 -0
  449. package/src/engine/agent.ts +13 -3
  450. package/src/engine/ai.ts +26 -8
  451. package/src/engine/antigravity/subprocess-runtime.ts +386 -120
  452. package/src/engine/api-registry.ts +3 -0
  453. package/src/engine/apis/ollama-native.ts +15 -0
  454. package/src/engine/apis/openai-completions.ts +117 -14
  455. package/src/engine/claude/subprocess-runtime.ts +107 -60
  456. package/src/engine/external-subprocess.ts +122 -6
  457. package/src/entry/background-model-metadata.ts +18 -0
  458. package/src/entry/compaction-prompt.ts +57 -0
  459. package/src/entry/orchestrator.ts +416 -218
  460. package/src/entry/task-memory-lifecycle.ts +35 -0
  461. package/src/interactive/chat-loop-messages.ts +13 -4
  462. package/src/interactive/chat-loop.ts +65 -2
  463. package/src/interactive/chat-renderer.ts +1 -0
  464. package/src/interactive/cost-overlay.ts +26 -2
  465. package/src/interactive/dispatch-board.ts +46 -717
  466. package/src/interactive/fleet-run-preview.ts +2 -1
  467. package/src/interactive/interactive-application.ts +3 -2
  468. package/src/interactive/interactive-presentation.ts +55 -12
  469. package/src/interactive/interactive-slash-runtime.ts +4 -2
  470. package/src/interactive/oracle.ts +5 -2
  471. package/src/interactive/overlays/fleet-run-approval.ts +3 -2
  472. package/src/interactive/overlays/message-picker.ts +2 -2
  473. package/src/interactive/overlays/settings.ts +2 -2
  474. package/src/interactive/overlays/tree-selector.ts +2 -2
  475. package/src/interactive/renderers/branch-summary.ts +1 -1
  476. package/src/interactive/renderers/worker-entry.ts +32 -0
  477. package/src/interactive/slash-autocomplete.ts +4 -6
  478. package/src/interactive/slash-commands.ts +49 -45
  479. package/src/interactive/slash-spec.ts +28 -0
  480. package/src/interactive/theme/labels.ts +19 -13
  481. package/src/interactive/turn-context.ts +9 -5
  482. package/src/interactive/turn-recovery.ts +8 -0
  483. package/src/interactive/turn-runtime.ts +27 -11
  484. package/src/interactive/turn-state.ts +7 -0
  485. package/src/interactive/view/artifacts.ts +2 -0
  486. package/src/interactive/worker-receipts.ts +1 -0
  487. package/src/interactive/worker-stream.ts +13 -4
  488. package/src/tools/bootstrap.ts +4 -0
  489. package/src/tools/builtin-tool-catalog.ts +31 -0
  490. package/src/tools/compete-worktrees.ts +7 -1
  491. package/src/tools/context/index.ts +30 -9
  492. package/src/tools/core-bootstrap.ts +16 -0
  493. package/src/tools/decide.ts +136 -0
  494. package/src/tools/dispatch-admission.ts +21 -0
  495. package/src/tools/dispatch-arguments.ts +1 -0
  496. package/src/tools/dispatch-event-text.ts +10 -0
  497. package/src/tools/dispatch-plan.ts +6 -2
  498. package/src/tools/dispatch-runner.ts +27 -1
  499. package/src/tools/dispatch-types.ts +6 -0
  500. package/src/tools/evidence.ts +96 -0
  501. package/src/tools/limitation.ts +76 -0
  502. package/src/tools/policy.ts +9 -0
  503. package/src/tools/presentation.ts +3 -0
  504. package/src/tools/registry.ts +11 -5
  505. package/src/tools/result-shaping.ts +17 -5
  506. package/src/tools/task-worktree.ts +13 -3
  507. package/src/tools/tasks.ts +10 -1
  508. package/src/tools/verify/authoring.ts +170 -83
  509. package/src/tools/verify/catalog.ts +122 -5
  510. package/src/tools/verify/index.ts +2 -1
  511. package/src/tools/verify/numeric.ts +298 -0
  512. package/src/tools/verify/perf.ts +143 -0
  513. package/src/tools/verify/scripts.ts +229 -2
  514. package/src/tools/worker-evidence.ts +3 -1
  515. package/src/worker/spec-contract.ts +4 -0
  516. package/dist/chunk-2Z2IKEXI.js +0 -1554
  517. package/dist/chunk-RVG5JXAL.js +0 -41
  518. package/dist/chunk-T56WDKA5.js +0 -183
  519. package/dist/chunk-VN3SHNBN.js +0 -313
  520. package/dist/chunk-VPKWYKEY.js +0 -169
  521. package/dist/reset-OAQP3W4O.js +0 -230
  522. package/dist/uninstall-N34PCTGJ.js +0 -331
  523. package/dist/upgrade-PXK3S2YM.js +0 -325
@@ -0,0 +1,589 @@
1
+ /**
2
+ * The architecture seed: an archify architecture specification derived from
3
+ * the codewiki index, with no model call.
4
+ *
5
+ * `clio-coder context map` writes it so a "map this repository" turn starts
6
+ * from real evidence instead of a blank page: components are the index's
7
+ * largest directory areas, connections are its import edges collapsed
8
+ * area-to-area, and every `sources` entry names a file and line the index
9
+ * actually recorded. Clio never renders the seed; the archify skill validates
10
+ * and delivers it, and `--repo-root` re-verifies every source path there.
11
+ *
12
+ * The output is deterministic for one index: keys are sorted, ids derive from
13
+ * area paths, and every ranking breaks ties on path order. Two runs over the
14
+ * same codewiki.json produce byte-identical JSON.
15
+ */
16
+
17
+ import type { Codewiki, CodewikiFile, CodewikiInternalEdge, CodewikiSymbol } from "../codewiki/schema.js";
18
+ import { areaForPath, classifyDepth, WIKI_DEPTH_STRATEGY } from "./plan.js";
19
+
20
+ export type SeedComponentType = "frontend" | "backend" | "database" | "external";
21
+
22
+ export interface SeedSource {
23
+ path: string;
24
+ line?: number;
25
+ }
26
+
27
+ export type SeedSide = "top" | "bottom";
28
+
29
+ export interface SeedComponent {
30
+ id: string;
31
+ type: SeedComponentType;
32
+ label: string;
33
+ sublabel: string;
34
+ row: number;
35
+ col: number;
36
+ size: [number, number];
37
+ sources?: SeedSource[];
38
+ }
39
+
40
+ export interface SeedConnection {
41
+ id: string;
42
+ from: string;
43
+ to: string;
44
+ label: string;
45
+ fromSide: SeedSide;
46
+ toSide: SeedSide;
47
+ route?: "straight";
48
+ via?: [number, number][];
49
+ /** Label center; set on straight routes, whose midpoint would otherwise sit on a node. */
50
+ labelAt?: [number, number];
51
+ }
52
+
53
+ export interface SeedLayout {
54
+ mode: "grid";
55
+ origin: [number, number];
56
+ cols: number;
57
+ cellW: number;
58
+ cellH: number;
59
+ gapX: number;
60
+ gapY: number;
61
+ }
62
+
63
+ export interface SeedRepository {
64
+ url: string;
65
+ revision: string;
66
+ }
67
+
68
+ export interface ArchitectureSeed {
69
+ schema_version: 1;
70
+ diagram_type: "architecture";
71
+ meta: {
72
+ title: string;
73
+ quality_profile: "standard";
74
+ repository?: SeedRepository;
75
+ };
76
+ layout: SeedLayout;
77
+ components: SeedComponent[];
78
+ connections: SeedConnection[];
79
+ }
80
+
81
+ export interface BuildArchitectureSeedOptions {
82
+ title: string;
83
+ /**
84
+ * Recorded as `meta.repository` only when it is a GitHub repository URL at
85
+ * a full 40-hex revision. Components carry `sources` only in that case,
86
+ * since archify accepts source citations only against a pinned revision.
87
+ */
88
+ repository?: { url: string; revision: string } | undefined;
89
+ }
90
+
91
+ /** Most primary (internal area) components a seed carries. */
92
+ export const MAX_SEED_COMPONENTS = 12;
93
+ /** Most external-package components a seed carries. */
94
+ export const MAX_SEED_EXTERNALS = 3;
95
+ /** Most connections a seed carries, by descending import count. */
96
+ export const MAX_SEED_CONNECTIONS = 16;
97
+ /** Most `sources` entries per component; the schema caps at 3. */
98
+ const MAX_SEED_SOURCES = 3;
99
+ const GRID_COLS = 4;
100
+ const CELL_W = 220;
101
+ const CELL_H = 72;
102
+ const GAP_X = 70;
103
+ /** Vertical distance between route lanes inside one row gap or one margin. */
104
+ const LANE_STEP = 16;
105
+ /** Clearance between a node edge and the nearest lane, and beyond the last lane. */
106
+ const LANE_MARGIN = 24;
107
+ /** Horizontal offset of a straight route's label center from its line. */
108
+ const LABEL_BESIDE_OFFSET = 48;
109
+
110
+ const GITHUB_REPOSITORY_URL = /^https:\/\/github\.com\/[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+(?:\.git)?\/?$/;
111
+ const FULL_REVISION = /^[a-fA-F0-9]{40}$/;
112
+ const DATABASE_DIR =
113
+ /^(?:store|stores|storage|persistence|persist|db|database|databases|repository|repositories|dao)$/i;
114
+
115
+ interface Area {
116
+ key: string;
117
+ files: CodewikiFile[];
118
+ loc: number;
119
+ }
120
+
121
+ /** A schema-legal id from an area path: letters, digits, `_`, `-`, starting with a letter. */
122
+ function areaId(key: string): string {
123
+ const slug = key
124
+ .replace(/[^A-Za-z0-9]+/g, "-")
125
+ .replace(/^-+|-+$/g, "")
126
+ .toLowerCase();
127
+ const body = slug.length > 0 ? slug : "root";
128
+ return /^[a-z]/.test(body) ? body : `a-${body}`;
129
+ }
130
+
131
+ /** Keep readable ids, reserving every preferred spelling before adding collision suffixes. */
132
+ function uniqueIds(preferred: ReadonlyArray<string>): string[] {
133
+ const reserved = new Set(preferred);
134
+ const used = new Set<string>();
135
+ return preferred.map((base) => {
136
+ let id = base;
137
+ if (used.has(id)) {
138
+ let suffix = 2;
139
+ do {
140
+ id = `${base}-${suffix++}`;
141
+ } while (reserved.has(id) || used.has(id));
142
+ }
143
+ used.add(id);
144
+ return id;
145
+ });
146
+ }
147
+
148
+ function componentTypeFor(area: Area): SeedComponentType {
149
+ const last = area.key.split("/").filter(Boolean).at(-1) ?? "";
150
+ if (DATABASE_DIR.test(last)) return "database";
151
+ if (area.files.some((file) => file.role === "entry")) return "frontend";
152
+ return "backend";
153
+ }
154
+
155
+ function collectAreas(files: ReadonlyArray<CodewikiFile>, areaDepth: number): Area[] {
156
+ const byKey = new Map<string, Area>();
157
+ for (const file of files) {
158
+ const key = areaForPath(file.path, areaDepth);
159
+ const area = byKey.get(key) ?? { key, files: [], loc: 0 };
160
+ area.files.push(file);
161
+ area.loc += Math.max(0, file.loc);
162
+ byKey.set(key, area);
163
+ }
164
+ return [...byKey.values()].sort(
165
+ (a, b) => b.files.length - a.files.length || b.loc - a.loc || a.key.localeCompare(b.key),
166
+ );
167
+ }
168
+
169
+ /** The first declared symbol's line for each file id, when the index has one. */
170
+ function firstSymbolLines(symbols: ReadonlyArray<CodewikiSymbol>): Map<string, number> {
171
+ const lines = new Map<string, number>();
172
+ for (const symbol of symbols) {
173
+ if (!Number.isInteger(symbol.line) || symbol.line < 1) continue;
174
+ const current = lines.get(symbol.fileId);
175
+ if (current === undefined || symbol.line < current) lines.set(symbol.fileId, symbol.line);
176
+ }
177
+ return lines;
178
+ }
179
+
180
+ function sourcesFor(area: Area, lines: ReadonlyMap<string, number>): SeedSource[] {
181
+ return [...area.files]
182
+ .sort((a, b) => b.loc - a.loc || a.path.localeCompare(b.path))
183
+ .slice(0, MAX_SEED_SOURCES)
184
+ .map((file) => {
185
+ const line = lines.get(file.id);
186
+ return line === undefined ? { path: file.path } : { line, path: file.path };
187
+ });
188
+ }
189
+
190
+ function isInternalEdge(edge: Codewiki["edges"][number]): edge is CodewikiInternalEdge {
191
+ return "toFileId" in edge;
192
+ }
193
+
194
+ /**
195
+ * The package an external import specifier names: `@scope/pkg/deep` is
196
+ * `@scope/pkg`, `pkg/sub` is `pkg`. Runtime builtins (`node:fs`, `fs`) are
197
+ * not dependencies of the repository and return null.
198
+ */
199
+ function externalPackage(specifier: string): string | null {
200
+ if (specifier.startsWith("node:") || NODE_BUILTINS.has(specifier)) return null;
201
+ const segments = specifier.split("/");
202
+ if (specifier.startsWith("@")) return segments.length >= 2 ? `${segments[0]}/${segments[1]}` : null;
203
+ return segments[0] && segments[0].length > 0 ? segments[0] : null;
204
+ }
205
+
206
+ const NODE_BUILTINS = new Set([
207
+ "assert",
208
+ "buffer",
209
+ "child_process",
210
+ "crypto",
211
+ "events",
212
+ "fs",
213
+ "http",
214
+ "https",
215
+ "module",
216
+ "net",
217
+ "os",
218
+ "path",
219
+ "process",
220
+ "readline",
221
+ "stream",
222
+ "url",
223
+ "util",
224
+ "zlib",
225
+ ]);
226
+
227
+ /** JSON with every object's keys sorted, so equal seeds serialize identically. */
228
+ export function serializeArchitectureSeed(seed: ArchitectureSeed): string {
229
+ const sortKeys = (value: unknown): unknown => {
230
+ if (Array.isArray(value)) return value.map(sortKeys);
231
+ if (value && typeof value === "object") {
232
+ return Object.fromEntries(
233
+ Object.keys(value as Record<string, unknown>)
234
+ .sort()
235
+ .map((key) => [key, sortKeys((value as Record<string, unknown>)[key])]),
236
+ );
237
+ }
238
+ return value;
239
+ };
240
+ return `${JSON.stringify(sortKeys(seed), null, 2)}\n`;
241
+ }
242
+
243
+ interface Unplaced {
244
+ id: string;
245
+ type: SeedComponentType;
246
+ label: string;
247
+ sublabel: string;
248
+ sources?: SeedSource[];
249
+ }
250
+
251
+ interface WeightedEdge {
252
+ from: string;
253
+ to: string;
254
+ weight: number;
255
+ }
256
+
257
+ /**
258
+ * Rows by import direction. Edges are admitted by descending weight into a
259
+ * DAG (an edge that would close a cycle is drawn anyway, but does not shape
260
+ * the rows), and each node's row is its longest path from a source. Rows
261
+ * wider than the grid wrap onto following rows; externals sit last since
262
+ * nothing imports back into them.
263
+ */
264
+ function assignRows(nodes: ReadonlyArray<Unplaced>, edges: ReadonlyArray<WeightedEdge>): Map<string, number> {
265
+ const ids = nodes.filter((node) => node.type !== "external").map((node) => node.id);
266
+ const successors = new Map<string, Set<string>>(ids.map((id) => [id, new Set<string>()]));
267
+ const reaches = (from: string, to: string): boolean => {
268
+ const stack = [from];
269
+ const seen = new Set<string>();
270
+ while (stack.length > 0) {
271
+ const current = stack.pop() as string;
272
+ if (current === to) return true;
273
+ if (seen.has(current)) continue;
274
+ seen.add(current);
275
+ for (const next of successors.get(current) ?? []) stack.push(next);
276
+ }
277
+ return false;
278
+ };
279
+ for (const edge of edges) {
280
+ if (!successors.has(edge.from) || !successors.has(edge.to)) continue;
281
+ if (reaches(edge.to, edge.from)) continue;
282
+ successors.get(edge.from)?.add(edge.to);
283
+ }
284
+ const layer = new Map<string, number>();
285
+ const depth = (id: string): number => {
286
+ const known = layer.get(id);
287
+ if (known !== undefined) return known;
288
+ let best = 0;
289
+ for (const node of ids) {
290
+ if (successors.get(node)?.has(id)) best = Math.max(best, depth(node) + 1);
291
+ }
292
+ layer.set(id, best);
293
+ return best;
294
+ };
295
+ for (const id of ids) depth(id);
296
+ const rows = new Map<string, number>();
297
+ let row = 0;
298
+ const layers = [...new Set(ids.map((id) => layer.get(id) as number))].sort((a, b) => a - b);
299
+ for (const current of layers) {
300
+ // Node order within a layer follows the caller's ranking (file count).
301
+ const members = ids.filter((id) => layer.get(id) === current);
302
+ members.forEach((id, index) => {
303
+ rows.set(id, row + Math.floor(index / GRID_COLS));
304
+ });
305
+ row += Math.ceil(members.length / GRID_COLS);
306
+ }
307
+ const externals = nodes.filter((node) => node.type === "external");
308
+ externals.forEach((node, index) => {
309
+ rows.set(node.id, row + Math.floor(index / GRID_COLS));
310
+ });
311
+ return rows;
312
+ }
313
+
314
+ /**
315
+ * Place every node on the grid and give every connection an explicit
316
+ * orthogonal route that cannot cross a node: routes leave and enter on the
317
+ * top or bottom side, run horizontally only inside the gap between two rows,
318
+ * and when they must pass other rows they do so in a margin column outside
319
+ * the grid. Each gap and margin hands out distinct lanes so routes never
320
+ * share a segment. The geometry is fixed cell math, the same the renderer
321
+ * applies to `row`/`col`, so the via points land where the nodes are.
322
+ */
323
+ function placeAndRoute(
324
+ nodes: ReadonlyArray<Unplaced>,
325
+ edges: ReadonlyArray<WeightedEdge>,
326
+ ): { layout: SeedLayout; components: SeedComponent[]; connections: SeedConnection[] } {
327
+ const rowOf = assignRows(nodes, edges);
328
+ const colOf = new Map<string, number>();
329
+ const used = new Map<number, number>();
330
+ for (const node of nodes) {
331
+ const row = rowOf.get(node.id) as number;
332
+ const col = used.get(row) ?? 0;
333
+ colOf.set(node.id, col);
334
+ used.set(row, col + 1);
335
+ }
336
+
337
+ // Lane bookkeeping: which gap (below row r) and which margin each route uses.
338
+ const gapLanes = new Map<number, number>();
339
+ const leftLanes = { count: 0 };
340
+ const rightLanes = { count: 0 };
341
+ const takeGap = (row: number): number => {
342
+ const lane = gapLanes.get(row) ?? 0;
343
+ gapLanes.set(row, lane + 1);
344
+ return lane;
345
+ };
346
+ interface Plan {
347
+ edge: WeightedEdge;
348
+ fromSide: SeedSide;
349
+ toSide: SeedSide;
350
+ straight: boolean;
351
+ /** [gap row, lane] pairs in route order, and an optional margin lane. */
352
+ gaps: Array<[number, number]>;
353
+ margin?: { side: "left" | "right"; lane: number };
354
+ }
355
+ const plans: Plan[] = edges.map((edge) => {
356
+ const fromRow = rowOf.get(edge.from) as number;
357
+ const toRow = rowOf.get(edge.to) as number;
358
+ const sameCol = colOf.get(edge.from) === colOf.get(edge.to);
359
+ if (fromRow === toRow) {
360
+ return { edge, fromSide: "bottom", toSide: "bottom", straight: false, gaps: [[fromRow, takeGap(fromRow)]] };
361
+ }
362
+ if (fromRow < toRow) {
363
+ if (toRow === fromRow + 1) {
364
+ return {
365
+ edge,
366
+ fromSide: "bottom",
367
+ toSide: "top",
368
+ straight: sameCol,
369
+ gaps: sameCol ? [] : [[fromRow, takeGap(fromRow)]],
370
+ };
371
+ }
372
+ return {
373
+ edge,
374
+ fromSide: "bottom",
375
+ toSide: "top",
376
+ straight: false,
377
+ gaps: [
378
+ [fromRow, takeGap(fromRow)],
379
+ [toRow - 1, takeGap(toRow - 1)],
380
+ ],
381
+ margin: { side: "left", lane: leftLanes.count++ },
382
+ };
383
+ }
384
+ if (fromRow === toRow + 1) {
385
+ return {
386
+ edge,
387
+ fromSide: "top",
388
+ toSide: "bottom",
389
+ straight: sameCol,
390
+ gaps: sameCol ? [] : [[toRow, takeGap(toRow)]],
391
+ };
392
+ }
393
+ return {
394
+ edge,
395
+ fromSide: "top",
396
+ toSide: "bottom",
397
+ straight: false,
398
+ gaps: [
399
+ [fromRow - 1, takeGap(fromRow - 1)],
400
+ [toRow, takeGap(toRow)],
401
+ ],
402
+ margin: { side: "right", lane: rightLanes.count++ },
403
+ };
404
+ });
405
+
406
+ const maxGapLanes = Math.max(0, ...gapLanes.values());
407
+ const gapY = Math.max(90, 2 * LANE_MARGIN + Math.max(1, maxGapLanes) * LANE_STEP);
408
+ const originX = LANE_MARGIN + Math.max(1, leftLanes.count) * LANE_STEP + LANE_MARGIN;
409
+ const layout: SeedLayout = {
410
+ mode: "grid",
411
+ origin: [originX, 80],
412
+ cols: GRID_COLS,
413
+ cellW: CELL_W,
414
+ cellH: CELL_H,
415
+ gapX: GAP_X,
416
+ gapY,
417
+ };
418
+ const centerX = (id: string): number => originX + (colOf.get(id) as number) * (CELL_W + GAP_X) + CELL_W / 2;
419
+ const topY = (row: number): number => layout.origin[1] + row * (CELL_H + gapY);
420
+ const laneY = (row: number, lane: number): number => topY(row) + CELL_H + LANE_MARGIN + lane * LANE_STEP;
421
+ const gridRight = originX + GRID_COLS * (CELL_W + GAP_X) - GAP_X;
422
+ const marginX = (margin: NonNullable<Plan["margin"]>): number =>
423
+ margin.side === "left"
424
+ ? originX - LANE_MARGIN - margin.lane * LANE_STEP
425
+ : gridRight + LANE_MARGIN + margin.lane * LANE_STEP;
426
+
427
+ const components: SeedComponent[] = nodes.map((node) => ({
428
+ id: node.id,
429
+ type: node.type,
430
+ label: node.label,
431
+ sublabel: node.sublabel,
432
+ row: rowOf.get(node.id) as number,
433
+ col: colOf.get(node.id) as number,
434
+ size: [CELL_W, CELL_H],
435
+ ...(node.sources ? { sources: node.sources } : {}),
436
+ }));
437
+ const connectionIds = uniqueIds(plans.map(({ edge }) => `${edge.from}-to-${edge.to}`));
438
+ const connections: SeedConnection[] = plans.map((plan, index) => {
439
+ const { edge } = plan;
440
+ const base: SeedConnection = {
441
+ id: connectionIds[index] as string,
442
+ from: edge.from,
443
+ to: edge.to,
444
+ label: `${edge.weight} import${edge.weight === 1 ? "" : "s"}`,
445
+ fromSide: plan.fromSide,
446
+ toSide: plan.toSide,
447
+ };
448
+ const xa = centerX(edge.from);
449
+ const xb = centerX(edge.to);
450
+ if (plan.straight) {
451
+ // A straight vertical between two adjacent rows in one column: put the
452
+ // label beside the line, centered on the gap, so it covers neither node.
453
+ const upperRow = Math.min(rowOf.get(edge.from) as number, rowOf.get(edge.to) as number);
454
+ const gapMid = topY(upperRow) + CELL_H + gapY / 2;
455
+ return { ...base, route: "straight", labelAt: [xa + LABEL_BESIDE_OFFSET, gapMid] };
456
+ }
457
+ const [first, second] = plan.gaps;
458
+ if (!first) return { ...base, route: "straight" };
459
+ const y1 = laneY(first[0], first[1]);
460
+ if (!plan.margin || !second)
461
+ return {
462
+ ...base,
463
+ via: [
464
+ [xa, y1],
465
+ [xb, y1],
466
+ ],
467
+ };
468
+ const y2 = laneY(second[0], second[1]);
469
+ const mx = marginX(plan.margin);
470
+ return {
471
+ ...base,
472
+ via: [
473
+ [xa, y1],
474
+ [mx, y1],
475
+ [mx, y2],
476
+ [xb, y2],
477
+ ],
478
+ };
479
+ });
480
+ return { layout, components, connections };
481
+ }
482
+
483
+ export function buildArchitectureSeed(codewiki: Codewiki, options: BuildArchitectureSeedOptions): ArchitectureSeed {
484
+ const source = codewiki.files.filter((file) => file.lang !== "config");
485
+ const sourceLines = source.reduce((total, file) => total + Math.max(0, file.loc), 0);
486
+ const { areaDepth } = WIKI_DEPTH_STRATEGY[classifyDepth(source.length, sourceLines)];
487
+ const areas = collectAreas(source, areaDepth).slice(0, MAX_SEED_COMPONENTS);
488
+ const lines = firstSymbolLines(codewiki.symbols);
489
+ const areaByFile = new Map<string, string>();
490
+ for (const area of areas) for (const file of area.files) areaByFile.set(file.id, area.key);
491
+
492
+ // Archify's repository-evidence contract: `sources` are only legal when
493
+ // `meta.repository` pins the revision they were read at. Without a GitHub
494
+ // origin at a full sha the seed cites nothing rather than citing what the
495
+ // validator would reject.
496
+ const repository = options.repository;
497
+ const pinned =
498
+ repository && GITHUB_REPOSITORY_URL.test(repository.url) && FULL_REVISION.test(repository.revision)
499
+ ? { url: repository.url, revision: repository.revision.toLowerCase() }
500
+ : undefined;
501
+
502
+ // External packages: one component per top external module by import
503
+ // count, so the map shows what the repository leans on beyond itself.
504
+ const externalCounts = new Map<string, number>();
505
+ const externalWeights = new Map<string, number>();
506
+ for (const edge of codewiki.edges) {
507
+ if (isInternalEdge(edge)) continue;
508
+ const fromArea = areaByFile.get(edge.fileId);
509
+ const pkg = externalPackage(edge.externalModule);
510
+ if (fromArea === undefined || pkg === null) continue;
511
+ externalCounts.set(pkg, (externalCounts.get(pkg) ?? 0) + 1);
512
+ const key = `${fromArea}\0${pkg}`;
513
+ externalWeights.set(key, (externalWeights.get(key) ?? 0) + 1);
514
+ }
515
+ const externals = [...externalCounts.entries()]
516
+ .sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))
517
+ .slice(0, MAX_SEED_EXTERNALS)
518
+ .map(([module]) => module);
519
+ // Both component kinds share one identity namespace. Reserve all readable
520
+ // spellings before allocating suffixes, including names already ending in -2.
521
+ const componentIds = uniqueIds([
522
+ ...areas.map((area) => areaId(area.key)),
523
+ ...externals.map((module) => `ext-${areaId(module)}`),
524
+ ]);
525
+ const idByArea = new Map(areas.map((area, index) => [area.key, componentIds[index] as string]));
526
+ const idByExternal = new Map(externals.map((module, index) => [module, componentIds[areas.length + index] as string]));
527
+ const nodes: Unplaced[] = areas.map((area) => {
528
+ const sources = pinned ? sourcesFor(area, lines) : [];
529
+ return {
530
+ id: idByArea.get(area.key) as string,
531
+ type: componentTypeFor(area),
532
+ label: area.key,
533
+ sublabel: `${area.files.length} file${area.files.length === 1 ? "" : "s"}, ${area.loc} LOC`,
534
+ ...(sources.length > 0 ? { sources } : {}),
535
+ };
536
+ });
537
+ for (const module of externals) {
538
+ const count = externalCounts.get(module) ?? 0;
539
+ nodes.push({
540
+ id: idByExternal.get(module) as string,
541
+ type: "external",
542
+ label: module,
543
+ sublabel: `${count} import${count === 1 ? "" : "s"}`,
544
+ });
545
+ }
546
+
547
+ // Internal edges collapsed area to area; self edges are the area's own
548
+ // internal structure and say nothing about boundaries. Preserve destination
549
+ // kind in the weight key: a local area and a package may have the same name.
550
+ const weights = new Map<string, number>();
551
+ for (const edge of codewiki.edges) {
552
+ if (!isInternalEdge(edge)) continue;
553
+ const from = areaByFile.get(edge.fileId);
554
+ const to = areaByFile.get(edge.toFileId);
555
+ if (from === undefined || to === undefined || from === to) continue;
556
+ const key = `${from}\0${to}\0internal`;
557
+ weights.set(key, (weights.get(key) ?? 0) + 1);
558
+ }
559
+ for (const module of externals) {
560
+ for (const area of areas) {
561
+ const weight = externalWeights.get(`${area.key}\0${module}`);
562
+ if (weight) weights.set(`${area.key}\0${module}\0external`, weight);
563
+ }
564
+ }
565
+ const edges: WeightedEdge[] = [...weights.entries()]
566
+ .sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))
567
+ .slice(0, MAX_SEED_CONNECTIONS)
568
+ .map(([key, weight]) => {
569
+ const [fromKey, toKey, kind] = key.split("\0") as [string, string, "internal" | "external"];
570
+ const from = idByArea.get(fromKey) as string;
571
+ const to = (kind === "internal" ? idByArea : idByExternal).get(toKey) as string;
572
+ return { from, to, weight };
573
+ });
574
+ const { layout, components, connections } = placeAndRoute(nodes, edges);
575
+
576
+ const meta: ArchitectureSeed["meta"] = {
577
+ title: options.title,
578
+ quality_profile: "standard",
579
+ ...(pinned ? { repository: pinned } : {}),
580
+ };
581
+ return {
582
+ schema_version: 1,
583
+ diagram_type: "architecture",
584
+ meta,
585
+ layout,
586
+ components,
587
+ connections,
588
+ };
589
+ }
@@ -92,13 +92,13 @@ interface Area {
92
92
  * filename is dropped first, so a file sitting directly in `src` joins the
93
93
  * `src` area instead of becoming an area of its own named after itself.
94
94
  */
95
- function areaForPath(path: string, maxDepth: number): string {
95
+ export function areaForPath(path: string, maxDepth: number): string {
96
96
  const directories = path.split("/").filter(Boolean).slice(0, -1);
97
97
  if (directories.length === 0) return ".";
98
98
  return directories.slice(0, Math.max(1, maxDepth)).join("/");
99
99
  }
100
100
 
101
- function classifyDepth(sourceFiles: number, sourceLines: number): ResolvedWikiDepth {
101
+ export function classifyDepth(sourceFiles: number, sourceLines: number): ResolvedWikiDepth {
102
102
  if (sourceFiles <= 150 && sourceLines <= 30_000) return "simple";
103
103
  if (sourceFiles <= 800 && sourceLines <= 150_000) return "medium";
104
104
  return "detailed";
@@ -14,6 +14,7 @@ import { execFileSync } from "node:child_process";
14
14
  import { existsSync, realpathSync, statSync } from "node:fs";
15
15
  import { isAbsolute, join, relative } from "node:path";
16
16
  import { loadFragments } from "../../prompts/fragment-loader.js";
17
+ import { type DecisionLedgerEntry, decisionRef } from "../../session/entries.js";
17
18
  import { renderCodewikiDigest } from "../codewiki/digest.js";
18
19
  import type { Codewiki } from "../codewiki/schema.js";
19
20
  import { WIKI_PLAN_FILE } from "./layout.js";
@@ -229,6 +230,8 @@ function scopedSymbols(codewiki: Codewiki, sources: ReadonlyArray<string>, limit
229
230
  }
230
231
 
231
232
  export interface BuildWikiPagePromptInput {
233
+ /** The current session board, already scoped to its active branch. */
234
+ decisions?: ReadonlyArray<DecisionLedgerEntry>;
232
235
  cwd: string;
233
236
  mode: WikiGenerateMode;
234
237
  codewiki: Codewiki;
@@ -272,6 +275,8 @@ export function buildWikiPagePrompt(input: BuildWikiPagePromptInput): string {
272
275
  "## Repository guidance",
273
276
  repositoryGuidance(input.cwd),
274
277
  ];
278
+ const decisions = recordedDecisions(input);
279
+ if (decisions.length > 0) sections.push("# Recorded decisions", "```json", JSON.stringify(decisions, null, 2), "```");
275
280
  if (input.seeded) {
276
281
  sections.push(
277
282
  "## Revision",
@@ -281,3 +286,41 @@ export function buildWikiPagePrompt(input: BuildWikiPagePromptInput): string {
281
286
  }
282
287
  return `${sections.join("\n\n")}\n`;
283
288
  }
289
+
290
+ /** Match a source itself or a descendant, without accepting similarly named siblings. */
291
+ function underSource(path: string, source: string): boolean {
292
+ const root = source.replace(/^\.\//, "").replace(/\/$/, "");
293
+ const candidate = path.replace(/^\.\//, "");
294
+ return candidate === root || candidate.startsWith(`${root}/`);
295
+ }
296
+
297
+ function recordedDecisions(input: BuildWikiPagePromptInput) {
298
+ const files = new Set(
299
+ input.codewiki.files
300
+ .filter((file) => input.page.sources.some((source) => underSource(file.path, source)))
301
+ .map((file) => file.id),
302
+ );
303
+ const symbols = new Set(
304
+ input.codewiki.symbols.filter((symbol) => files.has(symbol.fileId)).map((symbol) => symbol.name),
305
+ );
306
+ return (input.decisions ?? [])
307
+ .flatMap((entry) =>
308
+ entry.decisions
309
+ .filter((record) => {
310
+ if (record.status !== "active") return false;
311
+ if (symbols.has(record.key)) return true;
312
+ const paths = [record.rationale ?? "", ...(record.alternatives ?? [])].join(" ").match(/[\w@./-]+/g) ?? [];
313
+ return paths.some((path) => input.page.sources.some((source) => underSource(path.replace(/\.$/, ""), source)));
314
+ })
315
+ .map((record) => ({
316
+ ref: decisionRef(entry.interviewId, record.key),
317
+ key: record.key,
318
+ value: record.value,
319
+ alternatives: record.alternatives ?? [],
320
+ rationale: record.rationale ?? record.source_question ?? "",
321
+ decidedAt: record.decidedAt,
322
+ source: record.source ?? (entry.origin === "agent" ? "agent" : "operator"),
323
+ })),
324
+ )
325
+ .slice(0, 12);
326
+ }
@@ -37,6 +37,9 @@ export function routeValidationProjection(
37
37
  // Presentation-only parentage stamped by the calling tool, on the same
38
38
  // terms: a model must not be able to author it.
39
39
  parentToolCallId,
40
+ // Sealed from the parent decision board by the dispatch tool; a model
41
+ // must not be able to author which decisions a receipt claims.
42
+ decisionRefs,
40
43
  resolvedVerification,
41
44
  resultContractOverride,
42
45
  fleetGateReceipt,
@@ -60,6 +63,7 @@ export function routeValidationProjection(
60
63
  ...(assignmentDeadlineAt !== undefined ? { assignmentDeadlineAt } : {}),
61
64
  ...(ledger !== undefined ? { ledger } : {}),
62
65
  ...(parentToolCallId !== undefined ? { parentToolCallId } : {}),
66
+ ...(decisionRefs !== undefined ? { decisionRefs } : {}),
63
67
  ...(resolvedVerification !== undefined
64
68
  ? { resolvedVerification: resolvedVerification.map((check) => ({ ...check, argv: [...check.argv] })) }
65
69
  : {}),