@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
@@ -1003,6 +1003,7 @@ function formatUrl(status: TargetStatus): string {
1003
1003
 
1004
1004
  function formatAuth(providers: ProvidersContract, status: TargetStatus): string {
1005
1005
  if (!status.runtime) return "-";
1006
+ if (status.runtime.externalAgentLoop !== undefined && status.runtime.auth !== "claude-cli") return "operator session";
1006
1007
  if (status.runtime.auth !== "api-key" && status.runtime.auth !== "oauth") return status.runtime.auth;
1007
1008
  const auth = providers.auth.statusForTarget(status.target, status.runtime);
1008
1009
  if (!auth.available) return "disconnected";
@@ -1138,6 +1139,7 @@ interface SerializedStatus {
1138
1139
  probeNotes?: TargetStatus["probeNotes"];
1139
1140
  probeSurfaces?: TargetStatus["probeSurfaces"];
1140
1141
  discoveredModels: TargetStatus["discoveredModels"];
1142
+ discoveredModelLabels?: TargetStatus["discoveredModelLabels"];
1141
1143
  discoveredModelsSource?: TargetStatus["discoveredModelsSource"];
1142
1144
  discoveredModelStates?: TargetStatus["discoveredModelStates"];
1143
1145
  tier: ProviderOutputTier;
@@ -1165,6 +1167,7 @@ function serializeStatus(
1165
1167
  detectedReasoning: extras.detectedReasoning,
1166
1168
  reasoningCandidateModelId: extras.candidateModelId,
1167
1169
  };
1170
+ if (status.discoveredModelLabels !== undefined) out.discoveredModelLabels = status.discoveredModelLabels;
1168
1171
  const endpointCapacity = endpointCapacityForStatus(status);
1169
1172
  if (endpointCapacity !== null) out.endpointCapacity = endpointCapacity;
1170
1173
  if (status.contextWindowProvenance !== undefined) {
@@ -0,0 +1,84 @@
1
+ import { normalizeIntentExpectedOutputs, normalizeIntentVerification } from "../domains/dispatch/intent.js";
2
+ import type { UserTaskAcceptance } from "../domains/user-tasks/acceptance.js";
3
+ import { createUserTasksStore } from "../domains/user-tasks/store.js";
4
+ import { packageDeclaredCheck } from "../tools/verify/catalog.js";
5
+ import { discoverDeclaredChecksAtRoot, discoverDeclaredProjectEntriesAtRoot } from "../tools/verify/scripts.js";
6
+ import { printError } from "./argv.js";
7
+
8
+ /** Operator flags use the same bounds and normalization as dispatch intent. */
9
+ export function acceptanceFromTaskFlags(
10
+ cwd: string,
11
+ expectedOutputs: string[],
12
+ verify: string[],
13
+ ): UserTaskAcceptance | undefined {
14
+ if (expectedOutputs.length === 0 && verify.length === 0) return undefined;
15
+ const discovery = discoverDeclaredChecksAtRoot(cwd, undefined);
16
+ if (!discovery.ok) throw new Error(discovery.reason);
17
+ const checks = new Map(
18
+ discovery.sources.flatMap((source) => source.checks.map((check) => [check.id, check] as const)),
19
+ );
20
+ for (const entry of discoverDeclaredProjectEntriesAtRoot(cwd)) {
21
+ if (entry.kind === "package-script" && !checks.has(entry.id))
22
+ checks.set(entry.id, packageDeclaredCheck(entry.id, entry.path, ".", []));
23
+ }
24
+ const verification = verify.map((value) => {
25
+ const suffix = checks.has(value) ? null : /^(.*):([0-9]+)$/.exec(value);
26
+ const check = suffix?.[1] ?? value;
27
+ if (!checks.has(check))
28
+ throw new Error(
29
+ `Unknown verification check '${check}'. Known ids: ${[...checks.keys()].sort().join(", ") || "(none)"}`,
30
+ );
31
+ return { check, ...(suffix ? { timeout_ms: Number(suffix[2]) } : {}) };
32
+ });
33
+ const outputs = normalizeIntentExpectedOutputs(expectedOutputs);
34
+ if (!Array.isArray(outputs)) throw new Error(outputs.ok ? "invalid expected outputs" : outputs.message);
35
+ const normalized = normalizeIntentVerification(verification, checks);
36
+ if (!Array.isArray(normalized)) throw new Error(normalized.ok ? "invalid verification" : normalized.message);
37
+ return { expectedOutputs: outputs, verification: normalized };
38
+ }
39
+
40
+ const HELP = `Usage:
41
+ clio-coder tasks [list]
42
+ clio-coder tasks add [--expect <path>] [--verify <checkId>[:timeoutMs]] <text>
43
+ clio-coder tasks hand|done|drop <uN>
44
+
45
+ --expect and --verify are repeatable. Check ids must be declared in package.json or .clio-coder/verifiers.yaml.`;
46
+
47
+ export function runTasksCommand(args: string[]): number {
48
+ try {
49
+ if (args.includes("--help") || args.includes("-h")) {
50
+ console.log(HELP);
51
+ return 0;
52
+ }
53
+ const store = createUserTasksStore({ cwd: process.cwd() });
54
+ const [action = "list", ...rest] = args;
55
+ if (action === "add") {
56
+ const expected: string[] = [],
57
+ verify: string[] = [],
58
+ title: string[] = [];
59
+ for (let index = 0; index < rest.length; index++) {
60
+ const token = rest[index] ?? "";
61
+ if (token === "--") {
62
+ title.push(...rest.slice(index + 1));
63
+ break;
64
+ }
65
+ if (token === "--expect" || token === "--verify") {
66
+ const value = rest[++index];
67
+ if (!value || value.startsWith("--")) throw new Error(`${token} requires a value`);
68
+ (token === "--expect" ? expected : verify).push(value);
69
+ } else if (token.startsWith("--")) throw new Error(`Unknown flag ${token}`);
70
+ else title.push(token);
71
+ }
72
+ const task = store.add(title.join(" "), undefined, acceptanceFromTaskFlags(process.cwd(), expected, verify));
73
+ console.log(`logged operator task ${task.id}: ${task.title}`);
74
+ } else if (action === "list" && rest.length === 0) {
75
+ console.log(JSON.stringify(store.snapshot(), null, 2));
76
+ } else if ((action === "hand" || action === "done" || action === "drop") && rest.length === 1) {
77
+ console.log(JSON.stringify(store[action](rest[0] ?? ""), null, 2));
78
+ } else throw new Error(HELP);
79
+ return 0;
80
+ } catch (error) {
81
+ printError(error instanceof Error ? error.message : String(error));
82
+ return 1;
83
+ }
84
+ }
@@ -5,38 +5,50 @@ import { delimiter, dirname, isAbsolute, join, resolve, sep } from "node:path";
5
5
 
6
6
  import { resolvePackageRoot } from "../core/package-root.js";
7
7
  import { resetXdgCache, resolveClioDirs } from "../core/xdg.js";
8
+ import { detectInstallMethod } from "../domains/lifecycle/install-method.js";
9
+ import { createLifecyclePresenter, type LifecycleItem, measurePath, shortenPath } from "./lifecycle-presenter.js";
8
10
  import { type RemovalFailure, removePath, reportRemovalFailures } from "./removal.js";
9
- import { printError, printHeader, printOk } from "./shared.js";
11
+ import { printError } from "./shared.js";
10
12
 
11
- const HELP = `clio-coder uninstall [--remove-binary] [--dry-run] [--force]
13
+ const HELP = `clio-coder uninstall [--remove-binary] [--keep-config] [--keep-data] [--dry-run] [--force] [--json]
12
14
 
13
15
  Remove all Clio Coder state: the config, data, state, and cache roots.
14
16
 
15
- Per-project \`.clio-coder/\` directories are outside those roots and are never removed
16
- here. Every project Clio has run in is recorded in the session metadata, so both
17
- the real run and --dry-run list them and name the command that clears one,
18
- before the launcher is touched.
17
+ Per-project \`.clio-coder/\` directories sit outside those roots and are never
18
+ removed here. Every project Clio has run in is recorded in the session metadata,
19
+ so the real run and --dry-run both list them and name the command that clears one.
20
+ Shell startup files are reported, never edited.
19
21
 
20
22
  Flags:
23
+ --keep-config preserve the configuration root (settings.yaml, credentials)
24
+ --keep-data preserve the data root (memory, evidence, vendored tools)
21
25
  --remove-binary also remove the launcher symlink when it points at this
22
26
  installation. A real file, or a link into a different clio-coder
23
27
  installation, is kept and reported.
24
28
  --dry-run print what would be removed without changing anything
25
- --force required for destructive execution
29
+ --force, -f skip confirmation prompt and proceed immediately
30
+ --json emit machine-readable JSON output
31
+ --help, -h show this message
26
32
  `;
27
33
 
28
34
  interface ParsedUninstallArgs {
29
35
  removeBinary: boolean;
36
+ keepConfig: boolean;
37
+ keepData: boolean;
30
38
  force: boolean;
31
39
  dryRun: boolean;
40
+ json: boolean;
32
41
  help: boolean;
33
42
  }
34
43
 
35
44
  function parseUninstallArgs(argv: ReadonlyArray<string>): ParsedUninstallArgs {
36
45
  const parsed: ParsedUninstallArgs = {
37
46
  removeBinary: false,
47
+ keepConfig: false,
48
+ keepData: false,
38
49
  force: false,
39
50
  dryRun: false,
51
+ json: false,
40
52
  help: false,
41
53
  };
42
54
  for (const arg of argv) {
@@ -44,6 +56,12 @@ function parseUninstallArgs(argv: ReadonlyArray<string>): ParsedUninstallArgs {
44
56
  case "--remove-binary":
45
57
  parsed.removeBinary = true;
46
58
  break;
59
+ case "--keep-config":
60
+ parsed.keepConfig = true;
61
+ break;
62
+ case "--keep-data":
63
+ parsed.keepData = true;
64
+ break;
47
65
  case "--force":
48
66
  case "-f":
49
67
  parsed.force = true;
@@ -51,6 +69,9 @@ function parseUninstallArgs(argv: ReadonlyArray<string>): ParsedUninstallArgs {
51
69
  case "--dry-run":
52
70
  parsed.dryRun = true;
53
71
  break;
72
+ case "--json":
73
+ parsed.json = true;
74
+ break;
54
75
  case "--help":
55
76
  case "-h":
56
77
  parsed.help = true;
@@ -62,10 +83,6 @@ function parseUninstallArgs(argv: ReadonlyArray<string>): ParsedUninstallArgs {
62
83
  return parsed;
63
84
  }
64
85
 
65
- function report(label: string, path: string): void {
66
- process.stdout.write(` ${label.padEnd(8)} remove ${path}${existsSync(path) ? "" : " (absent)"}\n`);
67
- }
68
-
69
86
  export interface ProjectContextInventory {
70
87
  /** Project directories the session store recorded, one per cwd hash. */
71
88
  recorded: number;
@@ -78,17 +95,6 @@ export interface ProjectContextInventory {
78
95
  /**
79
96
  * The projects Clio has run in, read from the session metadata under
80
97
  * `<stateDir>/sessions/`.
81
- *
82
- * Uninstall removes four roots under the home directory and nothing else, so
83
- * every `.clio-coder/` it ever wrote inside a repository survived it, unlisted. The
84
- * operator was left to remember which repositories those were, after the
85
- * command that could have told them had deleted the record and, with
86
- * `--remove-binary`, the binary that reads it.
87
- *
88
- * One `meta.json` per cwd-hash directory is enough: every session under a hash
89
- * shares the `cwd` that produced it, so this reads one small file per project
90
- * rather than one per session. Directories whose `.clio-coder/` is already gone are
91
- * dropped, because an inventory of nothing to do is noise.
92
98
  */
93
99
  function projectContextInventory(stateDir: string): ProjectContextInventory {
94
100
  const root = join(stateDir, "sessions");
@@ -129,37 +135,6 @@ function firstRecordedCwd(hashDir: string): string | null {
129
135
  return null;
130
136
  }
131
137
 
132
- /**
133
- * Print the project inventory and the command that clears one.
134
- *
135
- * Ordering is the point. This runs before the roots are removed, because the
136
- * record it reads is inside one of them, and before the launcher is removed,
137
- * because `clio-coder context reset --all` needs the binary that is about to go.
138
- */
139
- function reportProjectContext(inventory: ProjectContextInventory, removeBinary: boolean): void {
140
- process.stdout.write("\nPer-project context (not removed by uninstall):\n");
141
- if (inventory.storeAbsent) {
142
- process.stdout.write(" no session store to read; any .clio-coder/ directories must be found by hand\n");
143
- return;
144
- }
145
- if (inventory.dirs.length === 0) {
146
- process.stdout.write(
147
- ` none: ${inventory.recorded} project director${inventory.recorded === 1 ? "y" : "ies"} recorded, none still has a .clio-coder/\n`,
148
- );
149
- return;
150
- }
151
- for (const dir of inventory.dirs) process.stdout.write(` ${join(dir, ".clio-coder")}\n`);
152
- // The cleaner is a clio subcommand, so with --remove-binary this run is
153
- // taking the thing that would have run it. Saying "clear these first" after
154
- // the launcher is already gone would be advice the operator cannot follow.
155
- process.stdout.write(
156
- removeBinary
157
- ? "\nThis run also removes the launcher. Clear each one from inside it first, then re-run:\n"
158
- : "\nClear each one from inside it, while clio still runs:\n",
159
- );
160
- process.stdout.write(" clio-coder context reset --all\n\n");
161
- }
162
-
163
138
  function launcherLinkPath(): string {
164
139
  const binDir = process.env.CLIO_CODER_BIN_DIR?.trim() || join(homedir(), ".local", "bin");
165
140
  return join(binDir, "clio-coder");
@@ -171,32 +146,12 @@ function ownedCliEntry(): string {
171
146
  try {
172
147
  return realpathSync(entry);
173
148
  } catch {
174
- // A source checkout with no build yet, or a dist this process was not
175
- // launched from. The unresolved path is still the right identity.
176
149
  return entry;
177
150
  }
178
151
  }
179
152
 
180
153
  type LauncherVerdict = { kind: "absent" } | { kind: "keep"; detail: string } | { kind: "remove"; detail: string };
181
154
 
182
- /**
183
- * Decide whether the launcher at `linkPath` belongs to this installation.
184
- *
185
- * Ownership is identity, not shape. The previous rule accepted any symlink
186
- * whose target path ended in `dist/cli/index.js`, which is a string test three
187
- * ways too broad: it matched a live symlink into a *different* clio checkout,
188
- * and it matched a target that is not even a file, so `clio-coder uninstall
189
- * --remove-binary` from one installation would silently unlink another one's
190
- * launcher and leave that installation on disk with no way to start it.
191
- *
192
- * A link that resolves to this installation's own entry is ours and goes. A
193
- * link that resolves anywhere else is somebody's, so it stays with the path it
194
- * points at and the command that removes it deliberately. A dangling link is
195
- * the one case with no owner to defer to: the installation it named is gone,
196
- * unlinking it cannot touch a target that does not exist, and leaving it puts
197
- * a broken `clio-coder` on PATH after an uninstall that claimed to finish. Those are
198
- * removed when the name they carry is a clio entry, and reported as dangling.
199
- */
200
155
  function classifyLauncher(linkPath: string): LauncherVerdict {
201
156
  let isSymlink: boolean;
202
157
  try {
@@ -235,25 +190,6 @@ function classifyLauncher(linkPath: string): LauncherVerdict {
235
190
  };
236
191
  }
237
192
 
238
- /** Returns the failure when the owned launcher existed but could not be unlinked. */
239
- function removeLauncher(dryRun: boolean): RemovalFailure | null {
240
- const linkPath = launcherLinkPath();
241
- const verdict = classifyLauncher(linkPath);
242
- if (verdict.kind === "absent") {
243
- process.stdout.write(` binary absent ${linkPath}\n`);
244
- return null;
245
- }
246
- if (verdict.kind === "keep") {
247
- process.stdout.write(` binary keep ${linkPath} (${verdict.detail})\n`);
248
- return null;
249
- }
250
- process.stdout.write(` binary remove ${linkPath} ${verdict.detail}\n`);
251
- // Shares removePath so the launcher gets the same unlink-the-link handling
252
- // every other removed path gets. Removing the link with `rmSync` left a
253
- // dangling one in place while reporting that it had gone.
254
- return removePath("binary", linkPath, dryRun);
255
- }
256
-
257
193
  function findClioOnPath(): string | null {
258
194
  const names =
259
195
  process.platform === "win32" ? ["clio-coder.cmd", "clio-coder.ps1", "clio-coder.exe", "clio-coder"] : ["clio-coder"];
@@ -273,11 +209,6 @@ function readNpmPrefix(): string | null {
273
209
  encoding: "utf8",
274
210
  timeout: 5000,
275
211
  stdio: ["ignore", "pipe", "ignore"],
276
- // A read-only probe that writes. npm drops a debug log into
277
- // $HOME/.npm/_logs on every invocation, so the documented
278
- // side-effect-free `--dry-run` path left a file behind in the home
279
- // directory it had just finished promising not to touch. `logs-max=0`
280
- // keeps npm from retaining any; the notifier is off for the same reason.
281
212
  env: { ...process.env, npm_config_logs_max: "0", npm_config_update_notifier: "false" },
282
213
  });
283
214
  if (result.status !== 0) return null;
@@ -288,16 +219,6 @@ function readNpmPrefix(): string | null {
288
219
  }
289
220
  }
290
221
 
291
- /**
292
- * The `clio` a shell will find, when that is not the launcher this uninstall
293
- * was about.
294
- *
295
- * Both paths are resolved through their symlinks before they are compared: the
296
- * PATH entry is normally a link into this checkout, and comparing the link to
297
- * its own target reported two installations where there is one. A PATH entry
298
- * that cannot be resolved is dangling, which is still something the operator
299
- * will hit and still not this installation.
300
- */
301
222
  function otherClioOnPath(pathClio: string | null, localLink: string): string | null {
302
223
  if (pathClio === null) return null;
303
224
  if (pathClio === localLink) return null;
@@ -313,93 +234,240 @@ function otherClioOnPath(pathClio: string | null, localLink: string): string | n
313
234
  return pathClio;
314
235
  }
315
236
 
316
- function printRemovalGuidance(removeBinaryRequested: boolean): void {
317
- const pathClio = findClioOnPath();
318
- const npmPrefix = readNpmPrefix();
319
- const localLink = launcherLinkPath();
320
- const currentLauncher = process.argv[1];
321
-
322
- process.stdout.write("\nBinary removal guidance:\n");
323
- if (currentLauncher) process.stdout.write(` current launcher: ${currentLauncher}\n`);
324
- process.stdout.write(` PATH lookup: ${pathClio ?? "not currently found"}\n`);
325
- if (npmPrefix) process.stdout.write(` npm prefix bin: ${join(npmPrefix, "bin")}\n`);
326
- process.stdout.write(` local source bin: ${localLink}${existsSync(localLink) ? "" : " (absent)"}\n`);
327
- // The two lines above are adjacent and were left for the reader to compare.
328
- // When they differ they are two installations, and the operator who just read
329
- // "removed Clio Coder state" will type `clio-coder` next and reach the other one.
330
- // Saying so is the whole point of printing both paths.
331
- const survivor = otherClioOnPath(pathClio, localLink);
332
- if (survivor !== null) {
333
- process.stdout.write(`\nanother clio-coder remains on your PATH at ${survivor}\n`);
334
- process.stdout.write(" it is a different installation from the one this uninstall touched\n");
335
- process.stdout.write(` check it with: ${survivor} --version\n`);
237
+ /**
238
+ * Shell startup files that mention Clio. Uninstall reports them and never edits
239
+ * them: a login file is the user's own, an installer is not the only thing that
240
+ * writes `clio-coder` into one, and a wrong automated edit costs a working
241
+ * shell. Naming the file and leaving the edit to the operator is the honest
242
+ * trade, so these rows are listed as kept rather than as removals.
243
+ */
244
+ function detectShellRcEdits(): string[] {
245
+ const candidates = [join(homedir(), ".bashrc"), join(homedir(), ".zshrc"), join(homedir(), ".profile")];
246
+ const results: string[] = [];
247
+ for (const file of candidates) {
248
+ try {
249
+ const content = readFileSync(file, "utf8");
250
+ if (content.includes("clio-coder") || content.includes("CLIO_CODER")) results.push(file);
251
+ } catch {
252
+ // Absent or unreadable says nothing to report.
253
+ }
336
254
  }
337
- process.stdout.write("\nUse the removal path that matches how you installed Clio Coder:\n");
338
- // Re-suggesting the flag the operator just passed reads as though it had not
339
- // run, so the source-symlink line only appears when it is still an option.
340
- if (!removeBinaryRequested) {
341
- process.stdout.write(" source symlink: clio-coder uninstall --remove-binary --force\n");
255
+ return results;
256
+ }
257
+
258
+ /**
259
+ * The one fact worth a line after the roots are gone: a second clio-coder that
260
+ * this uninstall did not touch is still first on PATH, so the next `clio-coder`
261
+ * runs it and the operator would conclude the uninstall failed.
262
+ */
263
+ function survivingClioOnPath(localLink: string): string | null {
264
+ return otherClioOnPath(findClioOnPath(), localLink);
265
+ }
266
+
267
+ /**
268
+ * How the launcher row reads. `--remove-binary` promises to unlink only a
269
+ * symlink into this installation; every other shape is kept, and saying so on
270
+ * the inventory is the difference between an operator who knows a launcher
271
+ * survived and one who finds out from the next `clio-coder`.
272
+ */
273
+ function launcherItemStatus(verdict: LauncherVerdict, removeRequested: boolean): LifecycleItem["status"] {
274
+ if (verdict.kind === "absent") return "absent";
275
+ if (verdict.kind === "keep") return "skip";
276
+ return removeRequested ? "remove" : "skip";
277
+ }
278
+
279
+ function launcherItemDetail(verdict: LauncherVerdict, removeRequested: boolean): string | undefined {
280
+ if (verdict.kind === "absent") return undefined;
281
+ if (verdict.kind === "keep") return verdict.detail;
282
+ return removeRequested ? undefined : "kept; --remove-binary unlinks it";
283
+ }
284
+
285
+ /** The removal command that matches how this installation was put on disk. */
286
+ function binaryRemovalAdvice(method: "source" | "npm", linkPath: string): { lead: string; command: string } {
287
+ if (method === "npm") {
288
+ const prefix = readNpmPrefix();
289
+ return {
290
+ lead: prefix === null ? "To remove the launcher, run:" : `To remove the launcher from ${join(prefix, "bin")}, run:`,
291
+ command: "npm uninstall -g @iowarp/clio-coder\nhash -r",
292
+ };
342
293
  }
343
- process.stdout.write(" npm global: npm uninstall -g @iowarp/clio-coder\n");
344
- process.stdout.write(" npm link: npm unlink -g @iowarp/clio-coder\n");
345
- process.stdout.write("\nAfter removing or replacing a clio-coder link, clear shell command caches:\n");
346
- process.stdout.write(" hash -r # Bash\n");
347
- process.stdout.write(" rehash # Zsh\n");
294
+ return { lead: "To finish removing the launcher, run:", command: `rm "${linkPath}"\nhash -r` };
348
295
  }
349
296
 
350
- export function runUninstallCommand(argv: ReadonlyArray<string>): number {
297
+ export async function runUninstallCommand(argv: ReadonlyArray<string>): Promise<number> {
351
298
  let args: ParsedUninstallArgs;
352
299
  try {
353
300
  args = parseUninstallArgs(argv);
354
301
  } catch (error) {
355
302
  printError(error instanceof Error ? error.message : String(error));
356
- process.stdout.write(HELP);
303
+ process.stderr.write(HELP);
357
304
  return 2;
358
305
  }
359
306
  if (args.help) {
360
307
  process.stdout.write(HELP);
361
308
  return 0;
362
309
  }
363
- if (!args.dryRun && !args.force) {
364
- printError("`clio-coder uninstall` requires --force unless you are using --dry-run");
365
- process.stdout.write(HELP);
310
+
311
+ // One sentence, and nothing on stdout: a caller that piped this run is
312
+ // parsing stdout, and a help dump there is indistinguishable from output.
313
+ const isInteractive = Boolean(process.stdin.isTTY);
314
+ if (!args.dryRun && !args.force && !isInteractive) {
315
+ printError("`clio-coder uninstall` needs a terminal to confirm; pass --force to skip the prompt");
366
316
  return 2;
367
317
  }
368
318
 
369
319
  const dirs = resolveClioDirs();
370
- printHeader("Clio Coder uninstall");
371
- const roots = [
372
- ["config", dirs.config],
373
- ["data", dirs.data],
374
- ["state", dirs.state],
375
- ["cache", dirs.cache],
376
- ] as const;
377
- for (const [label, path] of roots) report(label, path);
378
-
379
- // Read the session store before it is removed and report it before the
380
- // launcher is: both halves of that ordering are load-bearing.
381
- reportProjectContext(projectContextInventory(dirs.state), args.removeBinary);
382
-
383
- // Every root is attempted even after one fails, so a single unwritable
384
- // subtree cannot leave the other three behind unreported.
320
+ const method = detectInstallMethod();
321
+ const presenter = createLifecyclePresenter({ json: args.json });
322
+
323
+ presenter.header("Uninstall Clio Coder", "uninstall");
324
+ presenter.step(`Installation method: ${method === "source" ? "source symlink" : "npm global"}`);
325
+
326
+ const configSize = measurePath(dirs.config);
327
+ const dataSize = measurePath(dirs.data);
328
+ const stateSize = measurePath(dirs.state);
329
+ const cacheSize = measurePath(dirs.cache);
330
+ const linkPath = launcherLinkPath();
331
+ const linkSize = measurePath(linkPath);
332
+ const launcher = classifyLauncher(linkPath);
333
+ const shellEdits = detectShellRcEdits();
334
+
335
+ // The state root's own children (audit, sessions) are inside the State row
336
+ // and go with it; listing them again as separate removals double-counted the
337
+ // bytes and promised per-child results that one recursive delete never
338
+ // produces.
339
+ const items: LifecycleItem[] = [
340
+ {
341
+ label: "Data",
342
+ path: dirs.data,
343
+ bytes: dataSize.bytes,
344
+ status: args.keepData ? "keep" : dataSize.exists ? "remove" : "absent",
345
+ detail: args.keepData ? "kept by --keep-data" : undefined,
346
+ },
347
+ {
348
+ label: "Cache",
349
+ path: dirs.cache,
350
+ bytes: cacheSize.bytes,
351
+ status: cacheSize.exists ? "remove" : "absent",
352
+ },
353
+ {
354
+ label: "Config",
355
+ path: dirs.config,
356
+ bytes: configSize.bytes,
357
+ status: args.keepConfig ? "keep" : configSize.exists ? "remove" : "absent",
358
+ detail: args.keepConfig ? "kept by --keep-config" : undefined,
359
+ },
360
+ {
361
+ label: "State",
362
+ path: dirs.state,
363
+ bytes: stateSize.bytes,
364
+ status: stateSize.exists ? "remove" : "absent",
365
+ detail: stateSize.exists ? "sessions, audit, receipts" : undefined,
366
+ },
367
+ {
368
+ label: "Launcher",
369
+ path: linkPath,
370
+ bytes: linkSize.bytes,
371
+ status: launcherItemStatus(launcher, args.removeBinary),
372
+ detail: launcherItemDetail(launcher, args.removeBinary),
373
+ },
374
+ ];
375
+
376
+ // A login file is reported, never edited; see detectShellRcEdits.
377
+ for (const file of shellEdits) {
378
+ items.push({ label: "Shell config", path: file, status: "skip", detail: "mentions clio-coder; edit it by hand" });
379
+ }
380
+
381
+ presenter.listItems("The following will be removed", items);
382
+
383
+ const projectInv = projectContextInventory(dirs.state);
384
+ if (projectInv.dirs.length > 0) {
385
+ presenter.note("Per-project context, which uninstall does not remove:");
386
+ for (const dir of projectInv.dirs) {
387
+ presenter.substep(shortenPath(join(dir, ".clio-coder")), "–");
388
+ }
389
+ presenter.commandAdvice("To clear one, run inside that project:", "clio-coder context reset --all");
390
+ }
391
+
392
+ // The same guidance on the dry run and on the real run, so the preview is the
393
+ // listing the run produces and nothing more.
394
+ const survivor = survivingClioOnPath(linkPath);
395
+ const advice = binaryRemovalAdvice(method, linkPath);
396
+
397
+ if (args.dryRun) {
398
+ presenter.warn("Dry run: no changes made");
399
+ if (launcher.kind !== "absent" && !args.removeBinary) presenter.commandAdvice(advice.lead, advice.command);
400
+ if (survivor !== null)
401
+ presenter.warn(`Another clio-coder stays on your PATH at ${survivor}; it is a separate install`);
402
+ presenter.done("Done");
403
+ return 0;
404
+ }
405
+
406
+ if (!args.force) {
407
+ const confirmed = await presenter.confirm("Are you sure you want to uninstall?", false);
408
+ if (!confirmed) {
409
+ presenter.warn("Uninstall cancelled");
410
+ presenter.done("Cancelled");
411
+ return 0;
412
+ }
413
+ }
414
+
385
415
  const failures: RemovalFailure[] = [];
386
- for (const [label, path] of roots) {
387
- const failure = removePath(label, path, args.dryRun);
416
+
417
+ if (cacheSize.exists) {
418
+ const failure = removePath("cache", dirs.cache, false);
388
419
  if (failure) failures.push(failure);
420
+ else presenter.completedStep("Removed Cache");
389
421
  }
390
- if (args.removeBinary) {
391
- const failure = removeLauncher(args.dryRun);
422
+
423
+ if (!args.keepData && dataSize.exists) {
424
+ const failure = removePath("data", dirs.data, false);
392
425
  if (failure) failures.push(failure);
426
+ else presenter.completedStep("Removed Data");
393
427
  }
428
+
429
+ if (!args.keepConfig && configSize.exists) {
430
+ const failure = removePath("config", dirs.config, false);
431
+ if (failure) failures.push(failure);
432
+ else presenter.completedStep("Removed Config");
433
+ }
434
+
435
+ if (stateSize.exists) {
436
+ const failure = removePath("state", dirs.state, false);
437
+ if (failure) failures.push(failure);
438
+ else presenter.completedStep("Removed State");
439
+ }
440
+
441
+ // Only a symlink into this installation is ever unlinked. Reporting the
442
+ // removal from `--remove-binary` alone announced one for a launcher the
443
+ // classifier had already decided to keep.
444
+ let launcherRemoved = false;
445
+ if (args.removeBinary && launcher.kind === "remove") {
446
+ const failure = removePath("launcher", linkPath, false);
447
+ if (failure) failures.push(failure);
448
+ else {
449
+ presenter.completedStep("Removed launcher");
450
+ launcherRemoved = true;
451
+ }
452
+ }
453
+
394
454
  resetXdgCache();
395
455
 
396
456
  if (failures.length > 0) {
397
- printError("uninstall did not remove everything");
398
- reportRemovalFailures(`clio-coder uninstall${args.removeBinary ? " --remove-binary" : ""} --force`, failures);
457
+ presenter.fail("uninstall did not remove everything");
458
+ reportRemovalFailures(
459
+ `clio-coder uninstall${args.removeBinary ? " --remove-binary" : ""}${args.keepConfig ? " --keep-config" : ""}${args.keepData ? " --keep-data" : ""} --force`,
460
+ failures,
461
+ );
462
+ presenter.finish();
399
463
  return 1;
400
464
  }
401
465
 
402
- printOk(args.dryRun ? "uninstall preview complete" : "removed Clio Coder state");
403
- printRemovalGuidance(args.removeBinary);
466
+ if (launcher.kind !== "absent" && !launcherRemoved) presenter.commandAdvice(advice.lead, advice.command);
467
+ if (survivor !== null)
468
+ presenter.warn(`Another clio-coder stays on your PATH at ${survivor}; it is a separate install`);
469
+
470
+ presenter.message("Thank you for using Clio Coder.");
471
+ presenter.done("Done");
404
472
  return 0;
405
473
  }