@iowarp/clio-coder 0.3.0 → 0.3.2

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 (1187) hide show
  1. package/CHANGELOG.md +123 -2
  2. package/CONTRIBUTING.md +23 -23
  3. package/README.md +295 -627
  4. package/dist/acp-BIYHVZIM.js +128 -0
  5. package/dist/{agents-Q4MYPMUW.js → agents-YT6SSRIT.js} +52 -27
  6. package/dist/assets/codewiki.json +1 -0
  7. package/dist/assets/grammars/notices/@vscode__tree-sitter-wasm/LICENSE +21 -0
  8. package/dist/assets/grammars/notices/@vscode__tree-sitter-wasm/cgmanifest.json +16 -0
  9. package/dist/assets/grammars/notices/tree-sitter-wasms/LICENSE +24 -0
  10. package/dist/assets/grammars/tree-sitter-c-sharp.wasm +0 -0
  11. package/dist/assets/grammars/tree-sitter-c.wasm +0 -0
  12. package/dist/assets/grammars/tree-sitter-cpp.wasm +0 -0
  13. package/dist/assets/grammars/tree-sitter-go.wasm +0 -0
  14. package/dist/assets/grammars/tree-sitter-java.wasm +0 -0
  15. package/dist/assets/grammars/tree-sitter-javascript.wasm +0 -0
  16. package/dist/assets/grammars/tree-sitter-python.wasm +0 -0
  17. package/dist/assets/grammars/tree-sitter-ruby.wasm +0 -0
  18. package/dist/assets/grammars/tree-sitter-rust.wasm +0 -0
  19. package/dist/assets/grammars/tree-sitter-tsx.wasm +0 -0
  20. package/dist/assets/grammars/tree-sitter-typescript.wasm +0 -0
  21. package/dist/assets/grammars/tree-sitter.wasm +0 -0
  22. package/dist/{auth-O6HYIJ6J.js → auth-5TWEIYDN.js} +30 -15
  23. package/dist/chunk-2EHAIA3X.js +481 -0
  24. package/dist/{chunk-ME6DNWIU.js → chunk-2IR2NMPA.js} +12 -4
  25. package/dist/chunk-2SFS6XQE.js +122 -0
  26. package/dist/{chunk-KKKPTZLM.js → chunk-2STGEDFV.js} +8 -1
  27. package/dist/chunk-2VTFPG5O.js +48 -0
  28. package/dist/chunk-3I7MS7N2.js +40 -0
  29. package/dist/chunk-3R73A4XB.js +69 -0
  30. package/dist/{chunk-JPOWPFCU.js → chunk-3ZXDFGR5.js} +52 -23
  31. package/dist/chunk-4BJ5BYCE.js +61 -0
  32. package/dist/{chunk-26BZQOAD.js → chunk-4BPJXDWC.js} +161 -260
  33. package/dist/chunk-4KLWL3UC.js +18 -0
  34. package/dist/{chunk-5LDRNKX2.js → chunk-4VP4KH3K.js} +161 -262
  35. package/dist/chunk-4ZG3XFUR.js +77 -0
  36. package/dist/chunk-5B2AEOW5.js +5407 -0
  37. package/dist/chunk-5TSRNF4G.js +510 -0
  38. package/dist/{chunk-WD6AJM35.js → chunk-5UUP6MWO.js} +48 -69
  39. package/dist/{chunk-X3BR7HWV.js → chunk-5WIGXA4T.js} +7 -1
  40. package/dist/chunk-65DEGPJ6.js +52 -0
  41. package/dist/chunk-6EJMN2Y3.js +17 -0
  42. package/dist/chunk-6EJV5X2W.js +16405 -0
  43. package/dist/chunk-6N5PTWMY.js +136 -0
  44. package/dist/chunk-6XLNIQDB.js +27 -0
  45. package/dist/{chunk-XNISANGE.js → chunk-77VKQEHF.js} +171 -74
  46. package/dist/chunk-7CR24IG7.js +242 -0
  47. package/dist/{chunk-UWIJNAOB.js → chunk-7EYHLWU7.js} +907 -638
  48. package/dist/chunk-7MNJORFF.js +22 -0
  49. package/dist/{chunk-JWHCJDCI.js → chunk-A3CYT5EX.js} +257 -79
  50. package/dist/chunk-AGYYIBLL.js +1069 -0
  51. package/dist/chunk-AO4RKG4M.js +277 -0
  52. package/dist/chunk-APJ265NV.js +7410 -0
  53. package/dist/chunk-ARBGF5F7.js +174 -0
  54. package/dist/{chunk-TFSSEXL6.js → chunk-BMEMKKIT.js} +14 -4
  55. package/dist/{chunk-X3NE4WVW.js → chunk-BNAZZHFG.js} +7 -1
  56. package/dist/chunk-CBCAPZAA.js +229 -0
  57. package/dist/{chunk-QV47YRF4.js → chunk-CGKSTWHD.js} +7 -1
  58. package/dist/chunk-CMZWFGD2.js +352 -0
  59. package/dist/chunk-ECH6PKUQ.js +39 -0
  60. package/dist/{chunk-67MTHP2E.js → chunk-ED4KHGC3.js} +13 -5
  61. package/dist/chunk-EKMEHE4H.js +340 -0
  62. package/dist/{chunk-O4EJEDHO.js → chunk-EPVUXGXG.js} +50 -35
  63. package/dist/chunk-FCSXB6T2.js +338 -0
  64. package/dist/chunk-FJ3H4MN5.js +48 -0
  65. package/dist/chunk-FQ4SKYE4.js +29 -0
  66. package/dist/chunk-G2DE3C7R.js +644 -0
  67. package/dist/chunk-G4BMMOKF.js +182 -0
  68. package/dist/{chunk-7BHLZB3A.js → chunk-GGXXDWE4.js} +190 -1218
  69. package/dist/chunk-HC4CLZ2Y.js +68 -0
  70. package/dist/{chunk-E3NYWENM.js → chunk-HFSBBKSQ.js} +55 -61
  71. package/dist/chunk-HKIYEGME.js +30 -0
  72. package/dist/chunk-I4HZDVNP.js +73 -0
  73. package/dist/chunk-IGLFWIYI.js +161 -0
  74. package/dist/chunk-IHXBNWMM.js +137 -0
  75. package/dist/chunk-IKCO5N3L.js +162 -0
  76. package/dist/chunk-IR4CFBFN.js +56 -0
  77. package/dist/{chunk-DXQNI4PC.js → chunk-IWHMRKLL.js} +8 -1
  78. package/dist/{chunk-VOO7NYPP.js → chunk-J5HN4RYU.js} +27 -9
  79. package/dist/{chunk-4UQA7NCT.js → chunk-J5Q24KAG.js} +7 -2
  80. package/dist/{chunk-KBR4MZZR.js → chunk-JVCV3ICN.js} +7 -1
  81. package/dist/chunk-KJ5LWLOE.js +1077 -0
  82. package/dist/chunk-LBMZMYH2.js +285 -0
  83. package/dist/{chunk-3DANZDGR.js → chunk-LBNRH5WM.js} +100 -161
  84. package/dist/{chunk-TKHQ4DGZ.js → chunk-LZSJBIVT.js} +7358 -7414
  85. package/dist/{chunk-UGYAX5YI.js → chunk-M6SHUN7Q.js} +13 -8
  86. package/dist/chunk-MAW544W2.js +1882 -0
  87. package/dist/chunk-MBS4V7ZP.js +217 -0
  88. package/dist/{chunk-2J63S4SF.js → chunk-MFFY33HR.js} +167 -140
  89. package/dist/chunk-MNA4JGU4.js +255 -0
  90. package/dist/chunk-MQSRRFWA.js +3428 -0
  91. package/dist/{chunk-RQDWMVRB.js → chunk-MVVUPGPW.js} +138 -137
  92. package/dist/chunk-OAO4GE4M.js +619 -0
  93. package/dist/chunk-OHHN2SO4.js +5135 -0
  94. package/dist/chunk-OKGUZO2U.js +34 -0
  95. package/dist/{chunk-BBUH4VAA.js → chunk-OOJYHWRB.js} +60 -361
  96. package/dist/{chunk-D5YD55AR.js → chunk-OQ33BKR3.js} +12 -1
  97. package/dist/chunk-OQE5J4C6.js +73 -0
  98. package/dist/{chunk-AMFR5YA3.js → chunk-ORBHGJC5.js} +26 -12
  99. package/dist/chunk-POHLU5DW.js +1186 -0
  100. package/dist/chunk-QKMUKYO7.js +4961 -0
  101. package/dist/{chunk-7RBKDI66.js → chunk-QTYWRVRA.js} +104 -12
  102. package/dist/{chunk-5N2FG33Q.js → chunk-R346GLFC.js} +7 -1
  103. package/dist/chunk-SRF2PJNW.js +184 -0
  104. package/dist/chunk-SST6Z5JA.js +80 -0
  105. package/dist/{chunk-XV4ZJ6ZM.js → chunk-STBPMHSX.js} +473 -1194
  106. package/dist/{chunk-HBU5MTAM.js → chunk-SVNXH4L2.js} +7 -1
  107. package/dist/chunk-T6YILFSB.js +80 -0
  108. package/dist/chunk-TXOTCRLG.js +15 -0
  109. package/dist/chunk-TZTZS7QK.js +227 -0
  110. package/dist/chunk-UOV2BYIW.js +107 -0
  111. package/dist/{chunk-527KG6XR.js → chunk-V4RXGQ5Q.js} +72 -185
  112. package/dist/chunk-VAKQQHWR.js +434 -0
  113. package/dist/chunk-VG7TBQIY.js +128 -0
  114. package/dist/chunk-VJWL6YS5.js +244 -0
  115. package/dist/chunk-WEH5XRJQ.js +32 -0
  116. package/dist/{chunk-VPAWTYLY.js → chunk-WEPFGWHJ.js} +7 -1
  117. package/dist/chunk-WMSVI4G2.js +2095 -0
  118. package/dist/chunk-WVO7V2QY.js +797 -0
  119. package/dist/chunk-X4RCMKVQ.js +641 -0
  120. package/dist/chunk-X75S7HFS.js +374 -0
  121. package/dist/chunk-XN3L4EYL.js +46 -0
  122. package/dist/{chunk-HMYNFFY4.js → chunk-XPLRXC72.js} +7 -2
  123. package/dist/{chunk-PIDUD6M2.js → chunk-YCWGATWI.js} +12 -5
  124. package/dist/chunk-YHZX5GEU.js +193 -0
  125. package/dist/chunk-YXLYO42X.js +91 -0
  126. package/dist/{chunk-UHTSULZS.js → chunk-ZDOOVTXZ.js} +38 -73
  127. package/dist/chunk-ZI647VB5.js +37 -0
  128. package/dist/{chunk-CLJ5HLUD.js → chunk-ZWLZP4ZT.js} +25 -6
  129. package/dist/cli/index.js +70 -56
  130. package/dist/clio-4LY5K2AC.js +25 -0
  131. package/dist/code-nav-7AX6FYE6.js +600 -0
  132. package/dist/codewiki/build-worker.js +66 -0
  133. package/dist/compile-cache-CVJMMODC.js +18 -0
  134. package/dist/{components-JVHMUBEB.js → components-KELWS457.js} +31 -9
  135. package/dist/{config-ZFCDBMDC.js → config-GTLUW2PR.js} +104 -56
  136. package/dist/configure-R6A64DHX.js +42 -0
  137. package/dist/context-5VKGUVJJ.js +866 -0
  138. package/dist/{context-CDXTP2MP.js → context-JFZEJ7W5.js} +21 -13
  139. package/dist/{context-E3KIFVXI.js → context-RW5HC47S.js} +77 -36
  140. package/dist/{context-clear-3F4PLXOS.js → context-clear-6ZHBAZZT.js} +64 -30
  141. package/dist/{context-index-Q7YSYTR3.js → context-index-BZ4UYMTC.js} +36 -24
  142. package/dist/dispatch-runner-VKBRCWQC.js +1997 -0
  143. package/dist/{docs-YIETIWZI.js → docs-2C2LTVT2.js} +32 -13
  144. package/dist/doctor-KI767GSN.js +87 -0
  145. package/dist/{eval-B3KZZESM.js → eval-XSSNATB4.js} +93 -27
  146. package/dist/{evidence-V67CHM35.js → evidence-UA6AWDQQ.js} +55 -27
  147. package/dist/{evolve-YDZSUQYA.js → evolve-QNTFGV6Z.js} +59 -26
  148. package/dist/{extensions-SRG7XCAH.js → extensions-QVDOHDGJ.js} +23 -8
  149. package/dist/{fleet-CA2CRTVG.js → fleet-Q7UOMUSG.js} +173 -56
  150. package/dist/fleet-preflight-DDN536IT.js +26 -0
  151. package/dist/{init-2OZDJE2D.js → init-WBB65ZHQ.js} +79 -34
  152. package/dist/{memory-3PIQQAKX.js → memory-MD3O64RI.js} +57 -28
  153. package/dist/{models-DY35XI7Y.js → models-BZU34YWD.js} +49 -24
  154. package/dist/monitor-MEQA5C3I.js +661 -0
  155. package/dist/{chunk-PS4PFJQP.js → orchestrator-CGFKEP27.js} +22837 -18564
  156. package/dist/{paths-5OMXW7Z4.js → paths-UXLN5YYZ.js} +17 -6
  157. package/dist/preload-P6DGH2PZ.js +13 -0
  158. package/dist/{reset-PIFYNOS3.js → reset-L2FQEE3E.js} +25 -13
  159. package/dist/{run-3VSPP24F.js → run-IV4Q6RLN.js} +115 -63
  160. package/dist/{share-D36RQCXM.js → share-S5BZQC5I.js} +23 -10
  161. package/dist/{skills-F2MRLELY.js → skills-LQEKRDTN.js} +42 -15
  162. package/dist/{skills-eval-E2ZTW4PL.js → skills-eval-3DC4HEWS.js} +90 -45
  163. package/dist/steer-GGWFUJUD.js +77 -0
  164. package/dist/{targets-DZMEZAH4.js → targets-C4SSGQOB.js} +78 -60
  165. package/dist/terminal-lease-IT5JW2NR.js +395 -0
  166. package/dist/{trace-7NYCUI2J.js → trace-PNCASAXC.js} +48 -17
  167. package/dist/tree-sitter-HGKH6LG4.js +4673 -0
  168. package/dist/{uninstall-AD3JWHBB.js → uninstall-FZCQCDKC.js} +19 -8
  169. package/dist/{upgrade-WYYBKGDY.js → upgrade-7TT7SQ3G.js} +66 -24
  170. package/dist/{usage-ULIDAGFF.js → usage-GV4PKT3M.js} +71 -32
  171. package/dist/verify-G6V4D2G7.js +716 -0
  172. package/dist/version-KGEG7EPO.js +21 -0
  173. package/dist/web-fetch-2YHJ3KTG.js +638 -0
  174. package/dist/{wiki-generate-PKFIX6OB.js → wiki-generate-DQF6Z66B.js} +98 -48
  175. package/dist/worker/entry.js +297 -54
  176. package/dist/workspace-G4ZWUIPR.js +22 -0
  177. package/docs/README.md +29 -21
  178. package/docs/acp.md +191 -16
  179. package/docs/alcf-provider.md +1 -1
  180. package/docs/architecture.md +157 -7
  181. package/docs/artifact-placement.md +101 -0
  182. package/docs/artifact-versions.md +1 -1
  183. package/docs/built-in-agents.md +4 -2
  184. package/docs/capacity-and-scheduling.md +1 -1
  185. package/docs/commands-and-modes.md +224 -97
  186. package/docs/config-knobs-audit.md +1 -3
  187. package/docs/configuration-and-targets.md +236 -38
  188. package/docs/context-engine.md +34 -7
  189. package/docs/development-pipeline.md +102 -0
  190. package/docs/dispatch-architecture-rationale.md +1 -1
  191. package/docs/documentation-coverage.md +4 -4
  192. package/docs/documentation-guide.md +3 -3
  193. package/docs/environment-variables.md +15 -6
  194. package/docs/eval-runner.md +3 -3
  195. package/docs/evals-internal.md +2 -2
  196. package/docs/evidence-and-memory.md +10 -2
  197. package/docs/evolution.md +2 -2
  198. package/docs/exit-codes-and-output.md +15 -9
  199. package/docs/extensions-and-sharing.md +25 -18
  200. package/docs/fleet-demo-runbook.md +22 -23
  201. package/docs/fleet-dispatch.md +117 -16
  202. package/docs/git-commit-provenance.md +120 -0
  203. package/docs/glossary.md +107 -15
  204. package/docs/installation-and-lifecycle.md +75 -17
  205. package/docs/middleware-and-components.md +1 -1
  206. package/docs/model-catalog.md +46 -15
  207. package/docs/observability.md +8 -5
  208. package/docs/performance-methodology.md +491 -0
  209. package/docs/pi-boundary.md +72 -0
  210. package/docs/proactive-memory.md +14 -14
  211. package/docs/prompt-envelope-and-tools.md +25 -4
  212. package/docs/provider-adapter-cookbook.md +57 -4
  213. package/docs/release-cut-checklist.md +129 -111
  214. package/docs/safety-model.md +28 -8
  215. package/docs/scientific-validation.md +3 -3
  216. package/docs/session-lifecycle.md +55 -12
  217. package/docs/skills-marketplace.md +12 -8
  218. package/docs/time-conventions.md +101 -0
  219. package/docs/tool-usage.md +6 -5
  220. package/docs/trace-store.md +1 -1
  221. package/docs/troubleshooting.md +10 -7
  222. package/docs/tui-design.md +121 -28
  223. package/docs/worker-dispatch-mechanics.md +3 -3
  224. package/package.json +33 -36
  225. package/skills/README.md +5 -6
  226. package/skills/coding/ast-grep/SKILL.md +136 -0
  227. package/skills/coding/ast-grep/evals.md +56 -0
  228. package/skills/coding/ast-grep/references/rule_reference.md +297 -0
  229. package/skills/coding/coding-standards/SKILL.md +113 -0
  230. package/skills/coding/coding-standards/evals.md +34 -0
  231. package/skills/coding/prototype/SKILL.md +86 -0
  232. package/skills/coding/prototype/evals.md +42 -0
  233. package/skills/coding/prototype/references/LOGIC.md +67 -0
  234. package/skills/coding/prototype/references/UI.md +112 -0
  235. package/skills/coding/tdd/SKILL.md +101 -0
  236. package/skills/coding/tdd/evals.md +41 -0
  237. package/skills/coding/tdd/references/mocking.md +59 -0
  238. package/skills/coding/tdd/references/tests.md +77 -0
  239. package/skills/context/context-handoff/SKILL.md +126 -0
  240. package/skills/context/context-handoff/evals.md +57 -0
  241. package/skills/context/context-handoff/scripts/new-handoff.sh +26 -0
  242. package/skills/context/context-prime/SKILL.md +95 -0
  243. package/skills/context/context-prime/evals.md +54 -0
  244. package/skills/git/file-ticket/SKILL.md +107 -0
  245. package/skills/git/file-ticket/evals.md +54 -0
  246. package/skills/git/fix-issue/SKILL.md +106 -0
  247. package/skills/git/fix-issue/evals.md +71 -0
  248. package/skills/git/ship/SKILL.md +92 -0
  249. package/skills/git/ship/evals.md +72 -0
  250. package/skills/meta/clio-dev/SKILL.md +91 -0
  251. package/skills/meta/clio-dev/evals.md +45 -0
  252. package/skills/meta/clio-test/SKILL.md +130 -0
  253. package/skills/meta/clio-test/evals.md +43 -0
  254. package/skills/meta/clio-test/references/harness.md +97 -0
  255. package/skills/meta/clio-test/references/test-map.md +59 -0
  256. package/skills/meta/credentials/SKILL.md +125 -0
  257. package/skills/meta/credentials/evals.md +104 -0
  258. package/skills/meta/find-skills/SKILL.md +72 -0
  259. package/skills/meta/find-skills/evals.md +47 -0
  260. package/skills/meta/herdr/SKILL.md +127 -0
  261. package/skills/meta/herdr/evals.md +38 -0
  262. package/skills/meta/skill-craft/SKILL.md +102 -0
  263. package/skills/meta/skill-craft/evals.md +41 -0
  264. package/skills/planning/architecture/SKILL.md +129 -0
  265. package/skills/planning/architecture/evals.md +36 -0
  266. package/skills/planning/backlog/SKILL.md +90 -0
  267. package/skills/planning/backlog/evals.md +43 -0
  268. package/skills/planning/prd/SKILL.md +82 -0
  269. package/skills/planning/prd/evals.md +49 -0
  270. package/skills/planning/product-intent/SKILL.md +112 -0
  271. package/skills/planning/product-intent/evals.md +36 -0
  272. package/skills/planning/tech-spec/SKILL.md +115 -0
  273. package/skills/planning/tech-spec/evals.md +47 -0
  274. package/skills/registry.yaml +136 -0
  275. package/skills/research/arxiv-literature/SKILL.md +104 -0
  276. package/skills/research/arxiv-literature/evals.md +58 -0
  277. package/skills/research/experiment-protocol/SKILL.md +122 -0
  278. package/skills/research/experiment-protocol/evals.md +91 -0
  279. package/skills/research/scientific-debugging/SKILL.md +119 -0
  280. package/skills/research/scientific-debugging/evals.md +138 -0
  281. package/skills/research/scientific-modernization/SKILL.md +138 -0
  282. package/skills/research/scientific-modernization/evals.md +84 -0
  283. package/skills/skill-marketplace.json +12 -20
  284. package/skills/workflow/design-council/SKILL.md +139 -0
  285. package/skills/workflow/design-council/evals.md +97 -0
  286. package/skills/workflow/grill-me/SKILL.md +186 -0
  287. package/skills/workflow/grill-me/evals.md +78 -0
  288. package/skills/workflow/workflow-distiller/SKILL.md +136 -0
  289. package/skills/workflow/workflow-distiller/evals.md +107 -0
  290. package/src/cli/acp.ts +115 -0
  291. package/src/cli/agents.ts +60 -0
  292. package/src/cli/args.ts +280 -0
  293. package/src/cli/argv.ts +170 -0
  294. package/src/cli/ask.ts +34 -0
  295. package/src/cli/auth.ts +468 -0
  296. package/src/cli/bootstrap-generate.ts +498 -0
  297. package/src/cli/clio.ts +96 -0
  298. package/src/cli/components.ts +195 -0
  299. package/src/cli/config-inspect.ts +336 -0
  300. package/src/cli/config.ts +72 -0
  301. package/src/cli/configure-interop.ts +67 -0
  302. package/src/cli/configure-layout.ts +172 -0
  303. package/src/cli/configure.ts +1525 -0
  304. package/src/cli/context-clear.ts +76 -0
  305. package/src/cli/context-index.ts +100 -0
  306. package/src/cli/context.ts +321 -0
  307. package/src/cli/default-target.ts +55 -0
  308. package/src/cli/docs.ts +346 -0
  309. package/src/cli/doctor.ts +54 -0
  310. package/src/cli/eval.ts +315 -0
  311. package/src/cli/evidence.ts +225 -0
  312. package/src/cli/evolve.ts +219 -0
  313. package/src/cli/extensions.ts +214 -0
  314. package/src/cli/fleet.ts +868 -0
  315. package/src/cli/index.ts +338 -0
  316. package/src/cli/init.ts +219 -0
  317. package/src/cli/initial-message.ts +47 -0
  318. package/src/cli/internal-dispatch.ts +55 -0
  319. package/src/cli/memory.ts +182 -0
  320. package/src/cli/models.ts +257 -0
  321. package/src/cli/modes/json-stream.ts +121 -0
  322. package/src/cli/modes/jsonl.ts +9 -0
  323. package/src/cli/modes/print.ts +604 -0
  324. package/src/cli/oauth-manual-input.ts +72 -0
  325. package/src/cli/oauth-select.ts +36 -0
  326. package/src/cli/output-guard.ts +48 -0
  327. package/src/cli/paths.ts +44 -0
  328. package/src/cli/provider-target.ts +113 -0
  329. package/src/cli/removal.ts +72 -0
  330. package/src/cli/reset.ts +253 -0
  331. package/src/cli/run.ts +497 -0
  332. package/src/cli/share.ts +243 -0
  333. package/src/cli/shared.ts +60 -0
  334. package/src/cli/skills-eval.ts +1240 -0
  335. package/src/cli/skills.ts +485 -0
  336. package/src/cli/steer-channel.ts +86 -0
  337. package/src/cli/targets.ts +1154 -0
  338. package/src/cli/text-layout.ts +112 -0
  339. package/src/cli/trace.ts +322 -0
  340. package/src/cli/uninstall.ts +405 -0
  341. package/src/cli/upgrade.ts +286 -0
  342. package/src/cli/usage.ts +876 -0
  343. package/src/cli/validate-model.ts +28 -0
  344. package/src/cli/version.ts +7 -0
  345. package/src/cli/wiki-generate.ts +510 -0
  346. package/src/core/agent-environment.ts +7 -0
  347. package/src/core/artifact-paths.ts +43 -0
  348. package/src/core/bash-exec.ts +313 -0
  349. package/src/core/boot-trace.ts +42 -0
  350. package/src/core/bus-events.ts +744 -0
  351. package/src/core/bus-trace.ts +53 -0
  352. package/src/core/c-header-language.ts +265 -0
  353. package/src/core/clio-repo.ts +78 -0
  354. package/src/core/commit-attribution.ts +157 -0
  355. package/src/core/compile-cache.ts +159 -0
  356. package/src/core/config.ts +1722 -0
  357. package/src/core/context-floor.ts +33 -0
  358. package/src/core/defaults.ts +659 -0
  359. package/src/core/domain-loader.ts +177 -0
  360. package/src/core/event-bus.ts +94 -0
  361. package/src/core/file-references.ts +282 -0
  362. package/src/core/git-commit-attribution.ts +362 -0
  363. package/src/core/guardrails.ts +185 -0
  364. package/src/core/headless-permission.ts +21 -0
  365. package/src/core/incomplete-installation.ts +45 -0
  366. package/src/core/init.ts +223 -0
  367. package/src/core/json-payload.ts +58 -0
  368. package/src/core/package-root.ts +54 -0
  369. package/src/core/path-canonical.ts +37 -0
  370. package/src/core/process-identity.ts +41 -0
  371. package/src/core/recent-models.ts +91 -0
  372. package/src/core/residency-protection.ts +56 -0
  373. package/src/core/resolve-config-value.ts +88 -0
  374. package/src/core/response-schema.ts +279 -0
  375. package/src/core/run-overrides.ts +77 -0
  376. package/src/core/safe-exec.ts +205 -0
  377. package/src/core/safe-id.ts +37 -0
  378. package/src/core/safe-resource-write.ts +162 -0
  379. package/src/core/session-routing.ts +339 -0
  380. package/src/core/settings-layers.ts +354 -0
  381. package/src/core/shared-bus.ts +8 -0
  382. package/src/core/shell-quote.ts +26 -0
  383. package/src/core/skill-activation.ts +190 -0
  384. package/src/core/startup-timer.ts +37 -0
  385. package/src/core/state-file-lock.ts +219 -0
  386. package/src/core/termination.ts +275 -0
  387. package/src/core/timers.ts +38 -0
  388. package/src/core/tool-names.ts +65 -0
  389. package/src/core/verification-scripts.ts +13 -0
  390. package/src/core/workspace-files.ts +492 -0
  391. package/src/core/xdg.ts +177 -0
  392. package/src/domains/agents/builtins/architect.md +4 -4
  393. package/src/domains/agents/builtins/coder.md +3 -2
  394. package/src/domains/agents/builtins/debugger.md +1 -1
  395. package/src/domains/agents/builtins/documenter.md +1 -1
  396. package/src/domains/agents/builtins/git-master.md +3 -3
  397. package/src/domains/agents/builtins/provenance.md +1 -1
  398. package/src/domains/agents/builtins/researcher.md +1 -1
  399. package/src/domains/agents/builtins/scout.md +1 -1
  400. package/src/domains/agents/builtins/tester.md +1 -1
  401. package/src/domains/agents/builtins/verifier.md +1 -1
  402. package/src/domains/agents/builtins/wiki-writer.md +1 -1
  403. package/src/domains/agents/catalog.ts +172 -0
  404. package/src/domains/agents/contract.ts +16 -0
  405. package/src/domains/agents/extension.ts +110 -0
  406. package/src/domains/agents/fleet-commands.ts +154 -0
  407. package/src/domains/agents/fleet-contract.ts +797 -0
  408. package/src/domains/agents/frontmatter.ts +40 -0
  409. package/src/domains/agents/index.ts +102 -0
  410. package/src/domains/agents/manifest.ts +6 -0
  411. package/src/domains/agents/recipe-schema.ts +202 -0
  412. package/src/domains/agents/recipe.ts +125 -0
  413. package/src/domains/agents/registry.ts +111 -0
  414. package/src/domains/agents/result-contract.ts +1265 -0
  415. package/src/domains/agents/spec.ts +371 -0
  416. package/src/domains/agents/write-boundary.ts +109 -0
  417. package/src/domains/components/diff.ts +99 -0
  418. package/src/domains/components/hash.ts +21 -0
  419. package/src/domains/components/index.ts +3 -0
  420. package/src/domains/components/scan.ts +304 -0
  421. package/src/domains/components/snapshot.ts +108 -0
  422. package/src/domains/components/types.ts +82 -0
  423. package/src/domains/config/agent-namespace.ts +13 -0
  424. package/src/domains/config/classify.ts +106 -0
  425. package/src/domains/config/contract.ts +22 -0
  426. package/src/domains/config/extension.ts +142 -0
  427. package/src/domains/config/index.ts +23 -0
  428. package/src/domains/config/keybindings.ts +200 -0
  429. package/src/domains/config/manifest.ts +6 -0
  430. package/src/domains/config/watcher.ts +41 -0
  431. package/src/domains/context/adoption.ts +880 -0
  432. package/src/domains/context/bootstrap-prompt.ts +273 -0
  433. package/src/domains/context/bootstrap.ts +1502 -0
  434. package/src/domains/context/clear.ts +91 -0
  435. package/src/domains/context/clio-md.ts +429 -0
  436. package/src/domains/context/codewiki/artifact.ts +400 -0
  437. package/src/domains/context/codewiki/build-worker-protocol.ts +24 -0
  438. package/src/domains/context/codewiki/build-worker.ts +54 -0
  439. package/src/domains/context/codewiki/cmake.ts +356 -0
  440. package/src/domains/context/codewiki/cooperative.ts +46 -0
  441. package/src/domains/context/codewiki/coordinator.ts +182 -0
  442. package/src/domains/context/codewiki/digest.ts +135 -0
  443. package/src/domains/context/codewiki/grammar-assets.ts +33 -0
  444. package/src/domains/context/codewiki/indexer.ts +1529 -0
  445. package/src/domains/context/codewiki/paths.ts +67 -0
  446. package/src/domains/context/codewiki/schema.ts +80 -0
  447. package/src/domains/context/codewiki/tree-sitter.ts +771 -0
  448. package/src/domains/context/contract.ts +68 -0
  449. package/src/domains/context/excluded-dirs.ts +1 -0
  450. package/src/domains/context/extension.ts +358 -0
  451. package/src/domains/context/fingerprint.ts +198 -0
  452. package/src/domains/context/index.ts +154 -0
  453. package/src/domains/context/init-options.ts +69 -0
  454. package/src/domains/context/manifest.ts +6 -0
  455. package/src/domains/context/operator-profile.ts +157 -0
  456. package/src/domains/context/project-metadata.ts +529 -0
  457. package/src/domains/context/project-rules.ts +227 -0
  458. package/src/domains/context/prompt-context.ts +61 -0
  459. package/src/domains/context/refresh.ts +178 -0
  460. package/src/domains/context/runtime.ts +17 -0
  461. package/src/domains/context/sibling-files.ts +10 -0
  462. package/src/domains/context/state.ts +237 -0
  463. package/src/domains/context/wiki/assemble.ts +303 -0
  464. package/src/domains/context/wiki/frontmatter.ts +210 -0
  465. package/src/domains/context/wiki/generate.ts +595 -0
  466. package/src/domains/context/wiki/layout.ts +111 -0
  467. package/src/domains/context/wiki/meta.ts +221 -0
  468. package/src/domains/context/wiki/plan-store.ts +217 -0
  469. package/src/domains/context/wiki/plan.ts +250 -0
  470. package/src/domains/context/wiki/prompts.ts +283 -0
  471. package/src/domains/context/wiki/staleness.ts +198 -0
  472. package/src/domains/dispatch/active-route-planner.ts +168 -0
  473. package/src/domains/dispatch/admission-queue.ts +150 -0
  474. package/src/domains/dispatch/admission.ts +334 -0
  475. package/src/domains/dispatch/agent-candidates.ts +307 -0
  476. package/src/domains/dispatch/agent-ledger-hub.ts +71 -0
  477. package/src/domains/dispatch/agent-ledger-store.ts +257 -0
  478. package/src/domains/dispatch/agent-ledger.ts +212 -0
  479. package/src/domains/dispatch/agent-plan-adapter.ts +85 -0
  480. package/src/domains/dispatch/assignment-events.ts +132 -0
  481. package/src/domains/dispatch/assignment-reconcile.ts +76 -0
  482. package/src/domains/dispatch/assignment-store.ts +162 -0
  483. package/src/domains/dispatch/assignment.ts +278 -0
  484. package/src/domains/dispatch/backoff.ts +59 -0
  485. package/src/domains/dispatch/batch-store.ts +134 -0
  486. package/src/domains/dispatch/batch-tracker.ts +66 -0
  487. package/src/domains/dispatch/capability-match.ts +155 -0
  488. package/src/domains/dispatch/capacity-lease.ts +413 -0
  489. package/src/domains/dispatch/code-step-store.ts +52 -0
  490. package/src/domains/dispatch/code-step.ts +387 -0
  491. package/src/domains/dispatch/contract.ts +278 -0
  492. package/src/domains/dispatch/dedup.ts +133 -0
  493. package/src/domains/dispatch/event-pump.ts +251 -0
  494. package/src/domains/dispatch/execution-handoff.ts +29 -0
  495. package/src/domains/dispatch/execution-plan.ts +328 -0
  496. package/src/domains/dispatch/execution-role.ts +277 -0
  497. package/src/domains/dispatch/execution-scheduler.ts +583 -0
  498. package/src/domains/dispatch/extension.ts +6006 -0
  499. package/src/domains/dispatch/failure-classification.ts +147 -0
  500. package/src/domains/dispatch/fleet-commit-attribution.ts +56 -0
  501. package/src/domains/dispatch/fleet-plan.ts +225 -0
  502. package/src/domains/dispatch/fleet-preflight.ts +394 -0
  503. package/src/domains/dispatch/gate-decisions.ts +1040 -0
  504. package/src/domains/dispatch/gate-role-prompts.ts +58 -0
  505. package/src/domains/dispatch/heartbeat.ts +27 -0
  506. package/src/domains/dispatch/index.ts +137 -0
  507. package/src/domains/dispatch/joint-route-adapter.ts +114 -0
  508. package/src/domains/dispatch/joint-route-resolver.ts +283 -0
  509. package/src/domains/dispatch/manifest.ts +6 -0
  510. package/src/domains/dispatch/orphan-recovery.ts +266 -0
  511. package/src/domains/dispatch/outcome.ts +109 -0
  512. package/src/domains/dispatch/phase-timing.ts +47 -0
  513. package/src/domains/dispatch/placement.ts +202 -0
  514. package/src/domains/dispatch/receipt-findings.ts +255 -0
  515. package/src/domains/dispatch/receipt-integrity.ts +383 -0
  516. package/src/domains/dispatch/recovery-candidates.ts +74 -0
  517. package/src/domains/dispatch/reproducibility.ts +48 -0
  518. package/src/domains/dispatch/reservation-store.ts +501 -0
  519. package/src/domains/dispatch/route-approval.ts +177 -0
  520. package/src/domains/dispatch/route-candidates.ts +57 -0
  521. package/src/domains/dispatch/route-decision.ts +1079 -0
  522. package/src/domains/dispatch/route-facts.ts +187 -0
  523. package/src/domains/dispatch/route-history.ts +238 -0
  524. package/src/domains/dispatch/route-observer.ts +488 -0
  525. package/src/domains/dispatch/route-policy.ts +327 -0
  526. package/src/domains/dispatch/route-quality.ts +256 -0
  527. package/src/domains/dispatch/route-readiness.ts +120 -0
  528. package/src/domains/dispatch/routing-intent.ts +287 -0
  529. package/src/domains/dispatch/run-identity.ts +56 -0
  530. package/src/domains/dispatch/scout-transition.ts +130 -0
  531. package/src/domains/dispatch/state.ts +302 -0
  532. package/src/domains/dispatch/tool-stats.ts +132 -0
  533. package/src/domains/dispatch/transport.ts +210 -0
  534. package/src/domains/dispatch/types.ts +799 -0
  535. package/src/domains/dispatch/validation-grounding.ts +154 -0
  536. package/src/domains/dispatch/validation.ts +721 -0
  537. package/src/domains/dispatch/worker-protocol.ts +275 -0
  538. package/src/domains/dispatch/worker-spawn.ts +585 -0
  539. package/src/domains/dispatch/write-boundary-enforcer.ts +97 -0
  540. package/src/domains/dispatch/write-boundary.ts +426 -0
  541. package/src/domains/eval/artifacts/redact.ts +42 -0
  542. package/src/domains/eval/artifacts/store.ts +173 -0
  543. package/src/domains/eval/compare/compare.ts +33 -0
  544. package/src/domains/eval/compare/gates.ts +66 -0
  545. package/src/domains/eval/compare/thresholds.ts +92 -0
  546. package/src/domains/eval/harness-metrics.ts +62 -0
  547. package/src/domains/eval/index.ts +66 -0
  548. package/src/domains/eval/metrics/chaos-stream.ts +93 -0
  549. package/src/domains/eval/metrics/context.ts +34 -0
  550. package/src/domains/eval/metrics/coverage.ts +21 -0
  551. package/src/domains/eval/metrics/evidence.ts +182 -0
  552. package/src/domains/eval/metrics/fleet-loop-stream.ts +196 -0
  553. package/src/domains/eval/metrics/invariants.ts +736 -0
  554. package/src/domains/eval/metrics/latency.ts +4 -0
  555. package/src/domains/eval/metrics/token-stream.ts +139 -0
  556. package/src/domains/eval/metrics/tokens.ts +51 -0
  557. package/src/domains/eval/metrics/tool-calls.ts +7 -0
  558. package/src/domains/eval/proactive-memory.ts +279 -0
  559. package/src/domains/eval/provenance.ts +35 -0
  560. package/src/domains/eval/report.ts +234 -0
  561. package/src/domains/eval/reports/json.ts +5 -0
  562. package/src/domains/eval/reports/junit.ts +23 -0
  563. package/src/domains/eval/reports/markdown.ts +20 -0
  564. package/src/domains/eval/reports/swe-jsonl.ts +16 -0
  565. package/src/domains/eval/reports/text.ts +25 -0
  566. package/src/domains/eval/run-compare.ts +274 -0
  567. package/src/domains/eval/runner.ts +244 -0
  568. package/src/domains/eval/runners/clio-run.ts +148 -0
  569. package/src/domains/eval/runners/context-index.ts +56 -0
  570. package/src/domains/eval/runners/context-init.ts +203 -0
  571. package/src/domains/eval/runners/external-command.ts +350 -0
  572. package/src/domains/eval/runtime-paths.ts +171 -0
  573. package/src/domains/eval/schema/artifact.ts +75 -0
  574. package/src/domains/eval/schema/suite.ts +235 -0
  575. package/src/domains/eval/schema/validate.ts +339 -0
  576. package/src/domains/eval/store.ts +392 -0
  577. package/src/domains/eval/suites/load.ts +74 -0
  578. package/src/domains/eval/suites/matrix.ts +19 -0
  579. package/src/domains/eval/suites/resolve.ts +44 -0
  580. package/src/domains/eval/suites/run.ts +325 -0
  581. package/src/domains/eval/task-file.ts +186 -0
  582. package/src/domains/eval/types.ts +140 -0
  583. package/src/domains/eval/verifiers/command.ts +27 -0
  584. package/src/domains/eval/verifiers/file-exists.ts +6 -0
  585. package/src/domains/eval/verifiers/patch.ts +22 -0
  586. package/src/domains/eval/workspaces/git.ts +41 -0
  587. package/src/domains/eval/workspaces/local.ts +17 -0
  588. package/src/domains/eval/workspaces/temp-copy.ts +29 -0
  589. package/src/domains/evidence/build.ts +1754 -0
  590. package/src/domains/evidence/eval.ts +605 -0
  591. package/src/domains/evidence/failure-attribution.ts +54 -0
  592. package/src/domains/evidence/finish-contract-map.ts +42 -0
  593. package/src/domains/evidence/index.ts +55 -0
  594. package/src/domains/evidence/provenance.ts +200 -0
  595. package/src/domains/evidence/redact.ts +81 -0
  596. package/src/domains/evidence/store.ts +291 -0
  597. package/src/domains/evidence/types.ts +325 -0
  598. package/src/domains/evolution/SELF_EDIT_GATE.md +91 -0
  599. package/src/domains/evolution/index.ts +26 -0
  600. package/src/domains/evolution/manifest.ts +154 -0
  601. package/src/domains/evolution/validate.ts +304 -0
  602. package/src/domains/extensions/contract.ts +22 -0
  603. package/src/domains/extensions/discovery.ts +193 -0
  604. package/src/domains/extensions/extension.ts +46 -0
  605. package/src/domains/extensions/index.ts +34 -0
  606. package/src/domains/extensions/manager.ts +30 -0
  607. package/src/domains/extensions/manifest.ts +6 -0
  608. package/src/domains/extensions/resources.ts +38 -0
  609. package/src/domains/extensions/state.ts +224 -0
  610. package/src/domains/extensions/types.ts +83 -0
  611. package/src/domains/interop/consent.ts +185 -0
  612. package/src/domains/interop/contract.ts +29 -0
  613. package/src/domains/interop/detect.ts +173 -0
  614. package/src/domains/interop/extension.ts +59 -0
  615. package/src/domains/interop/index.ts +34 -0
  616. package/src/domains/interop/manifest.ts +6 -0
  617. package/src/domains/interop/registry.ts +139 -0
  618. package/src/domains/interop/state.ts +92 -0
  619. package/src/domains/interop/types.ts +109 -0
  620. package/src/domains/lifecycle/contract.ts +11 -0
  621. package/src/domains/lifecycle/doctor.ts +536 -0
  622. package/src/domains/lifecycle/extension.ts +23 -0
  623. package/src/domains/lifecycle/index.ts +21 -0
  624. package/src/domains/lifecycle/install-method.ts +51 -0
  625. package/src/domains/lifecycle/manifest.ts +6 -0
  626. package/src/domains/lifecycle/migrations/2026-08-18-lmstudio-runtime-id.ts +52 -0
  627. package/src/domains/lifecycle/migrations/index.ts +114 -0
  628. package/src/domains/lifecycle/state.ts +93 -0
  629. package/src/domains/lifecycle/upgrade-notice.ts +35 -0
  630. package/src/domains/lifecycle/version.ts +35 -0
  631. package/src/domains/memory/index.ts +128 -0
  632. package/src/domains/memory/operations.ts +143 -0
  633. package/src/domains/memory/prompt-section.ts +86 -0
  634. package/src/domains/memory/proposal.ts +180 -0
  635. package/src/domains/memory/store.ts +163 -0
  636. package/src/domains/memory/task-bank.ts +229 -0
  637. package/src/domains/memory/task-memory-handoff.ts +222 -0
  638. package/src/domains/memory/task-memory-policy.ts +602 -0
  639. package/src/domains/memory/task-memory-status.ts +58 -0
  640. package/src/domains/memory/task-memory-telemetry.ts +346 -0
  641. package/src/domains/memory/task-memory-trace.ts +89 -0
  642. package/src/domains/memory/types.ts +74 -0
  643. package/src/domains/memory/validate.ts +297 -0
  644. package/src/domains/middleware/budget.ts +216 -0
  645. package/src/domains/middleware/contract.ts +35 -0
  646. package/src/domains/middleware/dispatch-nudge.ts +469 -0
  647. package/src/domains/middleware/extension.ts +129 -0
  648. package/src/domains/middleware/hook-receipts.ts +70 -0
  649. package/src/domains/middleware/hooks-io.ts +186 -0
  650. package/src/domains/middleware/hooks.ts +432 -0
  651. package/src/domains/middleware/index.ts +154 -0
  652. package/src/domains/middleware/manifest.ts +6 -0
  653. package/src/domains/middleware/memory-intervention.ts +701 -0
  654. package/src/domains/middleware/rules.ts +42 -0
  655. package/src/domains/middleware/runtime.ts +333 -0
  656. package/src/domains/middleware/skills-reminder.ts +202 -0
  657. package/src/domains/middleware/snapshot.ts +71 -0
  658. package/src/domains/middleware/stalled-turn.ts +71 -0
  659. package/src/domains/middleware/task-board-reminder.ts +87 -0
  660. package/src/domains/middleware/task-nudge.ts +77 -0
  661. package/src/domains/middleware/tool-choice-control.ts +42 -0
  662. package/src/domains/middleware/types.ts +131 -0
  663. package/src/domains/middleware/validate.ts +329 -0
  664. package/src/domains/observability/accountability.ts +67 -0
  665. package/src/domains/observability/contract.ts +168 -0
  666. package/src/domains/observability/cost.ts +206 -0
  667. package/src/domains/observability/evidence-index.ts +123 -0
  668. package/src/domains/observability/extension.ts +281 -0
  669. package/src/domains/observability/index.ts +78 -0
  670. package/src/domains/observability/manifest.ts +10 -0
  671. package/src/domains/observability/metrics.ts +37 -0
  672. package/src/domains/observability/projection.ts +477 -0
  673. package/src/domains/observability/telemetry.ts +89 -0
  674. package/src/domains/observability/trace-store.ts +1454 -0
  675. package/src/domains/prompts/compiler.ts +614 -0
  676. package/src/domains/prompts/contract.ts +46 -0
  677. package/src/domains/prompts/extension.ts +336 -0
  678. package/src/domains/prompts/fragment-loader.ts +138 -0
  679. package/src/domains/prompts/fragments/identity/clio.md +5 -6
  680. package/src/domains/prompts/fragments/identity/docs-routing.md +10 -0
  681. package/src/domains/prompts/fragments/identity/self-awareness.md +19 -0
  682. package/src/domains/prompts/fragments/operating/contract.md +4 -41
  683. package/src/domains/prompts/fragments/operating/delegation.md +42 -0
  684. package/src/domains/prompts/fragments/operating/skills.md +26 -0
  685. package/src/domains/prompts/fragments/operating/worker.md +16 -0
  686. package/src/domains/prompts/fragments/safety/auto-edit.md +5 -5
  687. package/src/domains/prompts/fragments/safety/full-auto.md +3 -3
  688. package/src/domains/prompts/fragments/safety/read-only.md +4 -4
  689. package/src/domains/prompts/fragments/safety/suggest.md +2 -2
  690. package/src/domains/prompts/fragments/wiki/page.md +10 -0
  691. package/src/domains/prompts/fragments/wiki/plan.md +10 -0
  692. package/src/domains/prompts/hash.ts +73 -0
  693. package/src/domains/prompts/index.ts +32 -0
  694. package/src/domains/prompts/manifest.ts +8 -0
  695. package/src/domains/prompts/memory-intervention.ts +57 -0
  696. package/src/domains/prompts/preload.ts +82 -0
  697. package/src/domains/providers/auth/api-key.ts +47 -0
  698. package/src/domains/providers/auth/backend-file.ts +79 -0
  699. package/src/domains/providers/auth/backend-memory.ts +72 -0
  700. package/src/domains/providers/auth/boot-status.ts +65 -0
  701. package/src/domains/providers/auth/index.ts +37 -0
  702. package/src/domains/providers/auth/oauth.ts +37 -0
  703. package/src/domains/providers/auth/storage.ts +726 -0
  704. package/src/domains/providers/capabilities.ts +58 -0
  705. package/src/domains/providers/catalog.ts +162 -0
  706. package/src/domains/providers/contract.ts +162 -0
  707. package/src/domains/providers/credentials.ts +20 -0
  708. package/src/domains/providers/eligibility.ts +24 -0
  709. package/src/domains/providers/errors.ts +64 -0
  710. package/src/domains/providers/extension.ts +548 -0
  711. package/src/domains/providers/index.ts +142 -0
  712. package/src/domains/providers/knowledge-base-path.ts +102 -0
  713. package/src/domains/providers/manifest.ts +6 -0
  714. package/src/domains/providers/model-capabilities.ts +136 -0
  715. package/src/domains/providers/model-discovery.ts +144 -0
  716. package/src/domains/providers/model-family.ts +32 -0
  717. package/src/domains/providers/model-runtime-capabilities.ts +723 -0
  718. package/src/domains/providers/models/local-models/clio-local-coding-targets.yaml +120 -37
  719. package/src/domains/providers/plugins.ts +61 -0
  720. package/src/domains/providers/probe/fingerprint.ts +64 -0
  721. package/src/domains/providers/probe/http.ts +114 -0
  722. package/src/domains/providers/probe/reasoning.ts +111 -0
  723. package/src/domains/providers/registry.ts +187 -0
  724. package/src/domains/providers/resolver.ts +156 -0
  725. package/src/domains/providers/runtime-resolution.ts +720 -0
  726. package/src/domains/providers/runtimes/antigravity/antigravity-code.ts +90 -0
  727. package/src/domains/providers/runtimes/boot-manifest.ts +55 -0
  728. package/src/domains/providers/runtimes/builtins.ts +78 -0
  729. package/src/domains/providers/runtimes/claude/claude-code.ts +38 -0
  730. package/src/domains/providers/runtimes/claude/claude-sdk.ts +38 -0
  731. package/src/domains/providers/runtimes/claude/common.ts +55 -0
  732. package/src/domains/providers/runtimes/cloud/alcf.ts +171 -0
  733. package/src/domains/providers/runtimes/cloud/anthropic-max.ts +71 -0
  734. package/src/domains/providers/runtimes/cloud/anthropic.ts +43 -0
  735. package/src/domains/providers/runtimes/cloud/bedrock.ts +35 -0
  736. package/src/domains/providers/runtimes/cloud/deepseek.ts +50 -0
  737. package/src/domains/providers/runtimes/cloud/google.ts +41 -0
  738. package/src/domains/providers/runtimes/cloud/groq.ts +46 -0
  739. package/src/domains/providers/runtimes/cloud/mistral.ts +46 -0
  740. package/src/domains/providers/runtimes/cloud/openai-codex.ts +49 -0
  741. package/src/domains/providers/runtimes/cloud/openai.ts +46 -0
  742. package/src/domains/providers/runtimes/cloud/openrouter.ts +111 -0
  743. package/src/domains/providers/runtimes/common/lmstudio-http.ts +423 -0
  744. package/src/domains/providers/runtimes/common/local-synth.ts +164 -0
  745. package/src/domains/providers/runtimes/common/probe-helpers.ts +474 -0
  746. package/src/domains/providers/runtimes/local-native/lemonade-anthropic.ts +27 -0
  747. package/src/domains/providers/runtimes/local-native/lemonade-openai.ts +26 -0
  748. package/src/domains/providers/runtimes/local-native/llamacpp-anthropic.ts +88 -0
  749. package/src/domains/providers/runtimes/local-native/llamacpp-completion.ts +207 -0
  750. package/src/domains/providers/runtimes/local-native/llamacpp-embed.ts +180 -0
  751. package/src/domains/providers/runtimes/local-native/llamacpp-rerank.ts +126 -0
  752. package/src/domains/providers/runtimes/local-native/llamacpp.ts +98 -0
  753. package/src/domains/providers/runtimes/local-native/lmstudio.ts +241 -0
  754. package/src/domains/providers/runtimes/local-native/ollama-native.ts +117 -0
  755. package/src/domains/providers/runtimes/local-native/sglang.ts +26 -0
  756. package/src/domains/providers/runtimes/local-native/vllm.ts +27 -0
  757. package/src/domains/providers/runtimes/protocol/anthropic-compat.ts +104 -0
  758. package/src/domains/providers/runtimes/protocol/anthropic-messages.ts +28 -0
  759. package/src/domains/providers/runtimes/protocol/bedrock.ts +26 -0
  760. package/src/domains/providers/runtimes/protocol/google.ts +27 -0
  761. package/src/domains/providers/runtimes/protocol/openai-compat.ts +145 -0
  762. package/src/domains/providers/support.ts +241 -0
  763. package/src/domains/providers/thinking-control-policy.ts +85 -0
  764. package/src/domains/providers/types/capability-flags.ts +114 -0
  765. package/src/domains/providers/types/cost-provenance.ts +7 -0
  766. package/src/domains/providers/types/inference.ts +41 -0
  767. package/src/domains/providers/types/knowledge-base.ts +156 -0
  768. package/src/domains/providers/types/local-model-quirks.ts +216 -0
  769. package/src/domains/providers/types/runtime-descriptor.ts +181 -0
  770. package/src/domains/providers/types/target-descriptor.ts +60 -0
  771. package/src/domains/resources/collision.ts +92 -0
  772. package/src/domains/resources/common-loader.ts +140 -0
  773. package/src/domains/resources/contract.ts +24 -0
  774. package/src/domains/resources/extension.ts +59 -0
  775. package/src/domains/resources/index.ts +74 -0
  776. package/src/domains/resources/loader.ts +85 -0
  777. package/src/domains/resources/manifest.ts +6 -0
  778. package/src/domains/resources/prompts/loader.ts +246 -0
  779. package/src/domains/resources/prompts/substitute.ts +1 -0
  780. package/src/domains/resources/skills/content-hash.ts +107 -0
  781. package/src/domains/resources/skills/evals.ts +175 -0
  782. package/src/domains/resources/skills/install.ts +427 -0
  783. package/src/domains/resources/skills/loader.ts +985 -0
  784. package/src/domains/resources/skills/marketplace.ts +301 -0
  785. package/src/domains/resources/skills/provenance-pin.ts +115 -0
  786. package/src/domains/safety/action-classifier.ts +270 -0
  787. package/src/domains/safety/approval-axis.ts +23 -0
  788. package/src/domains/safety/audit.ts +493 -0
  789. package/src/domains/safety/autonomy.ts +174 -0
  790. package/src/domains/safety/call-target.ts +59 -0
  791. package/src/domains/safety/contract.ts +65 -0
  792. package/src/domains/safety/damage-control.ts +44 -0
  793. package/src/domains/safety/default-path-policy.ts +117 -0
  794. package/src/domains/safety/extension.ts +383 -0
  795. package/src/domains/safety/finish-contract-registration.ts +128 -0
  796. package/src/domains/safety/finish-contract.ts +554 -0
  797. package/src/domains/safety/index.ts +44 -0
  798. package/src/domains/safety/loop-detector.ts +143 -0
  799. package/src/domains/safety/manifest.ts +6 -0
  800. package/src/domains/safety/path-policy.ts +164 -0
  801. package/src/domains/safety/policy-engine.ts +994 -0
  802. package/src/domains/safety/project-policy.ts +391 -0
  803. package/src/domains/safety/protected-artifacts-registration.ts +189 -0
  804. package/src/domains/safety/protected-artifacts.ts +993 -0
  805. package/src/domains/safety/rejection-feedback.ts +102 -0
  806. package/src/domains/safety/rigor.ts +72 -0
  807. package/src/domains/safety/rule-compiler.ts +48 -0
  808. package/src/domains/safety/rule-pack-loader.ts +92 -0
  809. package/src/domains/safety/run-effects.ts +197 -0
  810. package/src/domains/safety/scope.ts +61 -0
  811. package/src/domains/scheduling/budget.ts +35 -0
  812. package/src/domains/scheduling/cluster.ts +175 -0
  813. package/src/domains/scheduling/contract.ts +30 -0
  814. package/src/domains/scheduling/extension.ts +91 -0
  815. package/src/domains/scheduling/index.ts +12 -0
  816. package/src/domains/scheduling/manifest.ts +6 -0
  817. package/src/domains/session/archive-readers.ts +208 -0
  818. package/src/domains/session/checkpoint.ts +38 -0
  819. package/src/domains/session/compaction/auto.ts +89 -0
  820. package/src/domains/session/compaction/branch-summary.ts +187 -0
  821. package/src/domains/session/compaction/compact.ts +493 -0
  822. package/src/domains/session/compaction/cut-point.ts +172 -0
  823. package/src/domains/session/compaction/defaults.ts +34 -0
  824. package/src/domains/session/compaction/mask-observations.ts +265 -0
  825. package/src/domains/session/compaction/session-entries.ts +18 -0
  826. package/src/domains/session/compaction/tokens.ts +148 -0
  827. package/src/domains/session/context-accounting.ts +583 -0
  828. package/src/domains/session/context-ledger.ts +362 -0
  829. package/src/domains/session/contract.ts +159 -0
  830. package/src/domains/session/cwd-fallback.ts +65 -0
  831. package/src/domains/session/decision-board.ts +190 -0
  832. package/src/domains/session/entries.ts +572 -0
  833. package/src/domains/session/extension.ts +403 -0
  834. package/src/domains/session/history.ts +172 -0
  835. package/src/domains/session/index.ts +84 -0
  836. package/src/domains/session/manager.ts +128 -0
  837. package/src/domains/session/manifest.ts +6 -0
  838. package/src/domains/session/migrations/index.ts +27 -0
  839. package/src/domains/session/prompt-manifest.ts +173 -0
  840. package/src/domains/session/protected-artifact-journal.ts +241 -0
  841. package/src/domains/session/protected-artifacts.ts +90 -0
  842. package/src/domains/session/retry.ts +230 -0
  843. package/src/domains/session/session-artifacts.ts +107 -0
  844. package/src/domains/session/task-board.ts +569 -0
  845. package/src/domains/session/tree/active-path.ts +137 -0
  846. package/src/domains/session/tree/fork.ts +159 -0
  847. package/src/domains/session/tree/manager.ts +128 -0
  848. package/src/domains/session/tree/navigator.ts +177 -0
  849. package/src/domains/session/tree/preview.ts +259 -0
  850. package/src/domains/session/usage.ts +148 -0
  851. package/src/domains/session/workspace/git-probe.ts +167 -0
  852. package/src/domains/session/workspace/index.ts +4 -0
  853. package/src/domains/session/workspace/project-type.ts +217 -0
  854. package/src/domains/session/workspace/snapshot.ts +74 -0
  855. package/src/domains/share/archive.ts +684 -0
  856. package/src/domains/share/contract.ts +9 -0
  857. package/src/domains/share/extension.ts +26 -0
  858. package/src/domains/share/index.ts +28 -0
  859. package/src/domains/share/manifest.ts +6 -0
  860. package/src/domains/user-tasks/store.ts +297 -0
  861. package/src/engine/acp/adapter.ts +397 -0
  862. package/src/engine/acp/errors.ts +128 -0
  863. package/src/engine/acp/event-mapper.ts +154 -0
  864. package/src/engine/acp/server.ts +2238 -0
  865. package/src/engine/acp/tool-mediator.ts +686 -0
  866. package/src/engine/acp/transport.ts +775 -0
  867. package/src/engine/acp/types.ts +196 -0
  868. package/src/engine/agent.ts +29 -0
  869. package/src/engine/ai.ts +207 -0
  870. package/src/engine/alcf-oauth.ts +205 -0
  871. package/src/engine/antigravity/subprocess-runtime.ts +205 -0
  872. package/src/engine/api-registry.ts +223 -0
  873. package/src/engine/apis/degraded-inference.ts +95 -0
  874. package/src/engine/apis/index.ts +16 -0
  875. package/src/engine/apis/llamacpp-residency.ts +292 -0
  876. package/src/engine/apis/lmstudio-residency.ts +76 -0
  877. package/src/engine/apis/lmstudio.ts +243 -0
  878. package/src/engine/apis/ollama-native.ts +528 -0
  879. package/src/engine/apis/openai-completions.ts +795 -0
  880. package/src/engine/apis/output-budget.ts +99 -0
  881. package/src/engine/apis/residency-lock.ts +29 -0
  882. package/src/engine/apis/residency.ts +776 -0
  883. package/src/engine/apis/resident-models.ts +42 -0
  884. package/src/engine/apis/sampling-overrides.ts +38 -0
  885. package/src/engine/apis/types.ts +16 -0
  886. package/src/engine/claude/sdk-runtime.ts +685 -0
  887. package/src/engine/claude/session-id.ts +5 -0
  888. package/src/engine/claude/subprocess-runtime.ts +316 -0
  889. package/src/engine/claude/tool-safety.ts +400 -0
  890. package/src/engine/env-api-keys.ts +98 -0
  891. package/src/engine/external-subprocess.ts +23 -0
  892. package/src/engine/gemma-channel-filter.ts +223 -0
  893. package/src/engine/harmony-response.ts +165 -0
  894. package/src/engine/instrumented-tui.ts +192 -0
  895. package/src/engine/loop-guard.ts +1127 -0
  896. package/src/engine/messages.ts +14 -0
  897. package/src/engine/models.ts +42 -0
  898. package/src/engine/oauth.ts +196 -0
  899. package/src/engine/pi-mono-names.ts +13 -0
  900. package/src/engine/prompt-templates.ts +1 -0
  901. package/src/engine/provider-payload.ts +272 -0
  902. package/src/engine/select-list.ts +53 -0
  903. package/src/engine/session.ts +834 -0
  904. package/src/engine/strip-tokenizer-sentinels.ts +125 -0
  905. package/src/engine/truncate.ts +9 -0
  906. package/src/engine/tui.ts +111 -0
  907. package/src/engine/types.ts +63 -0
  908. package/src/engine/worker-events.ts +100 -0
  909. package/src/engine/worker-runtime-capabilities.ts +5 -0
  910. package/src/engine/worker-runtime.ts +1022 -0
  911. package/src/engine/worker-tools.ts +208 -0
  912. package/src/entry/boot-options.ts +50 -0
  913. package/src/entry/orchestrator.ts +2011 -0
  914. package/src/interactive/application-controller.ts +433 -0
  915. package/src/interactive/bus-notices.ts +265 -0
  916. package/src/interactive/chat-loop-messages.ts +626 -0
  917. package/src/interactive/chat-loop-policy.ts +18 -0
  918. package/src/interactive/chat-loop.ts +1090 -0
  919. package/src/interactive/chat-panel.ts +1820 -0
  920. package/src/interactive/chat-renderer.ts +1228 -0
  921. package/src/interactive/clio-editor.ts +161 -0
  922. package/src/interactive/command-fallbacks.ts +23 -0
  923. package/src/interactive/command-output.ts +85 -0
  924. package/src/interactive/context-activity.ts +203 -0
  925. package/src/interactive/context-meter.ts +223 -0
  926. package/src/interactive/context-overlay.ts +246 -0
  927. package/src/interactive/cost-overlay.ts +279 -0
  928. package/src/interactive/dispatch-board.ts +1319 -0
  929. package/src/interactive/dispatch-steering.ts +86 -0
  930. package/src/interactive/editor-bash.ts +46 -0
  931. package/src/interactive/editor-steer.ts +51 -0
  932. package/src/interactive/editor-submit.ts +507 -0
  933. package/src/interactive/export-html/ansi-to-html.ts +161 -0
  934. package/src/interactive/export-html/index.ts +51 -0
  935. package/src/interactive/export-html/template.ts +45 -0
  936. package/src/interactive/export-html/tool-renderer.ts +54 -0
  937. package/src/interactive/external-editor.ts +67 -0
  938. package/src/interactive/follow-up-queue-panel.ts +75 -0
  939. package/src/interactive/footer/dashboard.ts +538 -0
  940. package/src/interactive/footer/notifications.ts +275 -0
  941. package/src/interactive/footer/widgets.ts +1264 -0
  942. package/src/interactive/footer-panel.ts +187 -0
  943. package/src/interactive/format-time.ts +97 -0
  944. package/src/interactive/index.ts +11 -0
  945. package/src/interactive/interactive-application.ts +939 -0
  946. package/src/interactive/interactive-event-projection.ts +385 -0
  947. package/src/interactive/interactive-input-runtime.ts +307 -0
  948. package/src/interactive/interactive-presentation.ts +584 -0
  949. package/src/interactive/interactive-shell.ts +388 -0
  950. package/src/interactive/interactive-slash-runtime.ts +554 -0
  951. package/src/interactive/interactive-subscriptions.ts +111 -0
  952. package/src/interactive/interactive-tickers.ts +183 -0
  953. package/src/interactive/keybinding-manager.ts +496 -0
  954. package/src/interactive/layout.ts +57 -0
  955. package/src/interactive/leader-key.ts +143 -0
  956. package/src/interactive/loop-guard-interrupt.ts +101 -0
  957. package/src/interactive/memory-overlay.ts +280 -0
  958. package/src/interactive/overlay-ask-user-lifecycle.ts +110 -0
  959. package/src/interactive/overlay-auth-lifecycle.ts +308 -0
  960. package/src/interactive/overlay-frame.ts +502 -0
  961. package/src/interactive/overlay-general-openers.ts +274 -0
  962. package/src/interactive/overlay-key-routing.ts +216 -0
  963. package/src/interactive/overlay-lifecycle.ts +426 -0
  964. package/src/interactive/overlay-model-selectors.ts +127 -0
  965. package/src/interactive/overlay-permission-lifecycle.ts +345 -0
  966. package/src/interactive/overlay-resource-openers.ts +112 -0
  967. package/src/interactive/overlay-session-lifecycle.ts +327 -0
  968. package/src/interactive/overlay-transitions.ts +57 -0
  969. package/src/interactive/overlays/agents.ts +69 -0
  970. package/src/interactive/overlays/ask-user.ts +921 -0
  971. package/src/interactive/overlays/auth-dialog.ts +221 -0
  972. package/src/interactive/overlays/context-reset.ts +108 -0
  973. package/src/interactive/overlays/cwd-fallback.ts +141 -0
  974. package/src/interactive/overlays/decisions.ts +300 -0
  975. package/src/interactive/overlays/extensions.ts +54 -0
  976. package/src/interactive/overlays/help-reference.ts +145 -0
  977. package/src/interactive/overlays/interop.ts +139 -0
  978. package/src/interactive/overlays/keybinding-detail.ts +90 -0
  979. package/src/interactive/overlays/list-overlay.ts +606 -0
  980. package/src/interactive/overlays/message-picker.ts +155 -0
  981. package/src/interactive/overlays/model-selector.ts +1109 -0
  982. package/src/interactive/overlays/prompts.ts +72 -0
  983. package/src/interactive/overlays/session-selector-search.ts +31 -0
  984. package/src/interactive/overlays/session-selector.ts +284 -0
  985. package/src/interactive/overlays/settings.ts +3451 -0
  986. package/src/interactive/overlays/skills-hub.ts +237 -0
  987. package/src/interactive/overlays/tree-selector.ts +422 -0
  988. package/src/interactive/permission-overlay.ts +170 -0
  989. package/src/interactive/render-trace.ts +534 -0
  990. package/src/interactive/renderers/branch-summary.ts +86 -0
  991. package/src/interactive/renderers/code-ink.ts +420 -0
  992. package/src/interactive/renderers/compaction-summary.ts +112 -0
  993. package/src/interactive/renderers/diff.ts +137 -0
  994. package/src/interactive/renderers/mermaid.ts +53 -0
  995. package/src/interactive/renderers/notice.ts +28 -0
  996. package/src/interactive/renderers/retry-status.ts +31 -0
  997. package/src/interactive/renderers/structured.ts +89 -0
  998. package/src/interactive/renderers/tool-execution.ts +1357 -0
  999. package/src/interactive/renderers/worker-entry.ts +280 -0
  1000. package/src/interactive/session-last-turn.ts +186 -0
  1001. package/src/interactive/session-switch-settlement.ts +10 -0
  1002. package/src/interactive/session-transcript.ts +105 -0
  1003. package/src/interactive/session-usage-reseed.ts +74 -0
  1004. package/src/interactive/slash-autocomplete.ts +256 -0
  1005. package/src/interactive/slash-commands.ts +1407 -0
  1006. package/src/interactive/slash-spec.ts +424 -0
  1007. package/src/interactive/status/controller.ts +260 -0
  1008. package/src/interactive/status/index.ts +23 -0
  1009. package/src/interactive/status/state-machine.ts +530 -0
  1010. package/src/interactive/status/summary.ts +170 -0
  1011. package/src/interactive/status/types.ts +121 -0
  1012. package/src/interactive/status/verbs.ts +163 -0
  1013. package/src/interactive/status/watchdog.ts +24 -0
  1014. package/src/interactive/stdout-backpressure.ts +99 -0
  1015. package/src/interactive/stream-pacer.ts +530 -0
  1016. package/src/interactive/stream-pacing-policy.ts +66 -0
  1017. package/src/interactive/tasks-overlay.ts +540 -0
  1018. package/src/interactive/terminal-lease.ts +485 -0
  1019. package/src/interactive/theme/components.ts +55 -0
  1020. package/src/interactive/theme/glyphs.ts +70 -0
  1021. package/src/interactive/theme/index.ts +15 -0
  1022. package/src/interactive/theme/labels.ts +88 -0
  1023. package/src/interactive/theme/rules.ts +138 -0
  1024. package/src/interactive/theme/segments.ts +88 -0
  1025. package/src/interactive/theme/tokens.ts +121 -0
  1026. package/src/interactive/thinking-level-policy.ts +6 -0
  1027. package/src/interactive/tool-prose-loop.ts +122 -0
  1028. package/src/interactive/tool-prose-registration.ts +48 -0
  1029. package/src/interactive/turn-context.ts +855 -0
  1030. package/src/interactive/turn-middleware.ts +283 -0
  1031. package/src/interactive/turn-persistence.ts +458 -0
  1032. package/src/interactive/turn-queues.ts +181 -0
  1033. package/src/interactive/turn-recovery.ts +323 -0
  1034. package/src/interactive/turn-runtime.ts +869 -0
  1035. package/src/interactive/turn-state.ts +133 -0
  1036. package/src/interactive/view/artifacts.ts +1452 -0
  1037. package/src/interactive/view/view-overlay.ts +735 -0
  1038. package/src/interactive/welcome-dashboard.ts +537 -0
  1039. package/src/interactive/worker-receipts.ts +143 -0
  1040. package/src/interactive/worker-replay.ts +111 -0
  1041. package/src/interactive/worker-share.ts +100 -0
  1042. package/src/interactive/worker-stream.ts +446 -0
  1043. package/src/interactive/workspace-facts.ts +141 -0
  1044. package/src/tools/agent-tools.ts +402 -0
  1045. package/src/tools/artifact.ts +103 -0
  1046. package/src/tools/ask-user.ts +666 -0
  1047. package/src/tools/bash.ts +204 -0
  1048. package/src/tools/bootstrap.ts +77 -0
  1049. package/src/tools/builtin-tool-catalog.ts +265 -0
  1050. package/src/tools/codewiki/code-nav-surface.ts +29 -0
  1051. package/src/tools/codewiki/code-nav.ts +549 -0
  1052. package/src/tools/codewiki/shared.ts +118 -0
  1053. package/src/tools/compete-worktrees.ts +898 -0
  1054. package/src/tools/context/docs-engine.ts +630 -0
  1055. package/src/tools/context/index.ts +514 -0
  1056. package/src/tools/context/surface.ts +19 -0
  1057. package/src/tools/core-bootstrap.ts +168 -0
  1058. package/src/tools/credential-present.ts +151 -0
  1059. package/src/tools/dispatch-admission.ts +533 -0
  1060. package/src/tools/dispatch-arguments.ts +228 -0
  1061. package/src/tools/dispatch-background.ts +54 -0
  1062. package/src/tools/dispatch-event-text.ts +6 -0
  1063. package/src/tools/dispatch-plan.ts +746 -0
  1064. package/src/tools/dispatch-run-events.ts +238 -0
  1065. package/src/tools/dispatch-runner.ts +2370 -0
  1066. package/src/tools/dispatch-scout-admission.ts +295 -0
  1067. package/src/tools/dispatch-scout.ts +461 -0
  1068. package/src/tools/dispatch-types.ts +77 -0
  1069. package/src/tools/dispatch.ts +244 -0
  1070. package/src/tools/edit-diff.ts +534 -0
  1071. package/src/tools/edit.ts +128 -0
  1072. package/src/tools/executables.ts +22 -0
  1073. package/src/tools/file-mutation-queue.ts +35 -0
  1074. package/src/tools/find.ts +294 -0
  1075. package/src/tools/grep.ts +495 -0
  1076. package/src/tools/ignore-policy.ts +169 -0
  1077. package/src/tools/lazy-tool.ts +60 -0
  1078. package/src/tools/ledger.ts +206 -0
  1079. package/src/tools/ls.ts +110 -0
  1080. package/src/tools/monitor-surface.ts +36 -0
  1081. package/src/tools/monitor.ts +767 -0
  1082. package/src/tools/network-policy.ts +29 -0
  1083. package/src/tools/observation.ts +421 -0
  1084. package/src/tools/observers.ts +99 -0
  1085. package/src/tools/path-utils.ts +79 -0
  1086. package/src/tools/policy.ts +154 -0
  1087. package/src/tools/profiles.ts +108 -0
  1088. package/src/tools/read.ts +173 -0
  1089. package/src/tools/registry.ts +1169 -0
  1090. package/src/tools/result-shaping.ts +204 -0
  1091. package/src/tools/safe-exec.ts +128 -0
  1092. package/src/tools/spawn-hygiene.ts +182 -0
  1093. package/src/tools/steer-surface.ts +17 -0
  1094. package/src/tools/steer.ts +77 -0
  1095. package/src/tools/tasks.ts +265 -0
  1096. package/src/tools/truncate-utf8.ts +17 -0
  1097. package/src/tools/truncate.ts +43 -0
  1098. package/src/tools/verify/frontend.ts +687 -0
  1099. package/src/tools/verify/index.ts +31 -0
  1100. package/src/tools/verify/scripts.ts +108 -0
  1101. package/src/tools/verify/surface.ts +46 -0
  1102. package/src/tools/web-fetch-surface.ts +23 -0
  1103. package/src/tools/web-fetch.ts +759 -0
  1104. package/src/tools/worker-evidence.ts +215 -0
  1105. package/src/tools/write.ts +57 -0
  1106. package/src/utils/exif-orientation.ts +192 -0
  1107. package/src/utils/git.ts +24 -0
  1108. package/src/utils/image-resize.ts +148 -0
  1109. package/src/utils/photon.ts +103 -0
  1110. package/src/worker/control-lane.ts +22 -0
  1111. package/src/worker/entry.ts +294 -0
  1112. package/src/worker/event-projection.ts +56 -0
  1113. package/src/worker/heartbeat.ts +24 -0
  1114. package/src/worker/ledger-mirror.ts +95 -0
  1115. package/src/worker/ndjson.ts +40 -0
  1116. package/src/worker/protocol.ts +529 -0
  1117. package/src/worker/resource-facts.ts +79 -0
  1118. package/src/worker/runtime-registry.ts +12 -0
  1119. package/src/worker/spec-contract.ts +675 -0
  1120. package/src/worker/stdin-demux.ts +316 -0
  1121. package/dist/acp-UMLFVA3F.js +0 -92
  1122. package/dist/chunk-262G75JS.js +0 -35
  1123. package/dist/chunk-6CWDTGUC.js +0 -20
  1124. package/dist/chunk-BYEU76JP.js +0 -899
  1125. package/dist/chunk-GNGDQYDU.js +0 -34688
  1126. package/dist/chunk-GOTUR54M.js +0 -9
  1127. package/dist/chunk-NI4DEJMC.js +0 -88
  1128. package/dist/chunk-TPOCL34A.js +0 -2876
  1129. package/dist/chunk-UU3R62TT.js +0 -128
  1130. package/dist/clio-KIQ5SNDS.js +0 -53
  1131. package/dist/configure-G4E3A2PG.js +0 -27
  1132. package/dist/doctor-M5HJJZOL.js +0 -61
  1133. package/dist/domains/agents/builtins/architect.md +0 -33
  1134. package/dist/domains/agents/builtins/coder.md +0 -31
  1135. package/dist/domains/agents/builtins/context-bootstrap.md +0 -38
  1136. package/dist/domains/agents/builtins/debugger.md +0 -30
  1137. package/dist/domains/agents/builtins/documenter.md +0 -31
  1138. package/dist/domains/agents/builtins/git-master.md +0 -30
  1139. package/dist/domains/agents/builtins/provenance.md +0 -30
  1140. package/dist/domains/agents/builtins/researcher.md +0 -71
  1141. package/dist/domains/agents/builtins/scout.md +0 -42
  1142. package/dist/domains/agents/builtins/tester.md +0 -31
  1143. package/dist/domains/agents/builtins/verifier.md +0 -30
  1144. package/dist/domains/agents/builtins/wiki-writer.md +0 -41
  1145. package/dist/fleet-preflight-CLIAX7YR.js +0 -21
  1146. package/dist/preload-KZVHET2B.js +0 -11
  1147. package/dist/version-ROZ6CZKH.js +0 -16
  1148. package/docs/html/agents_blueprint.html +0 -936
  1149. package/docs/html/alcf_blueprint.html +0 -324
  1150. package/docs/html/architecture_blueprint.html +0 -850
  1151. package/docs/html/commands_blueprint.html +0 -794
  1152. package/docs/html/config_knobs_audit_blueprint.html +0 -178
  1153. package/docs/html/configuration_blueprint.html +0 -1080
  1154. package/docs/html/context_blueprint.html +0 -603
  1155. package/docs/html/documentation_blueprint.html +0 -832
  1156. package/docs/html/environment_blueprint.html +0 -404
  1157. package/docs/html/eval_blueprint.html +0 -743
  1158. package/docs/html/evals_internal_blueprint.html +0 -190
  1159. package/docs/html/evolution_blueprint.html +0 -674
  1160. package/docs/html/extensions_blueprint.html +0 -2065
  1161. package/docs/html/fleet_dispatch_blueprint.html +0 -286
  1162. package/docs/html/index.html +0 -919
  1163. package/docs/html/lifecycle_blueprint.html +0 -723
  1164. package/docs/html/memory_blueprint.html +0 -699
  1165. package/docs/html/middleware_blueprint.html +0 -664
  1166. package/docs/html/models_blueprint.html +0 -2366
  1167. package/docs/html/observability_blueprint.html +0 -683
  1168. package/docs/html/provider_adapter_blueprint.html +0 -245
  1169. package/docs/html/safety_blueprint.html +0 -1386
  1170. package/docs/html/shared.css +0 -571
  1171. package/docs/html/shared.js +0 -143
  1172. package/docs/html/skills_blueprint.html +0 -671
  1173. package/docs/html/soak_blueprint.html +0 -182
  1174. package/docs/html/tool_usage_blueprint.html +0 -350
  1175. package/docs/html/tools_blueprint.html +0 -2249
  1176. package/docs/html/trace_blueprint.html +0 -235
  1177. package/docs/html/tui_design_blueprint.html +0 -314
  1178. package/docs/html/validation_blueprint.html +0 -961
  1179. package/docs/html/worker_dispatch_blueprint.html +0 -231
  1180. package/skills/git/commit-crafting/SKILL.md +0 -79
  1181. package/skills/git/commit-crafting/evals.md +0 -92
  1182. package/skills/git/create-pr/SKILL.md +0 -116
  1183. package/skills/git/create-pr/evals.md +0 -114
  1184. package/skills/git/investigate-issue/SKILL.md +0 -139
  1185. package/skills/git/investigate-issue/evals.md +0 -94
  1186. package/skills/git/review-changes/SKILL.md +0 -103
  1187. package/skills/git/review-changes/evals.md +0 -85
@@ -0,0 +1,1525 @@
1
+ import { stdin as input, stdout as output } from "node:process";
2
+ import { createInterface } from "node:readline/promises";
3
+ import {
4
+ type ClioSettings,
5
+ readSettings,
6
+ removeTargetFromSettings,
7
+ settingsPath,
8
+ updateSettings,
9
+ } from "../core/config.js";
10
+ import { initializeClioHome } from "../core/init.js";
11
+ import { openAuthStorage, resolveAuthTarget, targetRequiresAuth } from "../domains/providers/auth/index.js";
12
+ import { getCatalogModelForRuntime } from "../domains/providers/catalog.js";
13
+ import { credentialsPresent } from "../domains/providers/credentials.js";
14
+ import {
15
+ buildProviderSupportEntry,
16
+ configuredTargetsForRuntime,
17
+ describeRuntimeModels,
18
+ isOrchestratorEligibleRuntime,
19
+ listKnownModelsForRuntime,
20
+ listProviderSupportEntries,
21
+ type ProviderSupportEntry,
22
+ resolveRuntimeAuthTarget,
23
+ supportGroupLabel,
24
+ } from "../domains/providers/index.js";
25
+ import { probeCapabilitiesForModel } from "../domains/providers/model-capabilities.js";
26
+ import { fingerprintNativeRuntime } from "../domains/providers/probe/fingerprint.js";
27
+ import { getRuntimeRegistry } from "../domains/providers/registry.js";
28
+ import { registerBuiltinRuntimes } from "../domains/providers/runtimes/builtins.js";
29
+ import { greetLmStudio } from "../domains/providers/runtimes/common/lmstudio-http.js";
30
+ import type { ProbeContext, ProbeResult, RuntimeDescriptor } from "../domains/providers/types/runtime-descriptor.js";
31
+ import type { TargetDescriptor } from "../domains/providers/types/target-descriptor.js";
32
+ import { registerClioOAuthProviders } from "../engine/oauth.js";
33
+ import { ask, askYesNo } from "./ask.js";
34
+ import { runInteropReview } from "./configure-interop.js";
35
+ import {
36
+ type ConfigureCategory,
37
+ formatCategoryMenu,
38
+ formatRuntimeList,
39
+ formatRuntimeMenu,
40
+ matchCategoryChoice,
41
+ type RuntimeListRow,
42
+ } from "./configure-layout.js";
43
+ import { createDelayedManualCodeInput } from "./oauth-manual-input.js";
44
+ import { promptOAuthSelection } from "./oauth-select.js";
45
+ import { credentialWriteFailed, printError, printOk, printPlaintextCredentialWarning } from "./shared.js";
46
+ import { terminalColumns, wrapPlain } from "./text-layout.js";
47
+ import { validateModelChoice } from "./validate-model.js";
48
+
49
+ const HELP = `clio-coder configure
50
+
51
+ Configure model targets for chat and fleet-agent dispatch.
52
+
53
+ Usage:
54
+ clio-coder configure interactive wizard
55
+ clio-coder configure --interop review detected coding agents as delegation peers
56
+ clio-coder configure --list list target runtimes (user-facing only)
57
+ clio-coder configure --list --all list every registered runtime including aliases
58
+ clio-coder configure --id <targetId> [flags] --runtime <runtimeId>
59
+
60
+ Non-interactive flags:
61
+ --id <targetId> target id to register (required when non-interactive)
62
+ --runtime <runtimeId> runtime to use when registering non-interactively
63
+ --url <host> target base URL (http(s):// or ws://)
64
+ --model <wireModelId> default model id for this target
65
+ --orchestrator-model <id> model to use when setting chat default
66
+ --background-model <id> model to use for proactive task memory
67
+ --fleet-model <id> model to use when setting fleet default
68
+ (mutually exclusive with --agent-profile)
69
+ --agent-profile <name> save this target as a named fleet profile
70
+ --agent-profile-model <id> model to use for --agent-profile
71
+ --api-key-env <VAR> read API key from this env var at call time
72
+ --api-key <literal> store API key in credentials.yaml
73
+ --force allow a model outside the runtime catalog
74
+ --gateway mark the target as a gateway
75
+ --lifecycle <user-managed|clio-managed>
76
+ resident model lifecycle policy
77
+ --set-orchestrator use this target for chat
78
+ --set-background use this target for proactive task memory
79
+ --set-fleet-default use this target for the fleet default
80
+ --context-window <N> capability override
81
+ --max-tokens <N> output token capability override
82
+ --reasoning <true|false> capability override
83
+ `;
84
+
85
+ const DEFAULT_PORTS: Record<string, number> = {
86
+ llamacpp: 8080,
87
+ "llamacpp-anthropic": 8080,
88
+ "llamacpp-completion": 8080,
89
+ "llamacpp-embed": 8080,
90
+ "llamacpp-rerank": 8080,
91
+ "lmstudio-native": 1234,
92
+ lmstudio: 1234,
93
+ "ollama-native": 11434,
94
+ vllm: 8000,
95
+ sglang: 30000,
96
+ "lemonade-anthropic": 8000,
97
+ lemonade: 8000,
98
+ "anthropic-compat": 8000,
99
+ "openai-compat": 8000,
100
+ };
101
+
102
+ interface ParsedArgs {
103
+ positional: string[];
104
+ help: boolean;
105
+ list: boolean;
106
+ all: boolean;
107
+ interop: boolean;
108
+ remove?: string;
109
+ renameOld?: string;
110
+ renameNew?: string;
111
+ id?: string;
112
+ runtime?: string;
113
+ url?: string;
114
+ model?: string;
115
+ orchestratorModel?: string;
116
+ backgroundModel?: string;
117
+ workerModel?: string;
118
+ workerProfile?: string;
119
+ workerProfileModel?: string;
120
+ apiKeyEnv?: string;
121
+ apiKey?: string;
122
+ force: boolean;
123
+ gateway: boolean;
124
+ lifecycle?: TargetDescriptor["lifecycle"];
125
+ setOrchestrator: boolean;
126
+ setBackground: boolean;
127
+ setWorkerDefault: boolean;
128
+ contextWindow?: number;
129
+ maxTokens?: number;
130
+ reasoning?: boolean;
131
+ }
132
+
133
+ function parseSetupArgs(argv: ReadonlyArray<string>): ParsedArgs {
134
+ const out: ParsedArgs = {
135
+ positional: [],
136
+ help: false,
137
+ list: false,
138
+ all: false,
139
+ interop: false,
140
+ force: false,
141
+ gateway: false,
142
+ setOrchestrator: false,
143
+ setBackground: false,
144
+ setWorkerDefault: false,
145
+ };
146
+ for (let i = 0; i < argv.length; i++) {
147
+ const a = argv[i] as string;
148
+ const need = (): string => {
149
+ const v = argv[i + 1];
150
+ if (v === undefined) throw new Error(`${a} requires a value`);
151
+ i += 1;
152
+ return v;
153
+ };
154
+ switch (a) {
155
+ case "--help":
156
+ case "-h":
157
+ out.help = true;
158
+ break;
159
+ case "--list":
160
+ out.list = true;
161
+ break;
162
+ case "--all":
163
+ out.all = true;
164
+ break;
165
+ case "--interop":
166
+ out.interop = true;
167
+ break;
168
+ case "--remove":
169
+ out.remove = need();
170
+ break;
171
+ case "--rename":
172
+ out.renameOld = need();
173
+ out.renameNew = need();
174
+ break;
175
+ case "--id":
176
+ out.id = need();
177
+ break;
178
+ case "--runtime":
179
+ out.runtime = need();
180
+ break;
181
+ case "--url":
182
+ out.url = need();
183
+ break;
184
+ case "--model":
185
+ out.model = need();
186
+ break;
187
+ case "--orchestrator-model":
188
+ out.orchestratorModel = need();
189
+ break;
190
+ case "--background-model":
191
+ out.backgroundModel = need();
192
+ break;
193
+ case "--fleet-model":
194
+ case "--worker-model":
195
+ out.workerModel = need();
196
+ break;
197
+ case "--agent-profile":
198
+ case "--worker-profile":
199
+ out.workerProfile = need();
200
+ break;
201
+ case "--agent-profile-model":
202
+ case "--worker-profile-model":
203
+ out.workerProfileModel = need();
204
+ break;
205
+ case "--api-key-env":
206
+ out.apiKeyEnv = need();
207
+ break;
208
+ case "--api-key":
209
+ out.apiKey = need();
210
+ break;
211
+ case "--force":
212
+ out.force = true;
213
+ break;
214
+ case "--gateway":
215
+ out.gateway = true;
216
+ break;
217
+ case "--lifecycle": {
218
+ const v = need();
219
+ if (v !== "user-managed" && v !== "clio-managed") {
220
+ throw new Error("--lifecycle must be user-managed or clio-managed");
221
+ }
222
+ out.lifecycle = v;
223
+ break;
224
+ }
225
+ case "--set-orchestrator":
226
+ out.setOrchestrator = true;
227
+ break;
228
+ case "--set-background":
229
+ out.setBackground = true;
230
+ break;
231
+ case "--set-fleet-default":
232
+ case "--set-worker-default":
233
+ out.setWorkerDefault = true;
234
+ break;
235
+ case "--context-window": {
236
+ const n = Number(need());
237
+ if (!Number.isFinite(n) || n <= 0) throw new Error("--context-window must be a positive number");
238
+ out.contextWindow = Math.floor(n);
239
+ break;
240
+ }
241
+ case "--max-tokens": {
242
+ const n = Number(need());
243
+ if (!Number.isFinite(n) || n <= 0) throw new Error("--max-tokens must be a positive number");
244
+ out.maxTokens = Math.floor(n);
245
+ break;
246
+ }
247
+ case "--reasoning": {
248
+ const v = need().toLowerCase();
249
+ if (v !== "true" && v !== "false") throw new Error("--reasoning must be true or false");
250
+ out.reasoning = v === "true";
251
+ break;
252
+ }
253
+ default:
254
+ if (a.startsWith("-")) throw new Error(`unknown flag: ${a}`);
255
+ out.positional.push(a);
256
+ }
257
+ }
258
+ return out;
259
+ }
260
+
261
+ function ensureRegistryPopulated(): void {
262
+ registerClioOAuthProviders();
263
+ const registry = getRuntimeRegistry();
264
+ if (registry.list().length === 0) registerBuiltinRuntimes(registry);
265
+ }
266
+
267
+ function trimTrailing(url: string): string {
268
+ return url.endsWith("/") && url.length > 1 ? url.slice(0, -1) : url;
269
+ }
270
+
271
+ function normalizeUrl(input: string, runtimeId: string): string {
272
+ const trimmed = input.trim();
273
+ if (trimmed.length === 0) return defaultUrlFor(runtimeId);
274
+ const hasScheme = /^[a-z][a-z0-9+.-]*:\/\//i.test(trimmed);
275
+ let withScheme = hasScheme ? trimmed : `http://${trimmed}`;
276
+ if (runtimeId === "lmstudio") withScheme = withScheme.replace(/^ws:/u, "http:").replace(/^wss:/u, "https:");
277
+ try {
278
+ const parsed = new URL(withScheme);
279
+ if (!hasScheme && !parsed.port && DEFAULT_PORTS[runtimeId]) {
280
+ parsed.port = String(DEFAULT_PORTS[runtimeId]);
281
+ }
282
+ return trimTrailing(parsed.toString());
283
+ } catch {
284
+ return trimTrailing(withScheme);
285
+ }
286
+ }
287
+
288
+ function defaultUrlFor(runtimeId: string): string {
289
+ const port = DEFAULT_PORTS[runtimeId];
290
+ return port ? `http://127.0.0.1:${port}` : "http://127.0.0.1:8080";
291
+ }
292
+
293
+ const RUNTIME_LIST_CAPTION =
294
+ "every registered runtime. run `clio-coder auth list` for the ones clio authenticates itself; the rest authenticate through their own tool (claude-cli, aws-sdk) or need no credential.";
295
+
296
+ function printRuntimeList(includeHidden: boolean): void {
297
+ const settings = readSettings();
298
+ const auth = openAuthStorage();
299
+ const rows: RuntimeListRow[] = [];
300
+ for (const entry of listProviderSupportEntries(getRuntimeRegistry().list(), { includeHidden })) {
301
+ const runtime = getRuntimeRegistry().get(entry.runtimeId);
302
+ const status =
303
+ runtime && entry.connectable
304
+ ? auth.statusForTarget(resolveRuntimeAuthTarget(runtime), { includeFallback: false })
305
+ : null;
306
+ const authLabel =
307
+ runtime?.auth === "oauth"
308
+ ? status?.available
309
+ ? "connected"
310
+ : "login"
311
+ : runtime?.auth === "api-key"
312
+ ? status?.available
313
+ ? "credential"
314
+ : "needs-key"
315
+ : (runtime?.auth ?? "none");
316
+ rows.push({
317
+ group: supportGroupLabel(entry.group),
318
+ runtimeId: entry.runtimeId,
319
+ label: entry.label,
320
+ auth: authLabel,
321
+ targets: configuredTargetsForRuntime(settings, entry.runtimeId).length,
322
+ models: describeRuntimeModels(entry, 2),
323
+ });
324
+ }
325
+ const width = terminalColumns();
326
+ for (const line of formatRuntimeList(rows, width)) {
327
+ process.stdout.write(`${line}\n`);
328
+ }
329
+ // The other half of the pair `clio-coder auth list` names. This table is every
330
+ // registered runtime; that one is the subset Clio holds a credential for,
331
+ // and a user who found a name here and could not find it there was reading
332
+ // two screens that each claimed to be the list of what you can connect.
333
+ for (const line of wrapPlain(RUNTIME_LIST_CAPTION, width)) {
334
+ process.stdout.write(`${line}\n`);
335
+ }
336
+ }
337
+
338
+ function deriveTargetId(runtimeId: string, existing: ReadonlyArray<TargetDescriptor>): string {
339
+ const base = runtimeId;
340
+ const taken = new Set(existing.map((e) => e.id));
341
+ if (!taken.has(base)) return base;
342
+ for (let i = 2; i < 1000; i++) {
343
+ const candidate = `${base}-${i}`;
344
+ if (!taken.has(candidate)) return candidate;
345
+ }
346
+ return `${base}-${Date.now()}`;
347
+ }
348
+
349
+ async function buildProbeContext(runtime?: RuntimeDescriptor, target?: TargetDescriptor): Promise<ProbeContext> {
350
+ const probeCtx: ProbeContext = {
351
+ credentialsPresent: credentialsPresent(),
352
+ httpTimeoutMs: 5000,
353
+ };
354
+ if (!runtime || !target || !targetRequiresAuth(target, runtime)) return probeCtx;
355
+ try {
356
+ const resolution = await openAuthStorage().resolveForTarget(resolveAuthTarget(target, runtime), {
357
+ includeFallback: false,
358
+ });
359
+ if (resolution.apiKey) probeCtx.authToken = resolution.apiKey;
360
+ } catch {
361
+ // Let the runtime's probe report its own missing-auth diagnostic.
362
+ }
363
+ return probeCtx;
364
+ }
365
+
366
+ function runtimeKnownModelsFor(runtimeId: string): ReadonlyArray<string> {
367
+ return listKnownModelsForRuntime(runtimeId);
368
+ }
369
+
370
+ function catalogContextWindowFor(runtime: RuntimeDescriptor, modelId: string): number | null {
371
+ const catalogModel = getCatalogModelForRuntime(runtime.id, modelId);
372
+ if (typeof catalogModel?.contextWindow === "number" && catalogModel.contextWindow > 0) {
373
+ return catalogModel.contextWindow;
374
+ }
375
+ if (runtimeKnownModelsFor(runtime.id).includes(modelId) && runtime.defaultCapabilities.contextWindow > 0) {
376
+ return runtime.defaultCapabilities.contextWindow;
377
+ }
378
+ return null;
379
+ }
380
+
381
+ function validateResolvedModel(runtimeId: string, modelId: string | undefined, force: boolean): boolean {
382
+ if (!modelId) return true;
383
+ const validation = validateModelChoice({
384
+ runtimeId,
385
+ modelId,
386
+ knownModels: runtimeKnownModelsFor(runtimeId),
387
+ force,
388
+ });
389
+ if (!validation.ok) {
390
+ process.stderr.write(`error: ${validation.reason}\n`);
391
+ return false;
392
+ }
393
+ if (validation.warning) process.stderr.write(`warning: ${validation.warning}\n`);
394
+ return true;
395
+ }
396
+
397
+ function validateContextWindowOverride(
398
+ runtime: RuntimeDescriptor,
399
+ modelId: string | undefined,
400
+ contextWindow: number | undefined,
401
+ force: boolean,
402
+ ): boolean {
403
+ if (contextWindow === undefined || !modelId) return true;
404
+ const catalogMax = catalogContextWindowFor(runtime, modelId);
405
+ if (catalogMax === null || contextWindow <= catalogMax) return true;
406
+ const message = `--context-window ${contextWindow} exceeds catalog max ${catalogMax} for model '${modelId}'`;
407
+ if (!force) {
408
+ process.stderr.write(`error: ${message}. Use --force to override.\n`);
409
+ return false;
410
+ }
411
+ process.stderr.write(`warning: ${message}\n`);
412
+ return true;
413
+ }
414
+
415
+ async function runtimeProbe(runtime: RuntimeDescriptor, target: TargetDescriptor): Promise<ProbeResult | null> {
416
+ if (typeof runtime.probe !== "function") return null;
417
+ try {
418
+ return await runtime.probe(target, await buildProbeContext(runtime, target));
419
+ } catch (err) {
420
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
421
+ }
422
+ }
423
+
424
+ async function runtimeProbeModels(
425
+ runtime: RuntimeDescriptor,
426
+ target: TargetDescriptor,
427
+ authToken?: string,
428
+ ): Promise<string[]> {
429
+ if (typeof runtime.probeModels !== "function") return [];
430
+ try {
431
+ const context = await buildProbeContext(runtime, target);
432
+ return await runtime.probeModels(target, authToken === undefined ? context : { ...context, authToken });
433
+ } catch {
434
+ return [];
435
+ }
436
+ }
437
+
438
+ function applyTarget(settings: ClioSettings, descriptor: TargetDescriptor): void {
439
+ const idx = settings.targets.findIndex((e) => e.id === descriptor.id);
440
+ if (idx >= 0) settings.targets[idx] = descriptor;
441
+ else settings.targets.push(descriptor);
442
+ }
443
+
444
+ function setOrchestratorPointer(settings: ClioSettings, descriptor: TargetDescriptor, model?: string | null): void {
445
+ const runtime = getRuntimeRegistry().get(descriptor.runtime);
446
+ if (!runtime) {
447
+ throw new Error(
448
+ `cannot use target '${descriptor.id}' as orchestrator target because runtime '${descriptor.runtime}' is not registered`,
449
+ );
450
+ }
451
+ if (!isOrchestratorEligibleRuntime(runtime)) {
452
+ throw new Error(
453
+ `cannot use target '${descriptor.id}' as orchestrator target because runtime '${runtime.id}' is not an HTTP/native runtime`,
454
+ );
455
+ }
456
+ settings.orchestrator.target = descriptor.id;
457
+ settings.orchestrator.model = model ?? descriptor.defaultModel ?? null;
458
+ }
459
+
460
+ function setWorkerDefaultPointer(settings: ClioSettings, descriptor: TargetDescriptor, model?: string | null): void {
461
+ settings.workers.default.target = descriptor.id;
462
+ settings.workers.default.model = model ?? descriptor.defaultModel ?? null;
463
+ }
464
+
465
+ function setBackgroundPointer(settings: ClioSettings, descriptor: TargetDescriptor, model?: string | null): void {
466
+ const runtime = getRuntimeRegistry().get(descriptor.runtime);
467
+ if (!runtime || !isOrchestratorEligibleRuntime(runtime)) {
468
+ throw new Error(
469
+ `cannot use target '${descriptor.id}' as background target because runtime '${descriptor.runtime}' is not an HTTP/native runtime`,
470
+ );
471
+ }
472
+ settings.background.target = descriptor.id;
473
+ settings.background.model = model ?? descriptor.defaultModel ?? null;
474
+ }
475
+
476
+ function assertOrchestratorReplacementEligible(settings: ClioSettings, descriptor: TargetDescriptor): void {
477
+ if (settings.orchestrator.target !== descriptor.id && settings.background.target !== descriptor.id) return;
478
+ const role = settings.orchestrator.target === descriptor.id ? "orchestrator" : "background";
479
+ const runtime = getRuntimeRegistry().get(descriptor.runtime);
480
+ if (!runtime) {
481
+ throw new Error(
482
+ `cannot update ${role} target '${descriptor.id}' because runtime '${descriptor.runtime}' is not registered`,
483
+ );
484
+ }
485
+ if (!isOrchestratorEligibleRuntime(runtime)) {
486
+ throw new Error(`cannot update ${role} target '${descriptor.id}' to non-HTTP/native runtime '${runtime.id}'`);
487
+ }
488
+ }
489
+
490
+ function setWorkerProfilePointer(
491
+ settings: ClioSettings,
492
+ name: string,
493
+ descriptor: TargetDescriptor,
494
+ model?: string | null,
495
+ ): void {
496
+ const trimmed = name.trim();
497
+ if (trimmed.length === 0) throw new Error("fleet profile name must be non-empty");
498
+ settings.workers.profiles[trimmed] = {
499
+ target: descriptor.id,
500
+ model: model ?? descriptor.defaultModel ?? null,
501
+ thinkingLevel: "off",
502
+ };
503
+ }
504
+
505
+ /**
506
+ * A target that was probed successfully and still reported no context window
507
+ * will run against the runtime descriptor's placeholder. Say so at the moment
508
+ * the target is written, because the alternative is a plausible-looking number
509
+ * the operator never chose and the server never claimed.
510
+ */
511
+ function warnUndiscoveredContextWindow(descriptor: TargetDescriptor, probe: ProbeResult | null): void {
512
+ if (!probe?.ok) return;
513
+ if (typeof descriptor.capabilities?.contextWindow === "number" && descriptor.capabilities.contextWindow > 0) return;
514
+ const discovered = probeCapabilitiesForModel(
515
+ {
516
+ target: descriptor,
517
+ probeCapabilities: probe.discoveredCapabilities ?? null,
518
+ probeModelCapabilities: probe.modelCapabilities ?? null,
519
+ probeModelId: probe.capabilityModelId ?? null,
520
+ },
521
+ descriptor.defaultModel,
522
+ );
523
+ if (typeof discovered?.contextWindow === "number" && discovered.contextWindow > 0) return;
524
+ process.stdout.write(
525
+ " warning: the target reported no context window; Clio will use the runtime default as a guess. Set one with --context-window.\n",
526
+ );
527
+ }
528
+
529
+ /**
530
+ * What the probe read, as opposed to whether it connected.
531
+ *
532
+ * A health check can pass while every enrichment read behind it returns
533
+ * nothing, and reporting that as `probe ok` makes it indistinguishable from a
534
+ * full read. That is how a target gets blessed at configure time and then
535
+ * fails on the first turn. Naming the gap is the difference between a user who
536
+ * knows to look now and one who finds out from a raw 404 later.
537
+ */
538
+ function probeReadings(probe: ProbeResult): string[] {
539
+ const readings: string[] = [];
540
+ if (probe.models && probe.models.length > 0) readings.push(`${probe.models.length} models`);
541
+ if (probe.serverVersion) readings.push(probe.serverVersion);
542
+ if (probe.discoveredCapabilities && Object.keys(probe.discoveredCapabilities).length > 0) {
543
+ readings.push("capabilities");
544
+ }
545
+ return readings;
546
+ }
547
+
548
+ /** The probe result as the lines a user reads, cause and next step included. */
549
+ function probeLines(descriptor: TargetDescriptor, probe: ProbeResult): string[] {
550
+ const latency = probe.latencyMs !== undefined ? ` (${probe.latencyMs}ms)` : "";
551
+ if (!probe.ok) {
552
+ const where = descriptor.url ? ` ${descriptor.url}` : "";
553
+ return [
554
+ `probe failed${latency}:${where} ${probe.error ?? "unknown"}`,
555
+ ` check the server is running and reachable, then re-run: clio-coder configure --id ${descriptor.id} --url <url>`,
556
+ ];
557
+ }
558
+ const readings = probeReadings(probe);
559
+ if (readings.length > 0) return [`probe ok${latency} ${readings.join(", ")}`];
560
+ return [
561
+ `probe reachable${latency}, but the target answered no model list and no version`,
562
+ " Clio cannot verify the model id or the context window from here and will send both as written.",
563
+ " re-read them once the server serves them with: clio-coder targets --probe",
564
+ ];
565
+ }
566
+
567
+ function printSummary(settings: ClioSettings, descriptor: TargetDescriptor, probe: ProbeResult | null): void {
568
+ process.stdout.write(`\nsaved target ${descriptor.id} (runtime=${descriptor.runtime})\n`);
569
+ if (descriptor.url) process.stdout.write(` url ${descriptor.url}\n`);
570
+ if (descriptor.defaultModel) process.stdout.write(` model ${descriptor.defaultModel}\n`);
571
+ if (descriptor.auth?.apiKeyEnvVar) process.stdout.write(` apiKeyEnv ${descriptor.auth.apiKeyEnvVar}\n`);
572
+ if (descriptor.gateway) process.stdout.write(" gateway true\n");
573
+ if (descriptor.lifecycle) process.stdout.write(` lifecycle ${descriptor.lifecycle}\n`);
574
+ if (probe) {
575
+ for (const line of probeLines(descriptor, probe)) process.stdout.write(` ${line}\n`);
576
+ }
577
+ warnUndiscoveredContextWindow(descriptor, probe);
578
+ if (settings.orchestrator.target === descriptor.id) process.stdout.write(" orchestrator target\n");
579
+ if (settings.background.target === descriptor.id) process.stdout.write(" background memory target\n");
580
+ if (settings.workers.default.target === descriptor.id) process.stdout.write(" fleet default\n");
581
+ for (const [name, profile] of Object.entries(settings.workers.profiles)) {
582
+ if (profile.target === descriptor.id) process.stdout.write(` fleet profile ${name}\n`);
583
+ }
584
+ process.stdout.write(`\nsettings written to ${settingsPath()}\n`);
585
+ }
586
+
587
+ function buildDescriptor(
588
+ runtime: RuntimeDescriptor,
589
+ id: string,
590
+ parts: {
591
+ url?: string;
592
+ model?: string;
593
+ wireModels?: string[];
594
+ apiKeyEnv?: string;
595
+ apiKeyRef?: string;
596
+ oauthProfile?: string;
597
+ gateway?: boolean;
598
+ lifecycle?: TargetDescriptor["lifecycle"];
599
+ contextWindow?: number;
600
+ maxTokens?: number;
601
+ reasoning?: boolean;
602
+ lmstudio?: TargetDescriptor["lmstudio"];
603
+ },
604
+ ): TargetDescriptor {
605
+ const descriptor: TargetDescriptor = { id, runtime: runtime.id };
606
+ if (parts.url) descriptor.url = parts.url;
607
+ const wireModels =
608
+ parts.wireModels?.filter((value, index, all) => value.trim().length > 0 && all.indexOf(value) === index) ?? [];
609
+ if (parts.model) descriptor.defaultModel = parts.model;
610
+ else {
611
+ const firstWireModel = wireModels[0];
612
+ if (firstWireModel) descriptor.defaultModel = firstWireModel;
613
+ }
614
+ const auth: NonNullable<TargetDescriptor["auth"]> = {};
615
+ if (parts.apiKeyEnv) auth.apiKeyEnvVar = parts.apiKeyEnv;
616
+ if (parts.apiKeyRef) auth.apiKeyRef = parts.apiKeyRef;
617
+ if (parts.oauthProfile) auth.oauthProfile = parts.oauthProfile;
618
+ if (Object.keys(auth).length > 0) descriptor.auth = auth;
619
+ if (wireModels.length > 0) descriptor.wireModels = wireModels;
620
+ if (parts.gateway) descriptor.gateway = true;
621
+ if (parts.lifecycle) descriptor.lifecycle = parts.lifecycle;
622
+ const caps: NonNullable<TargetDescriptor["capabilities"]> = {};
623
+ if (parts.contextWindow !== undefined) caps.contextWindow = parts.contextWindow;
624
+ if (parts.maxTokens !== undefined) caps.maxTokens = parts.maxTokens;
625
+ if (parts.reasoning !== undefined) caps.reasoning = parts.reasoning;
626
+ if (Object.keys(caps).length > 0) descriptor.capabilities = caps;
627
+ if (parts.lmstudio) descriptor.lmstudio = parts.lmstudio;
628
+ return descriptor;
629
+ }
630
+
631
+ function describeAuthStatus(runtime: RuntimeDescriptor): string {
632
+ const status = openAuthStorage().statusForTarget(resolveRuntimeAuthTarget(runtime), { includeFallback: false });
633
+ // This describes a credential, not a network state. It is printed before the
634
+ // wizard has asked for a URL, so `not connected` read as a connection that
635
+ // had already been tried and failed.
636
+ if (!status.available) return "none stored";
637
+ if (status.source === "environment") return `environment${status.detail ? ` (${status.detail})` : ""}`;
638
+ if (status.source === "stored-api-key") return "stored api key";
639
+ if (status.source === "stored-oauth") return "stored oauth";
640
+ return status.source;
641
+ }
642
+
643
+ async function loginOAuthRuntime(rl: ReturnType<typeof createInterface>, runtime: RuntimeDescriptor): Promise<boolean> {
644
+ const auth = openAuthStorage();
645
+ if (runtime.authNotice) process.stdout.write(`note: ${runtime.authNotice}\n`);
646
+ const manualCodeInput = createDelayedManualCodeInput(
647
+ rl,
648
+ "Paste verification code if browser callback does not complete automatically: ",
649
+ );
650
+ try {
651
+ await auth.login(runtime.oauthProviderId ?? runtime.id, {
652
+ onAuth: ({ url, instructions }) => {
653
+ process.stdout.write(`\nOpen: ${url}\n`);
654
+ if (instructions) process.stdout.write(`${instructions}\n`);
655
+ process.stdout.write("Waiting for the browser callback. A manual code prompt will appear if needed.\n");
656
+ },
657
+ onDeviceCode: ({ verificationUri, userCode }) => {
658
+ process.stdout.write(`\nOpen: ${verificationUri}\n`);
659
+ process.stdout.write(`Enter code: ${userCode}\n`);
660
+ },
661
+ onPrompt: async (prompt) => {
662
+ const answer = await rl.question(`${prompt.message}${prompt.allowEmpty ? " " : ": "}`);
663
+ return prompt.allowEmpty ? answer : answer.trim();
664
+ },
665
+ onSelect: (prompt) => promptOAuthSelection(rl, prompt),
666
+ onManualCodeInput: manualCodeInput.onManualCodeInput,
667
+ onProgress: (message) => {
668
+ process.stderr.write(`${message}\n`);
669
+ },
670
+ });
671
+ if (credentialWriteFailed(auth, `credential for ${runtime.id} was not stored`)) return false;
672
+ printOk(`authenticated ${runtime.id}`);
673
+ return true;
674
+ } catch (error) {
675
+ printError(error instanceof Error ? error.message : String(error));
676
+ return false;
677
+ } finally {
678
+ manualCodeInput.cancel();
679
+ }
680
+ }
681
+
682
+ async function resolveSupportedWireModels(
683
+ runtime: RuntimeDescriptor,
684
+ target: TargetDescriptor,
685
+ existing?: TargetDescriptor,
686
+ authToken?: string,
687
+ ): Promise<string[]> {
688
+ const known = listKnownModelsForRuntime(runtime.id);
689
+ if (known.length > 0) return known;
690
+ const discovered = runtime.kind === "http" ? await runtimeProbeModels(runtime, target, authToken) : [];
691
+ if (discovered.length > 0) return discovered;
692
+ return existing?.wireModels ? [...existing.wireModels] : [];
693
+ }
694
+
695
+ function resolveModelChoice(
696
+ answer: string,
697
+ wireModels: ReadonlyArray<string>,
698
+ defaultValue: string | undefined,
699
+ ): string | undefined {
700
+ if (answer.length === 0) return defaultValue;
701
+ const numeric = Number(answer);
702
+ if (Number.isInteger(numeric) && numeric >= 1 && numeric <= wireModels.length) {
703
+ return wireModels[numeric - 1];
704
+ }
705
+ return answer;
706
+ }
707
+
708
+ async function askModelChoice(
709
+ rl: ReturnType<typeof createInterface>,
710
+ label: string,
711
+ wireModels: ReadonlyArray<string>,
712
+ defaultValue: string | undefined,
713
+ ): Promise<string | null> {
714
+ const answer = await ask(rl, `${label} (number or id)`, defaultValue ?? "");
715
+ if (answer === null) return null;
716
+ return resolveModelChoice(answer, wireModels, defaultValue) ?? "";
717
+ }
718
+
719
+ /**
720
+ * A catalog-ordered list has no head worth persisting: openai's first of 38 ids
721
+ * is `gpt-4` because g sorts early, and a target configured without --model
722
+ * used to carry it as the model the operator chose.
723
+ */
724
+ function refuseCatalogSeededModel(runtime: RuntimeDescriptor, support: ProviderSupportEntry): void {
725
+ printError(
726
+ `--model is required for ${runtime.id}: its ${support.modelHints.length} model ids come from the provider catalog in name order, which recommends none of them`,
727
+ );
728
+ process.stderr.write(
729
+ ` run \`clio-coder configure --runtime ${runtime.id}\` with no other flags to choose from the full list\n`,
730
+ );
731
+ }
732
+
733
+ async function runNonInteractive(runtime: RuntimeDescriptor, args: ParsedArgs): Promise<number> {
734
+ if (!args.id) {
735
+ printError("--id is required when passing flags non-interactively");
736
+ return 2;
737
+ }
738
+ if (args.workerProfileModel !== undefined && args.workerProfile === undefined) {
739
+ printError("--agent-profile-model requires --agent-profile");
740
+ return 2;
741
+ }
742
+ if (args.workerProfile !== undefined && args.workerProfile.trim().length === 0) {
743
+ printError("--agent-profile must be non-empty");
744
+ return 2;
745
+ }
746
+ if (args.workerProfile !== undefined && args.workerModel !== undefined) {
747
+ printError(
748
+ "--fleet-model and --agent-profile conflict; use --agent-profile-model for the profile, or drop --agent-profile to set the fleet default",
749
+ );
750
+ return 2;
751
+ }
752
+ const settings = readSettings();
753
+ const auth = openAuthStorage();
754
+ const support = buildProviderSupportEntry(runtime);
755
+ const existing = settings.targets.find((e) => e.id === args.id);
756
+ if (existing && (getRuntimeRegistry().get(existing.runtime)?.id ?? existing.runtime) !== runtime.id) {
757
+ printError(`target ${args.id} already exists with runtime ${existing.runtime}`);
758
+ return 2;
759
+ }
760
+ let url: string | undefined = args.url ? normalizeUrl(args.url, runtime.id) : existing?.url;
761
+ if (!url && support.supportsCustomUrl) {
762
+ url = defaultUrlFor(runtime.id);
763
+ }
764
+ if (url && runtime.id === "lmstudio") {
765
+ const greeting = await greetLmStudio(
766
+ { id: args.id, runtime: runtime.id, url },
767
+ { credentialsPresent: new Set(), httpTimeoutMs: 750 },
768
+ );
769
+ if (!greeting.ok) {
770
+ printError(`refusing to save LM Studio target '${args.id}': ${url} did not return the LM Studio greeting`);
771
+ return 2;
772
+ }
773
+ }
774
+ if (url && (runtime.id === "openai-compat" || runtime.id === "anthropic-compat")) {
775
+ const fingerprint = await fingerprintNativeRuntime(url);
776
+ if (fingerprint) {
777
+ process.stdout.write(
778
+ `note: detected ${fingerprint.displayName} at ${url}; consider \`clio-coder targets convert ${args.id} --runtime ${fingerprint.runtimeId}\` for proper resident-model lifecycle\n`,
779
+ );
780
+ }
781
+ }
782
+ const authStatus = auth.statusForTarget(resolveRuntimeAuthTarget(runtime), { includeFallback: false });
783
+ const apiKeyEnv = args.apiKeyEnv ?? existing?.auth?.apiKeyEnvVar;
784
+ const apiKeyRef =
785
+ runtime.auth === "api-key" && (args.apiKey || existing?.auth?.apiKeyRef || authStatus.source === "stored-api-key")
786
+ ? runtime.id
787
+ : undefined;
788
+ const oauthProfile =
789
+ runtime.auth === "oauth" ? (existing?.auth?.oauthProfile ?? runtime.oauthProviderId ?? runtime.id) : undefined;
790
+ const seed = buildDescriptor(runtime, args.id, {
791
+ ...(url !== undefined ? { url } : {}),
792
+ ...(args.model !== undefined
793
+ ? { model: args.model }
794
+ : existing?.defaultModel
795
+ ? { model: existing.defaultModel }
796
+ : support.defaultModel
797
+ ? { model: support.defaultModel }
798
+ : {}),
799
+ ...(apiKeyEnv !== undefined ? { apiKeyEnv } : {}),
800
+ ...(apiKeyRef !== undefined ? { apiKeyRef } : {}),
801
+ ...(oauthProfile !== undefined ? { oauthProfile } : {}),
802
+ gateway: args.gateway || existing?.gateway === true,
803
+ ...(args.lifecycle !== undefined
804
+ ? { lifecycle: args.lifecycle }
805
+ : existing?.lifecycle !== undefined
806
+ ? { lifecycle: existing.lifecycle }
807
+ : {}),
808
+ ...(args.contextWindow !== undefined ? { contextWindow: args.contextWindow } : {}),
809
+ ...(args.maxTokens !== undefined ? { maxTokens: args.maxTokens } : {}),
810
+ ...(args.reasoning !== undefined ? { reasoning: args.reasoning } : {}),
811
+ ...(existing?.lmstudio ? { lmstudio: existing.lmstudio } : {}),
812
+ });
813
+ const wireModels = await resolveSupportedWireModels(runtime, seed, existing, args.apiKey);
814
+ const model =
815
+ args.model ??
816
+ existing?.defaultModel ??
817
+ support.defaultModel ??
818
+ (support.modelSource === "catalog" ? undefined : wireModels[0]);
819
+ if (model === undefined && support.modelSource === "catalog") {
820
+ refuseCatalogSeededModel(runtime, support);
821
+ return 2;
822
+ }
823
+ if (!validateResolvedModel(runtime.id, model, args.force)) return 2;
824
+ if (!validateContextWindowOverride(runtime, model, args.contextWindow, args.force)) return 2;
825
+ const descriptor = buildDescriptor(runtime, args.id, {
826
+ ...(url !== undefined ? { url } : {}),
827
+ ...(model ? { model } : {}),
828
+ ...(wireModels.length > 0 ? { wireModels } : {}),
829
+ ...(apiKeyEnv !== undefined ? { apiKeyEnv } : {}),
830
+ ...(apiKeyRef !== undefined ? { apiKeyRef } : {}),
831
+ ...(oauthProfile !== undefined ? { oauthProfile } : {}),
832
+ gateway: args.gateway || existing?.gateway === true,
833
+ ...(args.lifecycle !== undefined
834
+ ? { lifecycle: args.lifecycle }
835
+ : existing?.lifecycle !== undefined
836
+ ? { lifecycle: existing.lifecycle }
837
+ : {}),
838
+ ...(args.contextWindow !== undefined ? { contextWindow: args.contextWindow } : {}),
839
+ ...(args.maxTokens !== undefined ? { maxTokens: args.maxTokens } : {}),
840
+ ...(args.reasoning !== undefined ? { reasoning: args.reasoning } : {}),
841
+ ...(existing?.lmstudio ? { lmstudio: existing.lmstudio } : {}),
842
+ });
843
+ const setOrchestrator = args.setOrchestrator || args.orchestratorModel !== undefined;
844
+ const setBackground = args.setBackground || args.backgroundModel !== undefined;
845
+ if ((setOrchestrator || setBackground) && !isOrchestratorEligibleRuntime(runtime)) {
846
+ printError(
847
+ `cannot use target '${descriptor.id}' as a chat or background target because runtime '${runtime.id}' is not an HTTP/native runtime`,
848
+ );
849
+ return 1;
850
+ }
851
+ try {
852
+ assertOrchestratorReplacementEligible(settings, descriptor);
853
+ } catch (error) {
854
+ printError(error instanceof Error ? error.message : String(error));
855
+ return 1;
856
+ }
857
+ if (args.apiKey) {
858
+ auth.setApiKey(runtime.id, args.apiKey);
859
+ // Bailing here leaves nothing half-done: settings are not touched until
860
+ // applyConfiguration below, so a refused credential write means the whole
861
+ // command changed nothing, which is what the non-zero exit now claims.
862
+ if (credentialWriteFailed(auth, `credential for ${runtime.id} was not stored; target '${descriptor.id}' not saved`))
863
+ return 1;
864
+ printPlaintextCredentialWarning();
865
+ }
866
+ const setWorkerDefault = args.setWorkerDefault || (args.workerProfile === undefined && args.workerModel !== undefined);
867
+ const applyConfiguration = (target: ClioSettings): void => {
868
+ applyTarget(target, descriptor);
869
+ if (setOrchestrator)
870
+ setOrchestratorPointer(target, descriptor, args.orchestratorModel ?? descriptor.defaultModel ?? null);
871
+ if (setBackground) setBackgroundPointer(target, descriptor, args.backgroundModel ?? descriptor.defaultModel ?? null);
872
+ if (setWorkerDefault)
873
+ setWorkerDefaultPointer(target, descriptor, args.workerModel ?? descriptor.defaultModel ?? null);
874
+ if (args.workerProfile !== undefined) {
875
+ setWorkerProfilePointer(
876
+ target,
877
+ args.workerProfile,
878
+ descriptor,
879
+ args.workerProfileModel ?? descriptor.defaultModel ?? null,
880
+ );
881
+ }
882
+ };
883
+ // Apply to the local snapshot for the summary below, then persist the same
884
+ // mutation against the freshest on-disk state under the settings lock so a
885
+ // concurrent session's field-level write-through is never lost.
886
+ applyConfiguration(settings);
887
+ updateSettings(applyConfiguration);
888
+ const probe = await runtimeProbe(runtime, descriptor);
889
+ printSummary(settings, descriptor, probe);
890
+ if (
891
+ runtime.auth === "oauth" &&
892
+ !auth.statusForTarget(resolveRuntimeAuthTarget(runtime), { includeFallback: false }).available
893
+ ) {
894
+ process.stdout.write(
895
+ `note: authenticate ${runtime.id} with \`clio-coder auth login ${runtime.id}\` before using this target\n`,
896
+ );
897
+ }
898
+ printOk(`target ${args.id} saved`);
899
+ return 0;
900
+ }
901
+
902
+ async function pickRuntime(rl: ReturnType<typeof createInterface>): Promise<RuntimeDescriptor | null> {
903
+ const registry = getRuntimeRegistry();
904
+ const entries = listProviderSupportEntries(registry.list());
905
+ return pickRuntimeFromEntries(rl, entries, "\nSupported runtimes:");
906
+ }
907
+
908
+ async function pickRuntimeFromEntries(
909
+ rl: ReturnType<typeof createInterface>,
910
+ entries: ReadonlyArray<ProviderSupportEntry>,
911
+ heading: string,
912
+ ): Promise<RuntimeDescriptor | null> {
913
+ const registry = getRuntimeRegistry();
914
+ if (entries.length === 0) {
915
+ process.stderr.write("no runtimes available in this category\n");
916
+ return null;
917
+ }
918
+ process.stdout.write(`${heading}\n`);
919
+ const menu = formatRuntimeMenu(
920
+ entries.map((entry) => ({
921
+ group: supportGroupLabel(entry.group),
922
+ runtimeId: entry.runtimeId,
923
+ summary: entry.summary,
924
+ })),
925
+ terminalColumns(),
926
+ );
927
+ for (const line of menu) process.stdout.write(`${line}\n`);
928
+ const allowedIds = new Set(entries.map((entry) => entry.runtimeId));
929
+ // A default here reads as a recommendation, and the only basis this list has
930
+ // for one is the featured flag. Falling back to the first entry made the
931
+ // default whatever sorted first by label, so the bucket that advertises
932
+ // llama.cpp, vLLM, and SGLang offered Antigravity CLI to anyone who pressed
933
+ // Enter. With no featured entry there is no recommendation to make, and Enter
934
+ // asks again rather than choosing on the user's behalf.
935
+ const defaultRuntimeId = entries.find((entry) => entry.featured)?.runtimeId ?? "";
936
+ for (;;) {
937
+ const answer = await ask(rl, "\nSelection (number or runtime id)", defaultRuntimeId);
938
+ if (answer === null) return null;
939
+ if (answer.length === 0) {
940
+ process.stderr.write(`pick a number from 1 to ${entries.length}, or type a runtime id\n`);
941
+ continue;
942
+ }
943
+ const numeric = Number(answer);
944
+ if (Number.isInteger(numeric) && numeric >= 1 && numeric <= entries.length) {
945
+ const picked = entries[numeric - 1];
946
+ if (picked) {
947
+ const runtime = registry.get(picked.runtimeId);
948
+ if (runtime) return runtime;
949
+ }
950
+ }
951
+ if (allowedIds.has(answer)) {
952
+ const match = registry.get(answer);
953
+ if (match) return match;
954
+ }
955
+ process.stderr.write(`unknown runtime id for this category: ${answer}\n`);
956
+ }
957
+ }
958
+
959
+ const LOCAL_APP_RUNTIME_IDS: ReadonlySet<string> = new Set(["ollama-native", "lmstudio"]);
960
+
961
+ // Generic protocol-compatible runtimes. They are classified local-http (they
962
+ // carry a probe and no cloud catalog entry), but a hosted endpoint such as
963
+ // Inception/Mercury is exactly an OpenAI-compatible cloud API, so the wizard
964
+ // also surfaces them under the Cloud API path.
965
+ const PROTOCOL_COMPAT_RUNTIME_IDS: ReadonlySet<string> = new Set(["openai-compat", "anthropic-compat"]);
966
+
967
+ function runtimesForCategory(
968
+ entries: ReadonlyArray<ProviderSupportEntry>,
969
+ category: ConfigureCategory,
970
+ ): ProviderSupportEntry[] {
971
+ switch (category) {
972
+ case "local-app":
973
+ return entries.filter((entry) => LOCAL_APP_RUNTIME_IDS.has(entry.runtimeId));
974
+ case "local-http":
975
+ return entries.filter((entry) => entry.group === "local-http" && !LOCAL_APP_RUNTIME_IDS.has(entry.runtimeId));
976
+ case "chatgpt":
977
+ return entries.filter((entry) => entry.runtimeId === "openai-codex");
978
+ case "cloud-api": {
979
+ const byLabel = (a: ProviderSupportEntry, b: ProviderSupportEntry) =>
980
+ a.label.localeCompare(b.label) || a.runtimeId.localeCompare(b.runtimeId);
981
+ const named = entries
982
+ .filter((entry) => entry.group === "cloud-api")
983
+ .slice()
984
+ .sort(byLabel);
985
+ // Surface the generic OpenAI/Anthropic-compatible runtimes here too,
986
+ // shown last and under the cloud heading rather than their native group.
987
+ const compat = entries
988
+ .filter((entry) => PROTOCOL_COMPAT_RUNTIME_IDS.has(entry.runtimeId))
989
+ .map((entry) => ({ ...entry, group: "cloud-api" as const }))
990
+ .sort(byLabel);
991
+ return [...named, ...compat];
992
+ }
993
+ case "all":
994
+ return entries.slice();
995
+ }
996
+ }
997
+
998
+ async function pickCategory(rl: ReturnType<typeof createInterface>): Promise<ConfigureCategory | null> {
999
+ process.stdout.write("\nHow will you connect Clio to a model?\n\n");
1000
+ for (const line of formatCategoryMenu(terminalColumns())) process.stdout.write(`${line}\n`);
1001
+ for (;;) {
1002
+ const answer = await ask(rl, "\nSelection", "1");
1003
+ if (answer === null) return null;
1004
+ if (answer.length === 0) continue;
1005
+ const category = matchCategoryChoice(answer);
1006
+ if (category) return category;
1007
+ process.stderr.write(`invalid choice: ${answer}\n`);
1008
+ }
1009
+ }
1010
+
1011
+ async function pickRuntimeViaCategory(rl: ReturnType<typeof createInterface>): Promise<RuntimeDescriptor | null> {
1012
+ const registry = getRuntimeRegistry();
1013
+ const allEntries = listProviderSupportEntries(registry.list());
1014
+ const category = await pickCategory(rl);
1015
+ if (category === null) return null;
1016
+ if (category === "all") return pickRuntime(rl);
1017
+ const filtered = runtimesForCategory(allEntries, category);
1018
+ if (filtered.length === 0) {
1019
+ process.stderr.write("no runtimes available for that category; falling back to full list\n");
1020
+ return pickRuntime(rl);
1021
+ }
1022
+ if (category === "chatgpt") {
1023
+ const only = filtered[0];
1024
+ if (only) {
1025
+ const runtime = registry.get(only.runtimeId);
1026
+ if (runtime) {
1027
+ process.stdout.write(`\nUsing ${runtime.id} (${only.summary}).\n`);
1028
+ return runtime;
1029
+ }
1030
+ }
1031
+ return pickRuntime(rl);
1032
+ }
1033
+ if (filtered.length === 1) {
1034
+ const only = filtered[0];
1035
+ if (only) {
1036
+ const runtime = registry.get(only.runtimeId);
1037
+ if (runtime) {
1038
+ process.stdout.write(`\nUsing ${runtime.id} (${only.summary}).\n`);
1039
+ return runtime;
1040
+ }
1041
+ }
1042
+ }
1043
+ const heading =
1044
+ category === "local-app" ? "\nLocal apps:" : category === "local-http" ? "\nLocal HTTP servers:" : "\nCloud APIs:";
1045
+ return pickRuntimeFromEntries(rl, filtered, heading);
1046
+ }
1047
+
1048
+ async function maybeSteerToNativeRuntime(
1049
+ rl: ReturnType<typeof createInterface>,
1050
+ currentRuntime: RuntimeDescriptor,
1051
+ url: string,
1052
+ ): Promise<RuntimeDescriptor> {
1053
+ if (currentRuntime.id !== "openai-compat" && currentRuntime.id !== "anthropic-compat") return currentRuntime;
1054
+ const fingerprint = await fingerprintNativeRuntime(url);
1055
+ if (!fingerprint) return currentRuntime;
1056
+ const native = getRuntimeRegistry().get(fingerprint.runtimeId);
1057
+ if (!native) return currentRuntime;
1058
+ process.stdout.write(`\nDetected ${fingerprint.displayName} at ${url}.\n`);
1059
+ const switchIt = await askYesNo(rl, `Use ${fingerprint.runtimeId} runtime instead of ${currentRuntime.id}?`, true);
1060
+ if (!switchIt) return currentRuntime;
1061
+ process.stdout.write(`Using ${fingerprint.runtimeId} runtime.\n`);
1062
+ return native;
1063
+ }
1064
+
1065
+ async function runInteractive(
1066
+ rl: ReturnType<typeof createInterface>,
1067
+ preselectedRuntime: RuntimeDescriptor | null,
1068
+ defaults: ParsedArgs,
1069
+ ): Promise<number> {
1070
+ let runtime = preselectedRuntime ?? (await pickRuntimeViaCategory(rl));
1071
+ if (!runtime) {
1072
+ printError("configuration cancelled");
1073
+ return 0;
1074
+ }
1075
+ const auth = openAuthStorage();
1076
+ const settings = readSettings();
1077
+ let support = buildProviderSupportEntry(runtime);
1078
+ const initialRuntimeId = runtime.id;
1079
+ const existingForRuntime = configuredTargetsForRuntime(settings, initialRuntimeId);
1080
+ const existing =
1081
+ (defaults.id
1082
+ ? settings.targets.find((entry) => entry.id === defaults.id && entry.runtime === initialRuntimeId)
1083
+ : null) ??
1084
+ existingForRuntime[0] ??
1085
+ null;
1086
+ if (existingForRuntime.length > 0) {
1087
+ process.stdout.write(`\nExisting targets for ${runtime.id}:\n`);
1088
+ for (const target of existingForRuntime) {
1089
+ process.stdout.write(` - ${target.id}${target.defaultModel ? ` (${target.defaultModel})` : ""}\n`);
1090
+ }
1091
+ }
1092
+ process.stdout.write(`\nSelected runtime: ${runtime.id} (${support.summary})\n`);
1093
+ process.stdout.write(`Credentials: ${describeAuthStatus(runtime)}\n`);
1094
+ if (support.modelHints.length > 0) {
1095
+ process.stdout.write(`Known models: ${describeRuntimeModels(support, 4)}\n`);
1096
+ }
1097
+ const suggestedId = defaults.id ?? existing?.id ?? deriveTargetId(runtime.id, settings.targets);
1098
+ const idInput = await ask(rl, "Target id", suggestedId);
1099
+ if (idInput === null || idInput.length === 0) {
1100
+ printError("target id is required");
1101
+ return 2;
1102
+ }
1103
+ const targetId = idInput;
1104
+
1105
+ let url: string | undefined = existing?.url;
1106
+ if (support.supportsCustomUrl) {
1107
+ const urlDefault = defaults.url ?? existing?.url ?? defaultUrlFor(runtime.id);
1108
+ const urlInput = await ask(
1109
+ rl,
1110
+ support.group === "local-http" ? "Target URL" : "Base URL override (blank for runtime default)",
1111
+ urlDefault,
1112
+ );
1113
+ if (urlInput === null) return 0;
1114
+ if (urlInput.length > 0) url = normalizeUrl(urlInput, runtime.id);
1115
+ } else if (defaults.url) {
1116
+ url = normalizeUrl(defaults.url, runtime.id);
1117
+ }
1118
+
1119
+ if (url) {
1120
+ const steered = await maybeSteerToNativeRuntime(rl, runtime, url);
1121
+ if (steered.id !== runtime.id) {
1122
+ runtime = steered;
1123
+ support = buildProviderSupportEntry(runtime);
1124
+ }
1125
+ if (runtime.id === "lmstudio") {
1126
+ const greeting = await greetLmStudio(
1127
+ { id: targetId, runtime: runtime.id, url },
1128
+ { credentialsPresent: new Set(), httpTimeoutMs: 750 },
1129
+ );
1130
+ if (!greeting.ok) {
1131
+ printError(`refusing to save LM Studio target '${targetId}': ${url} did not return the LM Studio greeting`);
1132
+ return 2;
1133
+ }
1134
+ }
1135
+ }
1136
+
1137
+ let apiKeyEnv: string | undefined;
1138
+ let apiKeyLiteral: string | undefined;
1139
+ let apiKeyRef: string | undefined = existing?.auth?.apiKeyRef;
1140
+ let oauthProfile: string | undefined =
1141
+ runtime.auth === "oauth" ? (existing?.auth?.oauthProfile ?? runtime.oauthProviderId ?? runtime.id) : undefined;
1142
+ const authStatus = auth.statusForTarget(resolveRuntimeAuthTarget(runtime), { includeFallback: false });
1143
+ if (runtime.auth === "api-key") {
1144
+ // Default to the env-var path, which keeps the key off disk. A target that
1145
+ // needs no key at all defaults to skip instead: a local llama.cpp server
1146
+ // wants no credential, and offering `env` sent the user to an unexplained
1147
+ // `Env var name:` with nothing correct to type into it.
1148
+ const needsCredential = targetRequiresAuth({ id: targetId, runtime: runtime.id }, runtime);
1149
+ const defaultSource =
1150
+ authStatus.source === "stored-api-key"
1151
+ ? "keep"
1152
+ : authStatus.source === "environment" || existing?.auth?.apiKeyEnvVar || needsCredential
1153
+ ? "env"
1154
+ : "skip";
1155
+ process.stdout.write(
1156
+ "\nCredential source: env reads a key from an environment variable, stored writes one to\n" +
1157
+ "credentials.yaml, keep leaves the current one alone, skip uses no key at all.\n",
1158
+ );
1159
+ const choice = await ask(rl, "Credential source [env|stored|keep|skip]", defaultSource);
1160
+ if (choice === null) return 0;
1161
+ const normalized = choice.trim().toLowerCase();
1162
+ if (normalized === "stored") {
1163
+ const literal = await ask(rl, "API key literal (stored in credentials.yaml, mode 0600)");
1164
+ if (literal !== null && literal.length > 0) {
1165
+ apiKeyLiteral = literal;
1166
+ apiKeyRef = runtime.id;
1167
+ }
1168
+ } else if (normalized === "env") {
1169
+ const envDefault = defaults.apiKeyEnv ?? existing?.auth?.apiKeyEnvVar ?? runtime.credentialsEnvVar ?? "";
1170
+ const envAnswer = await ask(rl, "Env var name (blank for no key)", envDefault);
1171
+ if (envAnswer === null) return 0;
1172
+ if (envAnswer.length > 0) apiKeyEnv = envAnswer;
1173
+ apiKeyRef = undefined;
1174
+ } else if (normalized === "keep") {
1175
+ apiKeyEnv =
1176
+ existing?.auth?.apiKeyEnvVar ?? (authStatus.source === "environment" ? runtime.credentialsEnvVar : undefined);
1177
+ apiKeyRef = existing?.auth?.apiKeyRef ?? (authStatus.source === "stored-api-key" ? runtime.id : undefined);
1178
+ } else {
1179
+ apiKeyEnv = undefined;
1180
+ apiKeyRef = undefined;
1181
+ }
1182
+ }
1183
+ if (runtime.auth === "oauth") {
1184
+ const connectNow = authStatus.available
1185
+ ? await askYesNo(rl, `Reconnect ${runtime.displayName}?`, false)
1186
+ : await askYesNo(rl, `Connect ${runtime.displayName} now?`, true);
1187
+ if (connectNow) {
1188
+ const connected = await loginOAuthRuntime(rl, runtime);
1189
+ if (!connected) return 1;
1190
+ }
1191
+ oauthProfile = runtime.oauthProviderId ?? runtime.id;
1192
+ }
1193
+
1194
+ let model: string | undefined = defaults.model;
1195
+ let wireModels: string[] = existing?.wireModels ? [...existing.wireModels] : [];
1196
+ const tentative = buildDescriptor(runtime, targetId, {
1197
+ ...(url !== undefined ? { url } : {}),
1198
+ ...(apiKeyEnv !== undefined ? { apiKeyEnv } : {}),
1199
+ ...(apiKeyRef !== undefined ? { apiKeyRef } : {}),
1200
+ ...(oauthProfile !== undefined ? { oauthProfile } : {}),
1201
+ gateway: defaults.gateway,
1202
+ ...(defaults.lifecycle !== undefined
1203
+ ? { lifecycle: defaults.lifecycle }
1204
+ : existing?.lifecycle !== undefined
1205
+ ? { lifecycle: existing.lifecycle }
1206
+ : {}),
1207
+ ...(defaults.contextWindow !== undefined ? { contextWindow: defaults.contextWindow } : {}),
1208
+ ...(defaults.maxTokens !== undefined ? { maxTokens: defaults.maxTokens } : {}),
1209
+ ...(defaults.reasoning !== undefined ? { reasoning: defaults.reasoning } : {}),
1210
+ ...(existing?.lmstudio ? { lmstudio: existing.lmstudio } : {}),
1211
+ });
1212
+
1213
+ if (runtime.kind === "http") {
1214
+ wireModels = await resolveSupportedWireModels(runtime, tentative, existing ?? undefined);
1215
+ }
1216
+ // The wizard shows the whole list, so a catalog-ordered runtime does not need
1217
+ // --model here the way the non-interactive path does. It does need to stop
1218
+ // offering the alphabetically first id as though it were the recommended one.
1219
+ const catalogOrdered = support.modelSource === "catalog";
1220
+ model = model ?? existing?.defaultModel ?? support.defaultModel ?? (catalogOrdered ? undefined : wireModels[0]);
1221
+ if (wireModels.length > 0) {
1222
+ process.stdout.write("\nSelectable models:\n");
1223
+ for (const [index, wireModel] of wireModels.entries()) {
1224
+ process.stdout.write(` ${index + 1}. ${wireModel}${wireModel === model ? " [default]" : ""}\n`);
1225
+ }
1226
+ if (!model && catalogOrdered) {
1227
+ process.stdout.write(` listed in provider catalog order, which recommends none of them; pick one.\n`);
1228
+ }
1229
+ for (;;) {
1230
+ const pickedModel = await askModelChoice(rl, "Default target model", wireModels, model);
1231
+ if (pickedModel === null) return 0;
1232
+ if (pickedModel.length > 0) model = pickedModel;
1233
+ if (!model) {
1234
+ process.stdout.write(" a model is required: enter a number from the list or a model id.\n");
1235
+ continue;
1236
+ }
1237
+ if (validateResolvedModel(runtime.id, model, defaults.force)) break;
1238
+ }
1239
+ } else {
1240
+ for (;;) {
1241
+ if (model && validateResolvedModel(runtime.id, model, defaults.force)) break;
1242
+ const manual = await ask(rl, "Default model id (blank to leave empty)", model ?? "");
1243
+ if (manual === null) return 0;
1244
+ model = manual.length > 0 ? manual : undefined;
1245
+ if (!model) break;
1246
+ }
1247
+ }
1248
+ let contextWindowChoice = defaults.contextWindow;
1249
+ let reasoningChoice = defaults.reasoning;
1250
+ // Generic OpenAI/Anthropic-compatible endpoints have no cloud catalog and
1251
+ // their /v1/models rarely reports a context window or reasoning support, so
1252
+ // ask for the two capabilities that cannot be probed reliably. Output budget
1253
+ // is intentionally not asked: defaults.maxTokens applies globally and is
1254
+ // clamped down to the model at request time.
1255
+ if (PROTOCOL_COMPAT_RUNTIME_IDS.has(runtime.id)) {
1256
+ if (contextWindowChoice === undefined) {
1257
+ const cwDefault = existing?.capabilities?.contextWindow ?? runtime.defaultCapabilities.contextWindow;
1258
+ const cwAnswer = await ask(
1259
+ rl,
1260
+ "Context window in tokens (blank for runtime default)",
1261
+ cwDefault > 0 ? String(cwDefault) : "",
1262
+ );
1263
+ if (cwAnswer === null) return 0;
1264
+ if (cwAnswer.length > 0) {
1265
+ const parsed = Number(cwAnswer);
1266
+ if (Number.isInteger(parsed) && parsed > 0) contextWindowChoice = parsed;
1267
+ else process.stderr.write(`ignoring invalid context window: ${cwAnswer}\n`);
1268
+ }
1269
+ }
1270
+ if (reasoningChoice === undefined) {
1271
+ const reasoningDefault = existing?.capabilities?.reasoning ?? runtime.defaultCapabilities.reasoning === true;
1272
+ reasoningChoice = await askYesNo(rl, "Does this model support reasoning / thinking?", reasoningDefault);
1273
+ }
1274
+ }
1275
+ if (!validateContextWindowOverride(runtime, model, contextWindowChoice, defaults.force)) return 2;
1276
+
1277
+ const gatewayDefault = defaults.gateway || existing?.gateway === true;
1278
+ const gatewayAnswer = gatewayDefault ? true : await askYesNo(rl, "Mark as gateway?", false);
1279
+
1280
+ const descriptor = buildDescriptor(runtime, targetId, {
1281
+ ...(url !== undefined ? { url } : {}),
1282
+ ...(model !== undefined ? { model } : {}),
1283
+ ...(apiKeyEnv !== undefined ? { apiKeyEnv } : {}),
1284
+ ...(apiKeyRef !== undefined ? { apiKeyRef } : {}),
1285
+ ...(oauthProfile !== undefined ? { oauthProfile } : {}),
1286
+ ...(wireModels.length > 0 ? { wireModels } : {}),
1287
+ gateway: gatewayAnswer,
1288
+ ...(defaults.lifecycle !== undefined
1289
+ ? { lifecycle: defaults.lifecycle }
1290
+ : existing?.lifecycle !== undefined
1291
+ ? { lifecycle: existing.lifecycle }
1292
+ : {}),
1293
+ ...(contextWindowChoice !== undefined ? { contextWindow: contextWindowChoice } : {}),
1294
+ ...(defaults.maxTokens !== undefined ? { maxTokens: defaults.maxTokens } : {}),
1295
+ ...(reasoningChoice !== undefined ? { reasoning: reasoningChoice } : {}),
1296
+ ...(existing?.lmstudio ? { lmstudio: existing.lmstudio } : {}),
1297
+ });
1298
+ try {
1299
+ assertOrchestratorReplacementEligible(settings, descriptor);
1300
+ } catch (error) {
1301
+ printError(error instanceof Error ? error.message : String(error));
1302
+ return 1;
1303
+ }
1304
+ if (apiKeyLiteral) {
1305
+ auth.setApiKey(runtime.id, apiKeyLiteral);
1306
+ // As in the non-interactive path: the settings write is still ahead of us,
1307
+ // so refusing here leaves the whole wizard run without an effect.
1308
+ if (credentialWriteFailed(auth, `credential for ${runtime.id} was not stored; target '${descriptor.id}' not saved`))
1309
+ return 1;
1310
+ printPlaintextCredentialWarning();
1311
+ }
1312
+
1313
+ const probe = await runtimeProbe(runtime, descriptor);
1314
+ if (probe) {
1315
+ process.stdout.write("\n");
1316
+ for (const line of probeLines(descriptor, probe)) process.stdout.write(`${line}\n`);
1317
+ if (!probe.ok) {
1318
+ const keepAnyway = await askYesNo(rl, "save this target anyway, without a reply from it?", true);
1319
+ if (!keepAnyway) {
1320
+ printError("aborted; settings not changed");
1321
+ return 0;
1322
+ }
1323
+ }
1324
+ }
1325
+
1326
+ const setOrchestrator = !isOrchestratorEligibleRuntime(runtime)
1327
+ ? false
1328
+ : defaults.setOrchestrator
1329
+ ? true
1330
+ : await askYesNo(rl, "use as orchestrator (chat) target?", !settings.orchestrator.target);
1331
+ const setWorkerDefault = defaults.setWorkerDefault
1332
+ ? true
1333
+ : await askYesNo(rl, "use as fleet default?", !settings.workers.default.target);
1334
+ const setBackground = !isOrchestratorEligibleRuntime(runtime)
1335
+ ? false
1336
+ : defaults.setBackground
1337
+ ? true
1338
+ : await askYesNo(rl, "use as background memory target?", false);
1339
+ const orchestratorModel = setOrchestrator
1340
+ ? (defaults.orchestratorModel ??
1341
+ (await askModelChoice(
1342
+ rl,
1343
+ "Orchestrator model",
1344
+ wireModels,
1345
+ settings.orchestrator.target === targetId ? (settings.orchestrator.model ?? model) : model,
1346
+ )))
1347
+ : undefined;
1348
+ if (orchestratorModel === null) return 0;
1349
+ const workerModel = setWorkerDefault
1350
+ ? (defaults.workerModel ??
1351
+ (await askModelChoice(
1352
+ rl,
1353
+ "Fleet model",
1354
+ wireModels,
1355
+ settings.workers.default.target === targetId ? (settings.workers.default.model ?? model) : model,
1356
+ )))
1357
+ : undefined;
1358
+ if (workerModel === null) return 0;
1359
+ const backgroundModel = setBackground
1360
+ ? (defaults.backgroundModel ??
1361
+ (await askModelChoice(
1362
+ rl,
1363
+ "Background memory model",
1364
+ wireModels,
1365
+ settings.background.target === targetId ? (settings.background.model ?? model) : model,
1366
+ )))
1367
+ : undefined;
1368
+ if (backgroundModel === null) return 0;
1369
+
1370
+ const applyWizardChoice = (target: ClioSettings): void => {
1371
+ applyTarget(target, descriptor);
1372
+ if (setOrchestrator) setOrchestratorPointer(target, descriptor, orchestratorModel);
1373
+ if (setBackground) setBackgroundPointer(target, descriptor, backgroundModel);
1374
+ if (setWorkerDefault) setWorkerDefaultPointer(target, descriptor, workerModel);
1375
+ };
1376
+ applyWizardChoice(settings);
1377
+ updateSettings(applyWizardChoice);
1378
+
1379
+ printSummary(settings, descriptor, probe);
1380
+ printOk(`target ${targetId} saved`);
1381
+ await runInteropReview(rl);
1382
+ return 0;
1383
+ }
1384
+
1385
+ export function runTargetRemove(id: string): number {
1386
+ if (!readSettings().targets.some((e) => e.id === id)) {
1387
+ printError(`no target with id ${id}`);
1388
+ return 1;
1389
+ }
1390
+ updateSettings((settings) => {
1391
+ removeTargetFromSettings(settings, id);
1392
+ });
1393
+ printOk(`removed target ${id}`);
1394
+ return 0;
1395
+ }
1396
+
1397
+ export function runTargetRename(oldId: string, newId: string): number {
1398
+ if (oldId === newId) {
1399
+ printError("old and new id are identical");
1400
+ return 2;
1401
+ }
1402
+ const current = readSettings();
1403
+ if (current.targets.some((e) => e.id === newId)) {
1404
+ printError(`target id already exists: ${newId}`);
1405
+ return 2;
1406
+ }
1407
+ if (!current.targets.some((e) => e.id === oldId)) {
1408
+ printError(`no target with id ${oldId}`);
1409
+ return 1;
1410
+ }
1411
+ updateSettings((settings) => {
1412
+ const target = settings.targets.find((e) => e.id === oldId);
1413
+ if (!target) return;
1414
+ target.id = newId;
1415
+ if (settings.orchestrator.target === oldId) settings.orchestrator.target = newId;
1416
+ if (settings.background.target === oldId) settings.background.target = newId;
1417
+ if (settings.workers.default.target === oldId) settings.workers.default.target = newId;
1418
+ for (const profile of Object.values(settings.workers.profiles)) {
1419
+ if (profile.target === oldId) profile.target = newId;
1420
+ }
1421
+ settings.scope = settings.scope.map((entry) => {
1422
+ const [head, ...rest] = entry.split("/");
1423
+ if (head !== oldId) return entry;
1424
+ return rest.length === 0 ? newId : `${newId}/${rest.join("/")}`;
1425
+ });
1426
+ });
1427
+ printOk(`renamed ${oldId} to ${newId}`);
1428
+ return 0;
1429
+ }
1430
+
1431
+ export async function runConfigureCommand(argv: ReadonlyArray<string>): Promise<number> {
1432
+ let args: ParsedArgs;
1433
+ try {
1434
+ args = parseSetupArgs(argv);
1435
+ } catch (err) {
1436
+ printError(err instanceof Error ? err.message : String(err));
1437
+ process.stdout.write(HELP);
1438
+ return 2;
1439
+ }
1440
+ if (args.help) {
1441
+ process.stdout.write(HELP);
1442
+ return 0;
1443
+ }
1444
+ initializeClioHome();
1445
+ ensureRegistryPopulated();
1446
+
1447
+ if (args.list) {
1448
+ printRuntimeList(args.all);
1449
+ return 0;
1450
+ }
1451
+ if (args.interop) {
1452
+ if (!input.isTTY) return runInteropReview(null);
1453
+ const rl = createInterface({ input, output });
1454
+ try {
1455
+ return await runInteropReview(rl);
1456
+ } finally {
1457
+ rl.close();
1458
+ }
1459
+ }
1460
+ if (args.remove) return runTargetRemove(args.remove);
1461
+ if (args.renameOld && args.renameNew) return runTargetRename(args.renameOld, args.renameNew);
1462
+
1463
+ if (args.positional.length > 0) {
1464
+ printError(
1465
+ "`clio-coder configure` accepts flags, not positional runtimes. Use `clio-coder auth login <runtime>` first when authentication is needed, then `clio-coder configure --runtime <runtimeId> ...`.",
1466
+ );
1467
+ return 2;
1468
+ }
1469
+
1470
+ const runtimeId = args.runtime;
1471
+ let runtime: RuntimeDescriptor | null = null;
1472
+ if (runtimeId) {
1473
+ runtime = getRuntimeRegistry().get(runtimeId);
1474
+ if (!runtime) {
1475
+ printError(`unknown runtime id: ${runtimeId}`);
1476
+ process.stdout.write("run `clio-coder configure --list` to see registered runtimes\n");
1477
+ return 2;
1478
+ }
1479
+ if (runtimeId === "lmstudio-native" && runtime.id === "lmstudio") {
1480
+ process.stderr.write("warning: runtime 'lmstudio-native' is deprecated; using 'lmstudio'\n");
1481
+ }
1482
+ }
1483
+ const hasTargetSetupFlag =
1484
+ args.id !== undefined ||
1485
+ args.url !== undefined ||
1486
+ args.model !== undefined ||
1487
+ args.workerProfile !== undefined ||
1488
+ args.workerProfileModel !== undefined ||
1489
+ args.apiKey !== undefined ||
1490
+ args.apiKeyEnv !== undefined ||
1491
+ args.gateway ||
1492
+ args.lifecycle !== undefined ||
1493
+ args.setOrchestrator ||
1494
+ args.setWorkerDefault ||
1495
+ args.contextWindow !== undefined ||
1496
+ args.maxTokens !== undefined ||
1497
+ args.reasoning !== undefined;
1498
+ const nonInteractive = runtime !== null && hasTargetSetupFlag;
1499
+
1500
+ if (nonInteractive && runtime) return runNonInteractive(runtime, args);
1501
+
1502
+ // Setup flags were supplied but the non-interactive spec is incomplete
1503
+ // (missing --runtime, or a --runtime with no target flags). On a
1504
+ // non-interactive stdin the wizard below would read EOF, take the default
1505
+ // answers, write the initial settings template, and exit 0 without
1506
+ // configuring the requested target. Reject with the missing half instead.
1507
+ if ((runtimeId !== undefined || hasTargetSetupFlag) && !input.isTTY) {
1508
+ printError(
1509
+ runtime === null
1510
+ ? "--runtime is required when configuring a target non-interactively"
1511
+ : "--id is required when passing flags non-interactively",
1512
+ );
1513
+ return 2;
1514
+ }
1515
+
1516
+ const rl = createInterface({ input, output });
1517
+ try {
1518
+ return await runInteractive(rl, runtime, args);
1519
+ } catch (err) {
1520
+ printError(err instanceof Error ? err.message : String(err));
1521
+ return 1;
1522
+ } finally {
1523
+ rl.close();
1524
+ }
1525
+ }