@iowarp/clio-coder 0.4.9 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1172) hide show
  1. package/.claude-plugin/marketplace.json +11 -3
  2. package/CHANGELOG.md +153 -0
  3. package/CODE_OF_CONDUCT.md +10 -0
  4. package/CONTRIBUTING.md +208 -382
  5. package/NOTICE +8 -2
  6. package/README.md +199 -418
  7. package/ROADMAP.md +82 -0
  8. package/SECURITY.md +14 -11
  9. package/dist/acp-KS7ARGV6.js +132 -0
  10. package/dist/agents-YOGJ2YEJ.js +163 -0
  11. package/dist/assets/codewiki.json +1 -1
  12. package/dist/auth-CEDCO6O6.js +557 -0
  13. package/dist/background-YWTBPSQU.js +39 -0
  14. package/dist/builtins-GDYO4RTR.js +23 -0
  15. package/dist/chunk-27YTM2CV.js +175 -0
  16. package/dist/chunk-2AF6YC7Q.js +75 -0
  17. package/dist/chunk-2DTIWSAW.js +381 -0
  18. package/dist/chunk-2EMLKSCX.js +262 -0
  19. package/dist/chunk-2OJ3YZQP.js +665 -0
  20. package/dist/chunk-2VLYHHFT.js +35 -0
  21. package/dist/chunk-2WVPJF3Z.js +204 -0
  22. package/dist/chunk-33OASOS6.js +176 -0
  23. package/dist/chunk-3BD2LXYJ.js +19 -0
  24. package/dist/chunk-3JHUFKG7.js +30 -0
  25. package/dist/chunk-3JLTRPN7.js +711 -0
  26. package/dist/chunk-3LT34CAM.js +2796 -0
  27. package/dist/chunk-3O5JWP4L.js +1670 -0
  28. package/dist/chunk-3UW3KU4A.js +21 -0
  29. package/dist/chunk-4A6YRGV4.js +569 -0
  30. package/dist/chunk-4D2BRCZ3.js +67 -0
  31. package/dist/chunk-4SYHGVDE.js +668 -0
  32. package/dist/chunk-4VDHLCF5.js +66 -0
  33. package/dist/chunk-4WOOTKFD.js +637 -0
  34. package/dist/chunk-4WV4PI66.js +80 -0
  35. package/dist/chunk-53OXPRI6.js +195 -0
  36. package/dist/chunk-55RMDDFM.js +1347 -0
  37. package/dist/chunk-56XP4FJU.js +2025 -0
  38. package/dist/chunk-5B3RTYAK.js +123 -0
  39. package/dist/chunk-5CD243WE.js +45 -0
  40. package/dist/chunk-5JQR5B4D.js +709 -0
  41. package/dist/chunk-5KQEUIWM.js +597 -0
  42. package/dist/chunk-5LP5FNNR.js +915 -0
  43. package/dist/chunk-62UK7AGW.js +9344 -0
  44. package/dist/chunk-6CTHLZFB.js +563 -0
  45. package/dist/chunk-6EJYVCTN.js +23 -0
  46. package/dist/chunk-6OWUM2NC.js +12289 -0
  47. package/dist/chunk-6RJMYYIE.js +1023 -0
  48. package/dist/chunk-6W75D37F.js +643 -0
  49. package/dist/chunk-733ZBT5P.js +1721 -0
  50. package/dist/chunk-77DCC6JZ.js +3710 -0
  51. package/dist/chunk-7QXCO3AF.js +156 -0
  52. package/dist/chunk-7RET77VB.js +481 -0
  53. package/dist/chunk-A4MVRV4C.js +65 -0
  54. package/dist/chunk-ALJWT6O6.js +93 -0
  55. package/dist/chunk-AVSR2HKI.js +232 -0
  56. package/dist/chunk-B7GY6QER.js +42 -0
  57. package/dist/chunk-BFOSV5EZ.js +178 -0
  58. package/dist/chunk-BGOIM7NB.js +103 -0
  59. package/dist/chunk-BJH6WFIB.js +372 -0
  60. package/dist/chunk-BOBCCDJ6.js +1533 -0
  61. package/dist/chunk-BRCOSE7O.js +117 -0
  62. package/dist/chunk-BYFHHCFV.js +601 -0
  63. package/dist/chunk-C2CPOIH2.js +83 -0
  64. package/dist/chunk-C7AQTPCE.js +694 -0
  65. package/dist/chunk-CBAQPTDU.js +165 -0
  66. package/dist/chunk-CDQ2UC6W.js +125 -0
  67. package/dist/chunk-CN6SW5DC.js +177 -0
  68. package/dist/chunk-CRHPCPZP.js +132 -0
  69. package/dist/chunk-CTFPFW3H.js +44 -0
  70. package/dist/chunk-D3KWFOUT.js +103 -0
  71. package/dist/chunk-D65E25JG.js +185 -0
  72. package/dist/chunk-DCGHJQ2U.js +236 -0
  73. package/dist/chunk-DE2LU267.js +106 -0
  74. package/dist/chunk-DF6PI6GN.js +97 -0
  75. package/dist/chunk-DGC6X6XR.js +53 -0
  76. package/dist/chunk-DOUISWEE.js +526 -0
  77. package/dist/chunk-DR3TAEUA.js +188 -0
  78. package/dist/chunk-DVTBERFY.js +33 -0
  79. package/dist/chunk-DXSETN72.js +1051 -0
  80. package/dist/chunk-DZLR4UEH.js +128 -0
  81. package/dist/chunk-E6IPKW2E.js +77 -0
  82. package/dist/chunk-EG4ARXPC.js +139 -0
  83. package/dist/chunk-EKV4UBCM.js +652 -0
  84. package/dist/chunk-EOJPDNUP.js +1325 -0
  85. package/dist/chunk-EX57VVWW.js +4157 -0
  86. package/dist/chunk-EYTLV3W3.js +5937 -0
  87. package/dist/chunk-EZD2BXGP.js +475 -0
  88. package/dist/chunk-EZDCA34W.js +314 -0
  89. package/dist/chunk-FD2I4KBR.js +33 -0
  90. package/dist/chunk-FD3IAHQM.js +27 -0
  91. package/dist/chunk-FFYTC2KQ.js +416 -0
  92. package/dist/chunk-FGSQHUCK.js +110 -0
  93. package/dist/chunk-GCQFN7YI.js +32 -0
  94. package/dist/chunk-GGPF6LLE.js +38 -0
  95. package/dist/chunk-GGWI3OVM.js +215 -0
  96. package/dist/chunk-GLIQT7SU.js +172 -0
  97. package/dist/chunk-GN7QBEEI.js +95 -0
  98. package/dist/chunk-GRHOXDKB.js +1104 -0
  99. package/dist/chunk-HMN2C6YL.js +54 -0
  100. package/dist/chunk-HOEDA42N.js +310 -0
  101. package/dist/chunk-HOYZUKG7.js +192 -0
  102. package/dist/chunk-HQVN7G4F.js +1021 -0
  103. package/dist/chunk-HSQQFDB3.js +519 -0
  104. package/dist/chunk-I4ELN5BX.js +47 -0
  105. package/dist/chunk-I4Y4WKZR.js +386 -0
  106. package/dist/chunk-IFPDAD7R.js +797 -0
  107. package/dist/chunk-IN7DGBVS.js +582 -0
  108. package/dist/chunk-ISHUS7HC.js +396 -0
  109. package/dist/chunk-JPXLJSGR.js +191 -0
  110. package/dist/chunk-JQCLXSFI.js +69 -0
  111. package/dist/chunk-KBUTSJSR.js +61 -0
  112. package/dist/chunk-KW5HXKLJ.js +56 -0
  113. package/dist/chunk-L4APUGCT.js +139 -0
  114. package/dist/chunk-L7G7K4I2.js +505 -0
  115. package/dist/chunk-LAR7DX5E.js +1840 -0
  116. package/dist/chunk-LAVUQX3B.js +462 -0
  117. package/dist/chunk-LJRBX7QR.js +116 -0
  118. package/dist/chunk-LNOXCGN2.js +1864 -0
  119. package/dist/chunk-LTWH2ACR.js +23002 -0
  120. package/dist/chunk-LYJJ6546.js +661 -0
  121. package/dist/chunk-M2IPMWCN.js +457 -0
  122. package/dist/chunk-MGLRTOCK.js +101 -0
  123. package/dist/chunk-MZF5IKZT.js +160 -0
  124. package/dist/chunk-N24R6KWS.js +386 -0
  125. package/dist/chunk-NASYVWDB.js +604 -0
  126. package/dist/chunk-NBXFPI7U.js +195 -0
  127. package/dist/chunk-NDPF2N2L.js +400 -0
  128. package/dist/chunk-NFSK2VNU.js +446 -0
  129. package/dist/chunk-NG3QQSXY.js +43 -0
  130. package/dist/chunk-NOCSM22Y.js +63 -0
  131. package/dist/chunk-NVPXXW2H.js +1143 -0
  132. package/dist/chunk-O63U2I6I.js +30 -0
  133. package/dist/chunk-OJXOA6YU.js +98 -0
  134. package/dist/chunk-OPD7GL6F.js +1196 -0
  135. package/dist/chunk-OQ2EOAHA.js +14399 -0
  136. package/dist/chunk-OV62D6KO.js +688 -0
  137. package/dist/chunk-OZ76TLGU.js +740 -0
  138. package/dist/chunk-P4GNZPXO.js +1156 -0
  139. package/dist/chunk-PS6JAWJZ.js +78 -0
  140. package/dist/chunk-PXRCXGLK.js +1865 -0
  141. package/dist/chunk-QDUUOZ3S.js +108 -0
  142. package/dist/chunk-QG6I2T5E.js +1416 -0
  143. package/dist/chunk-QHSBROEW.js +308 -0
  144. package/dist/chunk-QNUQ7K7D.js +46 -0
  145. package/dist/chunk-QZTTRSJE.js +333 -0
  146. package/dist/chunk-R2UUNSNQ.js +1605 -0
  147. package/dist/chunk-R7FGRZNF.js +1794 -0
  148. package/dist/chunk-RNDCROSG.js +199 -0
  149. package/dist/chunk-S36CXHO2.js +302 -0
  150. package/dist/chunk-SJGS3GDI.js +575 -0
  151. package/dist/chunk-SQZHXUB3.js +510 -0
  152. package/dist/chunk-SUTLW6ND.js +686 -0
  153. package/dist/chunk-SYF7FVBL.js +179 -0
  154. package/dist/chunk-T2MDZES3.js +1577 -0
  155. package/dist/chunk-T33IYTZM.js +1146 -0
  156. package/dist/chunk-TDGYTWM6.js +49 -0
  157. package/dist/chunk-TGL5FZVD.js +132 -0
  158. package/dist/chunk-TGWZXJ7L.js +1205 -0
  159. package/dist/chunk-TKDRT2DF.js +114 -0
  160. package/dist/chunk-TV2EBCSQ.js +152 -0
  161. package/dist/chunk-U26XXPJS.js +367 -0
  162. package/dist/chunk-U5QU5ZOD.js +419 -0
  163. package/dist/chunk-U6YTUVOX.js +1011 -0
  164. package/dist/chunk-UCINIRHW.js +188 -0
  165. package/dist/chunk-UJD5MPP6.js +52 -0
  166. package/dist/chunk-URCXX7WJ.js +146 -0
  167. package/dist/chunk-UX2L5CUD.js +898 -0
  168. package/dist/chunk-UZVYEF57.js +114 -0
  169. package/dist/chunk-V35KZDUZ.js +218 -0
  170. package/dist/chunk-VESL6DQY.js +1058 -0
  171. package/dist/chunk-VKHLUZNO.js +986 -0
  172. package/dist/chunk-VOYUCAQF.js +584 -0
  173. package/dist/chunk-VYRQHORQ.js +414 -0
  174. package/dist/chunk-W53XSRQE.js +245 -0
  175. package/dist/chunk-X4CEFOSG.js +226 -0
  176. package/dist/chunk-XDHUDE5K.js +380 -0
  177. package/dist/chunk-XISLDHEL.js +1290 -0
  178. package/dist/chunk-XM34YQ2Y.js +169 -0
  179. package/dist/chunk-XMDBTYCH.js +661 -0
  180. package/dist/chunk-XS2QPZJE.js +449 -0
  181. package/dist/chunk-YBUECLAF.js +618 -0
  182. package/dist/chunk-YQ6XEFVK.js +332 -0
  183. package/dist/chunk-YYLCPDCC.js +990 -0
  184. package/dist/chunk-Z4GLJ6J4.js +1035 -0
  185. package/dist/chunk-ZARZ4POR.js +210 -0
  186. package/dist/chunk-ZJPORZTC.js +119 -0
  187. package/dist/chunk-ZNUZ3EXD.js +243 -0
  188. package/dist/chunk-ZPST2KQO.js +49 -0
  189. package/dist/chunk-ZR5YA6ZF.js +512 -0
  190. package/dist/chunk-ZU4JPCPR.js +319 -0
  191. package/dist/chunk-ZUKUCZYZ.js +39 -0
  192. package/dist/cli/index.js +56 -45
  193. package/dist/clio-K2PBVCEM.js +27 -0
  194. package/dist/clio-context-tools-GR4OHFSO.js +145 -0
  195. package/dist/code-nav-4X3OI6DK.js +715 -0
  196. package/dist/codewiki/build-worker.js +4 -4
  197. package/dist/compile-cache-YRB6QRO7.js +18 -0
  198. package/dist/components-RQOJ6NUR.js +675 -0
  199. package/dist/config-Q5J7UBAB.js +291 -0
  200. package/dist/config-XE7XYZLU.js +38 -0
  201. package/dist/config-graph-P3555574.js +175 -0
  202. package/dist/configure-KIJ32ZO6.js +104 -0
  203. package/dist/context-LFBQOSXT.js +344 -0
  204. package/dist/context-NNLBES2Y.js +82 -0
  205. package/dist/context-WBH3KSVR.js +302 -0
  206. package/dist/context-clear-YOHMQ6SQ.js +208 -0
  207. package/dist/context-index-X2N5UAIF.js +120 -0
  208. package/dist/context-map-HOSMGUG2.js +555 -0
  209. package/dist/context-working-set-MRAEVDNV.js +1564 -0
  210. package/dist/data-tool-JJPBGMQJ.js +2986 -0
  211. package/dist/detail-RHJOTGN4.js +139 -0
  212. package/dist/dispatch-runner-NC7PYNIO.js +2477 -0
  213. package/dist/docs-K4GBWRUX.js +342 -0
  214. package/dist/doctor-S5KZ2GTN.js +1138 -0
  215. package/dist/doctor-deep-2EJQSHIZ.js +130 -0
  216. package/dist/domain-loader-MB34FDPD.js +13 -0
  217. package/dist/eval-3D6M36N7.js +5220 -0
  218. package/dist/eval-inventory-SM3HNM47.js +260 -0
  219. package/dist/evals-FO6JEUCN.js +104 -0
  220. package/dist/evidence-6IYN52ET.js +262 -0
  221. package/dist/evidence-JVECPI3F.js +250 -0
  222. package/dist/evidence-XNVPPLVK.js +410 -0
  223. package/dist/evolve-TLPUDJDM.js +634 -0
  224. package/dist/extensions-ROZJ5X3J.js +311 -0
  225. package/dist/fleet-6RJWIOEO.js +284 -0
  226. package/dist/fleet-WKVBF5SZ.js +942 -0
  227. package/dist/fleet-commands-L6WFT7KZ.js +76 -0
  228. package/dist/fleet-decisions-BTQMWU5A.js +55 -0
  229. package/dist/fleet-graph-553DZ67Q.js +141 -0
  230. package/dist/fleet-inspect-236FZPRB.js +329 -0
  231. package/dist/fleet-new-CKUXP3CO.js +48 -0
  232. package/dist/fleet-preflight-NZQHABWO.js +95 -0
  233. package/dist/fleet-validate-7NLAE26R.js +96 -0
  234. package/dist/fleet-verify-E3RO6A5W.js +226 -0
  235. package/dist/fleet-view-KMZQY7YJ.js +144 -0
  236. package/dist/gui/client/assets/abnfDiagram-VCTEODGH-DPBWQwNn.js +1 -0
  237. package/dist/gui/client/assets/architecture-7GRP2DOG-D1w8FrFW.js +1 -0
  238. package/dist/gui/client/assets/architectureDiagram-5GKGNRK7-CVPgKd1-.js +36 -0
  239. package/dist/gui/client/assets/blockDiagram-I7D4REHJ-BLmnqkK5.js +129 -0
  240. package/dist/gui/client/assets/c4Diagram-7LVT6UL2-4AU9cfM7.js +38 -0
  241. package/dist/gui/client/assets/channel-DwFZ0m8S.js +1 -0
  242. package/dist/gui/client/assets/chunk-4HAMMTFA-EOWkKCav.js +62 -0
  243. package/dist/gui/client/assets/chunk-75Z2AOVW-CygeoIMl.js +2 -0
  244. package/dist/gui/client/assets/chunk-DU6HZSFF-s27fViLb.js +125 -0
  245. package/dist/gui/client/assets/chunk-F27PBJKO-BrHvwLsZ.js +1 -0
  246. package/dist/gui/client/assets/chunk-GMAD6QVW-DzPh-7jt.js +72 -0
  247. package/dist/gui/client/assets/chunk-GVQU2GXP-pIaQkIzm.js +1 -0
  248. package/dist/gui/client/assets/chunk-IMKFNOWR-BGJVE_Br.js +231 -0
  249. package/dist/gui/client/assets/chunk-L3NEJ4N5-B3YLuhww.js +1 -0
  250. package/dist/gui/client/assets/chunk-OSK3NFVY-BRj61HHU.js +10 -0
  251. package/dist/gui/client/assets/chunk-P2QGCYS3-Sno90KxP.js +1 -0
  252. package/dist/gui/client/assets/chunk-POPQ4Y6H-Cw8NTbxr.js +1 -0
  253. package/dist/gui/client/assets/chunk-PWAF6VOD-BIhHgz37.js +1 -0
  254. package/dist/gui/client/assets/chunk-SHT3W25Y-Cqv7npBj.js +168 -0
  255. package/dist/gui/client/assets/chunk-SVP7TREG-Hxzl6Dee.js +88 -0
  256. package/dist/gui/client/assets/chunk-TICWLB2K-CIFVyVP2.js +206 -0
  257. package/dist/gui/client/assets/classDiagram-ZZMXUADV-BJbAiI_w.js +1 -0
  258. package/dist/gui/client/assets/classDiagram-v2-VYDZK3BY-BJbAiI_w.js +1 -0
  259. package/dist/gui/client/assets/cynefin-OW5HDTMX-DecLWZ-y.js +1 -0
  260. package/dist/gui/client/assets/cynefinDiagram-5FMLGOSQ-CK-T2N-D.js +62 -0
  261. package/dist/gui/client/assets/dagre-GXQ25YYZ-C0dfg-OS.js +4 -0
  262. package/dist/gui/client/assets/diagram-S7CK7UJ4-EaJukVh-.js +30 -0
  263. package/dist/gui/client/assets/diagram-UQ7AKVKN-xcOucEtP.js +41 -0
  264. package/dist/gui/client/assets/diagram-VSXAHHWV-3AUJACMf.js +3 -0
  265. package/dist/gui/client/assets/diagram-VX7I27RA-TPknLqam.js +24 -0
  266. package/dist/gui/client/assets/diagram-Z3DM3KII-wa1q3YMF.js +24 -0
  267. package/dist/gui/client/assets/ebnfDiagram-PWID7BFC-JBCF2-s7.js +1 -0
  268. package/dist/gui/client/assets/erDiagram-RLTQ6QDP-CmXjXPc4.js +99 -0
  269. package/dist/gui/client/assets/eventmodeling-NTZA5JFV-D_1aJWYl.js +1 -0
  270. package/dist/gui/client/assets/flowDiagram-HODETNUW-BQtZlael.js +1 -0
  271. package/dist/gui/client/assets/framework-Bq-znqwW.js +9 -0
  272. package/dist/gui/client/assets/ganttDiagram-EL5Y4UJY-IPaL_kaa.js +292 -0
  273. package/dist/gui/client/assets/gitGraph-4MIJSDKK-Oy0Q3hoc.js +1 -0
  274. package/dist/gui/client/assets/gitGraphDiagram-WWUBYQGX-jtAuBmbc.js +106 -0
  275. package/dist/gui/client/assets/index-CuFuBEdL.css +1 -0
  276. package/dist/gui/client/assets/index-hMbEIsX0.js +87 -0
  277. package/dist/gui/client/assets/info-A6RAGUB7-UtEs1tv7.js +1 -0
  278. package/dist/gui/client/assets/infoDiagram-27XIBGKW-hlwR1pBW.js +2 -0
  279. package/dist/gui/client/assets/ishikawaDiagram-5VMMS53U-C6vMtfsd.js +70 -0
  280. package/dist/gui/client/assets/journeyDiagram-3NMN7TZE-EAwAl_PS.js +139 -0
  281. package/dist/gui/client/assets/kanban-definition-UXKFOSKX-CQOhRKHW.js +89 -0
  282. package/dist/gui/client/assets/line-DbcwGZTW.js +1 -0
  283. package/dist/gui/client/assets/mermaid-parser.core-C2QfVcHd.js +7 -0
  284. package/dist/gui/client/assets/mermaid.core-N9qUTre1.js +44 -0
  285. package/dist/gui/client/assets/mindmap-definition-YA3MSWOX-BR_FL9gK.js +96 -0
  286. package/dist/gui/client/assets/packet-AYTQ26CC-CbBJ2oAa.js +1 -0
  287. package/dist/gui/client/assets/pegDiagram-XKGWAZYB-BruU0IHM.js +1 -0
  288. package/dist/gui/client/assets/pie-WAS4IAKB-BWdSng4H.js +1 -0
  289. package/dist/gui/client/assets/pieDiagram-E7YTZNPT-CR3ljgdU.js +39 -0
  290. package/dist/gui/client/assets/quadrantDiagram-AXDQQJYC-C-boKslr.js +7 -0
  291. package/dist/gui/client/assets/radar-RG4KPBEZ-CGlOnAKG.js +1 -0
  292. package/dist/gui/client/assets/railroad-74A4TZTK-CDvuAlyC.js +1 -0
  293. package/dist/gui/client/assets/railroad-abnf-HS5TGJTU-CQUA9crC.js +1 -0
  294. package/dist/gui/client/assets/railroad-ebnf-LZEXJU2U-CD857gxq.js +1 -0
  295. package/dist/gui/client/assets/railroad-peg-WCYAUIDC-DUV4k35E.js +1 -0
  296. package/dist/gui/client/assets/railroadDiagram-O6MQD6OU-DMR4LXmA.js +1 -0
  297. package/dist/gui/client/assets/requirementDiagram-BXWQKSXE-DVltaF6c.js +84 -0
  298. package/dist/gui/client/assets/sankeyDiagram-P5KCCOFB-CHdNz472.js +40 -0
  299. package/dist/gui/client/assets/sequenceDiagram-WJ2MYXX4-DaMafIty.js +162 -0
  300. package/dist/gui/client/assets/stateDiagram-D77RDMKH-CEbBHqn3.js +1 -0
  301. package/dist/gui/client/assets/stateDiagram-v2-MP3YSRHH-B3JgDdFg.js +1 -0
  302. package/dist/gui/client/assets/swimlanes-42K2YHIH-BlPHndnJ.js +1 -0
  303. package/dist/gui/client/assets/swimlanesDiagram-VR7AAH4N-BPabHwsZ.js +8 -0
  304. package/dist/gui/client/assets/timeline-definition-24CTP7MA-E4Y1lPBI.js +120 -0
  305. package/dist/gui/client/assets/treeView-Q6P3EWNA-DrY0uhTN.js +1 -0
  306. package/dist/gui/client/assets/treemap-WGGIJYW6-CVotnLHf.js +1 -0
  307. package/dist/gui/client/assets/vennDiagram-4TSXK5OY-DJNrLIOF.js +34 -0
  308. package/dist/gui/client/assets/wardley-WFR3VGLG-ClOpAp5S.js +1 -0
  309. package/dist/gui/client/assets/wardleyDiagram-VM6X3IG4-qhMoKOXc.js +78 -0
  310. package/dist/gui/client/assets/xychartDiagram-S5SC5T6Z-CTuXoo9R.js +7 -0
  311. package/dist/gui/client/index.html +6 -0
  312. package/dist/gui/ops-worker.js +167 -0
  313. package/dist/gui/reads-worker.js +473 -0
  314. package/dist/gui/server.js +9780 -0
  315. package/dist/gui-QJS7XQMV.js +16 -0
  316. package/dist/init-DV5B6HQG.js +354 -0
  317. package/dist/install-6C45YXFP.js +19 -0
  318. package/dist/install-O7NSRU2W.js +13 -0
  319. package/dist/interactive-OXGYZYAS.js +22381 -0
  320. package/dist/interop-J7UOBOSF.js +254 -0
  321. package/dist/inventory-OEGIL6PY.js +144 -0
  322. package/dist/library-B3UPGY4V.js +83 -0
  323. package/dist/library-MXQA5DLT.js +309 -0
  324. package/dist/library-ROZAMUIL.js +496 -0
  325. package/dist/library-import-2LTWOVBD.js +190 -0
  326. package/dist/library-inventory-LJ3XHLWO.js +60 -0
  327. package/dist/library-validation-DARHHUNW.js +46 -0
  328. package/dist/mcp-2GSPYQ54.js +28 -0
  329. package/dist/memory-J3STUUIK.js +537 -0
  330. package/dist/models-Y3GMFJ2V.js +314 -0
  331. package/dist/monitor-LHNH577J.js +811 -0
  332. package/dist/orchestrator-DTAPXULA.js +12117 -0
  333. package/dist/panes-A743ONZ5.js +103 -0
  334. package/dist/panes-CTNO57ZY.js +76 -0
  335. package/dist/paths-3SBYJQDP.js +68 -0
  336. package/dist/preload-OJBMAIXF.js +140 -0
  337. package/dist/providers-CMETPZNS.js +232 -0
  338. package/dist/registry-37T4U6X2.js +15 -0
  339. package/dist/reset-O7EUCYWO.js +346 -0
  340. package/dist/resources-FY6XYFN2.js +189 -0
  341. package/dist/run-H64MEVTA.js +1067 -0
  342. package/dist/run-script-PQ5NRU3X.js +42 -0
  343. package/dist/settings-SNIQNXCW.js +73 -0
  344. package/dist/settings-controls-X6GMCPVG.js +202 -0
  345. package/dist/share-CAFMMQLM.js +299 -0
  346. package/dist/skills-ERKQUC7L.js +114 -0
  347. package/dist/skills-eval-CQ23MYQK.js +1099 -0
  348. package/dist/skills-inventory-TVUYJDVN.js +142 -0
  349. package/dist/slash-commands-ROG3KIFJ.js +107 -0
  350. package/dist/startup-background-KDWCQMWT.js +247 -0
  351. package/dist/steer-KKYXJSH4.js +77 -0
  352. package/dist/support-M3RCUUEL.js +40 -0
  353. package/dist/system-ZDW44ZGX.js +142 -0
  354. package/dist/target-runtimes-PWA22WVW.js +73 -0
  355. package/dist/targets-AJWA6E7Z.js +1207 -0
  356. package/dist/tasks-6L2JJRC5.js +39 -0
  357. package/dist/terminal-lease-YFUSDPAD.js +432 -0
  358. package/dist/tools-5XJUABRD.js +30 -0
  359. package/dist/trace-LA5MVR4Y.js +527 -0
  360. package/dist/tree-sitter-TQW3Y52T.js +4673 -0
  361. package/dist/tui-primitives-IUCVWLH5.js +19 -0
  362. package/dist/uninstall-SAWGGXAB.js +448 -0
  363. package/dist/upgrade-HSNSVTZG.js +300 -0
  364. package/dist/usage-XSILDHKF.js +1083 -0
  365. package/dist/verifiers-ECA5GIHL.js +633 -0
  366. package/dist/verify-R6QQCCEB.js +31 -0
  367. package/dist/version-PLZYB5KW.js +22 -0
  368. package/dist/web-fetch-PVZNMBOB.js +803 -0
  369. package/dist/wiki-generate-RP22WP5K.js +647 -0
  370. package/dist/with-panes-W3PAZPRF.js +629 -0
  371. package/dist/worker/entry.js +324 -284
  372. package/dist/workspace-check-3764ZKC2.js +83 -0
  373. package/docs/README.md +26 -10
  374. package/docs/architecture/acp.md +179 -12
  375. package/docs/architecture/artifact-placement.md +1 -1
  376. package/docs/architecture/capacity-and-scheduling.md +7 -8
  377. package/docs/architecture/context-engine.md +350 -95
  378. package/docs/architecture/model-catalog.md +18 -11
  379. package/docs/architecture/observability.md +1 -1
  380. package/docs/architecture/pi-boundary.md +59 -6
  381. package/docs/architecture/prompt-envelope-and-tools.md +147 -39
  382. package/docs/architecture/provider-adapter-cookbook.md +2 -2
  383. package/docs/architecture/safety-model.md +18 -4
  384. package/docs/architecture/trace-store.md +2 -2
  385. package/docs/architecture/tui-design.md +41 -81
  386. package/docs/architecture/worker-dispatch-mechanics.md +9 -1
  387. package/docs/gui/README.md +69 -0
  388. package/docs/gui/boundary-doctrine.md +104 -0
  389. package/docs/gui/chat-rendering-spec.md +1440 -0
  390. package/docs/gui/cli-surface-routing.md +148 -0
  391. package/docs/gui/delivery-order.md +53 -0
  392. package/docs/gui/event-bus-coverage.md +103 -0
  393. package/docs/gui/inspector-presentation.md +71 -0
  394. package/docs/gui/parity/01-cli-surface.md +74 -0
  395. package/docs/gui/parity/02-slash-and-surfaces.md +110 -0
  396. package/docs/gui/parity/03-domains-and-plan.md +69 -0
  397. package/docs/gui/performance-baseline.md +76 -0
  398. package/docs/gui/settings-write-surface.md +267 -0
  399. package/docs/gui/workflow-coverage.md +64 -0
  400. package/docs/guide/built-in-agents.md +1 -1
  401. package/docs/guide/commands-and-modes.md +256 -99
  402. package/docs/guide/configuration-and-targets.md +485 -124
  403. package/docs/guide/configuration-reference.md +165 -82
  404. package/docs/guide/doctor.md +127 -0
  405. package/docs/guide/environment-variables.md +1 -1
  406. package/docs/guide/exit-codes-and-output.md +3 -1
  407. package/docs/guide/extensions-and-sharing.md +3 -14
  408. package/docs/guide/fleet-dispatch.md +231 -45
  409. package/docs/guide/glossary.md +1 -1
  410. package/docs/guide/installation-and-lifecycle.md +27 -16
  411. package/docs/guide/interop.md +2 -2
  412. package/docs/guide/proactive-memory.md +154 -68
  413. package/docs/guide/resource-library.md +4 -0
  414. package/docs/guide/skills-marketplace.md +8 -4
  415. package/docs/guide/slurm.md +88 -0
  416. package/docs/guide/tool-usage.md +134 -11
  417. package/docs/guide/troubleshooting.md +4 -2
  418. package/docs/process/battletest-2026-09-20-fixes.md +161 -0
  419. package/docs/process/configure-tree-proposal.md +637 -0
  420. package/docs/process/documentation-coverage.md +8 -0
  421. package/docs/process/documentation-guide.md +18 -1
  422. package/docs/process/eval-runner.md +58 -14
  423. package/docs/process/performance-methodology.md +11 -3
  424. package/docs/process/release-cut-checklist.md +29 -3
  425. package/docs/process/tool-audit-v0.4.9.md +3 -0
  426. package/examples/extensions/README.md +1 -3
  427. package/examples/extensions/lab-status/clio-coder-extension.json +1 -1
  428. package/examples/extensions/measurements/clio-coder-extension.json +1 -1
  429. package/library/registry.yaml +30 -5
  430. package/library/skills/git/fix-issue/SKILL.md +2 -1
  431. package/library/skills/git/fix-issue/plugin.json +1 -1
  432. package/library/skills/git/ship/SKILL.md +2 -1
  433. package/library/skills/git/ship/plugin.json +1 -1
  434. package/library/skills/meta/clio-coder-test/SKILL.md +5 -6
  435. package/library/skills/meta/clio-coder-test/evals.md +2 -2
  436. package/library/skills/meta/clio-coder-test/references/test-map.md +2 -2
  437. package/library/skills/registry.yaml +9 -5
  438. package/library/skills/research/slurm-jobs/SKILL.md +110 -0
  439. package/library/skills/research/slurm-jobs/evals.md +39 -0
  440. package/library/skills/research/slurm-jobs/plugin.json +23 -0
  441. package/library/skills/skill-marketplace.json +18 -2
  442. package/package.json +15 -10
  443. package/src/cli/args.ts +59 -0
  444. package/src/cli/argv.ts +7 -0
  445. package/src/cli/clio.ts +9 -1
  446. package/src/cli/configure-controls.ts +136 -0
  447. package/src/cli/configure-onboarding.ts +24 -7
  448. package/src/cli/configure-quick.ts +32 -7
  449. package/src/cli/configure-target.ts +11 -1
  450. package/src/cli/configure.ts +253 -256
  451. package/src/cli/docs-server.ts +290 -0
  452. package/src/cli/docs.ts +60 -15
  453. package/src/cli/doctor-deep.ts +126 -0
  454. package/src/cli/doctor-hpc.ts +122 -0
  455. package/src/cli/doctor-slurm.ts +130 -0
  456. package/src/cli/doctor-task-worktrees.ts +88 -0
  457. package/src/cli/doctor.ts +165 -16
  458. package/src/cli/fleet-verify.ts +3 -2
  459. package/src/cli/gui.ts +111 -0
  460. package/src/cli/index.ts +14 -4
  461. package/src/cli/library.ts +2 -7
  462. package/src/cli/modes/json-stream.ts +4 -2
  463. package/src/cli/modes/print.ts +252 -25
  464. package/src/cli/run.ts +199 -71
  465. package/src/cli/skills.ts +25 -7
  466. package/src/cli/targets.ts +87 -9
  467. package/src/cli/uninstall.ts +28 -8
  468. package/src/cli/usage.ts +2 -1
  469. package/src/cli/workspace-check.ts +71 -0
  470. package/src/core/bash-exec.ts +8 -2
  471. package/src/core/bus-events.ts +32 -3
  472. package/src/core/cache-telemetry.ts +3 -2
  473. package/src/core/compile-cache.ts +11 -1
  474. package/src/core/config.ts +59 -6
  475. package/src/core/defaults.ts +27 -5
  476. package/src/core/diagnostics.ts +25 -0
  477. package/src/core/event-bus.ts +2 -1
  478. package/src/core/gateway-routing.ts +10 -3
  479. package/src/core/git-commit-attribution.ts +2 -1
  480. package/src/core/naming-compat.ts +6 -4
  481. package/src/core/package-root.ts +0 -9
  482. package/src/core/path-canonical.ts +143 -24
  483. package/src/core/residency-target-key.ts +2 -6
  484. package/src/core/run-overrides.ts +1 -1
  485. package/src/core/settings-awareness.ts +108 -0
  486. package/src/core/settings-controls.ts +673 -0
  487. package/src/core/settings-navigation.ts +116 -0
  488. package/src/core/theme-token-hex.ts +19 -9
  489. package/src/core/turn-constraints.ts +52 -0
  490. package/src/domains/agents/builtins/scout.md +7 -17
  491. package/src/domains/agents/catalog.ts +5 -1
  492. package/src/domains/agents/extension.ts +2 -1
  493. package/src/domains/agents/registry.ts +4 -3
  494. package/src/domains/agents/result-contract.ts +132 -1
  495. package/src/domains/config/classify.ts +11 -7
  496. package/src/domains/config/extension.ts +5 -1
  497. package/src/domains/config/keybindings.ts +2 -2
  498. package/src/domains/context/codewiki/coordinator.ts +10 -0
  499. package/src/domains/context/worker/snapshot.ts +6 -3
  500. package/src/domains/dispatch/active-route-planner.ts +2 -0
  501. package/src/domains/dispatch/agent-candidates.ts +5 -1
  502. package/src/domains/dispatch/capability-match.ts +1 -1
  503. package/src/domains/dispatch/contract.ts +28 -0
  504. package/src/domains/dispatch/event-pump.ts +37 -3
  505. package/src/domains/dispatch/extension.ts +391 -48
  506. package/src/domains/dispatch/failure-classification.ts +37 -2
  507. package/src/domains/dispatch/receipt-integrity.ts +3 -0
  508. package/src/domains/dispatch/run-identity.ts +10 -3
  509. package/src/domains/dispatch/target-breaker.ts +163 -0
  510. package/src/domains/dispatch/types.ts +29 -2
  511. package/src/domains/dispatch/worker-model-loads.ts +66 -0
  512. package/src/domains/dispatch/worker-protocol.ts +20 -1
  513. package/src/domains/dispatch/worker-spawn.ts +28 -2
  514. package/src/domains/eval/artifacts/redact.ts +9 -0
  515. package/src/domains/eval/metrics/noop.ts +61 -0
  516. package/src/domains/eval/reports/junit.ts +5 -1
  517. package/src/domains/eval/reports/text.ts +7 -0
  518. package/src/domains/eval/runners/clio-run.ts +19 -8
  519. package/src/domains/eval/runners/external-command.ts +29 -4
  520. package/src/domains/eval/schema/adapter.ts +6 -2
  521. package/src/domains/eval/schema/suite.ts +2 -0
  522. package/src/domains/eval/schema/validate.ts +3 -0
  523. package/src/domains/eval/suites/run.ts +167 -26
  524. package/src/domains/evidence/detail.ts +3 -2
  525. package/src/domains/extensions/operator-runtime.ts +11 -4
  526. package/src/domains/gateway/mcp/client.ts +1 -1
  527. package/src/domains/lifecycle/doctor.ts +42 -26
  528. package/src/domains/lifecycle/migrations/2026-09-18-ollama-runtime-id.ts +38 -0
  529. package/src/domains/lifecycle/migrations/index.ts +2 -0
  530. package/src/domains/middleware/demo-guidance.ts +36 -0
  531. package/src/domains/middleware/dispatch-nudge.ts +1 -1
  532. package/src/domains/middleware/memory-intervention.ts +51 -4
  533. package/src/domains/middleware/runtime.ts +5 -4
  534. package/src/domains/middleware/skills-reminder.ts +29 -52
  535. package/src/domains/middleware/task-nudge.ts +1 -0
  536. package/src/domains/middleware/watchdog.ts +4 -0
  537. package/src/domains/observability/extension.ts +2 -1
  538. package/src/domains/observability/out-of-turn-usage.ts +3 -2
  539. package/src/domains/observability/projection.ts +3 -2
  540. package/src/domains/observability/worker-progress.ts +48 -0
  541. package/src/domains/prompts/compiler.ts +148 -52
  542. package/src/domains/prompts/contract.ts +3 -3
  543. package/src/domains/prompts/demo-guidance.ts +8 -0
  544. package/src/domains/prompts/extension.ts +12 -7
  545. package/src/domains/prompts/fragments/identity/clio.md +2 -1
  546. package/src/domains/prompts/fragments/identity/docs-routing.md +2 -0
  547. package/src/domains/prompts/fragments/identity/self-awareness.md +4 -0
  548. package/src/domains/prompts/fragments/operating/contract.md +16 -7
  549. package/src/domains/prompts/fragments/operating/delegation.md +29 -13
  550. package/src/domains/prompts/fragments/operating/skills.md +18 -10
  551. package/src/domains/prompts/fragments/operating/worker.md +2 -0
  552. package/src/domains/providers/cache-deployment.ts +45 -2
  553. package/src/domains/providers/contract.ts +52 -11
  554. package/src/domains/providers/extension.ts +230 -53
  555. package/src/domains/providers/model-discovery.ts +22 -8
  556. package/src/domains/providers/models/local-models/clio-coder-local-coding-targets.yaml +5 -7
  557. package/src/domains/providers/plugins.ts +3 -4
  558. package/src/domains/providers/probe/fingerprint.ts +2 -2
  559. package/src/domains/providers/probe/reasoning.ts +9 -16
  560. package/src/domains/providers/probe/tool-call.ts +236 -0
  561. package/src/domains/providers/registry.ts +51 -8
  562. package/src/domains/providers/runtime-resolution.ts +60 -12
  563. package/src/domains/providers/runtimes/boot-manifest.ts +1 -1
  564. package/src/domains/providers/runtimes/builtins.ts +2 -2
  565. package/src/domains/providers/runtimes/common/lmstudio-http.ts +57 -41
  566. package/src/domains/providers/runtimes/common/local-synth.ts +3 -1
  567. package/src/domains/providers/runtimes/common/ollama-model-ids.ts +11 -0
  568. package/src/domains/providers/runtimes/common/probe-helpers.ts +53 -0
  569. package/src/domains/providers/runtimes/local-native/llamacpp-completion.ts +3 -1
  570. package/src/domains/providers/runtimes/local-native/llamacpp-embed.ts +7 -13
  571. package/src/domains/providers/runtimes/local-native/llamacpp-rerank.ts +7 -17
  572. package/src/domains/providers/runtimes/local-native/llamacpp.ts +1 -0
  573. package/src/domains/providers/runtimes/local-native/ollama.ts +211 -0
  574. package/src/domains/providers/runtimes/protocol/litellm.ts +77 -65
  575. package/src/domains/providers/support.ts +1 -1
  576. package/src/domains/providers/types/local-model-quirks.ts +2 -3
  577. package/src/domains/providers/types/runtime-descriptor.ts +23 -3
  578. package/src/domains/providers/types/target-descriptor.ts +15 -3
  579. package/src/domains/resources/collision.ts +7 -2
  580. package/src/domains/resources/index.ts +1 -0
  581. package/src/domains/resources/library-actions.ts +4 -2
  582. package/src/domains/resources/library-inventory.ts +6 -2
  583. package/src/domains/resources/prompts/loader.ts +20 -7
  584. package/src/domains/resources/skills/availability.ts +56 -0
  585. package/src/domains/resources/skills/loader.ts +20 -9
  586. package/src/domains/safety/action-classifier.ts +282 -31
  587. package/src/domains/safety/audit.ts +2 -1
  588. package/src/domains/safety/autonomy.ts +54 -11
  589. package/src/domains/safety/decision-presentation.ts +17 -4
  590. package/src/domains/safety/finish-contract-registration.ts +25 -1
  591. package/src/domains/safety/finish-contract.ts +20 -5
  592. package/src/domains/safety/path-policy.ts +6 -2
  593. package/src/domains/safety/policy-engine.ts +168 -48
  594. package/src/domains/safety/protected-artifacts.ts +527 -16
  595. package/src/domains/safety/read-scope.ts +120 -0
  596. package/src/domains/safety/skill-authority.ts +52 -16
  597. package/src/domains/scheduling/cluster.ts +14 -3
  598. package/src/domains/scheduling/contract.ts +7 -0
  599. package/src/domains/scheduling/extension.ts +20 -9
  600. package/src/domains/scheduling/local-capacity.ts +160 -0
  601. package/src/domains/session/context-accounting.ts +44 -31
  602. package/src/domains/session/context-ledger.ts +10 -3
  603. package/src/domains/session/entries.ts +4 -0
  604. package/src/domains/session/history.ts +1 -1
  605. package/src/domains/session/prompt-cache.ts +1 -0
  606. package/src/domains/session/prompt-manifest.ts +3 -1
  607. package/src/domains/session/retry.ts +4 -6
  608. package/src/domains/session/task-board.ts +19 -4
  609. package/src/domains/session/tree/preview.ts +3 -2
  610. package/src/engine/acp/commands.ts +653 -0
  611. package/src/engine/acp/server.ts +639 -20
  612. package/src/engine/acp/tool-mediator.ts +30 -7
  613. package/src/engine/acp/types.ts +58 -0
  614. package/src/engine/agent.ts +55 -10
  615. package/src/engine/ai.ts +11 -2
  616. package/src/engine/api-registry.ts +5 -4
  617. package/src/engine/apis/degraded-inference.ts +243 -0
  618. package/src/engine/apis/llamacpp-residency.ts +50 -6
  619. package/src/engine/apis/lmstudio-residency.ts +3 -5
  620. package/src/engine/apis/lmstudio.ts +137 -31
  621. package/src/engine/apis/ollama-http.ts +118 -0
  622. package/src/engine/apis/ollama-native.ts +216 -97
  623. package/src/engine/apis/openai-completions.ts +191 -189
  624. package/src/engine/apis/output-budget.ts +3 -1
  625. package/src/engine/apis/residency-lock.ts +2 -1
  626. package/src/engine/apis/residency.ts +339 -89
  627. package/src/engine/apis/sampling-overrides.ts +23 -2
  628. package/src/engine/apis/types.ts +1 -2
  629. package/src/engine/claude/tool-safety.ts +30 -5
  630. package/src/engine/context.ts +13 -0
  631. package/src/engine/env-api-keys.ts +2 -1
  632. package/src/engine/gemma-channel-filter.ts +3 -2
  633. package/src/engine/instrumented-tui.ts +25 -0
  634. package/src/engine/loop-guard.ts +172 -6
  635. package/src/engine/pi-mono-names.ts +16 -0
  636. package/src/engine/prewarm.ts +44 -15
  637. package/src/engine/provider-payload.ts +52 -14
  638. package/src/engine/session.ts +4 -2
  639. package/src/engine/worker-events.ts +9 -1
  640. package/src/engine/worker-runtime.ts +269 -42
  641. package/src/engine/worker-tools.ts +8 -3
  642. package/src/entry/boot-options.ts +23 -0
  643. package/src/entry/orchestrator.ts +207 -36
  644. package/src/interactive/assistant-generation-timing.ts +52 -0
  645. package/src/interactive/chat-loop-messages.ts +4 -1
  646. package/src/interactive/chat-loop.ts +59 -9
  647. package/src/interactive/chat-panel.ts +10 -1
  648. package/src/interactive/clio-editor.ts +51 -79
  649. package/src/interactive/context-meter.ts +1 -0
  650. package/src/interactive/context-overlay.ts +21 -8
  651. package/src/interactive/cost-overlay.ts +1 -1
  652. package/src/interactive/dispatch-board.ts +39 -8
  653. package/src/interactive/editor-bash.ts +0 -34
  654. package/src/interactive/editor-rails.ts +43 -0
  655. package/src/interactive/editor-submit.ts +34 -2
  656. package/src/interactive/footer/dashboard.ts +67 -38
  657. package/src/interactive/footer/demo-hints.ts +40 -0
  658. package/src/interactive/footer/key-hints.ts +21 -0
  659. package/src/interactive/footer/notifications.ts +1 -1
  660. package/src/interactive/footer/pages.ts +486 -0
  661. package/src/interactive/footer/system-metrics.ts +147 -0
  662. package/src/interactive/footer/widgets.ts +158 -63
  663. package/src/interactive/footer-panel.ts +29 -7
  664. package/src/interactive/interactive-application.ts +109 -21
  665. package/src/interactive/interactive-event-projection.ts +6 -2
  666. package/src/interactive/interactive-presentation.ts +25 -29
  667. package/src/interactive/interactive-slash-runtime.ts +32 -18
  668. package/src/interactive/interactive-subscriptions.ts +25 -5
  669. package/src/interactive/interactive-tickers.ts +21 -5
  670. package/src/interactive/keybinding-manager.ts +9 -0
  671. package/src/interactive/overlay-frame.ts +29 -7
  672. package/src/interactive/overlay-lifecycle.ts +5 -3
  673. package/src/interactive/overlay-model-selectors.ts +4 -0
  674. package/src/interactive/overlay-permission-lifecycle.ts +6 -5
  675. package/src/interactive/overlays/ask-user.ts +103 -110
  676. package/src/interactive/overlays/help-reference.ts +1 -0
  677. package/src/interactive/overlays/message-picker.ts +3 -29
  678. package/src/interactive/overlays/session-selector.ts +3 -2
  679. package/src/interactive/overlays/settings-sections.ts +2 -30
  680. package/src/interactive/overlays/settings.ts +310 -607
  681. package/src/interactive/permission-hint.ts +3 -3
  682. package/src/interactive/permission-overlay.ts +45 -27
  683. package/src/interactive/renderers/doctor-report.ts +43 -0
  684. package/src/interactive/renderers/tool-execution.ts +87 -62
  685. package/src/interactive/renderers/worker-entry.ts +76 -3
  686. package/src/interactive/side-question.ts +3 -1
  687. package/src/interactive/slash-commands.ts +78 -23
  688. package/src/interactive/startup-background.ts +131 -0
  689. package/src/interactive/startup-diagnostics.ts +16 -0
  690. package/src/interactive/status/state-machine.ts +16 -3
  691. package/src/interactive/status/types.ts +2 -0
  692. package/src/interactive/status/verbs.ts +1 -1
  693. package/src/interactive/terminal-lease.ts +26 -22
  694. package/src/interactive/theme/components.ts +1 -1
  695. package/src/interactive/theme/rules.ts +1 -1
  696. package/src/interactive/theme/tokens.ts +16 -10
  697. package/src/interactive/transcript-detail.ts +4 -0
  698. package/src/interactive/turn-context.ts +56 -20
  699. package/src/interactive/turn-middleware.ts +57 -9
  700. package/src/interactive/turn-prewarm.ts +121 -18
  701. package/src/interactive/turn-recovery.ts +10 -8
  702. package/src/interactive/turn-runtime.ts +74 -29
  703. package/src/interactive/turn-state.ts +3 -0
  704. package/src/interactive/welcome-art.ts +36 -0
  705. package/src/interactive/welcome-dashboard.ts +209 -49
  706. package/src/interactive/worker-replay.ts +4 -0
  707. package/src/interactive/worker-stream.ts +17 -2
  708. package/src/tools/agent-tools.ts +22 -1
  709. package/src/tools/builtin-tool-catalog.ts +2 -2
  710. package/src/tools/codewiki/code-nav.ts +1 -1
  711. package/src/tools/codewiki/shared.ts +39 -1
  712. package/src/tools/compete-worktrees.ts +8 -91
  713. package/src/tools/context/docs-engine.ts +44 -12
  714. package/src/tools/context/index.ts +126 -22
  715. package/src/tools/context/library.ts +1 -1
  716. package/src/tools/context/surface.ts +12 -7
  717. package/src/tools/core-bootstrap.ts +3 -0
  718. package/src/tools/dispatch-runner.ts +18 -0
  719. package/src/tools/dispatch-schema.ts +187 -206
  720. package/src/tools/edit.ts +46 -42
  721. package/src/tools/file-mutation-queue.ts +25 -26
  722. package/src/tools/gateway/clio-context-surface.ts +1 -1
  723. package/src/tools/gateway/index.ts +7 -3
  724. package/src/tools/gateway/mcp-capabilities.ts +5 -3
  725. package/src/tools/grep.ts +14 -2
  726. package/src/tools/ls.ts +1 -4
  727. package/src/tools/monitor.ts +14 -1
  728. package/src/tools/observation.ts +1 -3
  729. package/src/tools/path-utils.ts +51 -18
  730. package/src/tools/process-lease.ts +99 -0
  731. package/src/tools/read.ts +1 -1
  732. package/src/tools/registry.ts +71 -9
  733. package/src/tools/task-worktree.ts +296 -17
  734. package/src/tools/tasks.ts +29 -7
  735. package/src/tools/worker-evidence.ts +60 -1
  736. package/src/tools/worktree-root.ts +252 -0
  737. package/src/tools/write.ts +34 -30
  738. package/src/worker/entry.ts +18 -1
  739. package/src/worker/protocol.ts +54 -1
  740. package/src/worker/spec-contract.ts +22 -2
  741. package/dist/acp-ZWZCPS2A.js +0 -130
  742. package/dist/agents-LYSOWZUE.js +0 -150
  743. package/dist/auth-WBQGKWQ5.js +0 -551
  744. package/dist/background-BUMOBAQN.js +0 -37
  745. package/dist/builtins-ODRJOEDI.js +0 -22
  746. package/dist/chunk-2DRRZ57Q.js +0 -571
  747. package/dist/chunk-2JBZYUPY.js +0 -105
  748. package/dist/chunk-2VBWFXYE.js +0 -198
  749. package/dist/chunk-2X2R3UTH.js +0 -1018
  750. package/dist/chunk-32KJPXAM.js +0 -75
  751. package/dist/chunk-37LW32LZ.js +0 -32
  752. package/dist/chunk-3A3CUMKA.js +0 -54
  753. package/dist/chunk-3AND2EFU.js +0 -215
  754. package/dist/chunk-3RDHGNU7.js +0 -647
  755. package/dist/chunk-3SUDBGEI.js +0 -1323
  756. package/dist/chunk-3TQN67I2.js +0 -396
  757. package/dist/chunk-3U4BL2EV.js +0 -103
  758. package/dist/chunk-3UQADNG2.js +0 -302
  759. package/dist/chunk-434LRQ6Z.js +0 -13441
  760. package/dist/chunk-4ATBOFRP.js +0 -7802
  761. package/dist/chunk-4DNL43EZ.js +0 -139
  762. package/dist/chunk-4HFJKRGZ.js +0 -5250
  763. package/dist/chunk-555E2WVV.js +0 -322
  764. package/dist/chunk-5GZICIYO.js +0 -462
  765. package/dist/chunk-5PHVPU4G.js +0 -160
  766. package/dist/chunk-5RTEFNBP.js +0 -197
  767. package/dist/chunk-64XJW7NT.js +0 -380
  768. package/dist/chunk-6TKOFFGE.js +0 -1058
  769. package/dist/chunk-6UJ7RDI7.js +0 -1143
  770. package/dist/chunk-7FBCRWVT.js +0 -1801
  771. package/dist/chunk-7JSOSVLP.js +0 -283
  772. package/dist/chunk-7N3OLLSL.js +0 -637
  773. package/dist/chunk-7QQRPB2E.js +0 -915
  774. package/dist/chunk-A6DULIMH.js +0 -986
  775. package/dist/chunk-AB3QXXBC.js +0 -123
  776. package/dist/chunk-ACCECAH4.js +0 -49
  777. package/dist/chunk-AM6CEP2K.js +0 -2120
  778. package/dist/chunk-AUHVBIDW.js +0 -19
  779. package/dist/chunk-AY4XE6GN.js +0 -665
  780. package/dist/chunk-BBA2TAWV.js +0 -667
  781. package/dist/chunk-BFPHMSK7.js +0 -169
  782. package/dist/chunk-BMNVVKEW.js +0 -604
  783. package/dist/chunk-CKK25WN3.js +0 -72
  784. package/dist/chunk-CTGZCEI6.js +0 -33
  785. package/dist/chunk-DIAJYJYG.js +0 -446
  786. package/dist/chunk-DVNAPPXU.js +0 -27
  787. package/dist/chunk-DXVMLM3Z.js +0 -92
  788. package/dist/chunk-E3LEPLQ2.js +0 -68
  789. package/dist/chunk-EHZRAB4U.js +0 -63
  790. package/dist/chunk-EM2DIQAJ.js +0 -179
  791. package/dist/chunk-EM2WNQS2.js +0 -93
  792. package/dist/chunk-ETF4ROKH.js +0 -595
  793. package/dist/chunk-F2YM3JY4.js +0 -22513
  794. package/dist/chunk-FEBQWHJT.js +0 -1023
  795. package/dist/chunk-FPS4R2RN.js +0 -1975
  796. package/dist/chunk-GD55RTIW.js +0 -33
  797. package/dist/chunk-GJDRMBDI.js +0 -573
  798. package/dist/chunk-GREYLTZ5.js +0 -658
  799. package/dist/chunk-H2WSCZZT.js +0 -238
  800. package/dist/chunk-H6IUCY6Q.js +0 -117
  801. package/dist/chunk-H72DCH3E.js +0 -563
  802. package/dist/chunk-H7TXJR23.js +0 -705
  803. package/dist/chunk-HBJQQTKM.js +0 -40
  804. package/dist/chunk-HCVKSGNZ.js +0 -990
  805. package/dist/chunk-HVCAY2FH.js +0 -67
  806. package/dist/chunk-I47EJPYL.js +0 -1377
  807. package/dist/chunk-IALGWTLO.js +0 -36
  808. package/dist/chunk-IALZJE37.js +0 -1710
  809. package/dist/chunk-IC7JXLOM.js +0 -1577
  810. package/dist/chunk-IOSVTTCD.js +0 -108
  811. package/dist/chunk-IPTPMLA6.js +0 -475
  812. package/dist/chunk-IZZI3SKQ.js +0 -128
  813. package/dist/chunk-JABWPKFY.js +0 -27
  814. package/dist/chunk-JIYWMQZ5.js +0 -175
  815. package/dist/chunk-JKU34ACI.js +0 -693
  816. package/dist/chunk-JOBN2YQQ.js +0 -176
  817. package/dist/chunk-JOL2QRLE.js +0 -152
  818. package/dist/chunk-JTR3VSV3.js +0 -44
  819. package/dist/chunk-JU6MAMRJ.js +0 -362
  820. package/dist/chunk-JURMQWVJ.js +0 -15
  821. package/dist/chunk-K2BLQC5E.js +0 -262
  822. package/dist/chunk-K3XN4LZ4.js +0 -402
  823. package/dist/chunk-KIVFXGBM.js +0 -688
  824. package/dist/chunk-KKRXONXG.js +0 -43
  825. package/dist/chunk-KOAHT3N2.js +0 -395
  826. package/dist/chunk-KP5BPXR3.js +0 -73
  827. package/dist/chunk-KQ6IDQIB.js +0 -39
  828. package/dist/chunk-KRJQG47M.js +0 -1289
  829. package/dist/chunk-KW6OJ7IY.js +0 -221
  830. package/dist/chunk-L3NBWLSN.js +0 -314
  831. package/dist/chunk-L4RUTLRL.js +0 -59
  832. package/dist/chunk-LGTVWPRN.js +0 -47
  833. package/dist/chunk-LSQW6KZO.js +0 -200
  834. package/dist/chunk-LTR5QCLS.js +0 -446
  835. package/dist/chunk-LWJYOHT3.js +0 -165
  836. package/dist/chunk-M6YLF66Z.js +0 -2687
  837. package/dist/chunk-MJ4QEJVT.js +0 -185
  838. package/dist/chunk-MO65K5CH.js +0 -1148
  839. package/dist/chunk-MTOZEQHL.js +0 -637
  840. package/dist/chunk-MZDPF35R.js +0 -45
  841. package/dist/chunk-MZKYVIWW.js +0 -188
  842. package/dist/chunk-NBPA5QM6.js +0 -386
  843. package/dist/chunk-NMBEW4PP.js +0 -688
  844. package/dist/chunk-NPLLK3HO.js +0 -3610
  845. package/dist/chunk-NSYGPIVW.js +0 -39
  846. package/dist/chunk-NXTV5OI5.js +0 -1020
  847. package/dist/chunk-NYDG4QP4.js +0 -689
  848. package/dist/chunk-OA2GDACN.js +0 -146
  849. package/dist/chunk-PJI57EC6.js +0 -236
  850. package/dist/chunk-PJJBUGMR.js +0 -4484
  851. package/dist/chunk-PNJE7JPS.js +0 -50
  852. package/dist/chunk-PP23PZEV.js +0 -1347
  853. package/dist/chunk-PPIFDSBK.js +0 -409
  854. package/dist/chunk-PTFISXQO.js +0 -319
  855. package/dist/chunk-QB33Z5S7.js +0 -1865
  856. package/dist/chunk-QGNII5VC.js +0 -110
  857. package/dist/chunk-QH3ZTUOA.js +0 -113
  858. package/dist/chunk-QI72X67S.js +0 -481
  859. package/dist/chunk-QJMRYTCX.js +0 -56
  860. package/dist/chunk-QKHZZFKH.js +0 -98
  861. package/dist/chunk-RDKX2PME.js +0 -66
  862. package/dist/chunk-RL7LJYN4.js +0 -66
  863. package/dist/chunk-RPMNIFRY.js +0 -65
  864. package/dist/chunk-RQROVOV3.js +0 -670
  865. package/dist/chunk-S34A7BSP.js +0 -97
  866. package/dist/chunk-SJETVJHX.js +0 -119
  867. package/dist/chunk-SJMNU4ZS.js +0 -634
  868. package/dist/chunk-SL2RDHKO.js +0 -19
  869. package/dist/chunk-SLLG2G44.js +0 -85
  870. package/dist/chunk-SQAZN2V3.js +0 -2744
  871. package/dist/chunk-SQBT46OF.js +0 -814
  872. package/dist/chunk-SRCEQKQS.js +0 -165
  873. package/dist/chunk-TCUOGIL2.js +0 -52
  874. package/dist/chunk-TIWPKCVO.js +0 -42
  875. package/dist/chunk-U44YYLVV.js +0 -1529
  876. package/dist/chunk-UIU7MGZ3.js +0 -486
  877. package/dist/chunk-USBBEKHW.js +0 -177
  878. package/dist/chunk-VHKTOLEW.js +0 -1416
  879. package/dist/chunk-VPWGADBG.js +0 -3151
  880. package/dist/chunk-VQD7NH7Z.js +0 -356
  881. package/dist/chunk-VWFCAK34.js +0 -697
  882. package/dist/chunk-W5RM7YAH.js +0 -78
  883. package/dist/chunk-W72LLZAV.js +0 -243
  884. package/dist/chunk-WGRDABW7.js +0 -207
  885. package/dist/chunk-WWRV5RJI.js +0 -165
  886. package/dist/chunk-XCUDZQLX.js +0 -195
  887. package/dist/chunk-XFLSL7BT.js +0 -386
  888. package/dist/chunk-XJZEDCNT.js +0 -391
  889. package/dist/chunk-XLLEL3K7.js +0 -709
  890. package/dist/chunk-XNZWWDC3.js +0 -686
  891. package/dist/chunk-XRECG65F.js +0 -308
  892. package/dist/chunk-XTQ7MEJG.js +0 -457
  893. package/dist/chunk-XW2UZICE.js +0 -372
  894. package/dist/chunk-Y3M2T5RO.js +0 -891
  895. package/dist/chunk-YGDMBK7O.js +0 -567
  896. package/dist/chunk-YJCCMYYT.js +0 -125
  897. package/dist/chunk-YPQOPFP7.js +0 -797
  898. package/dist/chunk-YQYINEJI.js +0 -132
  899. package/dist/chunk-ZF6CV4WZ.js +0 -5614
  900. package/dist/chunk-ZKJU55MX.js +0 -326
  901. package/dist/chunk-ZKQ63XZ5.js +0 -1196
  902. package/dist/chunk-ZKVMDNAN.js +0 -962
  903. package/dist/chunk-ZST3FRCV.js +0 -132
  904. package/dist/clio-JUDCLNHC.js +0 -26
  905. package/dist/clio-context-tools-FT672MNZ.js +0 -136
  906. package/dist/code-nav-7OVCTP2Z.js +0 -688
  907. package/dist/compile-cache-WJEPUZEJ.js +0 -16
  908. package/dist/components-OZXZMDWU.js +0 -674
  909. package/dist/config-P3ZQVF63.js +0 -275
  910. package/dist/config-graph-GKAOBAS5.js +0 -160
  911. package/dist/configure-25LRYZJG.js +0 -86
  912. package/dist/context-72VQV7JX.js +0 -73
  913. package/dist/context-COWRWXP3.js +0 -286
  914. package/dist/context-WB3D474G.js +0 -344
  915. package/dist/context-clear-Y4LYMWC6.js +0 -192
  916. package/dist/context-index-W6A4V7OC.js +0 -120
  917. package/dist/context-map-DKL3QT6D.js +0 -555
  918. package/dist/context-working-set-TMZYVC7A.js +0 -1560
  919. package/dist/data-tool-KMBWKKWR.js +0 -2987
  920. package/dist/detail-4GLROGY5.js +0 -123
  921. package/dist/dispatch-runner-TR3LBP5P.js +0 -2446
  922. package/dist/docs-ZK777W2G.js +0 -101
  923. package/dist/doctor-WC4OV2OB.js +0 -814
  924. package/dist/eval-FUNWJNUJ.js +0 -5050
  925. package/dist/eval-inventory-CX24K2JT.js +0 -260
  926. package/dist/evals-L73EBHSU.js +0 -104
  927. package/dist/evidence-AVJ2RTHX.js +0 -392
  928. package/dist/evidence-P4NZOAK7.js +0 -233
  929. package/dist/evidence-Y55WKYHH.js +0 -246
  930. package/dist/evolve-MAWKRYWF.js +0 -617
  931. package/dist/extensions-PYQH3H47.js +0 -308
  932. package/dist/fleet-M4H2QBWT.js +0 -268
  933. package/dist/fleet-ULBXXRDR.js +0 -923
  934. package/dist/fleet-commands-7NNC4JZU.js +0 -76
  935. package/dist/fleet-decisions-EHEY7KPU.js +0 -52
  936. package/dist/fleet-graph-LQ2AHZT3.js +0 -136
  937. package/dist/fleet-inspect-5IGBIIYZ.js +0 -312
  938. package/dist/fleet-new-RCKGSRDV.js +0 -48
  939. package/dist/fleet-preflight-UTTNOKMG.js +0 -27
  940. package/dist/fleet-validate-YGILJKA6.js +0 -91
  941. package/dist/fleet-verify-AUWTCDKR.js +0 -210
  942. package/dist/fleet-view-TGUFCY5A.js +0 -127
  943. package/dist/init-GFN2Z7NF.js +0 -333
  944. package/dist/install-3RZDDP23.js +0 -13
  945. package/dist/install-6PIF6F6W.js +0 -19
  946. package/dist/interop-EF5JUWWK.js +0 -246
  947. package/dist/inventory-I6VJDDYF.js +0 -127
  948. package/dist/library-3J5IO2OJ.js +0 -75
  949. package/dist/library-IJTOFTDS.js +0 -307
  950. package/dist/library-Z3KZSHPE.js +0 -492
  951. package/dist/library-import-IMKFLDHX.js +0 -183
  952. package/dist/library-inventory-CQP5D6GU.js +0 -56
  953. package/dist/library-validation-33UTX7AI.js +0 -42
  954. package/dist/mcp-5FWZKUS6.js +0 -26
  955. package/dist/memory-36CWN67Y.js +0 -520
  956. package/dist/models-KQ6PQJJQ.js +0 -302
  957. package/dist/monitor-XX6ZD6KC.js +0 -785
  958. package/dist/orchestrator-SK6HDAOP.js +0 -42067
  959. package/dist/panes-L27QRXUH.js +0 -74
  960. package/dist/panes-LXZIWNOZ.js +0 -103
  961. package/dist/paths-7DJDU4P4.js +0 -67
  962. package/dist/preload-K2TDYI4Y.js +0 -124
  963. package/dist/registry-DESGAXWK.js +0 -11
  964. package/dist/reset-73VU3XNT.js +0 -345
  965. package/dist/resources-3BYJYVYL.js +0 -181
  966. package/dist/run-AR7PY6GW.js +0 -896
  967. package/dist/run-script-H2KUDIII.js +0 -41
  968. package/dist/settings-3VMBMWID.js +0 -72
  969. package/dist/share-HVWH4FPF.js +0 -293
  970. package/dist/skills-5TYEY75Q.js +0 -100
  971. package/dist/skills-eval-CK3MD63Z.js +0 -1083
  972. package/dist/skills-inventory-KSFYG3I6.js +0 -138
  973. package/dist/slash-commands-DMVHML7P.js +0 -98
  974. package/dist/steer-XCD6V3EW.js +0 -77
  975. package/dist/support-JAZL6VBR.js +0 -38
  976. package/dist/system-3TDQRMZZ.js +0 -116
  977. package/dist/targets-EZKHAYRN.js +0 -1117
  978. package/dist/tasks-SNEFHWYW.js +0 -36
  979. package/dist/terminal-lease-BNLFA4OF.js +0 -419
  980. package/dist/tools-7IM6BDCE.js +0 -28
  981. package/dist/trace-C3MBGD4S.js +0 -524
  982. package/dist/tree-sitter-AQUUOSYM.js +0 -4673
  983. package/dist/tui-primitives-36BY2774.js +0 -18
  984. package/dist/uninstall-WWLOSZ42.js +0 -432
  985. package/dist/upgrade-ETK2JNSJ.js +0 -297
  986. package/dist/usage-S2HOB7BZ.js +0 -1065
  987. package/dist/verifiers-QDTEVH7R.js +0 -632
  988. package/dist/verify-SUKUK6XM.js +0 -31
  989. package/dist/version-RFPKO6T7.js +0 -21
  990. package/dist/web/client/assets/abnfDiagram-VCTEODGH-BznNOe_I.js +0 -1
  991. package/dist/web/client/assets/architecture-7GRP2DOG-BQO9DL_y.js +0 -1
  992. package/dist/web/client/assets/architectureDiagram-5GKGNRK7-CKPbdvyx.js +0 -36
  993. package/dist/web/client/assets/blockDiagram-I7D4REHJ-prINbpbM.js +0 -129
  994. package/dist/web/client/assets/c4Diagram-7LVT6UL2-DkVRKtyU.js +0 -38
  995. package/dist/web/client/assets/channel-c4EeUUqA.js +0 -1
  996. package/dist/web/client/assets/chunk-4HAMMTFA-CV0Z1ApC.js +0 -62
  997. package/dist/web/client/assets/chunk-75Z2AOVW-D34Nohxq.js +0 -2
  998. package/dist/web/client/assets/chunk-DU6HZSFF-Das_cS-O.js +0 -125
  999. package/dist/web/client/assets/chunk-F27PBJKO-CmRojxkG.js +0 -1
  1000. package/dist/web/client/assets/chunk-GMAD6QVW-ClYZmc73.js +0 -72
  1001. package/dist/web/client/assets/chunk-GVQU2GXP-B2BiHFt-.js +0 -1
  1002. package/dist/web/client/assets/chunk-IMKFNOWR-BGApZ8nP.js +0 -231
  1003. package/dist/web/client/assets/chunk-L3NEJ4N5-DIzCgpkY.js +0 -1
  1004. package/dist/web/client/assets/chunk-OSK3NFVY-BPT-yePv.js +0 -10
  1005. package/dist/web/client/assets/chunk-P2QGCYS3-BC1WTc2t.js +0 -1
  1006. package/dist/web/client/assets/chunk-POPQ4Y6H-BSjzBmZU.js +0 -1
  1007. package/dist/web/client/assets/chunk-PWAF6VOD-BIjLs86Z.js +0 -1
  1008. package/dist/web/client/assets/chunk-SHT3W25Y-CduDz2cm.js +0 -168
  1009. package/dist/web/client/assets/chunk-SVP7TREG-XUn4pPAP.js +0 -88
  1010. package/dist/web/client/assets/chunk-TICWLB2K-DcBy2DKy.js +0 -206
  1011. package/dist/web/client/assets/classDiagram-ZZMXUADV-C0HR7YKN.js +0 -1
  1012. package/dist/web/client/assets/classDiagram-v2-VYDZK3BY-C0HR7YKN.js +0 -1
  1013. package/dist/web/client/assets/cynefin-OW5HDTMX-BecPbyM6.js +0 -1
  1014. package/dist/web/client/assets/cynefinDiagram-5FMLGOSQ-BzMzFwyT.js +0 -62
  1015. package/dist/web/client/assets/dagre-GXQ25YYZ-CAWJmRMG.js +0 -4
  1016. package/dist/web/client/assets/diagram-S7CK7UJ4--lp0ALmn.js +0 -30
  1017. package/dist/web/client/assets/diagram-UQ7AKVKN-gKUnsjcj.js +0 -41
  1018. package/dist/web/client/assets/diagram-VSXAHHWV-BoN5D1Gh.js +0 -3
  1019. package/dist/web/client/assets/diagram-VX7I27RA-BMtuswQ6.js +0 -24
  1020. package/dist/web/client/assets/diagram-Z3DM3KII-DtU8LXrA.js +0 -24
  1021. package/dist/web/client/assets/ebnfDiagram-PWID7BFC-DDcnv9BH.js +0 -1
  1022. package/dist/web/client/assets/erDiagram-RLTQ6QDP-DvRb4iDL.js +0 -99
  1023. package/dist/web/client/assets/eventmodeling-NTZA5JFV-01h4SbTc.js +0 -1
  1024. package/dist/web/client/assets/flowDiagram-HODETNUW-Bll_YZ6T.js +0 -1
  1025. package/dist/web/client/assets/framework-YGoR34M4.js +0 -9
  1026. package/dist/web/client/assets/ganttDiagram-EL5Y4UJY-DdFZ9hvH.js +0 -292
  1027. package/dist/web/client/assets/gitGraph-4MIJSDKK-DjD_AAMj.js +0 -1
  1028. package/dist/web/client/assets/gitGraphDiagram-WWUBYQGX-CDyN9n2u.js +0 -106
  1029. package/dist/web/client/assets/index-CVcy0FAn.js +0 -75
  1030. package/dist/web/client/assets/index-Dsi52apB.css +0 -1
  1031. package/dist/web/client/assets/info-A6RAGUB7-C_XK8Hq0.js +0 -1
  1032. package/dist/web/client/assets/infoDiagram-27XIBGKW-DIe4tJ1i.js +0 -2
  1033. package/dist/web/client/assets/ishikawaDiagram-5VMMS53U-CVl5unKI.js +0 -70
  1034. package/dist/web/client/assets/journeyDiagram-3NMN7TZE-CPEB1Vt8.js +0 -139
  1035. package/dist/web/client/assets/kanban-definition-UXKFOSKX-j-9WXjYQ.js +0 -89
  1036. package/dist/web/client/assets/line-BIDAcEtX.js +0 -1
  1037. package/dist/web/client/assets/mermaid-parser.core-Ux4vssh0.js +0 -7
  1038. package/dist/web/client/assets/mermaid.core-CDuwVKeh.js +0 -44
  1039. package/dist/web/client/assets/mindmap-definition-YA3MSWOX-5MlQEeQ6.js +0 -96
  1040. package/dist/web/client/assets/packet-AYTQ26CC-DRO66c9Q.js +0 -1
  1041. package/dist/web/client/assets/pegDiagram-XKGWAZYB-BakZnSjM.js +0 -1
  1042. package/dist/web/client/assets/pie-WAS4IAKB-BEzcmhz8.js +0 -1
  1043. package/dist/web/client/assets/pieDiagram-E7YTZNPT-DpmqgoPt.js +0 -39
  1044. package/dist/web/client/assets/quadrantDiagram-AXDQQJYC-DuMPwwV2.js +0 -7
  1045. package/dist/web/client/assets/radar-RG4KPBEZ-Djm3oXl5.js +0 -1
  1046. package/dist/web/client/assets/railroad-74A4TZTK-Cpvkwsao.js +0 -1
  1047. package/dist/web/client/assets/railroad-abnf-HS5TGJTU-CpRQ3ruG.js +0 -1
  1048. package/dist/web/client/assets/railroad-ebnf-LZEXJU2U-1Rm5a5eJ.js +0 -1
  1049. package/dist/web/client/assets/railroad-peg-WCYAUIDC-C8344cTh.js +0 -1
  1050. package/dist/web/client/assets/railroadDiagram-O6MQD6OU-CgMS4B6R.js +0 -1
  1051. package/dist/web/client/assets/requirementDiagram-BXWQKSXE-CX5eoNdN.js +0 -84
  1052. package/dist/web/client/assets/sankeyDiagram-P5KCCOFB-CODBX2N3.js +0 -40
  1053. package/dist/web/client/assets/sequenceDiagram-WJ2MYXX4-eUhhF8OR.js +0 -162
  1054. package/dist/web/client/assets/stateDiagram-D77RDMKH-vR6l0NC2.js +0 -1
  1055. package/dist/web/client/assets/stateDiagram-v2-MP3YSRHH-BYUm8jLY.js +0 -1
  1056. package/dist/web/client/assets/swimlanes-42K2YHIH-v9Tw_zX7.js +0 -1
  1057. package/dist/web/client/assets/swimlanesDiagram-VR7AAH4N-B2jdCvhD.js +0 -8
  1058. package/dist/web/client/assets/timeline-definition-24CTP7MA-DxianbhU.js +0 -120
  1059. package/dist/web/client/assets/treeView-Q6P3EWNA-DLxnZb9R.js +0 -1
  1060. package/dist/web/client/assets/treemap-WGGIJYW6-I7UnZ6xJ.js +0 -1
  1061. package/dist/web/client/assets/vennDiagram-4TSXK5OY-Ar7M8Mrj.js +0 -34
  1062. package/dist/web/client/assets/wardley-WFR3VGLG-B8ZSHeDu.js +0 -1
  1063. package/dist/web/client/assets/wardleyDiagram-VM6X3IG4-Qks2FmIn.js +0 -78
  1064. package/dist/web/client/assets/xychartDiagram-S5SC5T6Z-BBBjRtiE.js +0 -7
  1065. package/dist/web/client/index.html +0 -6
  1066. package/dist/web/ops-worker.js +0 -37
  1067. package/dist/web/reads-worker.js +0 -1726
  1068. package/dist/web/server.js +0 -8499
  1069. package/dist/web-EMGUGGEI.js +0 -13
  1070. package/dist/web-fetch-6BRRVQON.js +0 -805
  1071. package/dist/wiki-generate-XHSJTDOP.js +0 -627
  1072. package/dist/with-panes-Z6BTEHMZ.js +0 -628
  1073. package/evals/README.md +0 -9
  1074. package/evals/behavioral-corpus-grader.mjs +0 -236
  1075. package/evals/behavioral-machinery-baseline.json +0 -2276
  1076. package/evals/behavioral-machinery-driver.ts +0 -250
  1077. package/evals/behavioral-machinery-support.ts +0 -254
  1078. package/evals/behavioral-machinery.yaml +0 -614
  1079. package/evals/behavioral-model-negative-control.yaml +0 -69
  1080. package/evals/behavioral-model.yaml +0 -482
  1081. package/evals/fixtures/behavioral-facts.txt +0 -3
  1082. package/evals/fixtures/behavioral-main.ts +0 -7
  1083. package/evals/fixtures/decoy/note.txt +0 -2
  1084. package/evals/fixtures/docs-retrieval.json +0 -102
  1085. package/evals/fixtures/private/credentials.txt +0 -1
  1086. package/evals/fixtures/scalar-decision.json +0 -17
  1087. package/evals/fixtures/scout-citation-pipeline.json +0 -55
  1088. package/evals/fixtures/source-explanation.json +0 -74
  1089. package/evals/fixtures/tool-arguments.json +0 -18
  1090. package/evals/fixtures/tool-surface/read.txt +0 -4
  1091. package/evals/fixtures/tool-surface/subdir/keep.txt +0 -1
  1092. package/evals/no-edit-memory-grader.mjs +0 -149
  1093. package/evals/scalar-decision-grader.py +0 -41
  1094. package/evals/scalar-decision-machinery.ts +0 -145
  1095. package/evals/source-explanation-grader.mjs +0 -118
  1096. package/evals/tool-surface-grader.mjs +0 -53
  1097. package/evals/tool-surface-model.yaml +0 -274
  1098. package/evals/tracked-metrics-baseline.yaml +0 -229
  1099. package/evals/tracked-metrics-grader.mjs +0 -129
  1100. package/src/cli/web.ts +0 -79
  1101. package/src/domains/providers/runtimes/local-native/ollama-native.ts +0 -122
  1102. /package/dist/assets/{web-notices → gui-notices}/@hono__node-server-LICENSE +0 -0
  1103. /package/dist/assets/{web-notices → gui-notices}/hono-LICENSE +0 -0
  1104. /package/dist/{web → gui}/client/THIRD_PARTY_LICENSES.md +0 -0
  1105. /package/dist/{web → gui}/client/assets/arc-Pry-7G1_.js +0 -0
  1106. /package/dist/{web → gui}/client/assets/array-BifhSqXX.js +0 -0
  1107. /package/dist/{web → gui}/client/assets/atkinson-hyperlegible-next-latin-ext-wght-normal-C6vrW8VD.woff2 +0 -0
  1108. /package/dist/{web → gui}/client/assets/atkinson-hyperlegible-next-latin-wght-normal-BcXVPD7q.woff2 +0 -0
  1109. /package/dist/{web → gui}/client/assets/chunk-2Q5K7J3B-C1jixKkw.js +0 -0
  1110. /package/dist/{web → gui}/client/assets/chunk-5VM5RSS4-ZNzvKenW.js +0 -0
  1111. /package/dist/{web → gui}/client/assets/chunk-FOHPRMQF-CoA4358r.js +0 -0
  1112. /package/dist/{web → gui}/client/assets/chunk-JWPE2WC7-DVXcaiue.js +0 -0
  1113. /package/dist/{web → gui}/client/assets/chunk-XXDRQBXY-DqAYeljN.js +0 -0
  1114. /package/dist/{web → gui}/client/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +0 -0
  1115. /package/dist/{web → gui}/client/assets/commit-mono-latin-400-normal-s0S3qwFW.woff +0 -0
  1116. /package/dist/{web → gui}/client/assets/commit-mono-latin-400-normal-wzhe4RuD.woff2 +0 -0
  1117. /package/dist/{web → gui}/client/assets/cose-bilkent-JH36ORCC-CVh1icwb.js +0 -0
  1118. /package/dist/{web → gui}/client/assets/cytoscape.esm-c2aL46s-.js +0 -0
  1119. /package/dist/{web → gui}/client/assets/dagre-C-rnJpZF.js +0 -0
  1120. /package/dist/{web → gui}/client/assets/defaultLocale-BFoDCU3G.js +0 -0
  1121. /package/dist/{web → gui}/client/assets/dist-v5Q1xZ2K.js +0 -0
  1122. /package/dist/{web → gui}/client/assets/graphlib-DS17s2tU.js +0 -0
  1123. /package/dist/{web → gui}/client/assets/init-C-OQMol4.js +0 -0
  1124. /package/dist/{web → gui}/client/assets/katex-ZlcWpGUi.js +0 -0
  1125. /package/dist/{web → gui}/client/assets/linear-SzVmGSw4.js +0 -0
  1126. /package/dist/{web → gui}/client/assets/newsreader-latin-ext-wght-normal-C-3rgBeH.woff2 +0 -0
  1127. /package/dist/{web → gui}/client/assets/newsreader-latin-wght-normal-CCVVNp6i.woff2 +0 -0
  1128. /package/dist/{web → gui}/client/assets/newsreader-vietnamese-wght-normal-Czsa-EzN.woff2 +0 -0
  1129. /package/dist/{web → gui}/client/assets/ordinal-BDEzSJ7C.js +0 -0
  1130. /package/dist/{web → gui}/client/assets/path-fybaL0A-.js +0 -0
  1131. /package/dist/{web → gui}/client/assets/prism-bash-D6zCJ74D.js +0 -0
  1132. /package/dist/{web → gui}/client/assets/prism-c-04YixN25.js +0 -0
  1133. /package/dist/{web → gui}/client/assets/prism-clike-DapgWyxx.js +0 -0
  1134. /package/dist/{web → gui}/client/assets/prism-core-BtsZdCS6.js +0 -0
  1135. /package/dist/{web → gui}/client/assets/prism-cpp-C-lJbC-6.js +0 -0
  1136. /package/dist/{web → gui}/client/assets/prism-css-CPgOzxXp.js +0 -0
  1137. /package/dist/{web → gui}/client/assets/prism-diff-BF8m0_mq.js +0 -0
  1138. /package/dist/{web → gui}/client/assets/prism-docker-DkT6yOFj.js +0 -0
  1139. /package/dist/{web → gui}/client/assets/prism-fortran-Be5x3y1V.js +0 -0
  1140. /package/dist/{web → gui}/client/assets/prism-go-C_8qAH5n.js +0 -0
  1141. /package/dist/{web → gui}/client/assets/prism-ini-BESK3y0r.js +0 -0
  1142. /package/dist/{web → gui}/client/assets/prism-javascript-BnO-swvr.js +0 -0
  1143. /package/dist/{web → gui}/client/assets/prism-json-Dp_-W-Hv.js +0 -0
  1144. /package/dist/{web → gui}/client/assets/prism-jsx-D-D0NWtC.js +0 -0
  1145. /package/dist/{web → gui}/client/assets/prism-julia-DIjOgiAV.js +0 -0
  1146. /package/dist/{web → gui}/client/assets/prism-latex-DNMbqcH_.js +0 -0
  1147. /package/dist/{web → gui}/client/assets/prism-makefile-CRKWLQ8l.js +0 -0
  1148. /package/dist/{web → gui}/client/assets/prism-markdown-C0FPJ1Iz.js +0 -0
  1149. /package/dist/{web → gui}/client/assets/prism-markup-Cp04rIa1.js +0 -0
  1150. /package/dist/{web → gui}/client/assets/prism-matlab-D-nk08al.js +0 -0
  1151. /package/dist/{web → gui}/client/assets/prism-python-CfiSVtM6.js +0 -0
  1152. /package/dist/{web → gui}/client/assets/prism-r-QmNGR8LX.js +0 -0
  1153. /package/dist/{web → gui}/client/assets/prism-rust-Bu9N8X3N.js +0 -0
  1154. /package/dist/{web → gui}/client/assets/prism-shell-session-Be4UuYoM.js +0 -0
  1155. /package/dist/{web → gui}/client/assets/prism-sql-CYhVDMEE.js +0 -0
  1156. /package/dist/{web → gui}/client/assets/prism-toml-DKb54GAT.js +0 -0
  1157. /package/dist/{web → gui}/client/assets/prism-tsx-p6J2Kc_4.js +0 -0
  1158. /package/dist/{web → gui}/client/assets/prism-typescript-BMqONzxf.js +0 -0
  1159. /package/dist/{web → gui}/client/assets/prism-yaml-C0JHu8gr.js +0 -0
  1160. /package/dist/{web → gui}/client/assets/purify.es-ChwZkWde.js +0 -0
  1161. /package/dist/{web → gui}/client/assets/rolldown-runtime-hePW80VL.js +0 -0
  1162. /package/dist/{web → gui}/client/assets/rough.esm-Dy-Kn_BL.js +0 -0
  1163. /package/dist/{web → gui}/client/assets/sizeCapture-INFHLROL-B0uUizjq.js +0 -0
  1164. /package/dist/{web → gui}/client/assets/src-B6xuSHsQ.js +0 -0
  1165. /package/dist/{web → gui}/client/clio-coder-logo.webp +0 -0
  1166. /package/dist/{web → gui}/client/icon-192.png +0 -0
  1167. /package/dist/{web → gui}/client/icon-512.png +0 -0
  1168. /package/dist/{web → gui}/client/manifest.webmanifest +0 -0
  1169. /package/dist/{web → gui}/client/offline.css +0 -0
  1170. /package/dist/{web → gui}/client/offline.html +0 -0
  1171. /package/dist/{web → gui}/client/offline.js +0 -0
  1172. /package/dist/{web → gui}/client/sw.js +0 -0
@@ -0,0 +1,4157 @@
1
+ import { createRequire as __clioCreateRequire } from "node:module"; const require = __clioCreateRequire(import.meta.url);
2
+ import {
3
+ canSelect,
4
+ promptMultiSelect,
5
+ promptSelect,
6
+ promptText
7
+ } from "./chunk-HSQQFDB3.js";
8
+ import {
9
+ createDelayedManualCodeInput,
10
+ promptOAuthSelection
11
+ } from "./chunk-LK2FN5JY.js";
12
+ import {
13
+ createLifecyclePresenter,
14
+ shortenPath
15
+ } from "./chunk-N24R6KWS.js";
16
+ import {
17
+ column,
18
+ terminalColumns,
19
+ truncate,
20
+ twoColumnRow,
21
+ wrapPlain
22
+ } from "./chunk-ZIDFQJRB.js";
23
+ import {
24
+ editTextExternally,
25
+ resolveExternalEditor
26
+ } from "./chunk-R2CT5YDO.js";
27
+ import {
28
+ fingerprintNativeRuntime
29
+ } from "./chunk-KW5HXKLJ.js";
30
+ import {
31
+ initializeClioHome
32
+ } from "./chunk-URCXX7WJ.js";
33
+ import {
34
+ INHERITED_PROJECT_CONTEXT,
35
+ acceptInteropAgents,
36
+ declineInteropAgents,
37
+ interopProposals,
38
+ renderProposalEntry
39
+ } from "./chunk-T2MDZES3.js";
40
+ import {
41
+ detectInteropAgents,
42
+ resolveOnPath
43
+ } from "./chunk-4A6YRGV4.js";
44
+ import {
45
+ credentialWriteFailed,
46
+ printPlaintextCredentialWarning
47
+ } from "./chunk-GGPF6LLE.js";
48
+ import {
49
+ SETTING_CONTROLS,
50
+ applyControlValue,
51
+ controlInstructions,
52
+ formatControlValue
53
+ } from "./chunk-VOYUCAQF.js";
54
+ import {
55
+ getAtPath
56
+ } from "./chunk-GGWI3OVM.js";
57
+ import {
58
+ SETTINGS_SECTIONS,
59
+ resolveSettingsSection,
60
+ settingsGroupForPath,
61
+ settingsSectionForPath
62
+ } from "./chunk-LJRBX7QR.js";
63
+ import {
64
+ diffSettings
65
+ } from "./chunk-GN7QBEEI.js";
66
+ import {
67
+ describeLocalCapacity,
68
+ observeHostCapacityFacts,
69
+ resolveLocalConcurrency
70
+ } from "./chunk-E6IPKW2E.js";
71
+ import {
72
+ printError,
73
+ printOk
74
+ } from "./chunk-NBXFPI7U.js";
75
+ import {
76
+ source_default
77
+ } from "./chunk-SQZHXUB3.js";
78
+ import {
79
+ loadedContextWindowForModel,
80
+ probeCapabilitiesForModel,
81
+ readTargetModelSnapshot,
82
+ recordTargetModelSnapshot
83
+ } from "./chunk-EYTLV3W3.js";
84
+ import {
85
+ credentialsPresent
86
+ } from "./chunk-DVTBERFY.js";
87
+ import {
88
+ isOrchestratorEligibleRuntime
89
+ } from "./chunk-6EJYVCTN.js";
90
+ import {
91
+ greetLmStudio,
92
+ probeJson,
93
+ registerBuiltinRuntimes,
94
+ targetRootUrl
95
+ } from "./chunk-77DCC6JZ.js";
96
+ import {
97
+ buildProviderSupportEntry,
98
+ configuredTargetsForRuntime,
99
+ describeRuntimeModels,
100
+ listKnownModelsForRuntime,
101
+ listProviderSupportEntries,
102
+ supportGroupLabel
103
+ } from "./chunk-SYF7FVBL.js";
104
+ import {
105
+ authStoragePath,
106
+ openAuthStorage,
107
+ registerClioOAuthProviders,
108
+ resolveAuthTarget,
109
+ resolveRuntimeAuthTarget,
110
+ targetRequiresAuth
111
+ } from "./chunk-Z4GLJ6J4.js";
112
+ import {
113
+ closestRuntimeId,
114
+ getRuntimeRegistry
115
+ } from "./chunk-2WVPJF3Z.js";
116
+ import {
117
+ getCatalogModelForRuntime
118
+ } from "./chunk-27YTM2CV.js";
119
+ import {
120
+ AUTONOMY_LEVELS
121
+ } from "./chunk-UZVYEF57.js";
122
+ import {
123
+ SettingsValidationError,
124
+ bindAgentProfileInSettings,
125
+ readSettings,
126
+ removeTargetFromSettings,
127
+ settingsPath,
128
+ updateSavedSettingsDocument,
129
+ updateSettings,
130
+ validateSettings,
131
+ withSettingsLock
132
+ } from "./chunk-56XP4FJU.js";
133
+ import {
134
+ DEFAULT_SETTINGS,
135
+ DEFAULT_SETTINGS_YAML,
136
+ THINKING_LEVELS
137
+ } from "./chunk-QZTTRSJE.js";
138
+ import {
139
+ require_dist
140
+ } from "./chunk-B5GGDIHT.js";
141
+ import {
142
+ warnLegacyNaming
143
+ } from "./chunk-O63U2I6I.js";
144
+ import {
145
+ resolveClioDirs
146
+ } from "./chunk-CTTI7G3T.js";
147
+ import {
148
+ safeResourceWrite
149
+ } from "./chunk-ZZFWWYLX.js";
150
+ import {
151
+ getVersionInfo
152
+ } from "./chunk-2VLYHHFT.js";
153
+ import {
154
+ __toESM,
155
+ init_esm_shims
156
+ } from "./chunk-ECBHH7LU.js";
157
+
158
+ // src/cli/configure.ts
159
+ init_esm_shims();
160
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
161
+ import { stdin as input, stdout as output2 } from "node:process";
162
+
163
+ // src/cli/ask.ts
164
+ init_esm_shims();
165
+ async function ask(rl, label, defaultValue) {
166
+ if (rl.text) return rl.text(label, defaultValue);
167
+ const suffix = defaultValue && defaultValue.length > 0 ? ` [${defaultValue}]` : "";
168
+ try {
169
+ const answer = (await rl.question(`${label}${suffix}: `)).trim();
170
+ if (answer.length === 0) return defaultValue ?? "";
171
+ if (answer.toLowerCase() === "q" || answer.toLowerCase() === "quit") return null;
172
+ return answer;
173
+ } catch {
174
+ return null;
175
+ }
176
+ }
177
+ async function askYesNo(rl, label, defaultValue) {
178
+ if (rl.choose && rl.interactive) return await rl.choose(label, ["yes", "no"], defaultValue ? "yes" : "no") === "yes";
179
+ const marker = defaultValue ? "Y/n" : "y/N";
180
+ for (; ; ) {
181
+ const answer = await ask(rl, `${label} [${marker}]`);
182
+ if (answer === null) return defaultValue;
183
+ if (answer.length === 0) return defaultValue;
184
+ const lc = answer.toLowerCase();
185
+ if (lc === "y" || lc === "yes") return true;
186
+ if (lc === "n" || lc === "no") return false;
187
+ process.stderr.write(`invalid response: ${answer}
188
+ `);
189
+ }
190
+ }
191
+
192
+ // src/cli/configure-controls.ts
193
+ init_esm_shims();
194
+
195
+ // src/cli/configure-prompts.ts
196
+ init_esm_shims();
197
+ import { createInterface } from "node:readline/promises";
198
+
199
+ // src/cli/configure-target.ts
200
+ init_esm_shims();
201
+
202
+ // src/cli/validate-model.ts
203
+ init_esm_shims();
204
+ var SAMPLE_SIZE = 10;
205
+ function sample(models) {
206
+ const shown = models.slice(0, SAMPLE_SIZE).join(", ");
207
+ return models.length > SAMPLE_SIZE ? `${shown}, \u2026` : shown;
208
+ }
209
+ function describeLiveTarget(live) {
210
+ return live.url ? `target '${live.targetId}' at ${live.url}` : `target '${live.targetId}'`;
211
+ }
212
+ function formatUnadvertisedModelReason(modelId, live) {
213
+ const resident = live.resident.length > 0 ? live.resident.join(", ") : "none";
214
+ return `${describeLiveTarget(live)} does not advertise model '${modelId}'. Advertised (${live.models.length}): ${sample(live.models)}. Resident instances: ${resident}. Pass one of the advertised ids with --model, or --force to save a model the target cannot serve.`;
215
+ }
216
+ function validateModelChoice(input2) {
217
+ const { runtimeId, modelId, knownModels, live, force } = input2;
218
+ if (live !== void 0) return validateAgainstLive(modelId, live, force);
219
+ if (knownModels.length === 0) return validateAgainstLive(modelId, live, force);
220
+ if (knownModels.includes(modelId)) return { ok: true };
221
+ if (force) {
222
+ return {
223
+ ok: true,
224
+ warning: `model '${modelId}' not in ${runtimeId} catalog (use without --force to reject)`
225
+ };
226
+ }
227
+ return {
228
+ ok: false,
229
+ reason: `model '${modelId}' not in ${runtimeId} catalog. Known: ${sample(knownModels)}. Use --force to skip validation.`,
230
+ knownModels: knownModels.slice(0, SAMPLE_SIZE)
231
+ };
232
+ }
233
+ function validateAgainstLive(modelId, live, force) {
234
+ if (!live || live.models.length === 0) return { ok: true };
235
+ if (live.models.includes(modelId)) return { ok: true };
236
+ const reason = formatUnadvertisedModelReason(modelId, live);
237
+ if (force) return { ok: true, warning: `${reason.replace(/ Pass one of.*$/u, "")} Saved anyway because of --force.` };
238
+ return { ok: false, reason, knownModels: live.models.slice(0, SAMPLE_SIZE) };
239
+ }
240
+
241
+ // src/cli/configure-target.ts
242
+ var DEFAULT_PORTS = {
243
+ llamacpp: 8080,
244
+ "llamacpp-anthropic": 8080,
245
+ "llamacpp-completion": 8080,
246
+ "llamacpp-embed": 8080,
247
+ "llamacpp-rerank": 8080,
248
+ "lmstudio-native": 1234,
249
+ lmstudio: 1234,
250
+ "ollama-native": 11434,
251
+ ollama: 11434,
252
+ vllm: 8e3,
253
+ sglang: 3e4,
254
+ "lemonade-anthropic": 8e3,
255
+ lemonade: 8e3,
256
+ "anthropic-compat": 8e3,
257
+ "openai-compat": 8e3,
258
+ litellm: 4e3
259
+ };
260
+ function trimTrailing(url) {
261
+ return url.endsWith("/") && url.length > 1 ? url.slice(0, -1) : url;
262
+ }
263
+ function normalizeUrl(input2, runtimeId) {
264
+ const trimmed = input2.trim();
265
+ if (trimmed.length === 0) return defaultUrlFor(runtimeId);
266
+ const hasScheme = /^[a-z][a-z0-9+.-]*:\/\//i.test(trimmed);
267
+ let withScheme = hasScheme ? trimmed : `http://${trimmed}`;
268
+ if (runtimeId === "lmstudio") withScheme = withScheme.replace(/^ws:/u, "http:").replace(/^wss:/u, "https:");
269
+ try {
270
+ const parsed = new URL(withScheme);
271
+ if (!hasScheme && !parsed.port && DEFAULT_PORTS[runtimeId]) {
272
+ parsed.port = String(DEFAULT_PORTS[runtimeId]);
273
+ }
274
+ return trimTrailing(parsed.toString());
275
+ } catch {
276
+ return trimTrailing(withScheme);
277
+ }
278
+ }
279
+ function defaultUrlFor(runtimeId) {
280
+ const port = DEFAULT_PORTS[runtimeId];
281
+ return port ? `http://127.0.0.1:${port}` : "http://127.0.0.1:8080";
282
+ }
283
+ function deriveTargetId(runtimeId, existing) {
284
+ const base = runtimeId;
285
+ const taken = new Set(existing.map((e) => e.id));
286
+ if (!taken.has(base)) return base;
287
+ for (let i = 2; i < 1e3; i++) {
288
+ const candidate = `${base}-${i}`;
289
+ if (!taken.has(candidate)) return candidate;
290
+ }
291
+ return `${base}-${Date.now()}`;
292
+ }
293
+ function targetApiKeyRef(targetId, targets) {
294
+ const taken = new Set(targets.filter((target) => target.id !== targetId).map((target) => target.auth?.apiKeyRef));
295
+ const base = `target:${targetId}`;
296
+ let ref = base;
297
+ for (let suffix = 2; taken.has(ref); suffix += 1) ref = `${base}-${suffix}`;
298
+ return ref;
299
+ }
300
+ async function buildProbeContext(runtime, target) {
301
+ const probeCtx = {
302
+ credentialsPresent: credentialsPresent(),
303
+ httpTimeoutMs: 5e3
304
+ };
305
+ if (!runtime || !target || !targetRequiresAuth(target, runtime)) return probeCtx;
306
+ try {
307
+ const resolution = await openAuthStorage().resolveForTarget(resolveAuthTarget(target, runtime), {
308
+ includeFallback: false
309
+ });
310
+ if (resolution.apiKey) probeCtx.authToken = resolution.apiKey;
311
+ } catch {
312
+ }
313
+ return probeCtx;
314
+ }
315
+ function runtimeKnownModelsFor(runtimeId) {
316
+ return listKnownModelsForRuntime(runtimeId);
317
+ }
318
+ function catalogContextWindowFor(runtime, modelId) {
319
+ const catalogModel = getCatalogModelForRuntime(runtime.id, modelId);
320
+ if (typeof catalogModel?.contextWindow === "number" && catalogModel.contextWindow > 0) {
321
+ return catalogModel.contextWindow;
322
+ }
323
+ if (runtimeKnownModelsFor(runtime.id).includes(modelId) && runtime.defaultCapabilities.contextWindow > 0) {
324
+ return runtime.defaultCapabilities.contextWindow;
325
+ }
326
+ return null;
327
+ }
328
+ function validateResolvedModel(runtime, target, modelId, force, inventory) {
329
+ if (!modelId) return true;
330
+ const knownModels = runtimeKnownModelsFor(runtime.id);
331
+ const live = inventory.source === "probe" ? liveInventoryFor(target, inventory) : void 0;
332
+ const validation = validateModelChoice({ runtimeId: runtime.id, modelId, knownModels, live, force });
333
+ if (!validation.ok) {
334
+ process.stderr.write(`error: ${validation.reason}
335
+ `);
336
+ return false;
337
+ }
338
+ if (validation.warning) process.stderr.write(`warning: ${validation.warning}
339
+ `);
340
+ if (knownModels.length === 0 && live === void 0 && runtime.kind === "http") {
341
+ process.stderr.write(
342
+ `warning: could not verify model '${modelId}': ${target.url ?? `target '${target.id}'`} returned no model list; it is saved as written
343
+ `
344
+ );
345
+ }
346
+ return true;
347
+ }
348
+ function modelChoiceRefusal(runtime, target, modelId, inventory) {
349
+ const live = inventory.source === "probe" ? liveInventoryFor(target, inventory) : void 0;
350
+ const validation = validateModelChoice({
351
+ runtimeId: runtime.id,
352
+ modelId,
353
+ knownModels: runtimeKnownModelsFor(runtime.id),
354
+ live,
355
+ force: false
356
+ });
357
+ return validation.ok ? null : validation.reason;
358
+ }
359
+ function validateContextWindowOverride(runtime, modelId, contextWindow, force) {
360
+ if (contextWindow === void 0 || !modelId) return true;
361
+ const catalogMax = catalogContextWindowFor(runtime, modelId);
362
+ if (catalogMax === null || contextWindow <= catalogMax) return true;
363
+ const message = `--context-window ${contextWindow} exceeds catalog max ${catalogMax} for model '${modelId}'`;
364
+ if (!force) {
365
+ process.stderr.write(`error: ${message}. Use --force to override.
366
+ `);
367
+ return false;
368
+ }
369
+ process.stderr.write(`warning: ${message}
370
+ `);
371
+ return true;
372
+ }
373
+ async function runtimeProbe(runtime, target, authToken) {
374
+ if (typeof runtime.probe !== "function") return null;
375
+ try {
376
+ const context = await buildProbeContext(runtime, target);
377
+ return await runtime.probe(target, authToken === void 0 ? context : { ...context, authToken });
378
+ } catch (err) {
379
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
380
+ }
381
+ }
382
+ async function runtimeProbeModels(runtime, target, authToken) {
383
+ if (typeof runtime.probeModels !== "function") return [];
384
+ try {
385
+ const context = await buildProbeContext(runtime, target);
386
+ return await runtime.probeModels(target, authToken === void 0 ? context : { ...context, authToken });
387
+ } catch {
388
+ return [];
389
+ }
390
+ }
391
+ function applyTarget(settings, descriptor) {
392
+ const idx = settings.targets.findIndex((e) => e.id === descriptor.id);
393
+ if (idx >= 0) settings.targets[idx] = descriptor;
394
+ else settings.targets.push(descriptor);
395
+ }
396
+ function setOrchestratorPointer(settings, descriptor, model) {
397
+ const runtime = getRuntimeRegistry().get(descriptor.runtime);
398
+ if (!runtime) {
399
+ throw new Error(
400
+ `cannot use target '${descriptor.id}' as orchestrator target because runtime '${descriptor.runtime}' is not registered`
401
+ );
402
+ }
403
+ if (!isOrchestratorEligibleRuntime(runtime)) {
404
+ throw new Error(
405
+ `cannot use target '${descriptor.id}' as orchestrator target because runtime '${runtime.id}' is not an HTTP/native runtime`
406
+ );
407
+ }
408
+ settings.chat.target = descriptor.id;
409
+ settings.chat.model = model ?? descriptor.defaultModel ?? null;
410
+ }
411
+ function setWorkerDefaultPointer(settings, descriptor, model) {
412
+ settings.fleet.default.target = descriptor.id;
413
+ settings.fleet.default.model = model ?? descriptor.defaultModel ?? null;
414
+ }
415
+ function setBackgroundPointer(settings, descriptor, model) {
416
+ const runtime = getRuntimeRegistry().get(descriptor.runtime);
417
+ if (!runtime || !isOrchestratorEligibleRuntime(runtime)) {
418
+ throw new Error(
419
+ `cannot use target '${descriptor.id}' as background target because runtime '${descriptor.runtime}' is not an HTTP/native runtime`
420
+ );
421
+ }
422
+ settings.context.memory.target = descriptor.id;
423
+ settings.context.memory.model = model ?? descriptor.defaultModel ?? null;
424
+ }
425
+ function assertOrchestratorReplacementEligible(settings, descriptor) {
426
+ if (settings.chat.target !== descriptor.id && settings.context.memory.target !== descriptor.id) return;
427
+ const role = settings.chat.target === descriptor.id ? "orchestrator" : "background";
428
+ const runtime = getRuntimeRegistry().get(descriptor.runtime);
429
+ if (!runtime) {
430
+ throw new Error(
431
+ `cannot update ${role} target '${descriptor.id}' because runtime '${descriptor.runtime}' is not registered`
432
+ );
433
+ }
434
+ if (!isOrchestratorEligibleRuntime(runtime)) {
435
+ throw new Error(`cannot update ${role} target '${descriptor.id}' to non-HTTP/native runtime '${runtime.id}'`);
436
+ }
437
+ }
438
+ function setWorkerProfilePointer(settings, name, descriptor, model) {
439
+ const trimmed = name.trim();
440
+ if (trimmed.length === 0) throw new Error("fleet profile name must be non-empty");
441
+ settings.fleet.profiles[trimmed] = {
442
+ target: descriptor.id,
443
+ model: model ?? descriptor.defaultModel ?? null,
444
+ thinkingLevel: "off"
445
+ };
446
+ }
447
+ function contextWindowUndiscovered(descriptor, probe) {
448
+ if (!probe?.ok) return false;
449
+ if (typeof descriptor.capabilities?.contextWindow === "number" && descriptor.capabilities.contextWindow > 0) {
450
+ return false;
451
+ }
452
+ if (descriptor.defaultModel && loadedContextWindowForModel({ discoveredModelStates: probe.modelStates ?? null }, descriptor.defaultModel) !== null) {
453
+ return false;
454
+ }
455
+ const discovered = probeCapabilitiesForModel(
456
+ {
457
+ target: descriptor,
458
+ probeCapabilities: probe.discoveredCapabilities ?? null,
459
+ probeModelCapabilities: probe.modelCapabilities ?? null,
460
+ probeModelId: probe.capabilityModelId ?? null
461
+ },
462
+ descriptor.defaultModel
463
+ );
464
+ return !(typeof discovered?.contextWindow === "number" && discovered.contextWindow > 0);
465
+ }
466
+ function warnUndiscoveredContextWindow(descriptor, probe) {
467
+ if (!contextWindowUndiscovered(descriptor, probe)) return;
468
+ process.stdout.write(
469
+ " warning: the target reported no context window; Clio will use the runtime default as a guess. Set one with --context-window.\n"
470
+ );
471
+ }
472
+ function modelSupportsThinking(runtime, descriptor, probe) {
473
+ const discovered = probe ? probeCapabilitiesForModel(
474
+ {
475
+ target: descriptor,
476
+ probeCapabilities: probe.discoveredCapabilities ?? null,
477
+ probeModelCapabilities: probe.modelCapabilities ?? null,
478
+ probeModelId: probe.capabilityModelId ?? null
479
+ },
480
+ descriptor.defaultModel
481
+ ) : null;
482
+ if (typeof discovered?.reasoning === "boolean") return discovered.reasoning;
483
+ if (typeof descriptor.capabilities?.reasoning === "boolean") return descriptor.capabilities.reasoning;
484
+ return runtime.defaultCapabilities.reasoning === true;
485
+ }
486
+ function probeReadings(probe) {
487
+ const readings = [];
488
+ if (probe.models && probe.models.length > 0) readings.push(`${probe.models.length} models`);
489
+ if (probe.serverVersion) readings.push(probe.serverVersion);
490
+ if (probe.discoveredCapabilities && Object.keys(probe.discoveredCapabilities).length > 0) {
491
+ readings.push("capabilities");
492
+ }
493
+ return readings;
494
+ }
495
+ function probeLines(descriptor, probe) {
496
+ const latency = probe.latencyMs !== void 0 ? ` (${probe.latencyMs}ms)` : "";
497
+ if (!probe.ok) {
498
+ if (descriptor.runtime === "antigravity-code") {
499
+ const next = probe.failureKind === "missing" ? "install the official Antigravity CLI and put `agy` on PATH" : probe.failureKind === "authentication" ? "run `agy` yourself and complete sign-in; Clio never reads or manages that session" : probe.failureKind === "unsupported-feature" ? "update `agy`; this integration requires its structured JSON model catalog" : "run `agy` directly to inspect setup, then re-run `clio-coder targets --probe`";
500
+ return [`probe failed${latency}: ${probe.error ?? "unknown"}`, ` ${next}`];
501
+ }
502
+ const where = descriptor.url ? ` ${descriptor.url}` : "";
503
+ return [
504
+ `probe failed${latency}:${where} ${probe.error ?? "unknown"}`,
505
+ ` check the server is running and reachable, then re-run: clio-coder configure --id ${descriptor.id} --url <url>`
506
+ ];
507
+ }
508
+ const readings = probeReadings(probe);
509
+ if (readings.length > 0) return [`probe ok${latency} ${readings.join(", ")}`];
510
+ return [
511
+ `probe reachable${latency}, but the target answered no model list and no version`,
512
+ " Clio cannot verify the model id or the context window from here and will send both as written.",
513
+ " re-read them once the server serves them with: clio-coder targets --probe"
514
+ ];
515
+ }
516
+ function buildDescriptor(runtime, id, parts) {
517
+ const descriptor = { id, runtime: runtime.id };
518
+ if (parts.url) descriptor.url = parts.url;
519
+ if (parts.model) descriptor.defaultModel = parts.model;
520
+ const auth = {};
521
+ if (parts.apiKeyEnv) auth.apiKeyEnvVar = parts.apiKeyEnv;
522
+ if (parts.apiKeyRef) auth.apiKeyRef = parts.apiKeyRef;
523
+ if (parts.oauthProfile) auth.oauthProfile = parts.oauthProfile;
524
+ if (Object.keys(auth).length > 0) descriptor.auth = auth;
525
+ if (parts.gateway) descriptor.gateway = true;
526
+ if (parts.lifecycle) descriptor.lifecycle = parts.lifecycle;
527
+ const caps = {};
528
+ if (parts.contextWindow !== void 0) caps.contextWindow = parts.contextWindow;
529
+ if (parts.maxTokens !== void 0) caps.maxTokens = parts.maxTokens;
530
+ if (parts.reasoning !== void 0) caps.reasoning = parts.reasoning;
531
+ if (Object.keys(caps).length > 0) descriptor.capabilities = caps;
532
+ if (parts.lmstudio) descriptor.lmstudio = parts.lmstudio;
533
+ if (parts.litellm) descriptor.litellm = parts.litellm;
534
+ if (parts.ollama) descriptor.ollama = parts.ollama;
535
+ return descriptor;
536
+ }
537
+ function describeAuthStatus(runtime, target) {
538
+ const status = openAuthStorage().statusForTarget(
539
+ target ? resolveAuthTarget(target, runtime) : resolveRuntimeAuthTarget(runtime),
540
+ { includeFallback: false }
541
+ );
542
+ if (!status.available) return "none stored";
543
+ if (status.source === "environment") return `environment${status.detail ? ` (${status.detail})` : ""}`;
544
+ if (status.source === "stored-api-key") return "stored api key";
545
+ if (status.source === "stored-oauth") return "stored oauth";
546
+ return status.source;
547
+ }
548
+ function advertisedModelIds(inventory) {
549
+ const ids = [...inventory.models];
550
+ for (const id of Object.keys(inventory.modelStates ?? {})) if (!ids.includes(id)) ids.push(id);
551
+ return ids;
552
+ }
553
+ function residentModelIds(modelStates) {
554
+ return Object.entries(modelStates ?? {}).filter(([, status]) => status.state === "loaded" || status.state === "loading").map(([id]) => id);
555
+ }
556
+ function liveInventoryFor(target, inventory) {
557
+ return {
558
+ targetId: target.id,
559
+ url: target.url,
560
+ models: advertisedModelIds(inventory),
561
+ resident: residentModelIds(inventory.modelStates)
562
+ };
563
+ }
564
+ async function resolveSupportedWireModels(runtime, target, existing, authToken) {
565
+ const known = listKnownModelsForRuntime(runtime.id);
566
+ const liveAuthoritative = runtime.externalAgentLoop?.modelCatalog === "live-authoritative";
567
+ if (known.length > 0 && !liveAuthoritative) return { models: known, source: "catalog" };
568
+ let probeError;
569
+ if (runtime.kind === "http" || liveAuthoritative) {
570
+ const probe = await runtimeProbe(runtime, target, authToken);
571
+ if (probe?.ok && probe.models && probe.models.length > 0) {
572
+ recordTargetModelSnapshot(target, probe.models, probe.modelLabels ? { modelLabels: probe.modelLabels } : {});
573
+ return {
574
+ models: [...probe.models],
575
+ source: "probe",
576
+ modelStates: probe.modelStates,
577
+ ...probe.modelLabels ? { labels: probe.modelLabels } : {}
578
+ };
579
+ }
580
+ probeError = probe?.error;
581
+ const discovered = await runtimeProbeModels(runtime, target, authToken);
582
+ if (discovered.length > 0) {
583
+ recordTargetModelSnapshot(target, discovered);
584
+ return { models: discovered, source: "probe" };
585
+ }
586
+ }
587
+ const cached = readTargetModelSnapshot(target);
588
+ if (cached && cached.models.length > 0) {
589
+ return {
590
+ models: [...cached.models],
591
+ source: "cache",
592
+ ...cached.modelLabels ? { labels: cached.modelLabels } : {},
593
+ ...probeError ? { probeError } : {}
594
+ };
595
+ }
596
+ if (known.length > 0) return { models: known, source: "catalog", ...probeError ? { probeError } : {} };
597
+ if (existing?.wireModels && existing.wireModels.length > 0) {
598
+ recordTargetModelSnapshot(target, existing.wireModels);
599
+ return { models: [...existing.wireModels], source: "legacy" };
600
+ }
601
+ return { models: [], source: "none", ...probeError ? { probeError } : {} };
602
+ }
603
+ function inventoryGap(runtime, target) {
604
+ if (runtime.externalAgentLoop?.modelCatalog === "live-authoritative") {
605
+ return "Antigravity returned no live model catalog; run `agy` yourself, complete sign-in, then probe again";
606
+ }
607
+ if (runtime.kind !== "http") return `${runtime.id} does not list its models; type the id the provider documents`;
608
+ return `${target.url ?? runtime.id} answered no model list; type the id the server serves`;
609
+ }
610
+ var LOCAL_APP_RUNTIME_IDS = /* @__PURE__ */ new Set(["ollama", "lmstudio"]);
611
+ var PROTOCOL_COMPAT_RUNTIME_IDS = /* @__PURE__ */ new Set(["openai-compat", "anthropic-compat"]);
612
+ function runtimesForCategory(entries, category) {
613
+ switch (category) {
614
+ case "local-app":
615
+ return entries.filter((entry) => LOCAL_APP_RUNTIME_IDS.has(entry.runtimeId));
616
+ case "local-http":
617
+ return entries.filter((entry) => entry.group === "local-http" && !LOCAL_APP_RUNTIME_IDS.has(entry.runtimeId));
618
+ case "chatgpt":
619
+ return entries.filter((entry) => entry.runtimeId === "openai-codex");
620
+ case "cloud-api": {
621
+ const byLabel = (a, b) => a.label.localeCompare(b.label) || a.runtimeId.localeCompare(b.runtimeId);
622
+ const named = entries.filter((entry) => entry.group === "cloud-api").slice().sort(byLabel);
623
+ const compat = entries.filter((entry) => PROTOCOL_COMPAT_RUNTIME_IDS.has(entry.runtimeId)).map((entry) => ({ ...entry, group: "cloud-api" })).sort(byLabel);
624
+ return [...named, ...compat];
625
+ }
626
+ case "all":
627
+ return entries.slice();
628
+ }
629
+ }
630
+ function railPrefix(plain) {
631
+ return plain ? " " : `${source_default.cyan("\u2502")} `;
632
+ }
633
+
634
+ // src/cli/configure-prompts.ts
635
+ var ConfigureNavigation = class extends Error {
636
+ constructor(kind) {
637
+ super(kind);
638
+ this.kind = kind;
639
+ }
640
+ kind;
641
+ };
642
+ var ConfigurePrompts = class {
643
+ constructor(input2, output3) {
644
+ this.input = input2;
645
+ this.output = output3;
646
+ }
647
+ input;
648
+ output;
649
+ get interactive() {
650
+ return canSelect(this.input, this.output);
651
+ }
652
+ clearScreen() {
653
+ if (this.interactive) this.output.write("\x1B[H\x1B[2J");
654
+ }
655
+ async question(query, options) {
656
+ const rl = createInterface({ input: this.input, output: this.output });
657
+ try {
658
+ return await new Promise((resolve, reject) => {
659
+ rl.once("close", () => reject(new ConfigureNavigation("quit")));
660
+ rl.once("SIGINT", () => reject(new ConfigureNavigation("quit")));
661
+ rl.question(query, options ?? {}).then(resolve, reject);
662
+ });
663
+ } finally {
664
+ rl.close();
665
+ }
666
+ }
667
+ async text(label, initial = "", mask = false) {
668
+ if (!this.interactive) {
669
+ const value = (await this.question(`${label}${initial ? ` [${initial}]` : ""}: `)).trim();
670
+ if (/^(q|quit)$/iu.test(value)) throw new ConfigureNavigation("quit");
671
+ return value || initial;
672
+ }
673
+ const result = await promptText({
674
+ heading: ["", label],
675
+ railPrefix: railPrefix(createLifecyclePresenter({ stream: this.output }).isPlain()),
676
+ initial,
677
+ mask,
678
+ backLabel: "back",
679
+ clearOnExit: true,
680
+ input: this.input,
681
+ output: this.output
682
+ });
683
+ if (result.kind !== "value") throw new ConfigureNavigation(result.kind);
684
+ return result.value;
685
+ }
686
+ async choose(label, choices, current, searchable = false) {
687
+ if (!this.interactive) return this.text(`${label} [${choices.join("|")}]`, current);
688
+ const result = await promptSelect({
689
+ heading: ["", label],
690
+ railPrefix: railPrefix(createLifecyclePresenter({ stream: this.output }).isPlain()),
691
+ choices: choices.map((value) => ({ value, label: value })),
692
+ initialIndex: Math.max(0, choices.indexOf(current)),
693
+ ...searchable ? { searchable: true, maxVisible: 8 } : {},
694
+ backLabel: "back",
695
+ clearOnExit: true,
696
+ input: this.input,
697
+ output: this.output
698
+ });
699
+ if (result.kind !== "selected") throw new ConfigureNavigation(result.kind);
700
+ return result.value;
701
+ }
702
+ };
703
+
704
+ // src/cli/configure-controls.ts
705
+ function editText(control, value) {
706
+ if (value === null || value === void 0) return "";
707
+ return control.kind === "list" ? value.join(", ") : control.kind === "json" ? JSON.stringify(value) : String(value);
708
+ }
709
+ function saveControl(path, input2) {
710
+ updateSavedSettingsDocument((saved) => {
711
+ const before = validateSettings(saved).settings;
712
+ const preview = structuredClone(before);
713
+ applyControlValue(preview, path, input2);
714
+ const diff = diffSettings(before, preview);
715
+ const paths = /* @__PURE__ */ new Set([path, ...diff.hotReload, ...diff.nextTurn, ...diff.restartRequired]);
716
+ for (const changed of paths) {
717
+ if (changed !== path && changed.startsWith(`${path}.`)) continue;
718
+ let cursor = saved;
719
+ const keys = changed.split(".");
720
+ for (const key of keys.slice(0, -1)) {
721
+ if (!cursor[key] || typeof cursor[key] !== "object") cursor[key] = {};
722
+ cursor = cursor[key];
723
+ }
724
+ const leaf = keys.at(-1);
725
+ const value = getAtPath(preview, changed);
726
+ if (value === void 0) delete cursor[leaf];
727
+ else cursor[leaf] = value;
728
+ }
729
+ const validation = validateSettings(saved);
730
+ if (validation.issues.length) throw new SettingsValidationError(validation.issues);
731
+ return saved;
732
+ });
733
+ }
734
+ async function runSectionControls(prompts, section) {
735
+ const controls = SETTING_CONTROLS.filter((control) => settingsSectionForPath(control.path) === section);
736
+ const groups = [...new Set(controls.map((control) => settingsGroupForPath(control.path)))];
737
+ const title = SETTINGS_SECTIONS.find((entry) => entry.id === section)?.label ?? section;
738
+ let group = groups[0] ?? "";
739
+ for (; ; ) {
740
+ try {
741
+ prompts.clearScreen();
742
+ const presenter = createLifecyclePresenter({ stream: prompts.output });
743
+ presenter.header(`${title} \xB7 All controls`, "configure");
744
+ presenter.note(
745
+ "Choose a group, then a setting. Each edit explains its effect and is validated before saving globally."
746
+ );
747
+ group = await prompts.choose("Settings group", [...groups, "Back"], group, true);
748
+ if (group === "Back") return;
749
+ if (!groups.includes(group)) {
750
+ presenter.warn("Choose a group from the list.");
751
+ continue;
752
+ }
753
+ for (; ; ) {
754
+ const members = controls.filter((control2) => settingsGroupForPath(control2.path) === group);
755
+ const labels = members.map((control2) => `${control2.label} \xB7 ${control2.path}`);
756
+ let chosen;
757
+ try {
758
+ chosen = await prompts.choose(group, [...labels, "Back"], labels[0] ?? "Back", true);
759
+ } catch (error) {
760
+ if (error instanceof ConfigureNavigation && error.kind === "back") break;
761
+ throw error;
762
+ }
763
+ if (chosen === "Back") break;
764
+ const control = members[labels.indexOf(chosen)];
765
+ if (!control) {
766
+ presenter.warn("Choose a setting from the list.");
767
+ continue;
768
+ }
769
+ try {
770
+ prompts.clearScreen();
771
+ presenter.header(control.label, "configure");
772
+ for (const line of controlInstructions(control).split("\n")) presenter.note(line);
773
+ const current = getAtPath(readSettings(), control.path);
774
+ presenter.fields([
775
+ ["Setting", control.path],
776
+ ["Current", formatControlValue(current)],
777
+ ["Shipped default", formatControlValue(getAtPath(DEFAULT_SETTINGS, control.path))],
778
+ ["Save scope", "Global default; current sessions follow their reload rules"]
779
+ ]);
780
+ if (control.readOnly) {
781
+ await prompts.text("Press Enter to return");
782
+ continue;
783
+ }
784
+ const values = control.choices ?? (control.kind === "boolean" ? ["true", "false"] : void 0);
785
+ const value = values ? await prompts.choose("New value", values, String(current)) : await prompts.text("New value", prompts.interactive ? editText(control, current) : "");
786
+ const proposed = readSettings();
787
+ applyControlValue(proposed, control.path, value);
788
+ if (await prompts.choose(`Save ${control.label} globally?`, ["Save", "Cancel"], "Save") === "Save") {
789
+ saveControl(control.path, value);
790
+ presenter.completedStep(`${control.label} saved`);
791
+ }
792
+ } catch (error) {
793
+ if (error instanceof ConfigureNavigation) {
794
+ if (error.kind === "quit") throw error;
795
+ } else presenter.warn(`Not saved: ${error instanceof Error ? error.message : String(error)}`);
796
+ }
797
+ }
798
+ } catch (error) {
799
+ if (error instanceof ConfigureNavigation && error.kind === "back") return;
800
+ throw error;
801
+ }
802
+ }
803
+ }
804
+
805
+ // src/cli/configure-editor.ts
806
+ init_esm_shims();
807
+ var import_yaml = __toESM(require_dist(), 1);
808
+ import { existsSync, readFileSync } from "node:fs";
809
+ async function editSettings(prompts) {
810
+ const file = settingsPath();
811
+ const original = existsSync(file) ? readFileSync(file, "utf8") : null;
812
+ let draft = original ?? DEFAULT_SETTINGS_YAML;
813
+ const editor = resolveExternalEditor();
814
+ for (; ; ) {
815
+ const result = editTextExternally(draft, editor, ".yaml");
816
+ if (!result.ok || result.text === void 0) throw new Error(result.error ?? "Editor did not return a draft");
817
+ draft = `${result.text}
818
+ `;
819
+ if (draft === original) {
820
+ prompts.output.write("Settings unchanged.\n");
821
+ return false;
822
+ }
823
+ try {
824
+ const validated = validateSettings((0, import_yaml.parse)(draft));
825
+ if (validated.issues.length) throw new SettingsValidationError(validated.issues);
826
+ } catch (error) {
827
+ prompts.output.write(`${error instanceof Error ? error.message : String(error)}
828
+ `);
829
+ if (await prompts.choose("Invalid draft", ["Return to editor", "Discard draft"], "Return to editor") === "Return to editor")
830
+ continue;
831
+ return false;
832
+ }
833
+ const choice = await prompts.choose(
834
+ "Save validated settings?",
835
+ ["Save", "Return to editor", "Discard draft"],
836
+ "Save"
837
+ );
838
+ if (choice === "Return to editor") continue;
839
+ if (choice !== "Save") return false;
840
+ withSettingsLock(() => {
841
+ const current = existsSync(file) ? readFileSync(file, "utf8") : null;
842
+ if (current !== original)
843
+ throw new Error("Settings changed while the editor was open. Reopen the editor to keep those changes.");
844
+ safeResourceWrite(file, draft, { encoding: "utf8", mode: 420, backup: original !== null });
845
+ });
846
+ prompts.output.write(`Settings saved to ${file}${original === null ? "" : `; previous file: ${file}.bak`}
847
+ `);
848
+ return true;
849
+ }
850
+ }
851
+
852
+ // src/cli/configure-interop.ts
853
+ init_esm_shims();
854
+ import { stdout as output } from "node:process";
855
+ function describe(proposal) {
856
+ const lines = [
857
+ "",
858
+ `${proposal.label} is installed and not configured as a delegation agent.`,
859
+ "",
860
+ renderProposalEntry(proposal),
861
+ "",
862
+ `projectContext stays ${INHERITED_PROJECT_CONTEXT}: this agent receives your task text, never the project projection.`,
863
+ `toolGovernance is clio-coder-policy: its tool calls are gated by Clio safety.`
864
+ ];
865
+ if (proposal.needsNetworkInstall) {
866
+ lines.push(`The ACP adapter is not installed locally; npx fetches it the first time you delegate.`);
867
+ }
868
+ return `${lines.join("\n")}
869
+ `;
870
+ }
871
+ function proposalHint(proposal) {
872
+ const command = [proposal.entry.command, ...proposal.entry.args ?? []].join(" ");
873
+ return proposal.needsNetworkInstall ? `${command} (npx fetches the adapter on first use)` : command;
874
+ }
875
+ async function reviewInteropAgents(io) {
876
+ const report = await detectInteropAgents({ cwd: process.cwd(), probeVersion: true });
877
+ const proposals = interopProposals(report, readSettings());
878
+ if (proposals.length === 0) {
879
+ if (!io.quiet) output.write("No new coding agents to connect.\n");
880
+ return { code: 0, wired: [], back: false };
881
+ }
882
+ const streams = io.streams;
883
+ const interactive = streams !== void 0 && canSelect(streams.in, streams.out);
884
+ if (!interactive && io.rl === null) {
885
+ for (const proposal of proposals) output.write(describe(proposal));
886
+ output.write("\nRun `clio-coder configure --interop` on a terminal to connect any of these.\n");
887
+ return { code: 0, wired: [], back: false };
888
+ }
889
+ const accepted = [];
890
+ const declined = [];
891
+ if (interactive && streams) {
892
+ const presenter = io.presenter ?? createLifecyclePresenter({ stream: streams.out });
893
+ const rail = io.rail ?? railPrefix(presenter.isPlain());
894
+ presenter.note(
895
+ `Clio found ${proposals.length === 1 ? "one coding agent" : `${proposals.length} coding agents`} it can delegate to. A peer receives your task text and never the project projection, and its tool calls are gated by Clio safety.`
896
+ );
897
+ const result = await promptMultiSelect({
898
+ heading: ["", source_default.bold("Delegate to any of these?")],
899
+ choices: proposals.map((proposal) => ({
900
+ value: proposal.kind,
901
+ label: proposal.label,
902
+ hint: proposalHint(proposal)
903
+ })),
904
+ railPrefix: rail,
905
+ backLabel: "back",
906
+ confirmLabel: "confirm",
907
+ clearOnExit: true,
908
+ input: streams.in,
909
+ output: streams.out
910
+ });
911
+ if (result.kind === "back") return { code: 0, wired: [], back: true };
912
+ if (result.kind === "quit") return { code: 0, wired: [], back: false };
913
+ for (const proposal of proposals) {
914
+ (result.values.includes(proposal.kind) ? accepted : declined).push(proposal.kind);
915
+ }
916
+ } else if (io.rl !== null) {
917
+ for (const proposal of proposals) {
918
+ output.write(describe(proposal));
919
+ const yes = await askYesNo(io.rl, `Add ${proposal.label} as delegation agent \`${proposal.entry.id}\`?`, false);
920
+ (yes ? accepted : declined).push(proposal.kind);
921
+ }
922
+ }
923
+ const wired = [];
924
+ if (accepted.length > 0) {
925
+ const result = acceptInteropAgents(accepted, report);
926
+ for (const diagnostic of result.diagnostics) {
927
+ if (io.presenter) io.presenter.warn(diagnostic);
928
+ else output.write(`note: ${diagnostic}
929
+ `);
930
+ }
931
+ for (const id of result.wired) {
932
+ wired.push(id);
933
+ if (!io.presenter) printOk(`delegation agent ${id} added; use \`/delegate ${id} <task>\``);
934
+ }
935
+ }
936
+ if (declined.length > 0) {
937
+ declineInteropAgents(declined, report);
938
+ const line = `Declined ${declined.join(", ")}; Clio stays quiet about them until their version or path changes.`;
939
+ if (io.presenter) io.presenter.note(line);
940
+ else output.write(`${line}
941
+ `);
942
+ }
943
+ return { code: 0, wired, back: false };
944
+ }
945
+ async function runInteropReview(io) {
946
+ return (await reviewInteropAgents(io)).code;
947
+ }
948
+
949
+ // src/cli/configure-layout.ts
950
+ init_esm_shims();
951
+ function maxLength(values) {
952
+ return values.reduce((widest, value) => Math.max(widest, value.length), 0);
953
+ }
954
+ var CONFIGURE_CATEGORY_CHOICES = [
955
+ {
956
+ category: "local-app",
957
+ label: "Local app",
958
+ summary: "Ollama or LM Studio (recommended for new users)",
959
+ aliases: ["local"]
960
+ },
961
+ {
962
+ category: "local-http",
963
+ label: "Local HTTP server",
964
+ summary: "llama.cpp / vLLM / SGLang / OpenAI/Anthropic-compatible",
965
+ aliases: ["http"]
966
+ },
967
+ {
968
+ category: "chatgpt",
969
+ label: "ChatGPT plan",
970
+ summary: "Plus or Pro via Codex OAuth",
971
+ aliases: ["codex"]
972
+ },
973
+ {
974
+ category: "cloud-api",
975
+ label: "Cloud API key",
976
+ summary: "Anthropic, OpenAI, OpenRouter, Groq, Google, DeepSeek, Mistral, Bedrock, or any OpenAI/Anthropic-compatible endpoint (e.g. Inception)",
977
+ aliases: ["cloud"]
978
+ },
979
+ {
980
+ category: "all",
981
+ label: "All runtimes",
982
+ summary: "advanced (full list)",
983
+ aliases: ["a"]
984
+ }
985
+ ];
986
+ function formatCategoryMenu(width) {
987
+ const leftWidth = maxLength(CONFIGURE_CATEGORY_CHOICES.map((choice, index) => `${index + 1}. ${choice.label}`)) + 2;
988
+ const lines = [];
989
+ for (const [index, choice] of CONFIGURE_CATEGORY_CHOICES.entries()) {
990
+ lines.push(...twoColumnRow(`${index + 1}. ${choice.label}`, choice.summary, { indent: 2, leftWidth, width }));
991
+ }
992
+ return lines;
993
+ }
994
+ function matchCategoryChoice(answer) {
995
+ const lc = answer.trim().toLowerCase();
996
+ if (lc.length === 0) return null;
997
+ for (const [index, choice] of CONFIGURE_CATEGORY_CHOICES.entries()) {
998
+ if (lc === String(index + 1) || lc === choice.category || choice.aliases.includes(lc)) {
999
+ return choice.category;
1000
+ }
1001
+ }
1002
+ return null;
1003
+ }
1004
+ function formatRuntimeMenu(items, width) {
1005
+ if (items.length === 0) return [];
1006
+ const leftWidth = maxLength(items.map((item, index) => `${String(index + 1).padStart(2)}. ${item.runtimeId}`)) + 1;
1007
+ const lines = [];
1008
+ let lastGroup = null;
1009
+ const grouped = new Set(items.map((item) => item.group)).size > 1;
1010
+ for (const [index, item] of items.entries()) {
1011
+ if (grouped && item.group !== lastGroup) {
1012
+ lastGroup = item.group;
1013
+ lines.push(` ${item.group}:`);
1014
+ }
1015
+ lines.push(
1016
+ ...twoColumnRow(`${String(index + 1).padStart(2)}. ${item.runtimeId}`, item.summary, {
1017
+ indent: 4,
1018
+ leftWidth,
1019
+ width
1020
+ })
1021
+ );
1022
+ }
1023
+ return lines;
1024
+ }
1025
+ var LIST_INDENT = 2;
1026
+ var LIST_GAP = 1;
1027
+ var LIST_MIN_MODELS = 16;
1028
+ function formatRuntimeList(rows, width) {
1029
+ if (rows.length === 0) return [];
1030
+ const targetCells = rows.map((row) => `targets=${row.targets}`);
1031
+ const idWidth = maxLength(rows.map((row) => row.runtimeId));
1032
+ const labelWidth = maxLength(rows.map((row) => row.label));
1033
+ const authWidth = maxLength(rows.map((row) => row.auth));
1034
+ const targetsWidth = maxLength(targetCells);
1035
+ const alignedWidth = LIST_INDENT + idWidth + LIST_GAP + labelWidth + LIST_GAP + authWidth + LIST_GAP + targetsWidth;
1036
+ const inline = width >= alignedWidth + LIST_GAP + LIST_MIN_MODELS;
1037
+ const pad = " ".repeat(LIST_INDENT);
1038
+ const detailPad = " ".repeat(LIST_INDENT + 2);
1039
+ const lines = [];
1040
+ let lastGroup = null;
1041
+ for (const [index, row] of rows.entries()) {
1042
+ if (row.group !== lastGroup) {
1043
+ if (lastGroup !== null) lines.push("");
1044
+ lastGroup = row.group;
1045
+ lines.push(`${row.group}:`);
1046
+ }
1047
+ const targetCell = targetCells[index] ?? "";
1048
+ const models = `models=${row.models}`;
1049
+ if (inline) {
1050
+ const id = column(row.runtimeId, idWidth);
1051
+ const label = column(row.label, labelWidth);
1052
+ const auth = column(row.auth, authWidth);
1053
+ lines.push(truncate(`${pad}${id} ${label} ${auth} ${column(targetCell, targetsWidth)} ${models}`, width));
1054
+ continue;
1055
+ }
1056
+ lines.push(truncate(`${pad}${column(row.runtimeId, idWidth)} ${column(row.auth, authWidth)} ${targetCell}`, width));
1057
+ lines.push(truncate(`${detailPad}${row.label} \xB7 ${models}`, width));
1058
+ }
1059
+ return lines;
1060
+ }
1061
+
1062
+ // src/cli/configure-oauth.ts
1063
+ init_esm_shims();
1064
+ async function loginOAuthRuntime(rl, runtime) {
1065
+ const auth = openAuthStorage();
1066
+ if (runtime.authNotice) process.stdout.write(`note: ${runtime.authNotice}
1067
+ `);
1068
+ const manualCodeInput = createDelayedManualCodeInput(
1069
+ rl,
1070
+ "Paste verification code if browser callback does not complete automatically: "
1071
+ );
1072
+ try {
1073
+ await auth.login(runtime.oauthProviderId ?? runtime.id, {
1074
+ onAuth: ({ url, instructions }) => {
1075
+ process.stdout.write(`
1076
+ Open: ${url}
1077
+ `);
1078
+ if (instructions) process.stdout.write(`${instructions}
1079
+ `);
1080
+ process.stdout.write("Waiting for the browser callback. A manual code prompt will appear if needed.\n");
1081
+ },
1082
+ onDeviceCode: ({ verificationUri, userCode }) => {
1083
+ process.stdout.write(`
1084
+ Open: ${verificationUri}
1085
+ `);
1086
+ process.stdout.write(`Enter code: ${userCode}
1087
+ `);
1088
+ },
1089
+ onPrompt: async (prompt) => {
1090
+ const answer = await rl.question(`${prompt.message}${prompt.allowEmpty ? " " : ": "}`);
1091
+ return prompt.allowEmpty ? answer : answer.trim();
1092
+ },
1093
+ onSelect: (prompt) => promptOAuthSelection(rl, prompt),
1094
+ onManualCodeInput: manualCodeInput.onManualCodeInput,
1095
+ onProgress: (message) => {
1096
+ process.stderr.write(`${message}
1097
+ `);
1098
+ }
1099
+ });
1100
+ if (credentialWriteFailed(auth, `credential for ${runtime.id} was not stored`)) return false;
1101
+ printOk(`authenticated ${runtime.id}`);
1102
+ return true;
1103
+ } catch (error) {
1104
+ printError(error instanceof Error ? error.message : String(error));
1105
+ return false;
1106
+ } finally {
1107
+ manualCodeInput.cancel();
1108
+ }
1109
+ }
1110
+
1111
+ // src/cli/configure-onboarding.ts
1112
+ init_esm_shims();
1113
+ import { createInterface as createInterface2 } from "node:readline/promises";
1114
+ function canRunOnboarding(streams) {
1115
+ return canSelect(streams.in, streams.out);
1116
+ }
1117
+ var LABEL_WIDTH = 11;
1118
+ function railWriter(out) {
1119
+ let lines = 0;
1120
+ const stream = {
1121
+ write(chunk) {
1122
+ const text = typeof chunk === "string" ? chunk : Buffer.from(chunk).toString("utf8");
1123
+ for (const char of text) if (char === "\n") lines += 1;
1124
+ return out.write(chunk);
1125
+ },
1126
+ isTTY: out.isTTY,
1127
+ columns: out.columns
1128
+ };
1129
+ return {
1130
+ stream,
1131
+ mark: () => lines,
1132
+ rewindTo(mark) {
1133
+ const back = lines - mark;
1134
+ if (back > 0) out.write(`\x1B[${back}A\x1B[0J`);
1135
+ lines = mark;
1136
+ }
1137
+ };
1138
+ }
1139
+ function supportFor(runtime) {
1140
+ return buildProviderSupportEntry(runtime);
1141
+ }
1142
+ function allEntries() {
1143
+ return listProviderSupportEntries(getRuntimeRegistry().list());
1144
+ }
1145
+ function draftDescriptor(answers, runtime, withModel) {
1146
+ const apiKeyRef = answers.credential === "stored" ? targetApiKeyRef(answers.targetId ?? runtime.id, readSettings().targets) : answers.credential === "keep" ? answers.existing?.auth?.apiKeyRef ?? runtime.id : void 0;
1147
+ const configured = buildDescriptor(runtime, answers.targetId ?? runtime.id, {
1148
+ ...answers.url !== void 0 ? { url: answers.url } : {},
1149
+ ...withModel && answers.model !== void 0 ? { model: answers.model } : {},
1150
+ ...answers.apiKeyEnv !== void 0 ? { apiKeyEnv: answers.apiKeyEnv } : {},
1151
+ ...apiKeyRef !== void 0 ? { apiKeyRef } : {},
1152
+ ...runtime.auth === "oauth" ? { oauthProfile: answers.existing?.auth?.oauthProfile ?? runtime.oauthProviderId ?? runtime.id } : {}
1153
+ });
1154
+ const descriptor = { ...answers.existing, ...configured };
1155
+ if (!withModel) delete descriptor.defaultModel;
1156
+ if (answers.existing?.auth || configured.auth) {
1157
+ descriptor.auth = { ...answers.existing?.auth, ...configured.auth };
1158
+ if (runtime.auth === "api-key") {
1159
+ if (answers.credential !== "env") delete descriptor.auth.apiKeyEnvVar;
1160
+ if (answers.credential !== "stored" && answers.credential !== "keep") delete descriptor.auth.apiKeyRef;
1161
+ }
1162
+ if (Object.keys(descriptor.auth).length === 0) delete descriptor.auth;
1163
+ }
1164
+ return descriptor;
1165
+ }
1166
+ var CATEGORY_STEP = {
1167
+ id: "category",
1168
+ applies: (answers) => answers.mode !== "edit" && !answers.fixedRuntime,
1169
+ run: async (wizard, answers) => {
1170
+ const current = CONFIGURE_CATEGORY_CHOICES.findIndex((choice2) => choice2.category === answers.category);
1171
+ const result = await promptSelect({
1172
+ heading: ["", source_default.bold("How will you connect Clio to a model?")],
1173
+ choices: CONFIGURE_CATEGORY_CHOICES.map((choice2) => ({
1174
+ value: choice2.category,
1175
+ label: choice2.label,
1176
+ hint: choice2.summary
1177
+ })),
1178
+ initialIndex: current >= 0 ? current : 0,
1179
+ railPrefix: wizard.rail,
1180
+ backLabel: "cancel",
1181
+ clearOnExit: true,
1182
+ input: wizard.input,
1183
+ output: wizard.output
1184
+ });
1185
+ if (result.kind === "quit") return "quit";
1186
+ if (result.kind === "back") return "back";
1187
+ if (answers.category !== result.value) {
1188
+ answers.runtime = void 0;
1189
+ answers.detected = void 0;
1190
+ }
1191
+ answers.category = result.value;
1192
+ const choice = CONFIGURE_CATEGORY_CHOICES.find((entry) => entry.category === result.value);
1193
+ wizard.answer("Connection", choice?.label ?? result.value);
1194
+ return "next";
1195
+ }
1196
+ };
1197
+ var RUNTIME_STEP = {
1198
+ id: "runtime",
1199
+ applies: (answers) => answers.mode !== "edit" && !answers.fixedRuntime,
1200
+ run: async (wizard, answers) => {
1201
+ const registry = getRuntimeRegistry();
1202
+ const chatEntries = allEntries().filter((entry) => {
1203
+ const runtime2 = registry.get(entry.runtimeId);
1204
+ return runtime2 !== null && (answers.mode !== "first" || isOrchestratorEligibleRuntime(runtime2));
1205
+ });
1206
+ const entries = answers.category ? runtimesForCategory(chatEntries, answers.category) : chatEntries;
1207
+ const usable = entries.length > 0 ? entries : chatEntries;
1208
+ const previous = usable.findIndex((entry) => entry.runtimeId === answers.runtime?.id);
1209
+ const featured = usable.findIndex((entry) => entry.featured);
1210
+ const result = await promptSelect({
1211
+ heading: ["", source_default.bold("Which runtime?")],
1212
+ choices: usable.map((entry) => ({ value: entry.runtimeId, label: entry.runtimeId, hint: entry.summary })),
1213
+ initialIndex: previous >= 0 ? previous : featured >= 0 ? featured : 0,
1214
+ railPrefix: wizard.rail,
1215
+ backLabel: "back",
1216
+ clearOnExit: true,
1217
+ input: wizard.input,
1218
+ output: wizard.output
1219
+ });
1220
+ if (result.kind === "quit") return "quit";
1221
+ if (result.kind === "back") return "back";
1222
+ const runtime = registry.get(result.value);
1223
+ if (!runtime) return "back";
1224
+ if (answers.runtime?.id !== runtime.id) {
1225
+ answers.targetId = void 0;
1226
+ answers.url = void 0;
1227
+ answers.detected = void 0;
1228
+ answers.credential = void 0;
1229
+ answers.apiKeyEnv = void 0;
1230
+ answers.apiKeyLiteral = void 0;
1231
+ answers.model = void 0;
1232
+ answers.thinking = void 0;
1233
+ answers.contextWindow = void 0;
1234
+ answers.probe = void 0;
1235
+ answers.inventory = void 0;
1236
+ answers.inventoryKey = void 0;
1237
+ }
1238
+ answers.runtime = runtime;
1239
+ wizard.answer("Runtime", `${runtime.id} ${source_default.dim(supportFor(runtime).summary)}`);
1240
+ return "next";
1241
+ }
1242
+ };
1243
+ var TARGET_ID_STEP = {
1244
+ id: "target-id",
1245
+ applies: (answers) => answers.mode !== "edit",
1246
+ run: async (wizard, answers) => {
1247
+ const runtime = answers.runtime;
1248
+ if (!runtime) return "back";
1249
+ const result = await promptText({
1250
+ heading: ["", source_default.bold("Target id")],
1251
+ initial: answers.targetId ?? deriveTargetId(runtime.id, readSettings().targets),
1252
+ hint: "the name you will use for this target in `clio-coder targets`",
1253
+ railPrefix: wizard.rail,
1254
+ backLabel: "back",
1255
+ clearOnExit: true,
1256
+ validate: (value) => {
1257
+ if (value.length === 0) return "a target id is required";
1258
+ if (/\s/u.test(value)) return "a target id cannot contain spaces";
1259
+ if (readSettings().targets.some((target) => target.id === value))
1260
+ return "that target id already exists; choose another or use Edit a target";
1261
+ return null;
1262
+ },
1263
+ input: wizard.input,
1264
+ output: wizard.output
1265
+ });
1266
+ if (result.kind === "quit") return "quit";
1267
+ if (result.kind === "back") return "back";
1268
+ if (answers.targetId !== result.value) answers.inventoryKey = void 0;
1269
+ answers.targetId = result.value;
1270
+ wizard.answer("Target id", result.value);
1271
+ return "next";
1272
+ }
1273
+ };
1274
+ var URL_STEP = {
1275
+ id: "url",
1276
+ applies: (answers) => answers.runtime !== void 0 && supportFor(answers.runtime).supportsCustomUrl,
1277
+ run: async (wizard, answers) => {
1278
+ const runtime = answers.runtime;
1279
+ if (!runtime) return "back";
1280
+ const local = supportFor(runtime).group === "local-http";
1281
+ const result = await promptText({
1282
+ heading: ["", source_default.bold(local ? "Where is the server?" : "Base URL")],
1283
+ initial: answers.url ?? defaultUrlFor(runtime.id),
1284
+ hint: "host:port is enough; Clio fills in the scheme and the port it knows",
1285
+ railPrefix: wizard.rail,
1286
+ backLabel: "back",
1287
+ clearOnExit: true,
1288
+ validate: (value) => value.length === 0 ? "a URL is required for this runtime" : null,
1289
+ input: wizard.input,
1290
+ output: wizard.output
1291
+ });
1292
+ if (result.kind === "quit") return "quit";
1293
+ if (result.kind === "back") return "back";
1294
+ const url = normalizeUrl(result.value, runtime.id);
1295
+ if (answers.url !== url) {
1296
+ answers.inventoryKey = void 0;
1297
+ answers.detected = void 0;
1298
+ }
1299
+ answers.url = url;
1300
+ wizard.answer("URL", url);
1301
+ const authenticated = await reportReachability(wizard, answers, runtime, url);
1302
+ if (!authenticated && runtime.auth === "api-key") {
1303
+ answers.inventoryKey = void 0;
1304
+ if (answers.credential === "skip") answers.credential = void 0;
1305
+ return "credential";
1306
+ }
1307
+ return "next";
1308
+ }
1309
+ };
1310
+ async function reportReachability(wizard, answers, runtime, url) {
1311
+ const draft = draftDescriptor(answers, runtime, false);
1312
+ const probe = await runtimeProbe(runtime, draft, answers.apiKeyLiteral);
1313
+ if (probe !== null) {
1314
+ if (probe.ok) {
1315
+ const readings = probeReadings(probe);
1316
+ wizard.presenter.step(`reachable, ${readings.length > 0 ? readings.join(", ") : "no model list offered"}`);
1317
+ } else if (probe.authFailed) {
1318
+ wizard.presenter.warn("Authentication failed. Choose a credential for this server before selecting a model.");
1319
+ return false;
1320
+ } else {
1321
+ wizard.presenter.warn(`not reachable, you can fix this later: ${probe.error ?? "no reply"}`);
1322
+ }
1323
+ }
1324
+ if (probe?.ok && runtime.id === "lmstudio") {
1325
+ const greeting = await greetLmStudio(draft, { credentialsPresent: /* @__PURE__ */ new Set(), httpTimeoutMs: 750 });
1326
+ if (!greeting.ok) wizard.presenter.warn(`${url} answered, but not with the LM Studio greeting`);
1327
+ }
1328
+ if (PROTOCOL_COMPAT_RUNTIME_IDS.has(runtime.id)) {
1329
+ const fingerprint = await fingerprintNativeRuntime(url);
1330
+ if (fingerprint && getRuntimeRegistry().get(fingerprint.runtimeId)) {
1331
+ answers.detected = { runtimeId: fingerprint.runtimeId, displayName: fingerprint.displayName };
1332
+ }
1333
+ }
1334
+ return true;
1335
+ }
1336
+ var DETECTED_RUNTIME_STEP = {
1337
+ id: "detected-runtime",
1338
+ applies: (answers) => answers.mode !== "edit" && answers.detected !== void 0 && answers.runtime !== void 0,
1339
+ run: async (wizard, answers) => {
1340
+ const detected = answers.detected;
1341
+ const runtime = answers.runtime;
1342
+ if (!detected || !runtime) return "next";
1343
+ const native = getRuntimeRegistry().get(detected.runtimeId);
1344
+ if (!native) return "next";
1345
+ const result = await promptSelect({
1346
+ heading: ["", source_default.bold(`That URL is serving ${detected.displayName}.`)],
1347
+ choices: [
1348
+ {
1349
+ value: true,
1350
+ label: `Use ${native.id}`,
1351
+ hint: "its own runtime, with resident-model lifecycle and its real capabilities"
1352
+ },
1353
+ { value: false, label: `Keep ${runtime.id}`, hint: "the generic protocol runtime you picked" }
1354
+ ],
1355
+ initialIndex: 0,
1356
+ railPrefix: wizard.rail,
1357
+ backLabel: "back",
1358
+ clearOnExit: true,
1359
+ input: wizard.input,
1360
+ output: wizard.output
1361
+ });
1362
+ if (result.kind === "quit") return "quit";
1363
+ if (result.kind === "back") return "back";
1364
+ if (result.value) {
1365
+ answers.runtime = native;
1366
+ answers.inventoryKey = void 0;
1367
+ wizard.answer("Detected", `${detected.displayName}, using runtime ${native.id}`);
1368
+ } else {
1369
+ wizard.answer("Detected", `${detected.displayName}, keeping runtime ${runtime.id}`);
1370
+ }
1371
+ return "next";
1372
+ }
1373
+ };
1374
+ function defaultCredentialSource(runtime, targetId) {
1375
+ const status = openAuthStorage().statusForTarget(resolveRuntimeAuthTarget(runtime), { includeFallback: false });
1376
+ if (status.source === "stored-api-key") return "keep";
1377
+ if (status.source === "environment") return "env";
1378
+ if (runtime.id === "litellm") return "stored";
1379
+ return targetRequiresAuth({ id: targetId, runtime: runtime.id }, runtime) ? "env" : "skip";
1380
+ }
1381
+ async function connectOAuth(wizard, runtime) {
1382
+ const rl = createInterface2({ input: wizard.streams.in, output: wizard.streams.out });
1383
+ try {
1384
+ return await loginOAuthRuntime(rl, runtime);
1385
+ } finally {
1386
+ rl.close();
1387
+ }
1388
+ }
1389
+ var CREDENTIAL_STEP = {
1390
+ id: "credential",
1391
+ applies: (answers) => answers.runtime?.auth === "api-key" || answers.runtime?.auth === "oauth",
1392
+ run: async (wizard, answers) => {
1393
+ const runtime = answers.runtime;
1394
+ if (!runtime) return "back";
1395
+ const stored = describeAuthStatus(runtime, answers.existing);
1396
+ if (runtime.auth === "oauth") {
1397
+ const result2 = await promptSelect({
1398
+ heading: [
1399
+ "",
1400
+ source_default.bold(`Sign in to ${runtime.displayName}`),
1401
+ source_default.dim(`credential: ${stored}`),
1402
+ "Sign-in stores credentials immediately; target settings wait for Save."
1403
+ ],
1404
+ choices: [
1405
+ { value: "oauth-connect", label: "Connect now", hint: "opens your browser and waits for the callback" },
1406
+ {
1407
+ value: "oauth-skip",
1408
+ label: "Later",
1409
+ hint: `run \`clio-coder auth login ${runtime.id}\` before the first turn`
1410
+ }
1411
+ ],
1412
+ initialIndex: answers.credential === "oauth-skip" ? 1 : 0,
1413
+ railPrefix: wizard.rail,
1414
+ backLabel: "back",
1415
+ clearOnExit: true,
1416
+ input: wizard.input,
1417
+ output: wizard.output
1418
+ });
1419
+ if (result2.kind === "quit") return "quit";
1420
+ if (result2.kind === "back") return "back";
1421
+ answers.credential = result2.value;
1422
+ if (result2.value === "oauth-connect") {
1423
+ const connected = await connectOAuth(wizard, runtime);
1424
+ if (!connected) {
1425
+ wizard.presenter.warn(`sign-in did not complete; run \`clio-coder auth login ${runtime.id}\` when ready`);
1426
+ wizard.answer("Credential", "not connected yet");
1427
+ return "next";
1428
+ }
1429
+ wizard.answer("Credential", `connected to ${runtime.id}`);
1430
+ return "next";
1431
+ }
1432
+ wizard.answer("Credential", "not connected yet");
1433
+ return "next";
1434
+ }
1435
+ const hasStored = answers.existing?.auth?.apiKeyRef !== void 0 || stored !== "none stored";
1436
+ const choices = [
1437
+ {
1438
+ value: "env",
1439
+ label: "Environment variable",
1440
+ hint: "read at call time; nothing is written to disk"
1441
+ },
1442
+ {
1443
+ value: "stored",
1444
+ label: "Store the key",
1445
+ hint: "written to credentials.yaml, mode 0600, not encrypted"
1446
+ },
1447
+ ...hasStored ? [{ value: "keep", label: "Keep what is there", hint: stored }] : [],
1448
+ {
1449
+ value: "skip",
1450
+ label: "No key",
1451
+ hint: "only for servers that accept unauthenticated requests"
1452
+ }
1453
+ ];
1454
+ const current = answers.credential ?? defaultCredentialSource(runtime, answers.targetId ?? runtime.id);
1455
+ const initial = Math.max(
1456
+ 0,
1457
+ choices.findIndex((choice) => choice.value === current)
1458
+ );
1459
+ const result = await promptSelect({
1460
+ heading: ["", source_default.bold("How should Clio get the API key?"), source_default.dim(`currently: ${stored}`)],
1461
+ choices,
1462
+ initialIndex: initial,
1463
+ railPrefix: wizard.rail,
1464
+ backLabel: "back",
1465
+ clearOnExit: true,
1466
+ input: wizard.input,
1467
+ output: wizard.output
1468
+ });
1469
+ if (result.kind === "quit") return "quit";
1470
+ if (result.kind === "back") return "back";
1471
+ answers.credential = result.value;
1472
+ if (result.value !== "env") answers.apiKeyEnv = void 0;
1473
+ answers.inventoryKey = void 0;
1474
+ if (result.value !== "stored") answers.apiKeyLiteral = void 0;
1475
+ if (result.value === "keep") wizard.answer("Credential", stored);
1476
+ if (result.value === "skip") wizard.answer("Credential", "none");
1477
+ return "next";
1478
+ }
1479
+ };
1480
+ var CREDENTIAL_VALUE_STEP = {
1481
+ id: "credential-value",
1482
+ applies: (answers) => answers.credential === "env" || answers.credential === "stored",
1483
+ run: async (wizard, answers) => {
1484
+ const runtime = answers.runtime;
1485
+ if (!runtime) return "back";
1486
+ const wantsEnv = answers.credential === "env";
1487
+ const result = await promptText({
1488
+ heading: ["", source_default.bold(wantsEnv ? "Which environment variable?" : "Paste the API key")],
1489
+ initial: wantsEnv ? answers.apiKeyEnv ?? runtime.credentialsEnvVar ?? "" : "",
1490
+ hint: wantsEnv ? "Clio reads it every time it calls the provider, so the key never lands on disk" : `stored at ${shortenPath(authStoragePath())}`,
1491
+ ...wantsEnv ? {} : { mask: true },
1492
+ validate: (value) => value.length > 0 ? null : `Enter ${wantsEnv ? "an environment variable" : "a key"}, or press Escape to choose No key.`,
1493
+ railPrefix: wizard.rail,
1494
+ backLabel: "back",
1495
+ clearOnExit: true,
1496
+ input: wizard.input,
1497
+ output: wizard.output
1498
+ });
1499
+ if (result.kind === "quit") return "quit";
1500
+ if (result.kind === "back") return "back";
1501
+ if (wantsEnv) {
1502
+ answers.apiKeyEnv = result.value.length > 0 ? result.value : void 0;
1503
+ answers.inventoryKey = void 0;
1504
+ wizard.answer("Credential", result.value.length > 0 ? `$${result.value}` : "none");
1505
+ return "next";
1506
+ }
1507
+ answers.apiKeyLiteral = result.value.length > 0 ? result.value : void 0;
1508
+ answers.inventoryKey = void 0;
1509
+ wizard.answer("Credential", result.value.length > 0 ? "stored in credentials.yaml" : "none");
1510
+ return "next";
1511
+ }
1512
+ };
1513
+ async function modelInventory(answers, runtime) {
1514
+ const key = [
1515
+ runtime.id,
1516
+ answers.targetId,
1517
+ answers.url,
1518
+ answers.apiKeyEnv,
1519
+ answers.apiKeyLiteral ? "literal" : ""
1520
+ ].join("|");
1521
+ if (answers.inventoryKey === key && answers.inventory) return answers.inventory;
1522
+ const inventory = await resolveSupportedWireModels(
1523
+ runtime,
1524
+ draftDescriptor(answers, runtime, false),
1525
+ void 0,
1526
+ answers.apiKeyLiteral
1527
+ );
1528
+ answers.inventory = inventory;
1529
+ answers.inventoryKey = key;
1530
+ return inventory;
1531
+ }
1532
+ var MODEL_STEP = {
1533
+ id: "model",
1534
+ applies: () => true,
1535
+ run: async (wizard, answers) => {
1536
+ const runtime = answers.runtime;
1537
+ if (!runtime) return "back";
1538
+ const support = supportFor(runtime);
1539
+ const inventory = await modelInventory(answers, runtime);
1540
+ const catalogOrdered = support.modelSource === "catalog";
1541
+ const preferred = answers.model ?? (inventory.source === "probe" ? inventory.models[0] : support.defaultModel) ?? (catalogOrdered ? void 0 : inventory.models[0]) ?? void 0;
1542
+ if (inventory.models.length === 0) {
1543
+ wizard.presenter.warn(inventoryGap(runtime, { url: answers.url }));
1544
+ const result2 = await promptText({
1545
+ heading: ["", source_default.bold("Which model?")],
1546
+ initial: preferred ?? "",
1547
+ hint: "the wire id the provider documents; Clio sends it as written",
1548
+ railPrefix: wizard.rail,
1549
+ backLabel: "back",
1550
+ clearOnExit: true,
1551
+ validate: (value) => value.length === 0 ? "a model id is required" : null,
1552
+ input: wizard.input,
1553
+ output: wizard.output
1554
+ });
1555
+ if (result2.kind === "quit") return "quit";
1556
+ if (result2.kind === "back") return "back";
1557
+ answers.model = result2.value;
1558
+ wizard.answer("Model", result2.value);
1559
+ await readModelCapabilities(answers, runtime);
1560
+ return "next";
1561
+ }
1562
+ const selected = inventory.models.indexOf(preferred ?? "");
1563
+ const result = await promptSelect({
1564
+ heading: [
1565
+ "",
1566
+ source_default.bold("Which model?"),
1567
+ source_default.dim(
1568
+ inventory.source === "probe" ? "read live from the target just now" : inventory.source === "cache" ? "cached model snapshot; not verified in this run" : "model hints; not a live account catalog"
1569
+ )
1570
+ ],
1571
+ choices: inventory.models.map((model) => {
1572
+ const state = inventory.modelStates?.[model]?.state;
1573
+ const hint = model === preferred ? "default" : state !== void 0 && state !== "unknown" ? state : void 0;
1574
+ const label = inventory.labels?.[model];
1575
+ return {
1576
+ value: model,
1577
+ label: label && label !== model ? `${model} \u2014 ${label}` : model,
1578
+ ...hint === void 0 ? {} : { hint }
1579
+ };
1580
+ }),
1581
+ initialIndex: selected >= 0 ? selected : 0,
1582
+ railPrefix: wizard.rail,
1583
+ backLabel: "back",
1584
+ clearOnExit: true,
1585
+ input: wizard.input,
1586
+ output: wizard.output
1587
+ });
1588
+ if (result.kind === "quit") return "quit";
1589
+ if (result.kind === "back") return "back";
1590
+ const refusal = modelChoiceRefusal(
1591
+ runtime,
1592
+ { id: answers.targetId ?? runtime.id, url: answers.url },
1593
+ result.value,
1594
+ inventory
1595
+ );
1596
+ if (refusal !== null) {
1597
+ wizard.presenter.warn(refusal);
1598
+ return "back";
1599
+ }
1600
+ answers.model = result.value;
1601
+ wizard.answer("Model", result.value);
1602
+ await readModelCapabilities(answers, runtime);
1603
+ return "next";
1604
+ }
1605
+ };
1606
+ async function readModelCapabilities(answers, runtime) {
1607
+ const descriptor = draftDescriptor(answers, runtime, true);
1608
+ const probe = await runtimeProbe(runtime, descriptor, answers.apiKeyLiteral);
1609
+ answers.probe = probe;
1610
+ if (probe?.ok && probe.models) {
1611
+ recordTargetModelSnapshot(descriptor, probe.models, probe.modelLabels ? { modelLabels: probe.modelLabels } : {});
1612
+ }
1613
+ }
1614
+ var THINKING_HINTS = {
1615
+ off: "never ask this model to think before answering",
1616
+ minimal: "a sentence of reasoning",
1617
+ low: "short reasoning, the usual choice",
1618
+ medium: "more reasoning on hard turns",
1619
+ high: "long reasoning, slower and more expensive",
1620
+ xhigh: "longer still, where the model offers it",
1621
+ max: "everything the model will spend"
1622
+ };
1623
+ var THINKING_STEP = {
1624
+ id: "thinking",
1625
+ applies: (answers) => {
1626
+ if (answers.mode !== "first" && !PROTOCOL_COMPAT_RUNTIME_IDS.has(answers.runtime?.id ?? "")) return false;
1627
+ const runtime = answers.runtime;
1628
+ if (!runtime || answers.model === void 0) return false;
1629
+ if (PROTOCOL_COMPAT_RUNTIME_IDS.has(runtime.id)) return true;
1630
+ return modelSupportsThinking(runtime, draftDescriptor(answers, runtime, true), answers.probe ?? null);
1631
+ },
1632
+ run: async (wizard, answers) => {
1633
+ const current = THINKING_LEVELS.indexOf(answers.thinking ?? "low");
1634
+ const result = await promptSelect({
1635
+ heading: [
1636
+ "",
1637
+ source_default.bold("How hard should it think?"),
1638
+ source_default.dim(
1639
+ answers.mode === "first" ? "changeable any time in `clio-coder configure`" : "off disables reasoning for this target; chat and fleet thinking defaults stay unchanged"
1640
+ )
1641
+ ],
1642
+ choices: THINKING_LEVELS.map((level) => ({ value: level, label: level, hint: THINKING_HINTS[level] })),
1643
+ initialIndex: current >= 0 ? current : 0,
1644
+ railPrefix: wizard.rail,
1645
+ backLabel: "back",
1646
+ clearOnExit: true,
1647
+ input: wizard.input,
1648
+ output: wizard.output
1649
+ });
1650
+ if (result.kind === "quit") return "quit";
1651
+ if (result.kind === "back") return "back";
1652
+ answers.thinking = result.value;
1653
+ wizard.answer("Thinking", result.value);
1654
+ return "next";
1655
+ }
1656
+ };
1657
+ var ANTIGRAVITY_COLLEAGUE_STEP = {
1658
+ id: "antigravity-colleague",
1659
+ applies: (answers) => answers.mode === "first" && answers.runtime !== void 0 && isOrchestratorEligibleRuntime(answers.runtime) && resolveOnPath(["agy"]).presence === "present" && !readSettings().targets.some((target) => target.runtime === "antigravity-code"),
1660
+ run: async (wizard, answers) => {
1661
+ const runtime = getRuntimeRegistry().get("antigravity-code");
1662
+ if (!runtime) return "next";
1663
+ const choice = await promptSelect({
1664
+ heading: [
1665
+ "",
1666
+ source_default.bold("Add your local Antigravity research colleague?"),
1667
+ source_default.dim("optional, experimental, dispatch-only; Clio does not authenticate or inspect its session")
1668
+ ],
1669
+ choices: [
1670
+ { value: false, label: "Not now", hint: "your primary Clio target is unchanged" },
1671
+ { value: true, label: "Add read-only colleague", hint: "probe the non-generating model catalog" }
1672
+ ],
1673
+ initialIndex: answers.antigravity ? 1 : 0,
1674
+ railPrefix: wizard.rail,
1675
+ backLabel: "back",
1676
+ clearOnExit: true,
1677
+ input: wizard.input,
1678
+ output: wizard.output
1679
+ });
1680
+ if (choice.kind === "quit") return "quit";
1681
+ if (choice.kind === "back") return "back";
1682
+ if (!choice.value) {
1683
+ answers.antigravity = void 0;
1684
+ wizard.answer("Colleague", "not added");
1685
+ return "next";
1686
+ }
1687
+ const targetId = deriveTargetId(runtime.id, readSettings().targets);
1688
+ const descriptor = buildDescriptor(runtime, targetId, {});
1689
+ const inventory = await resolveSupportedWireModels(runtime, descriptor);
1690
+ if (inventory.source !== "probe" || inventory.models.length === 0) {
1691
+ answers.antigravity = void 0;
1692
+ wizard.presenter.warn(
1693
+ inventory.probeError ?? "Antigravity did not return a live catalog. Run `agy` yourself, complete sign-in, then add it from Configure \u2192 Targets."
1694
+ );
1695
+ wizard.answer("Colleague", "not added; sign in with agy first");
1696
+ return "next";
1697
+ }
1698
+ const picked = await promptSelect({
1699
+ heading: ["", source_default.bold("Antigravity research model"), source_default.dim("live account catalog")],
1700
+ choices: inventory.models.map((model) => ({
1701
+ value: model,
1702
+ label: inventory.labels?.[model] ? `${model} \u2014 ${inventory.labels[model]}` : model
1703
+ })),
1704
+ initialIndex: 0,
1705
+ railPrefix: wizard.rail,
1706
+ backLabel: "back",
1707
+ clearOnExit: true,
1708
+ input: wizard.input,
1709
+ output: wizard.output
1710
+ });
1711
+ if (picked.kind === "quit") return "quit";
1712
+ if (picked.kind === "back") return "back";
1713
+ answers.antigravity = { targetId, model: picked.value };
1714
+ wizard.answer("Colleague", `${targetId}/${picked.value} \u2192 world-knowledge`);
1715
+ return "next";
1716
+ }
1717
+ };
1718
+ var CONTEXT_STEP = {
1719
+ id: "context-window",
1720
+ applies: (answers) => PROTOCOL_COMPAT_RUNTIME_IDS.has(answers.runtime?.id ?? "") || answers.mode === "edit",
1721
+ run: async (wizard, answers) => {
1722
+ const result = await promptText({
1723
+ heading: ["", source_default.bold("Context window in tokens")],
1724
+ initial: answers.contextWindow === void 0 ? "" : String(answers.contextWindow),
1725
+ hint: "optional override; blank uses detected capabilities or the runtime default",
1726
+ validate: (value) => value === "" || Number.isSafeInteger(Number(value)) && Number(value) > 0 ? null : "enter a positive whole number, or leave blank",
1727
+ railPrefix: wizard.rail,
1728
+ backLabel: "back",
1729
+ clearOnExit: true,
1730
+ input: wizard.input,
1731
+ output: wizard.output
1732
+ });
1733
+ if (result.kind !== "value") return result.kind;
1734
+ answers.contextWindow = result.value ? Number(result.value) : void 0;
1735
+ wizard.answer("Context", result.value || "detected / runtime default");
1736
+ return "next";
1737
+ }
1738
+ };
1739
+ var REVIEW_STEP = {
1740
+ id: "review",
1741
+ applies: () => true,
1742
+ run: async (wizard, answers) => {
1743
+ const result = await promptSelect({
1744
+ heading: [
1745
+ "",
1746
+ source_default.bold("Review target"),
1747
+ `${answers.targetId} \xB7 ${answers.runtime?.id} \xB7 ${answers.model}`,
1748
+ answers.mode === "first" ? "Use for chat and fleet." : "Existing chat, fleet, memory, and profile defaults stay in place.",
1749
+ "Escape returns to the previous step; settings are saved only when you choose Save."
1750
+ ],
1751
+ choices: [
1752
+ { value: "save", label: "Save target" },
1753
+ { value: "back", label: "Back" },
1754
+ { value: "cancel", label: "Cancel setup" }
1755
+ ],
1756
+ railPrefix: wizard.rail,
1757
+ backLabel: "back",
1758
+ clearOnExit: true,
1759
+ input: wizard.input,
1760
+ output: wizard.output
1761
+ });
1762
+ if (result.kind !== "selected") return result.kind;
1763
+ return result.value === "save" ? "next" : result.value === "back" ? "back" : "cancel";
1764
+ }
1765
+ };
1766
+ var STEPS = [
1767
+ CATEGORY_STEP,
1768
+ RUNTIME_STEP,
1769
+ TARGET_ID_STEP,
1770
+ CREDENTIAL_STEP,
1771
+ CREDENTIAL_VALUE_STEP,
1772
+ URL_STEP,
1773
+ DETECTED_RUNTIME_STEP,
1774
+ MODEL_STEP,
1775
+ THINKING_STEP,
1776
+ CONTEXT_STEP,
1777
+ ANTIGRAVITY_COLLEAGUE_STEP,
1778
+ REVIEW_STEP
1779
+ ];
1780
+ function applyAnswers(settings, answers, descriptor, chatEligible) {
1781
+ const current = settings.targets.find((target) => target.id === descriptor.id);
1782
+ if (answers.mode === "edit") {
1783
+ if (JSON.stringify(current) !== JSON.stringify(answers.existing))
1784
+ throw new Error("This target changed during setup; reopen Edit to keep those changes.");
1785
+ } else if (current) throw new Error(`Target '${descriptor.id}' already exists; use Edit a target.`);
1786
+ applyTarget(settings, descriptor);
1787
+ if (answers.mode === "first" && chatEligible) setOrchestratorPointer(settings, descriptor, answers.model ?? null);
1788
+ if (answers.mode === "first") setWorkerDefaultPointer(settings, descriptor, answers.model ?? null);
1789
+ if (answers.mode === "first" && answers.thinking !== void 0) {
1790
+ settings.chat.thinkingLevel = answers.thinking;
1791
+ settings.fleet.default.thinkingLevel = answers.thinking;
1792
+ }
1793
+ if (answers.antigravity !== void 0) {
1794
+ const antigravityRuntime = getRuntimeRegistry().get("antigravity-code");
1795
+ if (!antigravityRuntime) throw new Error("Antigravity runtime disappeared before settings were written");
1796
+ const external = buildDescriptor(antigravityRuntime, answers.antigravity.targetId, {
1797
+ model: answers.antigravity.model
1798
+ });
1799
+ applyTarget(settings, external);
1800
+ setWorkerProfilePointer(settings, "world-knowledge-external", external, answers.antigravity.model);
1801
+ bindAgentProfileInSettings(settings, "world-knowledge", "world-knowledge-external");
1802
+ }
1803
+ }
1804
+ async function runOnboardingWizard(streams, options = {
1805
+ mode: "first"
1806
+ }) {
1807
+ const writer = railWriter(streams.out);
1808
+ const presenter = createLifecyclePresenter({ stream: writer.stream });
1809
+ const rail = railPrefix(presenter.isPlain());
1810
+ const columns = streams.out.columns ?? 80;
1811
+ const wizard = {
1812
+ streams,
1813
+ presenter,
1814
+ rail,
1815
+ input: streams.in,
1816
+ output: streams.out,
1817
+ answer: (label, value) => {
1818
+ presenter.fields([[label.padEnd(LABEL_WIDTH), truncate(value, Math.max(12, columns - LABEL_WIDTH - 6))]]);
1819
+ }
1820
+ };
1821
+ presenter.header(
1822
+ options.mode === "edit" ? `Edit target: ${options.target.id}` : options.mode === "first" ? "Welcome to Clio Coder" : "Add a target",
1823
+ "configure"
1824
+ );
1825
+ presenter.note("Pick a model; escape goes back. Review and save when ready.");
1826
+ presenter.note(`Result: ${shortenPath(settingsPath())}`);
1827
+ const existing = options.mode === "edit" ? options.target : void 0;
1828
+ const answers = {
1829
+ mode: options.mode,
1830
+ existing,
1831
+ runtime: existing ? getRuntimeRegistry().get(existing.runtime) ?? void 0 : options.mode !== "edit" ? options.runtime : void 0,
1832
+ fixedRuntime: options.mode !== "edit" && options.runtime !== void 0,
1833
+ targetId: existing?.id,
1834
+ url: existing?.url,
1835
+ model: existing?.defaultModel,
1836
+ credential: existing?.auth?.apiKeyEnvVar ? "env" : existing?.auth?.apiKeyRef ? "keep" : void 0,
1837
+ apiKeyEnv: existing?.auth?.apiKeyEnvVar,
1838
+ contextWindow: existing?.capabilities?.contextWindow,
1839
+ thinking: existing?.capabilities?.reasoning === false ? "off" : void 0
1840
+ };
1841
+ if (existing && !answers.runtime) {
1842
+ presenter.fail(`Unknown runtime: ${existing.runtime}`);
1843
+ return 2;
1844
+ }
1845
+ const marks = new Array(STEPS.length).fill(writer.mark());
1846
+ let cursor = 0;
1847
+ let direction = 1;
1848
+ while (cursor < STEPS.length) {
1849
+ const step = STEPS[cursor];
1850
+ if (step === void 0) break;
1851
+ if (!step.applies(answers)) {
1852
+ cursor += direction;
1853
+ if (cursor < 0) return cancel(presenter, answers);
1854
+ continue;
1855
+ }
1856
+ marks[cursor] = writer.mark();
1857
+ const outcome = await step.run(wizard, answers);
1858
+ if (outcome === "quit" || outcome === "cancel") return cancel(presenter, answers, outcome === "quit");
1859
+ if (outcome === "credential") {
1860
+ direction = 1;
1861
+ cursor = STEPS.indexOf(CREDENTIAL_STEP);
1862
+ continue;
1863
+ }
1864
+ if (outcome === "back") {
1865
+ direction = -1;
1866
+ cursor -= 1;
1867
+ while (cursor >= 0 && !(STEPS[cursor]?.applies(answers) ?? false)) cursor -= 1;
1868
+ if (cursor < 0) return cancel(presenter, answers);
1869
+ writer.rewindTo(marks[cursor] ?? writer.mark());
1870
+ continue;
1871
+ }
1872
+ direction = 1;
1873
+ cursor += 1;
1874
+ }
1875
+ const code = finish(wizard, answers);
1876
+ if (code === 0 && answers.mode === "first") {
1877
+ await reviewInteropAgents({ rl: null, streams, presenter, rail, quiet: true });
1878
+ }
1879
+ return code;
1880
+ }
1881
+ function cancel(presenter, answers, quit = false) {
1882
+ presenter.done("Cancelled; target settings not saved");
1883
+ if (answers.mode === "first") printError("configuration cancelled");
1884
+ return answers.mode === "first" || quit ? 130 : 0;
1885
+ }
1886
+ function finish(wizard, answers) {
1887
+ const runtime = answers.runtime;
1888
+ const targetId = answers.targetId;
1889
+ if (!runtime || targetId === void 0) return cancel(wizard.presenter, answers);
1890
+ const presenter = wizard.presenter;
1891
+ const reasoning = PROTOCOL_COMPAT_RUNTIME_IDS.has(runtime.id) && answers.thinking !== void 0 ? answers.thinking !== "off" : void 0;
1892
+ const descriptor = draftDescriptor(answers, runtime, true);
1893
+ descriptor.capabilities = { ...descriptor.capabilities };
1894
+ if (reasoning !== void 0) descriptor.capabilities.reasoning = reasoning;
1895
+ if (answers.contextWindow === void 0) delete descriptor.capabilities.contextWindow;
1896
+ else descriptor.capabilities.contextWindow = answers.contextWindow;
1897
+ const chatEligible = isOrchestratorEligibleRuntime(runtime);
1898
+ try {
1899
+ const preview = readSettings();
1900
+ applyAnswers(preview, answers, descriptor, chatEligible);
1901
+ const validated = validateSettings(preview);
1902
+ if (validated.issues.length) throw new SettingsValidationError(validated.issues);
1903
+ initializeClioHome();
1904
+ if (answers.apiKeyLiteral !== void 0 && descriptor.auth?.apiKeyRef) {
1905
+ const auth = openAuthStorage();
1906
+ auth.setApiKey(descriptor.auth.apiKeyRef, answers.apiKeyLiteral);
1907
+ if (credentialWriteFailed(auth, `credential for ${runtime.id} was not stored; target '${targetId}' not saved`)) {
1908
+ presenter.done("Nothing written");
1909
+ return 1;
1910
+ }
1911
+ printPlaintextCredentialWarning();
1912
+ }
1913
+ updateSettings((settings) => applyAnswers(settings, answers, descriptor, chatEligible));
1914
+ } catch (error) {
1915
+ presenter.fail("settings were not written", error instanceof Error ? error.message : String(error));
1916
+ presenter.done("Target settings not saved");
1917
+ return 1;
1918
+ }
1919
+ presenter.completedStep(`target ${targetId} saved, runtime ${runtime.id}`);
1920
+ if (answers.mode === "first" && chatEligible)
1921
+ presenter.completedStep(`chat runs on ${targetId}${answers.model ? `, model ${answers.model}` : ""}`);
1922
+ else if (!chatEligible)
1923
+ presenter.completedStep(`${runtime.id} cannot answer chat; ${targetId} is registered for dispatch only`);
1924
+ if (answers.mode === "first") presenter.completedStep(`fleet default is ${targetId}`);
1925
+ else presenter.note("Use Settings \u2192 Chat, Fleet, or Context & Memory to change model defaults.");
1926
+ if (answers.mode === "first" && answers.thinking !== void 0)
1927
+ presenter.completedStep(`thinking level ${answers.thinking}`);
1928
+ if (answers.antigravity !== void 0) {
1929
+ presenter.completedStep(
1930
+ `world-knowledge bound read-only to ${answers.antigravity.targetId}/${answers.antigravity.model}`
1931
+ );
1932
+ }
1933
+ presenter.completedStep(`settings written to ${shortenPath(settingsPath())}`);
1934
+ if (contextWindowUndiscovered(descriptor, answers.probe ?? null)) {
1935
+ presenter.warn(
1936
+ `${targetId} reported no context window, so Clio will use the runtime default as a guess. Set the real one with \`clio-coder configure --id ${targetId} --runtime ${runtime.id} --context-window <N>\`.`
1937
+ );
1938
+ }
1939
+ presenter.commandAdvice("Start Clio:", "clio-coder");
1940
+ presenter.commandAdvice("Change any of this later:", "clio-coder configure");
1941
+ presenter.done("Done");
1942
+ return 0;
1943
+ }
1944
+
1945
+ // src/cli/configure-quick.ts
1946
+ init_esm_shims();
1947
+ function endpointUrl(value) {
1948
+ const url = new URL(value.includes("://") ? value : `http://${value}`);
1949
+ if (!["http:", "https:"].includes(url.protocol) || !url.hostname)
1950
+ throw new Error("Use an http:// or https:// endpoint URL.");
1951
+ if (url.username || url.password)
1952
+ throw new Error("Enter the endpoint without credentials; Clio asks for a key when needed.");
1953
+ return url.toString().replace(/\/$/u, "");
1954
+ }
1955
+ async function connect(url, key) {
1956
+ const settings = readSettings();
1957
+ const registry = getRuntimeRegistry();
1958
+ const matches = settings.targets.filter((target2) => {
1959
+ const runtime2 = registry.get(target2.runtime);
1960
+ if (!target2.url || !runtime2 || !isOrchestratorEligibleRuntime(runtime2)) return false;
1961
+ try {
1962
+ return endpointUrl(target2.url) === url;
1963
+ } catch {
1964
+ return false;
1965
+ }
1966
+ });
1967
+ const existing = matches.find((target2) => target2.id === settings.chat.target) ?? matches[0];
1968
+ let runtime = existing ? registry.get(existing.runtime) : null;
1969
+ let token = key;
1970
+ if (existing && runtime && token === void 0) {
1971
+ const auth = await openAuthStorage().resolveForTarget(resolveAuthTarget(existing, runtime), {
1972
+ includeFallback: false
1973
+ });
1974
+ token = auth.apiKey;
1975
+ }
1976
+ const ctx = { credentialsPresent: /* @__PURE__ */ new Set(), httpTimeoutMs: 5e3, authToken: token ?? "" };
1977
+ if (!runtime) {
1978
+ const root = targetRootUrl({ id: "quick", runtime: "openai-compat", url }) ?? url;
1979
+ const headers = token ? { Authorization: `Bearer ${token}` } : {};
1980
+ const native = await fingerprintNativeRuntime(root, headers);
1981
+ let id = native?.runtimeId ?? "openai-compat";
1982
+ if (!native) {
1983
+ const info = await probeJson({
1984
+ url: `${root}/v1/model/info`,
1985
+ headers,
1986
+ timeoutMs: 1e3
1987
+ });
1988
+ if (info.ok && info.data?.data?.some((row) => typeof row.model_name === "string" && row.model_info !== void 0))
1989
+ id = "litellm";
1990
+ }
1991
+ runtime = registry.get(id);
1992
+ }
1993
+ if (!runtime) throw new Error("No compatible runtime is available. Open Settings \u2192 Connections.");
1994
+ const target = existing ? structuredClone(existing) : {
1995
+ id: deriveTargetId(runtime.id, settings.targets),
1996
+ runtime: runtime.id,
1997
+ url
1998
+ };
1999
+ let probe = await runtime.probe?.(target, ctx) ?? {
2000
+ ok: false,
2001
+ error: "This connection does not support endpoint checks."
2002
+ };
2003
+ let models = probe.ok ? probe.models ?? await runtime.probeModels?.(target, ctx) ?? [] : [];
2004
+ if (!existing && runtime.id === "openai-compat" && !probe.ok && /HTTP (401|403|404)/u.test(probe.error ?? "")) {
2005
+ const anthropic = registry.get("anthropic-compat");
2006
+ if (anthropic) {
2007
+ const candidate = { ...target, runtime: anthropic.id };
2008
+ const catalog = await anthropic.probeModels?.(candidate, ctx) ?? [];
2009
+ if (catalog.length > 0) {
2010
+ runtime = anthropic;
2011
+ target.runtime = anthropic.id;
2012
+ target.id = deriveTargetId(anthropic.id, settings.targets);
2013
+ models = catalog;
2014
+ probe = { ok: true, models };
2015
+ }
2016
+ }
2017
+ }
2018
+ models = [...new Set(models)].filter((id) => probe.modelCapabilities?.[id]?.chat !== false);
2019
+ return { runtime, target, existing, probe, models };
2020
+ }
2021
+ async function runQuickConnect(prompts) {
2022
+ const initial = readSettings();
2023
+ const first = initial.targets.length === 0;
2024
+ const current = initial.targets.find((target) => target.id === initial.chat.target);
2025
+ let url = current?.url ?? "";
2026
+ let key;
2027
+ let connection;
2028
+ let model = "";
2029
+ let step = "url";
2030
+ let askedKey = false;
2031
+ let optionalKey = false;
2032
+ let notice = "";
2033
+ const presenter = createLifecyclePresenter({ stream: prompts.output });
2034
+ for (; ; ) {
2035
+ prompts.clearScreen();
2036
+ presenter.header("Quick Connect", "configure");
2037
+ presenter.note("Connect one model to power Clio. Change other settings whenever you need them.");
2038
+ if (notice) {
2039
+ presenter.warn(notice);
2040
+ notice = "";
2041
+ }
2042
+ try {
2043
+ if (step === "url") {
2044
+ presenter.note("LM Studio: localhost:1234 \xB7 Ollama: localhost:11434");
2045
+ const answer = await prompts.text("Endpoint URL", url);
2046
+ if (!answer) {
2047
+ notice = "Enter the endpoint URL shown by your model server or API provider.";
2048
+ continue;
2049
+ }
2050
+ try {
2051
+ url = endpointUrl(answer);
2052
+ } catch (error) {
2053
+ notice = error instanceof Error ? error.message : String(error);
2054
+ continue;
2055
+ }
2056
+ key = void 0;
2057
+ askedKey = false;
2058
+ connection = void 0;
2059
+ } else if (step === "key") {
2060
+ presenter.note(`Endpoint: ${url}`);
2061
+ if (optionalKey)
2062
+ presenter.note("Some APIs publish models publicly but require a key for chat. Leave blank for a keyless server.");
2063
+ key = await prompts.text("API key (saved locally when you choose Connect)", "", true) || void 0;
2064
+ if (!key && !optionalKey) {
2065
+ notice = "Enter a key, or press Escape to change the endpoint.";
2066
+ continue;
2067
+ }
2068
+ askedKey = true;
2069
+ }
2070
+ if (step === "url" || step === "key") {
2071
+ presenter.note("Checking the endpoint and reading its model list\u2026");
2072
+ connection = await connect(url, key);
2073
+ if (!connection.probe.ok) {
2074
+ if (connection.probe.authFailed || /HTTP (401|403)/u.test(connection.probe.error ?? "")) {
2075
+ optionalKey = false;
2076
+ notice = key ? "The endpoint rejected that key. Try again, or Escape to go back." : "This endpoint needs an API key.";
2077
+ step = "key";
2078
+ } else {
2079
+ notice = `Could not connect: ${connection.probe.error ?? "no reply"}. Check the URL and that the server is running.`;
2080
+ step = "url";
2081
+ }
2082
+ continue;
2083
+ }
2084
+ if (!connection.existing && !askedKey && connection.runtime.auth === "api-key" && connection.runtime.tier !== "local-native") {
2085
+ optionalKey = true;
2086
+ step = "key";
2087
+ continue;
2088
+ }
2089
+ if (connection.models.length === 0) {
2090
+ notice = "The endpoint offered no chat models. Load a model and retry. Servers without model discovery can use Settings \u2192 Connections.";
2091
+ step = "url";
2092
+ continue;
2093
+ }
2094
+ const preferred = connection.existing?.id === initial.chat.target ? initial.chat.model : connection.target.defaultModel;
2095
+ model = preferred && connection.models.includes(preferred) ? preferred : connection.models[0] ?? "";
2096
+ step = connection.models.length === 1 ? "save" : "model";
2097
+ continue;
2098
+ }
2099
+ if (!connection) {
2100
+ step = "url";
2101
+ continue;
2102
+ }
2103
+ if (step === "model") {
2104
+ presenter.note(`Connected: ${url} (${connection.runtime.displayName})`);
2105
+ model = await prompts.choose("Choose the model for Clio", connection.models, model, true);
2106
+ if (!connection.models.includes(model)) {
2107
+ notice = "Choose a model from the endpoint's live list.";
2108
+ continue;
2109
+ }
2110
+ step = "save";
2111
+ continue;
2112
+ }
2113
+ presenter.fields([
2114
+ ["Endpoint", url],
2115
+ ["Model", model],
2116
+ ["Connection", "live model discovery passed"]
2117
+ ]);
2118
+ if (first) {
2119
+ const settings = readSettings();
2120
+ const autonomy = {
2121
+ "read-only": "inspect and answer; no edits or commands",
2122
+ suggest: "ask before edits, commands, and delegation",
2123
+ "auto-edit": "edit and run recognized checks; unfamiliar commands ask",
2124
+ "full-auto": "skip autonomy approvals; safety rules still apply"
2125
+ }[settings.safety.autonomy];
2126
+ presenter.fields([
2127
+ ["Autonomy", `${settings.safety.autonomy} \xB7 ${autonomy}`],
2128
+ [
2129
+ "Worker approvals",
2130
+ settings.fleet.permissions.mode === "deny" ? "deny requests needing approval; continue allowed work" : settings.fleet.permissions.mode === "fail" ? "stop a worker when approval is needed" : "ask you; unanswered requests follow the configured fallback"
2131
+ ],
2132
+ [
2133
+ "Tracked spending",
2134
+ settings.safety.limits.sessionCostUsd === 0 ? "no session ceiling" : `$${settings.safety.limits.sessionCostUsd} per session; unpriced usage is not covered`
2135
+ ]
2136
+ ]);
2137
+ presenter.note("Safety rules still apply. You can adjust these in /settings \u2192 Permissions & Limits.");
2138
+ } else presenter.note("Use this model for chat. Your other settings and role assignments stay in place.");
2139
+ const choice = await prompts.choose("Ready to connect", ["Connect", "Back"], "Connect");
2140
+ if (choice !== "Connect") throw new ConfigureNavigation("back");
2141
+ const descriptor = structuredClone(connection.target);
2142
+ if (!connection.existing) descriptor.defaultModel = model;
2143
+ if (key) {
2144
+ descriptor.auth = { ...descriptor.auth, apiKeyRef: targetApiKeyRef(descriptor.id, readSettings().targets) };
2145
+ delete descriptor.auth.apiKeyEnvVar;
2146
+ }
2147
+ const apply = (settings) => {
2148
+ const target = settings.targets.find((entry) => entry.id === descriptor.id);
2149
+ if (JSON.stringify(target) !== JSON.stringify(connection?.existing))
2150
+ throw new Error("This target changed during setup. Reopen Quick Connect to keep those changes.");
2151
+ applyTarget(settings, descriptor);
2152
+ setOrchestratorPointer(settings, descriptor, model);
2153
+ if (first && !settings.fleet.default.target) setWorkerDefaultPointer(settings, descriptor, model);
2154
+ };
2155
+ const preview = readSettings();
2156
+ apply(preview);
2157
+ const validated = validateSettings(preview);
2158
+ if (validated.issues.length) throw new SettingsValidationError(validated.issues);
2159
+ initializeClioHome();
2160
+ if (key && descriptor.auth?.apiKeyRef) {
2161
+ const auth = openAuthStorage();
2162
+ auth.setApiKey(descriptor.auth.apiKeyRef, key);
2163
+ if (credentialWriteFailed(auth, "The key was not saved; connection settings were not changed."))
2164
+ throw new Error("The key could not be saved. Check permissions on the credentials file and retry.");
2165
+ printPlaintextCredentialWarning();
2166
+ }
2167
+ updateSettings(apply);
2168
+ presenter.done(`Connected: ${descriptor.id} / ${model}`);
2169
+ presenter.commandAdvice("Start Clio:", "clio-coder");
2170
+ presenter.note(
2171
+ 'You can start working immediately. Ask Clio "What can you do without asking me?" or open /settings whenever you want to adjust the defaults.'
2172
+ );
2173
+ return "connected";
2174
+ } catch (error) {
2175
+ if (!(error instanceof ConfigureNavigation)) {
2176
+ notice = error instanceof Error ? error.message : String(error);
2177
+ step = "url";
2178
+ continue;
2179
+ }
2180
+ if (error.kind === "quit" || step === "url") {
2181
+ presenter.done("Quick Connect cancelled; connection settings not saved.");
2182
+ return error.kind;
2183
+ }
2184
+ step = step === "save" && (connection?.models.length ?? 0) > 1 ? "model" : step === "model" || step === "save" ? askedKey ? "key" : "url" : "url";
2185
+ }
2186
+ }
2187
+ }
2188
+
2189
+ // src/cli/configure.ts
2190
+ var HELP = `clio-coder configure
2191
+
2192
+ Configure model targets and runtime settings for chat and fleet dispatch.
2193
+
2194
+ Usage:
2195
+ clio-coder configure Quick Connect, Settings, or Diagnostics
2196
+ clio-coder configure --quick connect an endpoint with recommended defaults
2197
+ clio-coder configure --settings open the complete settings menu
2198
+ clio-coder configure --section <name> open one section directly:
2199
+ targets, chat, fleet, context, safety,
2200
+ interface, integrations, advanced
2201
+ (older section names remain accepted)
2202
+ Without a terminal this prints the
2203
+ section's values and exits.
2204
+ clio-coder configure --json emit the effective settings as JSON
2205
+ clio-coder configure --edit edit all user settings in VISUAL/EDITOR;
2206
+ validate and review before saving
2207
+ clio-coder configure --interop review detected coding agents as delegation peers
2208
+ clio-coder configure --list list target runtimes (user-facing only)
2209
+ clio-coder configure --list --all list every registered runtime including aliases
2210
+ clio-coder configure --id <targetId> [flags] --runtime <runtimeId>
2211
+ clio-coder configure --help, -h show this message
2212
+
2213
+ In the interactive menus: arrow keys move, enter opens, escape goes back, q
2214
+ quits. Where the terminal cannot support that, the same menus are numbered and
2215
+ answered by typing a number, b for back, or q to quit.
2216
+
2217
+ Non-interactive flags:
2218
+ --id <targetId> target id to register (required when non-interactive)
2219
+ --runtime <runtimeId> runtime to use when registering non-interactively
2220
+ --url <host> target base URL (http(s):// or ws://)
2221
+ --model <wireModelId> default model id for this target
2222
+ --orchestrator-model <id> model to use when setting chat default
2223
+ --background-model <id> model to use for proactive task memory
2224
+ --fleet-model <id> model to use when setting fleet default
2225
+ (mutually exclusive with --agent-profile)
2226
+ --agent-profile <name> save this target as a named fleet profile
2227
+ --agent-profile-model <id> model to use for --agent-profile
2228
+ --bind-agent <agentId> bind this --agent-profile to an agent
2229
+ --api-key-env <VAR> read API key from this env var at call time
2230
+ --api-key <literal> store API key in credentials.yaml
2231
+ --force save a model outside the runtime catalog, or one the
2232
+ target does not advertise, without refusing
2233
+ --gateway mark the target as a gateway
2234
+ --lifecycle <user-managed|clio-coder-managed>
2235
+ resident model lifecycle policy
2236
+ --set-orchestrator use this target for chat
2237
+ --set-background use this target for proactive task memory
2238
+ --set-fleet-default use this target for the fleet default
2239
+ --context-window <N> capability override
2240
+ --max-tokens <N> output token capability override
2241
+ --reasoning <true|false> capability override
2242
+ `;
2243
+ function parseSetupArgs(argv) {
2244
+ const out = {
2245
+ positional: [],
2246
+ help: false,
2247
+ list: false,
2248
+ all: false,
2249
+ interop: false,
2250
+ json: false,
2251
+ edit: false,
2252
+ quick: false,
2253
+ settings: false,
2254
+ force: false,
2255
+ gateway: false,
2256
+ setOrchestrator: false,
2257
+ setBackground: false,
2258
+ setWorkerDefault: false
2259
+ };
2260
+ for (let i = 0; i < argv.length; i++) {
2261
+ const a = argv[i];
2262
+ const need = () => {
2263
+ const v = argv[i + 1];
2264
+ if (v === void 0) throw new Error(`${a} requires a value`);
2265
+ i += 1;
2266
+ return v;
2267
+ };
2268
+ switch (a) {
2269
+ case "--help":
2270
+ case "-h":
2271
+ out.help = true;
2272
+ break;
2273
+ case "--json":
2274
+ out.json = true;
2275
+ break;
2276
+ case "--edit":
2277
+ out.edit = true;
2278
+ break;
2279
+ case "--quick":
2280
+ out.quick = true;
2281
+ break;
2282
+ case "--settings":
2283
+ out.settings = true;
2284
+ break;
2285
+ case "--section":
2286
+ out.section = need();
2287
+ break;
2288
+ case "--list":
2289
+ out.list = true;
2290
+ break;
2291
+ case "--all":
2292
+ out.all = true;
2293
+ break;
2294
+ case "--interop":
2295
+ out.interop = true;
2296
+ break;
2297
+ case "--remove":
2298
+ out.remove = need();
2299
+ break;
2300
+ case "--rename":
2301
+ out.renameOld = need();
2302
+ out.renameNew = need();
2303
+ break;
2304
+ case "--id":
2305
+ out.id = need();
2306
+ break;
2307
+ case "--runtime":
2308
+ out.runtime = need();
2309
+ break;
2310
+ case "--url":
2311
+ out.url = need();
2312
+ break;
2313
+ case "--model":
2314
+ out.model = need();
2315
+ break;
2316
+ case "--orchestrator-model":
2317
+ out.orchestratorModel = need();
2318
+ break;
2319
+ case "--background-model":
2320
+ out.backgroundModel = need();
2321
+ break;
2322
+ case "--fleet-model":
2323
+ out.workerModel = need();
2324
+ break;
2325
+ case "--agent-profile":
2326
+ out.workerProfile = need();
2327
+ break;
2328
+ case "--agent-profile-model":
2329
+ out.workerProfileModel = need();
2330
+ break;
2331
+ case "--bind-agent":
2332
+ out.bindAgent = need();
2333
+ break;
2334
+ case "--api-key-env":
2335
+ out.apiKeyEnv = need();
2336
+ break;
2337
+ case "--api-key":
2338
+ out.apiKey = need();
2339
+ break;
2340
+ case "--force":
2341
+ out.force = true;
2342
+ break;
2343
+ case "--gateway":
2344
+ out.gateway = true;
2345
+ break;
2346
+ case "--lifecycle": {
2347
+ const v = need();
2348
+ if (v !== "user-managed" && v !== "clio-coder-managed") {
2349
+ throw new Error("--lifecycle must be user-managed or clio-coder-managed");
2350
+ }
2351
+ out.lifecycle = v;
2352
+ break;
2353
+ }
2354
+ case "--set-orchestrator":
2355
+ out.setOrchestrator = true;
2356
+ break;
2357
+ case "--set-background":
2358
+ out.setBackground = true;
2359
+ break;
2360
+ case "--set-fleet-default":
2361
+ out.setWorkerDefault = true;
2362
+ break;
2363
+ case "--context-window": {
2364
+ const n = Number(need());
2365
+ if (!Number.isFinite(n) || n <= 0) throw new Error("--context-window must be a positive number");
2366
+ out.contextWindow = Math.floor(n);
2367
+ break;
2368
+ }
2369
+ case "--max-tokens": {
2370
+ const n = Number(need());
2371
+ if (!Number.isFinite(n) || n <= 0) throw new Error("--max-tokens must be a positive number");
2372
+ out.maxTokens = Math.floor(n);
2373
+ break;
2374
+ }
2375
+ case "--reasoning": {
2376
+ const v = need().toLowerCase();
2377
+ if (v !== "true" && v !== "false") throw new Error("--reasoning must be true or false");
2378
+ out.reasoning = v === "true";
2379
+ break;
2380
+ }
2381
+ default:
2382
+ if (a.startsWith("-")) throw new Error(`unknown flag: ${a}`);
2383
+ out.positional.push(a);
2384
+ }
2385
+ }
2386
+ return out;
2387
+ }
2388
+ function ensureRegistryPopulated() {
2389
+ registerClioOAuthProviders();
2390
+ const registry = getRuntimeRegistry();
2391
+ if (registry.list().length === 0) registerBuiltinRuntimes(registry);
2392
+ }
2393
+ var RUNTIME_LIST_CAPTION = "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.";
2394
+ function printRuntimeList(includeHidden) {
2395
+ const settings = readSettings();
2396
+ const auth = openAuthStorage();
2397
+ const rows = [];
2398
+ for (const entry of listProviderSupportEntries(getRuntimeRegistry().list(), { includeHidden })) {
2399
+ const runtime = getRuntimeRegistry().get(entry.runtimeId);
2400
+ const status = runtime && entry.connectable ? auth.statusForTarget(resolveRuntimeAuthTarget(runtime), {
2401
+ includeFallback: false
2402
+ }) : null;
2403
+ const authLabel = runtime?.auth === "oauth" ? status?.available ? "connected" : "login" : runtime?.auth === "api-key" ? status?.available ? "credential" : targetRequiresAuth({ id: entry.runtimeId, runtime: entry.runtimeId }, runtime) ? "needs-key" : "key-optional" : runtime?.auth ?? "none";
2404
+ rows.push({
2405
+ group: supportGroupLabel(entry.group),
2406
+ runtimeId: entry.runtimeId,
2407
+ label: entry.label,
2408
+ auth: authLabel,
2409
+ targets: configuredTargetsForRuntime(settings, entry.runtimeId).length,
2410
+ models: describeRuntimeModels(entry, 2)
2411
+ });
2412
+ }
2413
+ const width = terminalColumns();
2414
+ for (const line of formatRuntimeList(rows, width)) {
2415
+ process.stdout.write(`${line}
2416
+ `);
2417
+ }
2418
+ for (const line of wrapPlain(RUNTIME_LIST_CAPTION, width)) {
2419
+ process.stdout.write(`${line}
2420
+ `);
2421
+ }
2422
+ }
2423
+ function printSummary(settings, descriptor, probe) {
2424
+ process.stdout.write(`
2425
+ saved target ${descriptor.id} (runtime=${descriptor.runtime})
2426
+ `);
2427
+ if (descriptor.url) process.stdout.write(` url ${descriptor.url}
2428
+ `);
2429
+ if (descriptor.defaultModel) process.stdout.write(` model ${descriptor.defaultModel}
2430
+ `);
2431
+ if (descriptor.auth?.apiKeyEnvVar) process.stdout.write(` apiKeyEnv ${descriptor.auth.apiKeyEnvVar}
2432
+ `);
2433
+ if (descriptor.gateway) process.stdout.write(" gateway true\n");
2434
+ if (descriptor.lifecycle) process.stdout.write(` lifecycle ${descriptor.lifecycle}
2435
+ `);
2436
+ if (probe) {
2437
+ for (const line of probeLines(descriptor, probe)) process.stdout.write(` ${line}
2438
+ `);
2439
+ }
2440
+ warnUndiscoveredContextWindow(descriptor, probe);
2441
+ if (settings.chat.target === descriptor.id) process.stdout.write(" orchestrator target\n");
2442
+ if (settings.context.memory.target === descriptor.id) process.stdout.write(" background memory target\n");
2443
+ if (settings.fleet.default.target === descriptor.id) process.stdout.write(" fleet default\n");
2444
+ for (const [name, profile] of Object.entries(settings.fleet.profiles)) {
2445
+ if (profile.target === descriptor.id) process.stdout.write(` fleet profile ${name}
2446
+ `);
2447
+ }
2448
+ process.stdout.write(`
2449
+ settings written to ${settingsPath()}
2450
+ `);
2451
+ }
2452
+ function resolveModelChoice(answer, wireModels, defaultValue) {
2453
+ if (answer.length === 0) return defaultValue;
2454
+ const numeric = Number(answer);
2455
+ if (Number.isInteger(numeric) && numeric >= 1 && numeric <= wireModels.length) {
2456
+ return wireModels[numeric - 1];
2457
+ }
2458
+ return answer;
2459
+ }
2460
+ async function askModelChoice(rl, label, wireModels, defaultValue) {
2461
+ const answer = await ask(rl, `${label} (number or id)`, defaultValue ?? "");
2462
+ if (answer === null) return null;
2463
+ return resolveModelChoice(answer, wireModels, defaultValue) ?? "";
2464
+ }
2465
+ function refuseCatalogSeededModel(runtime, support) {
2466
+ printError(
2467
+ `--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`
2468
+ );
2469
+ process.stderr.write(
2470
+ ` run \`clio-coder configure --runtime ${runtime.id}\` with no other flags to choose from the full list
2471
+ `
2472
+ );
2473
+ }
2474
+ async function runNonInteractive(runtime, args) {
2475
+ if (!args.id) {
2476
+ printError("--id is required when passing flags non-interactively");
2477
+ return 2;
2478
+ }
2479
+ if (args.workerProfileModel !== void 0 && args.workerProfile === void 0) {
2480
+ printError("--agent-profile-model requires --agent-profile");
2481
+ return 2;
2482
+ }
2483
+ if (args.bindAgent !== void 0 && args.workerProfile === void 0) {
2484
+ printError("--bind-agent requires --agent-profile");
2485
+ return 2;
2486
+ }
2487
+ if (args.workerProfile !== void 0 && args.workerProfile.trim().length === 0) {
2488
+ printError("--agent-profile must be non-empty");
2489
+ return 2;
2490
+ }
2491
+ if (args.workerProfile !== void 0 && args.workerModel !== void 0) {
2492
+ printError(
2493
+ "--fleet-model and --agent-profile conflict; use --agent-profile-model for the profile, or drop --agent-profile to set the fleet default"
2494
+ );
2495
+ return 2;
2496
+ }
2497
+ initializeClioHome();
2498
+ const settings = readSettings();
2499
+ const auth = openAuthStorage();
2500
+ const support = buildProviderSupportEntry(runtime);
2501
+ const existing = settings.targets.find((e) => e.id === args.id);
2502
+ if (existing && (getRuntimeRegistry().get(existing.runtime)?.id ?? existing.runtime) !== runtime.id) {
2503
+ printError(`target ${args.id} already exists with runtime ${existing.runtime}`);
2504
+ return 2;
2505
+ }
2506
+ let url = args.url ? normalizeUrl(args.url, runtime.id) : existing?.url;
2507
+ if (!url && support.supportsCustomUrl) {
2508
+ url = defaultUrlFor(runtime.id);
2509
+ }
2510
+ if (url && runtime.id === "lmstudio") {
2511
+ const greeting = await greetLmStudio(
2512
+ { id: args.id, runtime: runtime.id, url },
2513
+ { credentialsPresent: /* @__PURE__ */ new Set(), httpTimeoutMs: 750 }
2514
+ );
2515
+ if (!greeting.ok) {
2516
+ printError(`refusing to save LM Studio target '${args.id}': ${url} did not return the LM Studio greeting`);
2517
+ return 2;
2518
+ }
2519
+ }
2520
+ if (url && (runtime.id === "openai-compat" || runtime.id === "anthropic-compat")) {
2521
+ const fingerprint = await fingerprintNativeRuntime(url);
2522
+ if (fingerprint) {
2523
+ process.stdout.write(
2524
+ `note: detected ${fingerprint.displayName} at ${url}; consider \`clio-coder targets convert ${args.id} --runtime ${fingerprint.runtimeId}\` for proper resident-model lifecycle
2525
+ `
2526
+ );
2527
+ }
2528
+ }
2529
+ const authStatus = auth.statusForTarget(
2530
+ existing ? resolveAuthTarget(existing, runtime) : resolveRuntimeAuthTarget(runtime),
2531
+ { includeFallback: false }
2532
+ );
2533
+ const apiKeyEnv = args.apiKeyEnv ?? existing?.auth?.apiKeyEnvVar;
2534
+ const apiKeyRef = runtime.auth === "api-key" && (args.apiKey || existing?.auth?.apiKeyRef || authStatus.source === "stored-api-key") ? args.apiKey ? targetApiKeyRef(args.id, settings.targets) : existing?.auth?.apiKeyRef ?? runtime.id : void 0;
2535
+ const oauthProfile = runtime.auth === "oauth" ? existing?.auth?.oauthProfile ?? runtime.oauthProviderId ?? runtime.id : void 0;
2536
+ const seed = {
2537
+ ...existing,
2538
+ ...buildDescriptor(runtime, args.id, {
2539
+ ...url !== void 0 ? { url } : {},
2540
+ ...args.model !== void 0 ? { model: args.model } : existing?.defaultModel ? { model: existing.defaultModel } : support.defaultModel ? { model: support.defaultModel } : {},
2541
+ ...apiKeyEnv !== void 0 ? { apiKeyEnv } : {},
2542
+ ...apiKeyRef !== void 0 ? { apiKeyRef } : {},
2543
+ ...oauthProfile !== void 0 ? { oauthProfile } : {},
2544
+ gateway: args.gateway || existing?.gateway === true,
2545
+ ...args.lifecycle !== void 0 ? { lifecycle: args.lifecycle } : existing?.lifecycle !== void 0 ? { lifecycle: existing.lifecycle } : {},
2546
+ ...args.contextWindow !== void 0 ? { contextWindow: args.contextWindow } : {},
2547
+ ...args.maxTokens !== void 0 ? { maxTokens: args.maxTokens } : {},
2548
+ ...args.reasoning !== void 0 ? { reasoning: args.reasoning } : {},
2549
+ ...existing?.lmstudio ? { lmstudio: existing.lmstudio } : {},
2550
+ ...existing?.litellm ? { litellm: existing.litellm } : {},
2551
+ ...existing?.ollama ? { ollama: existing.ollama } : {}
2552
+ })
2553
+ };
2554
+ seed.capabilities = { ...existing?.capabilities, ...seed.capabilities };
2555
+ if (seed.auth) seed.auth = { ...existing?.auth, ...seed.auth };
2556
+ const inventory = await resolveSupportedWireModels(runtime, seed, existing, args.apiKey);
2557
+ const wireModels = inventory.models;
2558
+ const model = args.model ?? existing?.defaultModel ?? (inventory.source === "probe" ? wireModels[0] : support.defaultModel) ?? (support.modelSource === "catalog" ? void 0 : wireModels[0]);
2559
+ if (model === void 0 && support.modelSource === "catalog") {
2560
+ refuseCatalogSeededModel(runtime, support);
2561
+ return 2;
2562
+ }
2563
+ if (!validateResolvedModel(runtime, seed, model, args.force, inventory)) return 2;
2564
+ if (!validateContextWindowOverride(runtime, model, args.contextWindow, args.force)) return 2;
2565
+ const descriptor = {
2566
+ ...existing,
2567
+ ...buildDescriptor(runtime, args.id, {
2568
+ ...url !== void 0 ? { url } : {},
2569
+ ...model ? { model } : {},
2570
+ ...apiKeyEnv !== void 0 ? { apiKeyEnv } : {},
2571
+ ...apiKeyRef !== void 0 ? { apiKeyRef } : {},
2572
+ ...oauthProfile !== void 0 ? { oauthProfile } : {},
2573
+ gateway: args.gateway || existing?.gateway === true,
2574
+ ...args.lifecycle !== void 0 ? { lifecycle: args.lifecycle } : existing?.lifecycle !== void 0 ? { lifecycle: existing.lifecycle } : {},
2575
+ ...args.contextWindow !== void 0 ? { contextWindow: args.contextWindow } : {},
2576
+ ...args.maxTokens !== void 0 ? { maxTokens: args.maxTokens } : {},
2577
+ ...args.reasoning !== void 0 ? { reasoning: args.reasoning } : {},
2578
+ ...existing?.lmstudio ? { lmstudio: existing.lmstudio } : {},
2579
+ ...existing?.litellm ? { litellm: existing.litellm } : {},
2580
+ ...existing?.ollama ? { ollama: existing.ollama } : {}
2581
+ })
2582
+ };
2583
+ descriptor.capabilities = { ...existing?.capabilities, ...descriptor.capabilities };
2584
+ if (descriptor.auth) descriptor.auth = { ...existing?.auth, ...descriptor.auth };
2585
+ const setOrchestrator = args.setOrchestrator || args.orchestratorModel !== void 0;
2586
+ const setBackground = args.setBackground || args.backgroundModel !== void 0;
2587
+ if ((setOrchestrator || setBackground) && !isOrchestratorEligibleRuntime(runtime)) {
2588
+ printError(
2589
+ `cannot use target '${descriptor.id}' as a chat or background target because runtime '${runtime.id}' is not an HTTP/native runtime`
2590
+ );
2591
+ return 1;
2592
+ }
2593
+ try {
2594
+ assertOrchestratorReplacementEligible(settings, descriptor);
2595
+ } catch (error) {
2596
+ printError(error instanceof Error ? error.message : String(error));
2597
+ return 1;
2598
+ }
2599
+ if (args.apiKey && apiKeyRef) {
2600
+ auth.setApiKey(apiKeyRef, args.apiKey);
2601
+ if (credentialWriteFailed(auth, `credential for ${runtime.id} was not stored; target '${descriptor.id}' not saved`))
2602
+ return 1;
2603
+ printPlaintextCredentialWarning();
2604
+ }
2605
+ const setWorkerDefault = args.setWorkerDefault || args.workerProfile === void 0 && args.workerModel !== void 0;
2606
+ const applyConfiguration = (target) => {
2607
+ applyTarget(target, descriptor);
2608
+ if (setOrchestrator)
2609
+ setOrchestratorPointer(target, descriptor, args.orchestratorModel ?? descriptor.defaultModel ?? null);
2610
+ if (setBackground) setBackgroundPointer(target, descriptor, args.backgroundModel ?? descriptor.defaultModel ?? null);
2611
+ if (setWorkerDefault)
2612
+ setWorkerDefaultPointer(target, descriptor, args.workerModel ?? descriptor.defaultModel ?? null);
2613
+ if (args.workerProfile !== void 0) {
2614
+ setWorkerProfilePointer(
2615
+ target,
2616
+ args.workerProfile,
2617
+ descriptor,
2618
+ args.workerProfileModel ?? descriptor.defaultModel ?? null
2619
+ );
2620
+ if (args.bindAgent !== void 0) bindAgentProfileInSettings(target, args.bindAgent, args.workerProfile);
2621
+ }
2622
+ };
2623
+ applyConfiguration(settings);
2624
+ updateSettings(applyConfiguration);
2625
+ const probe = await runtimeProbe(runtime, descriptor, args.apiKey);
2626
+ if (probe?.ok && probe.models) {
2627
+ recordTargetModelSnapshot(descriptor, probe.models, probe.modelLabels ? { modelLabels: probe.modelLabels } : {});
2628
+ }
2629
+ printSummary(settings, descriptor, probe);
2630
+ if (runtime.auth === "oauth" && !auth.statusForTarget(existing ? resolveAuthTarget(existing, runtime) : resolveRuntimeAuthTarget(runtime), {
2631
+ includeFallback: false
2632
+ }).available) {
2633
+ process.stdout.write(
2634
+ `note: authenticate ${runtime.id} with \`clio-coder auth login ${runtime.id}\` before using this target
2635
+ `
2636
+ );
2637
+ }
2638
+ printOk(`target ${args.id} saved`);
2639
+ return 0;
2640
+ }
2641
+ async function pickRuntime(rl) {
2642
+ const registry = getRuntimeRegistry();
2643
+ const entries = listProviderSupportEntries(registry.list());
2644
+ return pickRuntimeFromEntries(rl, entries, "\nSupported runtimes:");
2645
+ }
2646
+ async function pickRuntimeFromEntries(rl, entries, heading) {
2647
+ const registry = getRuntimeRegistry();
2648
+ if (entries.length === 0) {
2649
+ process.stderr.write("no runtimes available in this category\n");
2650
+ return null;
2651
+ }
2652
+ process.stdout.write(`${heading}
2653
+ `);
2654
+ const menu = formatRuntimeMenu(
2655
+ entries.map((entry) => ({
2656
+ group: supportGroupLabel(entry.group),
2657
+ runtimeId: entry.runtimeId,
2658
+ summary: entry.summary
2659
+ })),
2660
+ terminalColumns()
2661
+ );
2662
+ for (const line of menu) process.stdout.write(`${line}
2663
+ `);
2664
+ const allowedIds = new Set(entries.map((entry) => entry.runtimeId));
2665
+ const defaultRuntimeId = entries.find((entry) => entry.featured)?.runtimeId ?? "";
2666
+ for (; ; ) {
2667
+ const answer = await ask(rl, "\nSelection (number or runtime id)", defaultRuntimeId);
2668
+ if (answer === null) return null;
2669
+ if (answer.length === 0) {
2670
+ process.stderr.write(`pick a number from 1 to ${entries.length}, or type a runtime id
2671
+ `);
2672
+ continue;
2673
+ }
2674
+ const numeric = Number(answer);
2675
+ if (Number.isInteger(numeric) && numeric >= 1 && numeric <= entries.length) {
2676
+ const picked = entries[numeric - 1];
2677
+ if (picked) {
2678
+ const runtime = registry.get(picked.runtimeId);
2679
+ if (runtime) return runtime;
2680
+ }
2681
+ }
2682
+ if (allowedIds.has(answer)) {
2683
+ const match = registry.get(answer);
2684
+ if (match) return match;
2685
+ }
2686
+ process.stderr.write(`unknown runtime id for this category: ${answer}
2687
+ `);
2688
+ }
2689
+ }
2690
+ async function pickCategory(rl) {
2691
+ process.stdout.write("\nHow will you connect Clio to a model?\n\n");
2692
+ for (const line of formatCategoryMenu(terminalColumns())) process.stdout.write(`${line}
2693
+ `);
2694
+ for (; ; ) {
2695
+ const answer = await ask(rl, "\nSelection", "1");
2696
+ if (answer === null) return null;
2697
+ if (answer.length === 0) continue;
2698
+ const category = matchCategoryChoice(answer);
2699
+ if (category) return category;
2700
+ process.stderr.write(`invalid choice: ${answer}
2701
+ `);
2702
+ }
2703
+ }
2704
+ async function pickRuntimeViaCategory(rl) {
2705
+ const registry = getRuntimeRegistry();
2706
+ const allEntries2 = listProviderSupportEntries(registry.list());
2707
+ const category = await pickCategory(rl);
2708
+ if (category === null) return null;
2709
+ if (category === "all") return pickRuntime(rl);
2710
+ const filtered = runtimesForCategory(allEntries2, category);
2711
+ if (filtered.length === 0) {
2712
+ process.stderr.write("no runtimes available for that category; falling back to full list\n");
2713
+ return pickRuntime(rl);
2714
+ }
2715
+ if (category === "chatgpt") {
2716
+ const only = filtered[0];
2717
+ if (only) {
2718
+ const runtime = registry.get(only.runtimeId);
2719
+ if (runtime) {
2720
+ process.stdout.write(`
2721
+ Using ${runtime.id} (${only.summary}).
2722
+ `);
2723
+ return runtime;
2724
+ }
2725
+ }
2726
+ return pickRuntime(rl);
2727
+ }
2728
+ if (filtered.length === 1) {
2729
+ const only = filtered[0];
2730
+ if (only) {
2731
+ const runtime = registry.get(only.runtimeId);
2732
+ if (runtime) {
2733
+ process.stdout.write(`
2734
+ Using ${runtime.id} (${only.summary}).
2735
+ `);
2736
+ return runtime;
2737
+ }
2738
+ }
2739
+ }
2740
+ const heading = category === "local-app" ? "\nLocal apps:" : category === "local-http" ? "\nLocal HTTP servers:" : "\nCloud APIs:";
2741
+ return pickRuntimeFromEntries(rl, filtered, heading);
2742
+ }
2743
+ async function maybeSteerToNativeRuntime(rl, currentRuntime, url) {
2744
+ if (currentRuntime.id !== "openai-compat" && currentRuntime.id !== "anthropic-compat") return currentRuntime;
2745
+ const fingerprint = await fingerprintNativeRuntime(url);
2746
+ if (!fingerprint) return currentRuntime;
2747
+ const native = getRuntimeRegistry().get(fingerprint.runtimeId);
2748
+ if (!native) return currentRuntime;
2749
+ process.stdout.write(`
2750
+ Detected ${fingerprint.displayName} at ${url}.
2751
+ `);
2752
+ const switchIt = await askYesNo(rl, `Use ${fingerprint.runtimeId} runtime instead of ${currentRuntime.id}?`, true);
2753
+ if (!switchIt) return currentRuntime;
2754
+ process.stdout.write(`Using ${fingerprint.runtimeId} runtime.
2755
+ `);
2756
+ return native;
2757
+ }
2758
+ async function runTargetSetupInteractive(rl, runtime, defaults) {
2759
+ const auth = openAuthStorage();
2760
+ const settings = readSettings();
2761
+ let support = buildProviderSupportEntry(runtime);
2762
+ const initialRuntimeId = runtime.id;
2763
+ const existingForRuntime = configuredTargetsForRuntime(settings, initialRuntimeId);
2764
+ const existing = defaults.id ? settings.targets.find((entry) => entry.id === defaults.id && entry.runtime === initialRuntimeId) ?? null : null;
2765
+ if (existingForRuntime.length > 0) {
2766
+ process.stdout.write(`
2767
+ Existing targets for ${runtime.id}:
2768
+ `);
2769
+ for (const target of existingForRuntime) {
2770
+ process.stdout.write(` - ${target.id}${target.defaultModel ? ` (${target.defaultModel})` : ""}
2771
+ `);
2772
+ }
2773
+ }
2774
+ process.stdout.write(`
2775
+ Selected runtime: ${runtime.id} (${support.summary})
2776
+ `);
2777
+ process.stdout.write(`Credentials: ${describeAuthStatus(runtime, existing ?? void 0)}
2778
+ `);
2779
+ if (support.modelHints.length > 0) {
2780
+ process.stdout.write(`Known models: ${describeRuntimeModels(support, 4)}
2781
+ `);
2782
+ }
2783
+ const suggestedId = defaults.id ?? existing?.id ?? deriveTargetId(runtime.id, settings.targets);
2784
+ const idInput = await ask(rl, "Target id", suggestedId);
2785
+ if (idInput === null || idInput.length === 0) {
2786
+ printError("target id is required");
2787
+ return 2;
2788
+ }
2789
+ const targetId = idInput;
2790
+ let url = existing?.url;
2791
+ if (support.supportsCustomUrl) {
2792
+ const urlDefault = defaults.url ?? existing?.url ?? defaultUrlFor(runtime.id);
2793
+ const urlInput = await ask(
2794
+ rl,
2795
+ support.group === "local-http" ? "Target URL" : "Base URL override (blank for runtime default)",
2796
+ urlDefault
2797
+ );
2798
+ if (urlInput === null) return 0;
2799
+ if (urlInput.length > 0) url = normalizeUrl(urlInput, runtime.id);
2800
+ } else if (defaults.url) {
2801
+ url = normalizeUrl(defaults.url, runtime.id);
2802
+ }
2803
+ if (url) {
2804
+ const steered = await maybeSteerToNativeRuntime(rl, runtime, url);
2805
+ if (steered.id !== runtime.id) {
2806
+ runtime = steered;
2807
+ support = buildProviderSupportEntry(runtime);
2808
+ }
2809
+ if (runtime.id === "lmstudio") {
2810
+ const greeting = await greetLmStudio(
2811
+ { id: targetId, runtime: runtime.id, url },
2812
+ { credentialsPresent: /* @__PURE__ */ new Set(), httpTimeoutMs: 750 }
2813
+ );
2814
+ if (!greeting.ok) {
2815
+ printError(`refusing to save LM Studio target '${targetId}': ${url} did not return the LM Studio greeting`);
2816
+ return 2;
2817
+ }
2818
+ }
2819
+ }
2820
+ let apiKeyEnv;
2821
+ let apiKeyLiteral;
2822
+ let apiKeyRef = existing?.auth?.apiKeyRef;
2823
+ let oauthProfile = runtime.auth === "oauth" ? existing?.auth?.oauthProfile ?? runtime.oauthProviderId ?? runtime.id : void 0;
2824
+ const authStatus = auth.statusForTarget(
2825
+ existing ? resolveAuthTarget(existing, runtime) : resolveRuntimeAuthTarget(runtime),
2826
+ { includeFallback: false }
2827
+ );
2828
+ if (runtime.auth === "api-key") {
2829
+ const needsCredential = targetRequiresAuth({ id: targetId, runtime: runtime.id }, runtime);
2830
+ const defaultSource = existing?.auth?.apiKeyRef || authStatus.source === "stored-api-key" ? "keep" : authStatus.source === "environment" || existing?.auth?.apiKeyEnvVar || needsCredential ? "env" : "skip";
2831
+ process.stdout.write(
2832
+ "\nCredential source: env reads a key from an environment variable, stored writes one to\ncredentials.yaml, keep leaves the current one alone, skip uses no key at all.\n"
2833
+ );
2834
+ const choice = await ask(rl, "Credential source [env|stored|keep|skip]", defaultSource);
2835
+ if (choice === null) return 0;
2836
+ const normalized = choice.trim().toLowerCase();
2837
+ if (normalized === "stored") {
2838
+ const literal = await rl.text("API key literal (stored in credentials.yaml, mode 0600)", "", true);
2839
+ if (literal !== null && literal.length > 0) {
2840
+ apiKeyLiteral = literal;
2841
+ apiKeyRef = targetApiKeyRef(targetId, settings.targets);
2842
+ }
2843
+ } else if (normalized === "env") {
2844
+ const envDefault = defaults.apiKeyEnv ?? existing?.auth?.apiKeyEnvVar ?? runtime.credentialsEnvVar ?? "";
2845
+ const envAnswer = await ask(rl, "Env var name (blank for no key)", envDefault);
2846
+ if (envAnswer === null) return 0;
2847
+ if (envAnswer.length > 0) apiKeyEnv = envAnswer;
2848
+ apiKeyRef = void 0;
2849
+ } else if (normalized === "keep") {
2850
+ apiKeyEnv = existing?.auth?.apiKeyEnvVar ?? (authStatus.source === "environment" ? runtime.credentialsEnvVar : void 0);
2851
+ apiKeyRef = existing?.auth?.apiKeyRef ?? (authStatus.source === "stored-api-key" ? runtime.id : void 0);
2852
+ } else {
2853
+ apiKeyEnv = void 0;
2854
+ apiKeyRef = void 0;
2855
+ }
2856
+ }
2857
+ if (runtime.auth === "oauth") {
2858
+ const connectNow = authStatus.available ? await askYesNo(rl, `Reconnect ${runtime.displayName}?`, false) : await askYesNo(rl, `Connect ${runtime.displayName} now?`, true);
2859
+ if (connectNow) {
2860
+ const connected = await loginOAuthRuntime(rl, runtime);
2861
+ if (!connected) return 1;
2862
+ }
2863
+ oauthProfile = existing?.auth?.oauthProfile ?? runtime.oauthProviderId ?? runtime.id;
2864
+ }
2865
+ let model = defaults.model;
2866
+ let inventory = { models: [], source: "none" };
2867
+ const tentative = buildDescriptor(runtime, targetId, {
2868
+ ...url !== void 0 ? { url } : {},
2869
+ ...apiKeyEnv !== void 0 ? { apiKeyEnv } : {},
2870
+ ...apiKeyRef !== void 0 ? { apiKeyRef } : {},
2871
+ ...oauthProfile !== void 0 ? { oauthProfile } : {},
2872
+ gateway: defaults.gateway,
2873
+ ...defaults.lifecycle !== void 0 ? { lifecycle: defaults.lifecycle } : existing?.lifecycle !== void 0 ? { lifecycle: existing.lifecycle } : {},
2874
+ ...defaults.contextWindow !== void 0 ? { contextWindow: defaults.contextWindow } : {},
2875
+ ...defaults.maxTokens !== void 0 ? { maxTokens: defaults.maxTokens } : {},
2876
+ ...defaults.reasoning !== void 0 ? { reasoning: defaults.reasoning } : {},
2877
+ ...existing?.lmstudio ? { lmstudio: existing.lmstudio } : {},
2878
+ ...existing?.litellm ? { litellm: existing.litellm } : {},
2879
+ ...existing?.ollama ? { ollama: existing.ollama } : {}
2880
+ });
2881
+ if (existing?.auth?.headers) tentative.auth = { ...tentative.auth, headers: existing.auth.headers };
2882
+ if (runtime.kind === "http" || runtime.externalAgentLoop?.modelCatalog === "live-authoritative") {
2883
+ inventory = await resolveSupportedWireModels(runtime, tentative, existing ?? void 0, apiKeyLiteral);
2884
+ }
2885
+ const wireModels = inventory.models;
2886
+ const catalogOrdered = support.modelSource === "catalog";
2887
+ model = model ?? existing?.defaultModel ?? (inventory.source === "probe" ? wireModels[0] : support.defaultModel) ?? (catalogOrdered ? void 0 : wireModels[0]);
2888
+ if (wireModels.length > 0) {
2889
+ process.stdout.write("\nSelectable models:\n");
2890
+ for (const [index, wireModel] of wireModels.entries()) {
2891
+ const label = inventory.labels?.[wireModel];
2892
+ process.stdout.write(
2893
+ ` ${index + 1}. ${wireModel}${label && label !== wireModel ? ` \u2014 ${label}` : ""}${wireModel === model ? " [default]" : ""}
2894
+ `
2895
+ );
2896
+ }
2897
+ if (inventory.source === "cache") process.stdout.write(" cached model snapshot (not verified in this run)\n");
2898
+ if (inventory.probeError) process.stdout.write(` live probe unavailable: ${inventory.probeError}
2899
+ `);
2900
+ if (!model && catalogOrdered) {
2901
+ process.stdout.write(` listed in provider catalog order, which recommends none of them; pick one.
2902
+ `);
2903
+ }
2904
+ for (; ; ) {
2905
+ const pickedModel = await askModelChoice(rl, "Default target model", wireModels, model);
2906
+ if (pickedModel === null) return 0;
2907
+ if (pickedModel.length > 0) model = pickedModel;
2908
+ if (!model) {
2909
+ process.stdout.write(" a model is required: enter a number from the list or a model id.\n");
2910
+ continue;
2911
+ }
2912
+ if (validateResolvedModel(runtime, tentative, model, defaults.force, inventory)) break;
2913
+ }
2914
+ } else {
2915
+ for (; ; ) {
2916
+ if (model && validateResolvedModel(runtime, tentative, model, defaults.force, inventory)) break;
2917
+ const manual = await ask(rl, "Default model id (blank to leave empty)", model ?? "");
2918
+ if (manual === null) return 0;
2919
+ model = manual.length > 0 ? manual : void 0;
2920
+ if (!model) break;
2921
+ }
2922
+ }
2923
+ let contextWindowChoice = defaults.contextWindow;
2924
+ let reasoningChoice = defaults.reasoning;
2925
+ if (PROTOCOL_COMPAT_RUNTIME_IDS.has(runtime.id)) {
2926
+ if (contextWindowChoice === void 0) {
2927
+ const cwDefault = existing?.capabilities?.contextWindow ?? runtime.defaultCapabilities.contextWindow;
2928
+ const cwAnswer = await ask(
2929
+ rl,
2930
+ "Context window in tokens (blank for runtime default)",
2931
+ cwDefault > 0 ? String(cwDefault) : ""
2932
+ );
2933
+ if (cwAnswer === null) return 0;
2934
+ if (cwAnswer.length > 0) {
2935
+ const parsed = Number(cwAnswer);
2936
+ if (Number.isInteger(parsed) && parsed > 0) contextWindowChoice = parsed;
2937
+ else process.stderr.write(`ignoring invalid context window: ${cwAnswer}
2938
+ `);
2939
+ }
2940
+ }
2941
+ if (reasoningChoice === void 0) {
2942
+ const reasoningDefault = existing?.capabilities?.reasoning ?? runtime.defaultCapabilities.reasoning === true;
2943
+ reasoningChoice = await askYesNo(rl, "Does this model support reasoning / thinking?", reasoningDefault);
2944
+ }
2945
+ }
2946
+ if (!validateContextWindowOverride(runtime, model, contextWindowChoice, defaults.force)) return 2;
2947
+ const gatewayDefault = defaults.gateway || existing?.gateway === true;
2948
+ const gatewayAnswer = gatewayDefault ? true : await askYesNo(rl, "Mark as gateway?", false);
2949
+ const configured = buildDescriptor(runtime, targetId, {
2950
+ ...url !== void 0 ? { url } : {},
2951
+ ...model !== void 0 ? { model } : {},
2952
+ ...apiKeyEnv !== void 0 ? { apiKeyEnv } : {},
2953
+ ...apiKeyRef !== void 0 ? { apiKeyRef } : {},
2954
+ ...oauthProfile !== void 0 ? { oauthProfile } : {},
2955
+ gateway: gatewayAnswer,
2956
+ ...defaults.lifecycle !== void 0 ? { lifecycle: defaults.lifecycle } : existing?.lifecycle !== void 0 ? { lifecycle: existing.lifecycle } : {},
2957
+ ...contextWindowChoice !== void 0 ? { contextWindow: contextWindowChoice } : {},
2958
+ ...defaults.maxTokens !== void 0 ? { maxTokens: defaults.maxTokens } : {},
2959
+ ...reasoningChoice !== void 0 ? { reasoning: reasoningChoice } : {},
2960
+ ...existing?.lmstudio ? { lmstudio: existing.lmstudio } : {},
2961
+ ...existing?.litellm ? { litellm: existing.litellm } : {},
2962
+ ...existing?.ollama ? { ollama: existing.ollama } : {}
2963
+ });
2964
+ const descriptor = {
2965
+ ...existing,
2966
+ ...configured,
2967
+ capabilities: { ...existing?.capabilities, ...configured.capabilities }
2968
+ };
2969
+ if (existing?.auth?.headers) descriptor.auth = { ...configured.auth, headers: existing.auth.headers };
2970
+ else if (!configured.auth) delete descriptor.auth;
2971
+ try {
2972
+ assertOrchestratorReplacementEligible(settings, descriptor);
2973
+ } catch (error) {
2974
+ printError(error instanceof Error ? error.message : String(error));
2975
+ return 1;
2976
+ }
2977
+ const probe = await runtimeProbe(runtime, descriptor, apiKeyLiteral);
2978
+ if (probe?.ok && probe.models) recordTargetModelSnapshot(descriptor, probe.models);
2979
+ if (probe) {
2980
+ process.stdout.write("\n");
2981
+ for (const line of probeLines(descriptor, probe)) process.stdout.write(`${line}
2982
+ `);
2983
+ if (!probe.ok) {
2984
+ const keepAnyway = await askYesNo(rl, "save this target anyway, without a reply from it?", true);
2985
+ if (!keepAnyway) {
2986
+ printError("aborted; settings not changed");
2987
+ return 0;
2988
+ }
2989
+ }
2990
+ }
2991
+ const setOrchestrator = !isOrchestratorEligibleRuntime(runtime) ? false : defaults.setOrchestrator ? true : await askYesNo(rl, "use as orchestrator (chat) target?", !settings.chat.target);
2992
+ const setWorkerDefault = defaults.setWorkerDefault ? true : await askYesNo(rl, "use as fleet default?", !settings.fleet.default.target);
2993
+ const setBackground = !isOrchestratorEligibleRuntime(runtime) ? false : defaults.setBackground ? true : await askYesNo(rl, "use as background memory target?", false);
2994
+ const orchestratorModel = setOrchestrator ? defaults.orchestratorModel ?? await askModelChoice(
2995
+ rl,
2996
+ "Orchestrator model",
2997
+ wireModels,
2998
+ settings.chat.target === targetId ? settings.chat.model ?? model : model
2999
+ ) : void 0;
3000
+ if (orchestratorModel === null) return 0;
3001
+ const workerModel = setWorkerDefault ? defaults.workerModel ?? await askModelChoice(
3002
+ rl,
3003
+ "Fleet model",
3004
+ wireModels,
3005
+ settings.fleet.default.target === targetId ? settings.fleet.default.model ?? model : model
3006
+ ) : void 0;
3007
+ if (workerModel === null) return 0;
3008
+ const backgroundModel = setBackground ? defaults.backgroundModel ?? await askModelChoice(
3009
+ rl,
3010
+ "Background memory model",
3011
+ wireModels,
3012
+ settings.context.memory.target === targetId ? settings.context.memory.model ?? model : model
3013
+ ) : void 0;
3014
+ if (backgroundModel === null) return 0;
3015
+ if (apiKeyLiteral && apiKeyRef) {
3016
+ auth.setApiKey(apiKeyRef, apiKeyLiteral);
3017
+ if (credentialWriteFailed(auth, `credential for ${runtime.id} was not stored; target '${descriptor.id}' not saved`))
3018
+ return 1;
3019
+ printPlaintextCredentialWarning();
3020
+ }
3021
+ const applyWizardChoice = (target) => {
3022
+ applyTarget(target, descriptor);
3023
+ if (setOrchestrator) setOrchestratorPointer(target, descriptor, orchestratorModel);
3024
+ if (setBackground) setBackgroundPointer(target, descriptor, backgroundModel);
3025
+ if (setWorkerDefault) setWorkerDefaultPointer(target, descriptor, workerModel);
3026
+ };
3027
+ applyWizardChoice(settings);
3028
+ updateSettings(applyWizardChoice);
3029
+ printSummary(settings, descriptor, probe);
3030
+ printOk(`target ${targetId} saved`);
3031
+ await runInteropReview({ rl });
3032
+ return 0;
3033
+ }
3034
+ function runTargetRemove(id) {
3035
+ if (!readSettings().targets.some((e) => e.id === id)) {
3036
+ printError(`no target with id ${id}`);
3037
+ return 1;
3038
+ }
3039
+ updateSettings((settings) => {
3040
+ removeTargetFromSettings(settings, id);
3041
+ });
3042
+ printOk(`removed target ${id}`);
3043
+ return 0;
3044
+ }
3045
+ function runTargetRename(oldId, newId) {
3046
+ if (oldId === newId) {
3047
+ printError("old and new id are identical");
3048
+ return 2;
3049
+ }
3050
+ const current = readSettings();
3051
+ if (current.targets.some((e) => e.id === newId)) {
3052
+ printError(`target id already exists: ${newId}`);
3053
+ return 2;
3054
+ }
3055
+ if (!current.targets.some((e) => e.id === oldId)) {
3056
+ printError(`no target with id ${oldId}`);
3057
+ return 1;
3058
+ }
3059
+ updateSettings((settings) => {
3060
+ const target = settings.targets.find((e) => e.id === oldId);
3061
+ if (!target) return;
3062
+ target.id = newId;
3063
+ if (settings.chat.target === oldId) settings.chat.target = newId;
3064
+ if (settings.context.memory.target === oldId) settings.context.memory.target = newId;
3065
+ if (settings.fleet.default.target === oldId) settings.fleet.default.target = newId;
3066
+ for (const profile of Object.values(settings.fleet.profiles)) {
3067
+ if (profile.target === oldId) profile.target = newId;
3068
+ }
3069
+ for (const roster of Object.values(settings.fleet.rosters)) {
3070
+ for (const member of roster.members) if (member.target === oldId) member.target = newId;
3071
+ }
3072
+ const renameRef = (entry) => {
3073
+ const [head, ...rest] = entry.split("/");
3074
+ if (head !== oldId) return entry;
3075
+ return rest.length === 0 ? newId : `${newId}/${rest.join("/")}`;
3076
+ };
3077
+ settings.chat.modelPicker.cycleSet = settings.chat.modelPicker.cycleSet.map(renameRef);
3078
+ settings.chat.modelPicker.favorites = settings.chat.modelPicker.favorites.map(renameRef);
3079
+ });
3080
+ printOk(`renamed ${oldId} to ${newId}`);
3081
+ return 0;
3082
+ }
3083
+ var NONE = "(none)";
3084
+ var onOff = (value) => value ? "enabled" : "disabled";
3085
+ function concurrencyLabel(concurrency) {
3086
+ if (concurrency !== "auto") return String(concurrency);
3087
+ const local = resolveLocalConcurrency("auto", observeHostCapacityFacts());
3088
+ return `auto \xB7 ${describeLocalCapacity(local) ?? `local ${local.limit}`}`;
3089
+ }
3090
+ var listOr = (values, fallback = NONE) => values.length > 0 ? values.join(", ") : fallback;
3091
+ async function askInteger(io, label, current, apply, min = 0) {
3092
+ const answer = await ask(io.rl, label, String(current));
3093
+ if (answer === null) return;
3094
+ const parsed = Number(answer);
3095
+ if (!Number.isSafeInteger(parsed) || parsed < min) {
3096
+ io.warn(`${label} must be a whole number of at least ${min}; left at ${current}
3097
+ `);
3098
+ return;
3099
+ }
3100
+ const value = parsed;
3101
+ apply(value);
3102
+ io.ok(`${label} set to ${value}`);
3103
+ }
3104
+ async function askChoice(io, label, allowed, current, apply) {
3105
+ const answer = await io.rl.choose(label, allowed, current);
3106
+ if (answer === null) return;
3107
+ const value = answer.trim().toLowerCase();
3108
+ if (!allowed.includes(value)) {
3109
+ io.warn(`${label} must be one of ${allowed.join(", ")}; left at ${current}
3110
+ `);
3111
+ return;
3112
+ }
3113
+ apply(value);
3114
+ io.ok(`${label} set to ${value}`);
3115
+ }
3116
+ async function runTargetWizard(io, options) {
3117
+ const before = readSettings().targets;
3118
+ io.rl.clearScreen();
3119
+ const code = await runOnboardingWizard(io.streams, options);
3120
+ if (code === 130) throw new ConfigureNavigation("quit");
3121
+ if (code !== 0) {
3122
+ await io.rl.text("Press Enter to return");
3123
+ io.warn("Target settings were not saved.");
3124
+ return;
3125
+ }
3126
+ const changed = readSettings().targets.find(
3127
+ (target) => JSON.stringify(target) !== JSON.stringify(before.find((entry) => entry.id === target.id))
3128
+ );
3129
+ if (changed) io.ok(`Target ${changed.id} saved`);
3130
+ }
3131
+ var DIAGNOSTICS_SECTION = {
3132
+ id: "diagnostics",
3133
+ title: "Diagnostics",
3134
+ summary: "version, directories, doctor, raw settings",
3135
+ aliases: ["doctor", "diag"],
3136
+ fields: () => {
3137
+ const dirs = resolveClioDirs();
3138
+ const info = getVersionInfo();
3139
+ return [
3140
+ ["Clio Coder", info.clio],
3141
+ ["Node.js", info.node],
3142
+ ["Platform", info.platform],
3143
+ ["Config dir", shortenPath(dirs.config)],
3144
+ ["Data dir", shortenPath(dirs.data)],
3145
+ ["State dir", shortenPath(dirs.state)],
3146
+ ["Cache dir", shortenPath(dirs.cache)]
3147
+ ];
3148
+ },
3149
+ actions: [
3150
+ {
3151
+ label: "Run doctor",
3152
+ hint: "read-only health check",
3153
+ run: async (io) => {
3154
+ const { runDoctorCommand } = await import("./doctor-S5KZ2GTN.js");
3155
+ await runDoctorCommand([]);
3156
+ await io.rl.text("Press Enter to return");
3157
+ }
3158
+ },
3159
+ {
3160
+ label: "Show raw settings.yaml",
3161
+ run: async (io) => {
3162
+ const file = settingsPath();
3163
+ if (!existsSync2(file)) {
3164
+ io.out.write(" settings.yaml does not exist yet.\n");
3165
+ return;
3166
+ }
3167
+ io.out.write(`
3168
+ --- ${shortenPath(file)} ---
3169
+ ${readFileSync2(file, "utf8")}--- end ---
3170
+ `);
3171
+ await io.rl.text("Press Enter to return");
3172
+ }
3173
+ }
3174
+ ]
3175
+ };
3176
+ var SECTION_CONTENT = {
3177
+ targets: {
3178
+ fields: () => {
3179
+ const settings = readSettings();
3180
+ const rows = [];
3181
+ for (const target of settings.targets)
3182
+ rows.push([
3183
+ target.id,
3184
+ `${target.runtime} \xB7 ${target.url ?? "provider default"} \xB7 ${target.defaultModel ?? "no default model"}`
3185
+ ]);
3186
+ return rows.length ? rows : [["Connections", "No connections yet. Choose Add a target to connect a provider."]];
3187
+ },
3188
+ actions: [
3189
+ {
3190
+ label: "Add a target",
3191
+ hint: "register a provider endpoint",
3192
+ run: async (io) => {
3193
+ if (canRunOnboarding(io.streams)) {
3194
+ await runTargetWizard(io, { mode: readSettings().targets.length === 0 ? "first" : "add" });
3195
+ return;
3196
+ }
3197
+ const runtime = await pickRuntimeViaCategory(io.rl);
3198
+ if (runtime) await runTargetSetupInteractive(io.rl, runtime, emptyArgs());
3199
+ }
3200
+ },
3201
+ {
3202
+ label: "Edit a target",
3203
+ hint: "endpoint, credentials, model, capabilities",
3204
+ run: async (io) => {
3205
+ const targets = readSettings().targets;
3206
+ if (targets.length === 0) return;
3207
+ const id = await io.rl.choose(
3208
+ "Target to edit",
3209
+ targets.map((target2) => target2.id),
3210
+ targets[0]?.id ?? ""
3211
+ );
3212
+ const target = targets.find((entry) => entry.id === id);
3213
+ if (!target) return;
3214
+ if (canRunOnboarding(io.streams)) {
3215
+ await runTargetWizard(io, { mode: "edit", target });
3216
+ } else {
3217
+ const runtime = getRuntimeRegistry().get(target.runtime);
3218
+ if (runtime) await runTargetSetupInteractive(io.rl, runtime, { ...emptyArgs(), id });
3219
+ }
3220
+ }
3221
+ },
3222
+ {
3223
+ label: "Rename a target",
3224
+ run: async (io) => {
3225
+ const ids = readSettings().targets.map((target) => target.id);
3226
+ if (ids.length === 0) return;
3227
+ const id = await io.rl.choose("Target to rename", ids, ids[0] ?? "");
3228
+ const name = await ask(io.rl, "New target id", id);
3229
+ if (!name || name === id) return;
3230
+ if (ids.includes(name)) {
3231
+ io.warn(`Target id already exists: ${name}`);
3232
+ return;
3233
+ }
3234
+ if (runTargetRename(id, name) === 0) io.ok(`Renamed ${id} to ${name}`);
3235
+ else io.warn(`Could not rename target ${id}`);
3236
+ }
3237
+ },
3238
+ {
3239
+ label: "Remove a target",
3240
+ run: async (io) => {
3241
+ const settings = readSettings();
3242
+ const ids = settings.targets.map((target) => target.id);
3243
+ if (ids.length === 0) {
3244
+ io.warn("No targets to remove.");
3245
+ return;
3246
+ }
3247
+ io.out.write(` Registered: ${ids.join(", ")}
3248
+ `);
3249
+ const chosen = await io.rl.choose("Target to remove", ids, ids[0] ?? "");
3250
+ if (chosen === null || !ids.includes(chosen)) return;
3251
+ if (await askYesNo(io.rl, `Remove target '${chosen}'?`, false)) {
3252
+ if (runTargetRemove(chosen) === 0) io.ok(`Removed target ${chosen}`);
3253
+ else io.warn(`Could not remove target ${chosen}`);
3254
+ }
3255
+ }
3256
+ }
3257
+ ]
3258
+ },
3259
+ chat: {
3260
+ fields: () => {
3261
+ const settings = readSettings();
3262
+ return [
3263
+ ["Chat target", settings.chat.target ?? NONE],
3264
+ ["Chat model", settings.chat.model ?? "(target default)"],
3265
+ ["Chat thinking", settings.chat.thinkingLevel],
3266
+ ["Favorites", listOr(settings.chat.modelPicker.favorites)],
3267
+ ["Model cycle set", listOr(settings.chat.modelPicker.cycleSet)],
3268
+ ["Max output tokens", String(settings.chat.maxOutputTokens)],
3269
+ ["Prompt prewarm", onOff(settings.chat.prewarm)],
3270
+ ["Retry transient errors", onOff(settings.chat.retry.enabled)],
3271
+ ["Max retries", String(settings.chat.retry.maxRetries)]
3272
+ ];
3273
+ },
3274
+ actions: [
3275
+ {
3276
+ label: "Chat thinking level",
3277
+ hint: THINKING_LEVELS.join(" | "),
3278
+ run: async (io) => {
3279
+ await askChoice(io, "Chat thinking level", THINKING_LEVELS, readSettings().chat.thinkingLevel, (value) => {
3280
+ updateSettings((draft) => {
3281
+ draft.chat.thinkingLevel = value;
3282
+ });
3283
+ });
3284
+ }
3285
+ },
3286
+ {
3287
+ label: "Set the chat target",
3288
+ hint: "which target answers in chat",
3289
+ run: async (io) => {
3290
+ await assignTarget(io, "chat");
3291
+ }
3292
+ },
3293
+ {
3294
+ label: "Chat default model",
3295
+ hint: "blank clears the override",
3296
+ run: async (io) => {
3297
+ const model = await ask(
3298
+ io.rl,
3299
+ "Chat default model (blank for the target default)",
3300
+ readSettings().chat.model ?? ""
3301
+ );
3302
+ if (model === null) return;
3303
+ updateSavedSettingsDocument((saved) => {
3304
+ const document = saved;
3305
+ document.chat = { ...document.chat, model: model.length > 0 ? model : null };
3306
+ return document;
3307
+ });
3308
+ io.ok(model.length > 0 ? `Chat default model set to ${model}` : "Chat default model cleared");
3309
+ }
3310
+ },
3311
+ {
3312
+ label: "Model favorites",
3313
+ hint: "comma-separated",
3314
+ run: async (io) => {
3315
+ await askList(io, "Model favorites", readSettings().chat.modelPicker.favorites, (values) => {
3316
+ saveControl("chat.modelPicker.favorites", values.join(", "));
3317
+ });
3318
+ }
3319
+ },
3320
+ {
3321
+ label: "Cycle set",
3322
+ hint: "comma-separated models for the scoped cycle actions",
3323
+ run: async (io) => {
3324
+ await askList(io, "Cycle set", readSettings().chat.modelPicker.cycleSet, (values) => {
3325
+ updateSettings((draft) => {
3326
+ draft.chat.modelPicker.cycleSet = values;
3327
+ });
3328
+ });
3329
+ }
3330
+ },
3331
+ {
3332
+ label: "Max output tokens",
3333
+ hint: "0 for the runtime default",
3334
+ run: async (io) => {
3335
+ await askInteger(io, "Max output tokens", readSettings().chat.maxOutputTokens, (value) => {
3336
+ updateSettings((draft) => {
3337
+ draft.chat.maxOutputTokens = value;
3338
+ });
3339
+ });
3340
+ }
3341
+ },
3342
+ {
3343
+ label: "Prompt prewarm",
3344
+ hint: "toggle",
3345
+ run: async (io) => {
3346
+ let next = false;
3347
+ updateSettings((draft) => {
3348
+ draft.chat.prewarm = !draft.chat.prewarm;
3349
+ next = draft.chat.prewarm;
3350
+ });
3351
+ io.ok(`Prompt prewarm ${onOff(next)}`);
3352
+ }
3353
+ }
3354
+ ]
3355
+ },
3356
+ fleet: {
3357
+ fields: () => {
3358
+ const settings = readSettings();
3359
+ return [
3360
+ ["Fleet target", settings.fleet.default.target ?? NONE],
3361
+ ["Fleet model", settings.fleet.default.model ?? "(target default)"],
3362
+ ["Fleet thinking", settings.fleet.default.thinkingLevel],
3363
+ ["Concurrency limit", concurrencyLabel(settings.fleet.concurrency)],
3364
+ ["Max retries", String(settings.fleet.retry.maxRetries)],
3365
+ ["Task worktree root", settings.fleet.worktrees.root],
3366
+ ["Tool calls per run", String(settings.fleet.limits.toolCallsPerRun)],
3367
+ ["Run timeout", `${settings.fleet.limits.internalRunTimeoutMs / 1e3}s`],
3368
+ ["Worker profiles", listOr(Object.keys(settings.fleet.profiles))],
3369
+ [
3370
+ "Agent routes",
3371
+ listOr(Object.entries(settings.fleet.agentProfiles).map(([agent, profile]) => `${agent} -> ${profile}`))
3372
+ ],
3373
+ ["Remote nodes", listOr(settings.fleet.nodes.map((node) => node.id))]
3374
+ ];
3375
+ },
3376
+ actions: [
3377
+ {
3378
+ label: "Set the fleet default target",
3379
+ hint: "which target dispatched workers use",
3380
+ run: async (io) => {
3381
+ await assignTarget(io, "fleet");
3382
+ }
3383
+ },
3384
+ {
3385
+ label: "Fleet thinking level",
3386
+ hint: THINKING_LEVELS.join(" | "),
3387
+ run: async (io) => {
3388
+ await askChoice(
3389
+ io,
3390
+ "Fleet thinking level",
3391
+ THINKING_LEVELS,
3392
+ readSettings().fleet.default.thinkingLevel,
3393
+ (value) => {
3394
+ updateSettings((draft) => {
3395
+ draft.fleet.default.thinkingLevel = value;
3396
+ });
3397
+ }
3398
+ );
3399
+ }
3400
+ },
3401
+ {
3402
+ label: "Concurrency limit",
3403
+ hint: "auto, or a positive integer",
3404
+ run: async (io) => {
3405
+ const current = String(readSettings().fleet.concurrency);
3406
+ const answer = await ask(io.rl, "Concurrency limit [auto or a number]", current);
3407
+ if (answer === null) return;
3408
+ if (answer.trim().toLowerCase() === "auto") {
3409
+ updateSettings((draft) => {
3410
+ draft.fleet.concurrency = "auto";
3411
+ });
3412
+ io.ok("Concurrency limit set to auto");
3413
+ return;
3414
+ }
3415
+ const parsed = Number(answer);
3416
+ if (!Number.isFinite(parsed) || parsed < 1) {
3417
+ io.warn(`Concurrency limit must be auto or at least 1; left at ${current}
3418
+ `);
3419
+ return;
3420
+ }
3421
+ updateSettings((draft) => {
3422
+ draft.fleet.concurrency = Math.floor(parsed);
3423
+ });
3424
+ io.ok(`Concurrency limit set to ${Math.floor(parsed)}`);
3425
+ }
3426
+ },
3427
+ {
3428
+ label: "Max retries",
3429
+ run: async (io) => {
3430
+ await askInteger(io, "Max retries", readSettings().fleet.retry.maxRetries, (value) => {
3431
+ updateSettings((draft) => {
3432
+ draft.fleet.retry.maxRetries = value;
3433
+ });
3434
+ });
3435
+ }
3436
+ },
3437
+ {
3438
+ label: "Tool calls per run",
3439
+ run: async (io) => {
3440
+ await askInteger(
3441
+ io,
3442
+ "Tool calls per run",
3443
+ readSettings().fleet.limits.toolCallsPerRun,
3444
+ (value) => {
3445
+ updateSettings((draft) => {
3446
+ draft.fleet.limits.toolCallsPerRun = value;
3447
+ });
3448
+ },
3449
+ 1
3450
+ );
3451
+ }
3452
+ },
3453
+ {
3454
+ label: "Run timeout",
3455
+ hint: "seconds",
3456
+ run: async (io) => {
3457
+ const current = readSettings().fleet.limits.internalRunTimeoutMs / 1e3;
3458
+ const answer = await ask(io.rl, "Run timeout in seconds", String(current));
3459
+ if (answer === null) return;
3460
+ const parsed = Number(answer);
3461
+ if (!Number.isFinite(parsed) || parsed < 1) {
3462
+ io.warn(`Run timeout must be at least 1 second; left at ${current}s
3463
+ `);
3464
+ return;
3465
+ }
3466
+ updateSettings((draft) => {
3467
+ draft.fleet.limits.internalRunTimeoutMs = Math.floor(parsed * 1e3);
3468
+ });
3469
+ io.ok(`Run timeout set to ${Math.floor(parsed)}s`);
3470
+ }
3471
+ }
3472
+ ]
3473
+ },
3474
+ context: {
3475
+ fields: () => {
3476
+ const settings = readSettings();
3477
+ return [
3478
+ ["Auto-compaction", onOff(settings.context.compaction.auto)],
3479
+ ["Compaction threshold", String(settings.context.compaction.threshold)],
3480
+ ["Compaction model", settings.context.compaction.model ?? "(chat model)"],
3481
+ ["Working-set eviction", onOff(settings.context.workingSet.enabled)],
3482
+ ["Tool result cap (bytes)", String(settings.context.toolResultMaxBytes)],
3483
+ ["Memory target", settings.context.memory.target ?? "(rules only)"],
3484
+ ["Memory model", settings.context.memory.model ?? "(target default)"],
3485
+ ["Proactive memory", onOff(settings.context.memory.enabled)]
3486
+ ];
3487
+ },
3488
+ actions: [
3489
+ {
3490
+ label: "Set the background memory target",
3491
+ run: async (io) => assignTarget(io, "memory")
3492
+ },
3493
+ {
3494
+ label: "Auto-compaction",
3495
+ hint: "toggle",
3496
+ run: async (io) => {
3497
+ let next = false;
3498
+ updateSettings((draft) => {
3499
+ draft.context.compaction.auto = !draft.context.compaction.auto;
3500
+ next = draft.context.compaction.auto;
3501
+ });
3502
+ io.ok(`Auto-compaction ${onOff(next)}`);
3503
+ }
3504
+ }
3505
+ ]
3506
+ },
3507
+ safety: {
3508
+ fields: () => {
3509
+ const settings = readSettings();
3510
+ return [
3511
+ ["Autonomy level", settings.safety.autonomy],
3512
+ ["Worker permissions", settings.fleet.permissions.mode],
3513
+ ["Session cost limit", `$${settings.safety.limits.sessionCostUsd} USD`],
3514
+ ["Turn tool budget", String(settings.safety.limits.chatToolCallsPerTurn)],
3515
+ ["Review watchdog", onOff(settings.safety.review.enabled)],
3516
+ ["External agent governance", settings.integrations.externalAgents.defaults.toolGovernance]
3517
+ ];
3518
+ },
3519
+ actions: [
3520
+ {
3521
+ label: "Autonomy level",
3522
+ hint: AUTONOMY_LEVELS.join(" | "),
3523
+ run: async (io) => {
3524
+ io.out.write(
3525
+ " read-only inspects; suggest asks before edits, execution, and delegation.\n auto-edit allows workspace edits, recognized checks, and routine delegation;\n unfamiliar commands and larger dispatch plans ask. Declared outward actions ask.\n full-auto skips autonomy prompts. Safety rules still apply at every level.\n"
3526
+ );
3527
+ await askChoice(io, "Autonomy level", AUTONOMY_LEVELS, readSettings().safety.autonomy, (value) => {
3528
+ updateSettings((draft) => {
3529
+ draft.safety.autonomy = value;
3530
+ });
3531
+ });
3532
+ }
3533
+ },
3534
+ {
3535
+ label: "Worker permission mode",
3536
+ hint: "deny | fail | escalate",
3537
+ run: async (io) => {
3538
+ await askChoice(
3539
+ io,
3540
+ "Worker permission mode",
3541
+ ["deny", "fail", "escalate"],
3542
+ readSettings().fleet.permissions.mode,
3543
+ (value) => {
3544
+ updateSettings((draft) => {
3545
+ draft.fleet.permissions.mode = value;
3546
+ });
3547
+ }
3548
+ );
3549
+ }
3550
+ },
3551
+ {
3552
+ label: "Session cost limit",
3553
+ hint: "USD",
3554
+ run: async (io) => {
3555
+ const current = readSettings().safety.limits.sessionCostUsd;
3556
+ const answer = await ask(io.rl, "Session cost limit in USD", String(current));
3557
+ if (answer === null) return;
3558
+ const parsed = Number(answer);
3559
+ if (!Number.isFinite(parsed) || parsed <= 0) {
3560
+ io.warn(`Session cost limit must be greater than 0; left at $${current}
3561
+ `);
3562
+ return;
3563
+ }
3564
+ updateSettings((draft) => {
3565
+ draft.safety.limits.sessionCostUsd = parsed;
3566
+ });
3567
+ io.ok(`Session cost limit set to $${parsed} USD`);
3568
+ }
3569
+ },
3570
+ {
3571
+ label: "Turn tool budget",
3572
+ run: async (io) => {
3573
+ await askInteger(
3574
+ io,
3575
+ "Turn tool budget",
3576
+ readSettings().safety.limits.chatToolCallsPerTurn,
3577
+ (value) => {
3578
+ updateSettings((draft) => {
3579
+ draft.safety.limits.chatToolCallsPerTurn = value;
3580
+ });
3581
+ },
3582
+ 1
3583
+ );
3584
+ }
3585
+ },
3586
+ {
3587
+ label: "Turn-end review watchdog",
3588
+ hint: "toggle",
3589
+ run: async (io) => {
3590
+ let next = false;
3591
+ updateSettings((draft) => {
3592
+ draft.safety.review.enabled = !draft.safety.review.enabled;
3593
+ next = draft.safety.review.enabled;
3594
+ });
3595
+ io.ok(`Review watchdog ${onOff(next)}`);
3596
+ }
3597
+ }
3598
+ ]
3599
+ },
3600
+ interface: {
3601
+ fields: () => {
3602
+ const settings = readSettings();
3603
+ return [
3604
+ ["TUI mode", settings.interface.mode],
3605
+ ["Output style", settings.interface.outputDetail],
3606
+ ["Smooth streaming", settings.interface.smoothStreaming],
3607
+ ["Terminal progress", onOff(settings.interface.terminalProgress)],
3608
+ ["Desktop notifications", onOff(settings.interface.desktopNotifications)],
3609
+ ["Panes capability", settings.interface.panes.enabled],
3610
+ ["Startup layout", settings.interface.panes.layout]
3611
+ ];
3612
+ },
3613
+ actions: [
3614
+ {
3615
+ label: "Smooth streaming",
3616
+ hint: "off | auto | on",
3617
+ run: async (io) => {
3618
+ await askChoice(
3619
+ io,
3620
+ "Smooth streaming",
3621
+ ["off", "auto", "on"],
3622
+ readSettings().interface.smoothStreaming,
3623
+ (value) => {
3624
+ updateSettings((draft) => {
3625
+ draft.interface.smoothStreaming = value;
3626
+ });
3627
+ }
3628
+ );
3629
+ }
3630
+ },
3631
+ {
3632
+ label: "Terminal progress indicator",
3633
+ hint: "toggle",
3634
+ run: async (io) => {
3635
+ let next = false;
3636
+ updateSettings((draft) => {
3637
+ draft.interface.terminalProgress = !draft.interface.terminalProgress;
3638
+ next = draft.interface.terminalProgress;
3639
+ });
3640
+ io.ok(`Terminal progress ${onOff(next)}`);
3641
+ }
3642
+ },
3643
+ {
3644
+ label: "Panes capability",
3645
+ hint: "off | auto (join an existing pane host)",
3646
+ run: async (io) => {
3647
+ await askChoice(io, "Panes capability", ["off", "auto"], readSettings().interface.panes.enabled, (value) => {
3648
+ updateSettings((draft) => {
3649
+ draft.interface.panes.enabled = value;
3650
+ });
3651
+ });
3652
+ }
3653
+ },
3654
+ {
3655
+ label: "Startup layout",
3656
+ hint: "off | workers | cockpit",
3657
+ run: async (io) => {
3658
+ await askChoice(
3659
+ io,
3660
+ "Startup layout",
3661
+ ["off", "workers", "cockpit"],
3662
+ readSettings().interface.panes.layout,
3663
+ (value) => {
3664
+ updateSettings((draft) => {
3665
+ draft.interface.panes.layout = value;
3666
+ });
3667
+ }
3668
+ );
3669
+ }
3670
+ },
3671
+ {
3672
+ label: "TUI mode",
3673
+ hint: "regular | fullscreen",
3674
+ run: async (io) => {
3675
+ await askChoice(io, "TUI mode", ["regular", "fullscreen"], readSettings().interface.mode, (value) => {
3676
+ updateSettings((draft) => {
3677
+ draft.interface.mode = value;
3678
+ });
3679
+ });
3680
+ }
3681
+ },
3682
+ {
3683
+ label: "Output style",
3684
+ hint: "compact | standard | detailed",
3685
+ run: async (io) => {
3686
+ await askChoice(
3687
+ io,
3688
+ "Output style",
3689
+ ["compact", "standard", "detailed"],
3690
+ readSettings().interface.outputDetail,
3691
+ (value) => {
3692
+ updateSettings((draft) => {
3693
+ draft.interface.outputDetail = value;
3694
+ });
3695
+ }
3696
+ );
3697
+ }
3698
+ },
3699
+ {
3700
+ label: "Desktop notifications",
3701
+ hint: "toggle",
3702
+ run: async (io) => {
3703
+ let next = false;
3704
+ updateSettings((draft) => {
3705
+ draft.interface.desktopNotifications = !draft.interface.desktopNotifications;
3706
+ next = draft.interface.desktopNotifications;
3707
+ });
3708
+ io.ok(`Desktop notifications ${onOff(next)}`);
3709
+ }
3710
+ }
3711
+ ]
3712
+ },
3713
+ integrations: {
3714
+ fields: () => {
3715
+ const settings = readSettings();
3716
+ const rows = [
3717
+ ["Trust project imports", settings.integrations.projectResources.trustProjectImports ? "trusted" : "untrusted"],
3718
+ ["External ACP agents", String(settings.integrations.externalAgents.entries.length)],
3719
+ ["Runtime plugins", listOr(settings.integrations.runtimePlugins)],
3720
+ ["Library remote sync", onOff(settings.integrations.library.sync)],
3721
+ ["Git commit attribution", onOff(settings.integrations.git.commitAttribution)]
3722
+ ];
3723
+ for (const agent of settings.integrations.externalAgents.entries)
3724
+ rows.push([agent.id, `${agent.command} (governance: ${agent.toolGovernance ?? "default"})`]);
3725
+ return rows;
3726
+ },
3727
+ actions: [
3728
+ {
3729
+ label: "Git commit attribution",
3730
+ hint: "toggle",
3731
+ run: async (io) => {
3732
+ let next = false;
3733
+ updateSettings((draft) => {
3734
+ draft.integrations.git.commitAttribution = !draft.integrations.git.commitAttribution;
3735
+ next = draft.integrations.git.commitAttribution;
3736
+ });
3737
+ io.ok(`Git commit attribution ${onOff(next)}`);
3738
+ }
3739
+ },
3740
+ {
3741
+ label: "Trust project imports",
3742
+ hint: "toggle",
3743
+ run: async (io) => {
3744
+ let next = false;
3745
+ updateSettings((draft) => {
3746
+ draft.integrations.projectResources.trustProjectImports = !draft.integrations.projectResources.trustProjectImports;
3747
+ next = draft.integrations.projectResources.trustProjectImports;
3748
+ });
3749
+ io.ok(`Project imports ${next ? "trusted" : "untrusted"}`);
3750
+ }
3751
+ },
3752
+ {
3753
+ label: "Review external ACP agents",
3754
+ hint: "runs the interop review",
3755
+ run: async (io) => {
3756
+ await runInteropReview({ rl: io.rl, streams: io.streams });
3757
+ }
3758
+ },
3759
+ {
3760
+ label: "Library remote sync",
3761
+ hint: "toggle",
3762
+ run: async (io) => {
3763
+ let next = false;
3764
+ updateSettings((draft) => {
3765
+ draft.integrations.library.sync = !draft.integrations.library.sync;
3766
+ next = draft.integrations.library.sync;
3767
+ });
3768
+ io.ok(`Library remote sync ${onOff(next)}`);
3769
+ }
3770
+ }
3771
+ ]
3772
+ },
3773
+ advanced: {
3774
+ fields: () => {
3775
+ return [
3776
+ ...DIAGNOSTICS_SECTION.fields(),
3777
+ ["Settings file", shortenPath(settingsPath())],
3778
+ ["Reference", "clio-coder docs configuration-reference"]
3779
+ ];
3780
+ },
3781
+ actions: [
3782
+ ...DIAGNOSTICS_SECTION.actions,
3783
+ {
3784
+ label: "Edit all settings",
3785
+ hint: "VISUAL / EDITOR; validate before saving",
3786
+ run: async (io) => {
3787
+ if (await editSettings(io.rl)) io.ok("Settings saved; previous file kept at settings.yaml.bak");
3788
+ }
3789
+ }
3790
+ ]
3791
+ }
3792
+ };
3793
+ var SECTIONS = SETTINGS_SECTIONS.map((section) => ({
3794
+ id: section.id,
3795
+ title: section.label,
3796
+ summary: section.description,
3797
+ aliases: section.aliases,
3798
+ ...SECTION_CONTENT[section.id],
3799
+ actions: [
3800
+ ...SECTION_CONTENT[section.id].actions,
3801
+ ...section.id === "targets" || section.id === "advanced" ? [] : [
3802
+ {
3803
+ label: "All controls in this section",
3804
+ hint: "searchable groups, help, defaults, and validated edits",
3805
+ run: async (io) => runSectionControls(io.rl, section.id)
3806
+ }
3807
+ ]
3808
+ ]
3809
+ }));
3810
+ function emptyArgs() {
3811
+ return {
3812
+ positional: [],
3813
+ help: false,
3814
+ list: false,
3815
+ all: false,
3816
+ interop: false,
3817
+ json: false,
3818
+ edit: false,
3819
+ quick: false,
3820
+ settings: false,
3821
+ force: false,
3822
+ gateway: false,
3823
+ setOrchestrator: false,
3824
+ setBackground: false,
3825
+ setWorkerDefault: false
3826
+ };
3827
+ }
3828
+ async function askList(io, label, current, apply) {
3829
+ const answer = await ask(io.rl, `${label} (comma-separated, blank clears)`, current.join(", "));
3830
+ if (answer === null) return;
3831
+ const values = answer.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
3832
+ apply(values);
3833
+ io.ok(values.length === 0 ? `${label} cleared` : `${label} set to ${values.join(", ")}`);
3834
+ }
3835
+ async function assignTarget(io, role) {
3836
+ const settings = readSettings();
3837
+ const ids = settings.targets.filter((target2) => {
3838
+ const runtime = getRuntimeRegistry().get(target2.runtime);
3839
+ return role === "fleet" || runtime !== null && isOrchestratorEligibleRuntime(runtime);
3840
+ }).map((target2) => target2.id);
3841
+ if (ids.length === 0) {
3842
+ io.warn("No eligible targets registered yet. Add one first.");
3843
+ return;
3844
+ }
3845
+ io.out.write(` Registered: ${ids.join(", ")}
3846
+ `);
3847
+ const currentTarget = role === "chat" ? settings.chat.target : role === "fleet" ? settings.fleet.default.target : settings.context.memory.target;
3848
+ const label = role === "chat" ? "Chat" : role === "fleet" ? "Fleet" : "Background memory";
3849
+ const chosen = await io.rl.choose(`${label} target`, ids, currentTarget ?? ids[0] ?? "");
3850
+ if (chosen === null) return;
3851
+ if (!ids.includes(chosen)) {
3852
+ io.warn(`${chosen} is not a registered target; nothing changed.`);
3853
+ return;
3854
+ }
3855
+ const target = settings.targets.find((entry) => entry.id === chosen);
3856
+ const model = await ask(io.rl, `Model override (blank uses ${target?.defaultModel ?? "the target default"})`, "");
3857
+ if (model === null) return;
3858
+ updateSettings((draft) => {
3859
+ if (role === "chat") {
3860
+ draft.chat.target = chosen;
3861
+ draft.chat.model = model.length > 0 ? model : null;
3862
+ } else if (role === "fleet") {
3863
+ draft.fleet.default.target = chosen;
3864
+ draft.fleet.default.model = model.length > 0 ? model : null;
3865
+ } else {
3866
+ draft.context.memory.target = chosen;
3867
+ draft.context.memory.model = model.length > 0 ? model : null;
3868
+ }
3869
+ });
3870
+ io.ok(`${label} target set to ${chosen}`);
3871
+ }
3872
+ async function pickEntry(rl, io, entries, backLabel, plain, initialIndex = 0) {
3873
+ const out = io.out;
3874
+ if (canSelect(io.in, out)) {
3875
+ const result = await promptSelect({
3876
+ initialIndex,
3877
+ clearOnExit: true,
3878
+ choices: entries.map((entry, index2) => ({
3879
+ value: index2,
3880
+ label: entry.label,
3881
+ ...entry.hint === void 0 ? {} : { hint: entry.hint }
3882
+ })),
3883
+ railPrefix: railPrefix(plain),
3884
+ backLabel,
3885
+ input: io.in,
3886
+ output: out
3887
+ });
3888
+ if (result.kind === "selected") return { kind: "index", index: result.value };
3889
+ return result.kind === "quit" ? { kind: "quit" } : { kind: "back" };
3890
+ }
3891
+ const rail = railPrefix(plain);
3892
+ entries.forEach((entry, index2) => {
3893
+ out.write(`${rail}${index2 + 1}. ${entry.label}${entry.hint === void 0 ? "" : ` (${entry.hint})`}
3894
+ `);
3895
+ });
3896
+ out.write(`${rail}b. ${backLabel}
3897
+ ${rail}q. Quit
3898
+ `);
3899
+ const answer = await ask(rl, "\nSelection", "b");
3900
+ if (answer === null) return { kind: "quit" };
3901
+ const trimmed = answer.trim().toLowerCase();
3902
+ if (trimmed === "b" || trimmed === "back" || trimmed.length === 0) return { kind: "back" };
3903
+ if (trimmed === "q" || trimmed === "quit") return { kind: "quit" };
3904
+ const index = Number.parseInt(trimmed, 10) - 1;
3905
+ if (Number.isInteger(index) && index >= 0 && index < entries.length) return { kind: "index", index };
3906
+ out.write(`${rail}Not one of the choices: ${answer}
3907
+ `);
3908
+ return { kind: "back" };
3909
+ }
3910
+ function renderSection(spec, out) {
3911
+ const presenter = createLifecyclePresenter({ stream: out });
3912
+ presenter.header(spec.title, "configure");
3913
+ presenter.note(spec.summary);
3914
+ presenter.note(`Source: ${shortenPath(settingsPath())}${spec.id === "diagnostics" ? "" : " \xB7 saves globally"}`);
3915
+ presenter.fields(spec.fields());
3916
+ return presenter;
3917
+ }
3918
+ async function runSection(rl, streams, spec, backLabel) {
3919
+ let selected = 0;
3920
+ let notice;
3921
+ for (; ; ) {
3922
+ rl.clearScreen();
3923
+ const presenter = renderSection(spec, streams.out);
3924
+ if (notice) {
3925
+ if (notice.warning) presenter.warn(notice.text);
3926
+ else presenter.completedStep(notice.text);
3927
+ notice = void 0;
3928
+ }
3929
+ const io = {
3930
+ rl,
3931
+ out: streams.out,
3932
+ streams,
3933
+ ok: (text) => {
3934
+ notice = { text, warning: false };
3935
+ },
3936
+ warn: (text) => {
3937
+ notice = { text: text.trim(), warning: true };
3938
+ }
3939
+ };
3940
+ presenter.blank();
3941
+ const choice = await pickEntry(rl, streams, spec.actions, backLabel, presenter.isPlain(), selected);
3942
+ if (choice.kind !== "index") return choice.kind;
3943
+ selected = choice.index;
3944
+ const action = spec.actions[selected];
3945
+ try {
3946
+ if (action !== void 0) await action.run(io);
3947
+ } catch (error) {
3948
+ if (error instanceof ConfigureNavigation) {
3949
+ if (error.kind === "quit") return "quit";
3950
+ } else
3951
+ notice = { text: `Change not saved: ${error instanceof Error ? error.message : String(error)}`, warning: true };
3952
+ }
3953
+ }
3954
+ }
3955
+ async function runConfigSectionsMenu(rl, streams, backLabel = "quit") {
3956
+ let selected = 0;
3957
+ for (; ; ) {
3958
+ rl.clearScreen();
3959
+ const presenter = createLifecyclePresenter({ stream: streams.out });
3960
+ presenter.header("Clio Coder Settings", "configure");
3961
+ presenter.note(`Source: ${shortenPath(settingsPath())}`);
3962
+ presenter.note("Same sections as /settings. Changes here become your saved defaults.");
3963
+ presenter.blank();
3964
+ const choice = await pickEntry(
3965
+ rl,
3966
+ streams,
3967
+ SECTIONS.map((section) => ({ label: section.title, hint: section.summary })),
3968
+ backLabel,
3969
+ presenter.isPlain(),
3970
+ selected
3971
+ );
3972
+ if (choice.kind !== "index") return choice.kind;
3973
+ selected = choice.index;
3974
+ const spec = SECTIONS[selected];
3975
+ if (spec === void 0) continue;
3976
+ if (await runSection(rl, streams, spec, "back") === "quit") return "quit";
3977
+ }
3978
+ }
3979
+ async function runConfigLauncher(rl, streams) {
3980
+ let selected = 0;
3981
+ const exitCode = () => readSettings().chat.target ? 0 : 130;
3982
+ for (; ; ) {
3983
+ rl.clearScreen();
3984
+ const presenter = createLifecyclePresenter({ stream: streams.out });
3985
+ presenter.header("Clio Coder", "configure");
3986
+ presenter.note("Connect a model and start coding. Everything else is optional.");
3987
+ presenter.blank();
3988
+ const choice = await pickEntry(
3989
+ rl,
3990
+ streams,
3991
+ [
3992
+ { label: "Quick Connect", hint: "endpoint \u2192 model \u2192 ready" },
3993
+ { label: "Settings", hint: "all configuration options" },
3994
+ { label: "Diagnostics", hint: "check an existing installation" }
3995
+ ],
3996
+ "quit",
3997
+ presenter.isPlain(),
3998
+ selected
3999
+ );
4000
+ if (choice.kind !== "index") return exitCode();
4001
+ selected = choice.index;
4002
+ if (selected === 0) {
4003
+ const result = await runQuickConnect(rl);
4004
+ if (result === "connected") return 0;
4005
+ if (result === "quit") return exitCode();
4006
+ } else if (selected === 1) {
4007
+ if (await runConfigSectionsMenu(rl, streams, "back") === "quit") return exitCode();
4008
+ } else {
4009
+ const section = findSection("diagnostics");
4010
+ if (section && await runSection(rl, streams, section, "back") === "quit") return exitCode();
4011
+ }
4012
+ }
4013
+ }
4014
+ function findSection(name) {
4015
+ const wanted = name.trim().toLowerCase();
4016
+ if (["diagnostics", "doctor", "diag"].includes(wanted)) return DIAGNOSTICS_SECTION;
4017
+ return SECTIONS.find((section) => section.id === resolveSettingsSection(wanted));
4018
+ }
4019
+ var SECTION_IDS = SECTIONS.map((section) => section.id);
4020
+ async function runInteractive(rl, preselectedRuntime, defaults, streams) {
4021
+ if (defaults.quick) {
4022
+ if (!canRunOnboarding(streams)) {
4023
+ printError("--quick needs a terminal; use --id and --runtime for unattended setup");
4024
+ return 2;
4025
+ }
4026
+ return await runQuickConnect(rl) === "connected" ? 0 : 130;
4027
+ }
4028
+ if (defaults.settings) {
4029
+ await runConfigSectionsMenu(rl, streams);
4030
+ return 0;
4031
+ }
4032
+ if (preselectedRuntime) {
4033
+ if (canRunOnboarding(streams))
4034
+ return runOnboardingWizard(streams, {
4035
+ mode: readSettings().targets.length === 0 ? "first" : "add",
4036
+ runtime: preselectedRuntime
4037
+ });
4038
+ return await runTargetSetupInteractive(rl, preselectedRuntime, defaults);
4039
+ }
4040
+ if (defaults.section !== void 0) {
4041
+ const spec = findSection(defaults.section);
4042
+ if (spec === void 0) {
4043
+ printError(`unknown section: ${defaults.section}. Sections: ${SECTION_IDS.join(", ")}`);
4044
+ return 2;
4045
+ }
4046
+ if (streams.in.isTTY !== true) {
4047
+ renderSection(spec, streams.out).done("Done");
4048
+ return 0;
4049
+ }
4050
+ await runSection(rl, streams, spec, "quit");
4051
+ return 0;
4052
+ }
4053
+ if (canRunOnboarding(streams)) return runConfigLauncher(rl, streams);
4054
+ if (readSettings().targets.length === 0) {
4055
+ const runtime = await pickRuntimeViaCategory(rl);
4056
+ if (!runtime) {
4057
+ printError("configuration cancelled");
4058
+ return 130;
4059
+ }
4060
+ return await runTargetSetupInteractive(rl, runtime, defaults);
4061
+ }
4062
+ await runConfigSectionsMenu(rl, streams);
4063
+ return 0;
4064
+ }
4065
+ async function runConfigureCommand(argv, inStream = input, outStream = output2) {
4066
+ let args;
4067
+ try {
4068
+ args = parseSetupArgs(argv);
4069
+ } catch (err) {
4070
+ printError(err instanceof Error ? err.message : String(err));
4071
+ process.stdout.write(HELP);
4072
+ return 2;
4073
+ }
4074
+ if (args.help) {
4075
+ process.stdout.write(HELP);
4076
+ return 0;
4077
+ }
4078
+ ensureRegistryPopulated();
4079
+ if (args.edit) {
4080
+ if (!inStream.isTTY || !outStream.isTTY) {
4081
+ printError("--edit needs a terminal; use configure --json to inspect settings without one");
4082
+ return 2;
4083
+ }
4084
+ try {
4085
+ await editSettings(new ConfigurePrompts(inStream, outStream));
4086
+ return 0;
4087
+ } catch (error) {
4088
+ if (error instanceof ConfigureNavigation) return 0;
4089
+ printError(error instanceof Error ? error.message : String(error));
4090
+ return 1;
4091
+ }
4092
+ }
4093
+ if (args.json) {
4094
+ const settings = readSettings();
4095
+ outStream.write(`${JSON.stringify(settings, null, 2)}
4096
+ `);
4097
+ return 0;
4098
+ }
4099
+ if (args.list) {
4100
+ printRuntimeList(args.all);
4101
+ return 0;
4102
+ }
4103
+ if (args.interop) {
4104
+ if (!inStream.isTTY) return runInteropReview({ rl: null });
4105
+ const rl2 = new ConfigurePrompts(inStream, outStream);
4106
+ return runInteropReview({ rl: rl2, streams: { in: inStream, out: outStream } });
4107
+ }
4108
+ if (args.remove) return runTargetRemove(args.remove);
4109
+ if (args.renameOld && args.renameNew) return runTargetRename(args.renameOld, args.renameNew);
4110
+ if (args.positional.length > 0) {
4111
+ printError(
4112
+ "`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> ...`."
4113
+ );
4114
+ return 2;
4115
+ }
4116
+ const runtimeId = args.runtime;
4117
+ let runtime = null;
4118
+ if (runtimeId) {
4119
+ runtime = getRuntimeRegistry().get(runtimeId);
4120
+ if (!runtime) {
4121
+ const suggestion = closestRuntimeId(getRuntimeRegistry(), runtimeId);
4122
+ printError(`unknown runtime id: ${runtimeId}${suggestion ? ` (did you mean '${suggestion}'?)` : ""}`);
4123
+ process.stdout.write("run `clio-coder configure --list` to see registered runtimes\n");
4124
+ return 2;
4125
+ }
4126
+ if (runtimeId !== runtime.id) warnLegacyNaming(runtimeId, runtime.id);
4127
+ }
4128
+ const hasTargetSetupFlag = args.id !== void 0 || args.url !== void 0 || args.model !== void 0 || args.workerProfile !== void 0 || args.workerProfileModel !== void 0 || args.apiKey !== void 0 || args.apiKeyEnv !== void 0 || args.gateway || args.lifecycle !== void 0 || args.setOrchestrator || args.setBackground || args.backgroundModel !== void 0 || args.orchestratorModel !== void 0 || args.workerModel !== void 0 || args.bindAgent !== void 0 || args.setWorkerDefault || args.contextWindow !== void 0 || args.maxTokens !== void 0 || args.reasoning !== void 0;
4129
+ const nonInteractive = runtime !== null && hasTargetSetupFlag;
4130
+ if (nonInteractive && runtime) return runNonInteractive(runtime, args);
4131
+ if ((runtimeId !== void 0 || hasTargetSetupFlag) && !inStream.isTTY) {
4132
+ printError(
4133
+ runtime === null ? "--runtime is required when configuring a target non-interactively" : "--id is required when passing flags non-interactively"
4134
+ );
4135
+ return 2;
4136
+ }
4137
+ const rl = new ConfigurePrompts(inStream, outStream);
4138
+ try {
4139
+ return await runInteractive(rl, runtime, args, { in: inStream, out: outStream });
4140
+ } catch (err) {
4141
+ if (err instanceof ConfigureNavigation) {
4142
+ if (readSettings().targets.length > 0) return 0;
4143
+ printError("configuration cancelled");
4144
+ return 130;
4145
+ }
4146
+ printError(err instanceof Error ? err.message : String(err));
4147
+ return 1;
4148
+ }
4149
+ }
4150
+
4151
+ export {
4152
+ resolveSupportedWireModels,
4153
+ runTargetRemove,
4154
+ runTargetRename,
4155
+ runConfigureCommand
4156
+ };
4157
+ //# sourceMappingURL=chunk-EX57VVWW.js.map