@iowarp/clio-coder 0.4.5 → 0.4.7

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 (700) hide show
  1. package/.claude-plugin/marketplace.json +283 -0
  2. package/CHANGELOG.md +74 -0
  3. package/CONTRIBUTING.md +116 -38
  4. package/NOTICE +24 -0
  5. package/README.md +341 -682
  6. package/dist/{acp-H3CU2HBQ.js → acp-W3Y3TRHD.js} +12 -12
  7. package/dist/{agents-IXQQZ7BD.js → agents-J4ICNLQ3.js} +57 -56
  8. package/dist/assets/codewiki.json +1 -1
  9. package/dist/assets/tui-notices/get-east-asian-width-LICENSE +9 -0
  10. package/dist/assets/tui-notices/marked-LICENSE +44 -0
  11. package/dist/assets/tui-notices/pi-tui-LICENSE +21 -0
  12. package/dist/{auth-R7KYF7N3.js → auth-X2UJUMOC.js} +25 -25
  13. package/dist/{builtins-CRFDQUVP.js → builtins-XLXWWSRF.js} +6 -6
  14. package/dist/{chunk-DZK63TZJ.js → chunk-24S3DN22.js} +336 -612
  15. package/dist/{chunk-NTK3WTHM.js → chunk-24TOGHPO.js} +2 -2
  16. package/dist/{chunk-M6TAYK66.js → chunk-2O2LVQQK.js} +11 -4
  17. package/dist/{chunk-OQM5IVJY.js → chunk-34XHRVKG.js} +3 -3
  18. package/dist/{chunk-LY4N4TTL.js → chunk-3LXJOICS.js} +2 -2
  19. package/dist/{chunk-SE4ZKILO.js → chunk-3XE4NRLF.js} +30 -9
  20. package/dist/{chunk-YYB3MC65.js → chunk-4MFBBY2Z.js} +3 -3
  21. package/dist/{chunk-5VTJP36Q.js → chunk-4N2RZ4TO.js} +2 -2
  22. package/dist/{chunk-FKIOX6DS.js → chunk-4QKAITQT.js} +10 -5
  23. package/dist/chunk-4UHVS5T7.js +207 -0
  24. package/dist/{chunk-VLPTKCKT.js → chunk-5AJPUR72.js} +6 -6
  25. package/dist/{chunk-5CY4Q6QI.js → chunk-5EQO5NWP.js} +105 -3
  26. package/dist/{chunk-RXIOCVBZ.js → chunk-65BGHOUR.js} +8 -5
  27. package/dist/{chunk-T53XI6I7.js → chunk-6CA2BHOR.js} +2 -2
  28. package/dist/{chunk-HL26ADLH.js → chunk-6CB2IL4N.js} +2 -1
  29. package/dist/{chunk-HR3HPQ76.js → chunk-6LRLOJHQ.js} +3 -3
  30. package/dist/{chunk-HXHFDHB6.js → chunk-6TAATXXH.js} +6 -6
  31. package/dist/{chunk-WFKDPU7U.js → chunk-6YHPAAZR.js} +3 -3
  32. package/dist/{chunk-ZMZQEBKI.js → chunk-7EEGBKV4.js} +11 -11
  33. package/dist/{chunk-BS4GAMUB.js → chunk-A67NR5AT.js} +2 -2
  34. package/dist/{chunk-WJIMKGD6.js → chunk-BAU36233.js} +8 -8
  35. package/dist/{chunk-MDU3C27C.js → chunk-BO4XV5VX.js} +8 -8
  36. package/dist/{chunk-KF6GFW6O.js → chunk-BQQ5MXUC.js} +11 -11
  37. package/dist/{chunk-K6RDB7IA.js → chunk-C3G5PNUO.js} +23 -23
  38. package/dist/{chunk-SRZOW5L2.js → chunk-C6GEXX4L.js} +1 -1
  39. package/dist/{chunk-U2JOLB7O.js → chunk-CE64C5K5.js} +227 -72
  40. package/dist/chunk-CP3HIR5H.js +2119 -0
  41. package/dist/{chunk-BBV5TKE6.js → chunk-CPXGJI2A.js} +2 -2
  42. package/dist/{chunk-5DDOTTG4.js → chunk-CULVKYTK.js} +5 -5
  43. package/dist/{chunk-F34AR6O3.js → chunk-D2T66PDV.js} +6 -6
  44. package/dist/{chunk-NF3BK5WR.js → chunk-DACXIVVF.js} +5 -5
  45. package/dist/{chunk-4SVIVOMC.js → chunk-DLIYANB7.js} +20 -15
  46. package/dist/{chunk-E3BQTQUP.js → chunk-DO7M3LSX.js} +9 -9
  47. package/dist/{chunk-2QPI3TR3.js → chunk-DVJL77SO.js} +2 -2
  48. package/dist/chunk-EM2WNQS2.js +93 -0
  49. package/dist/{chunk-ODUTYZIU.js → chunk-EUEXGXXR.js} +5 -5
  50. package/dist/{chunk-UL36QJX6.js → chunk-EUZRMP4Y.js} +18 -16
  51. package/dist/{chunk-R6MAYTMS.js → chunk-G4LGUTOE.js} +4 -4
  52. package/dist/{chunk-CBSKDFWL.js → chunk-GEVQNST4.js} +2 -2
  53. package/dist/{chunk-XXBQKW32.js → chunk-GFQ7P2UF.js} +7 -7
  54. package/dist/{chunk-SBZX6ARC.js → chunk-GI5RRMAH.js} +14 -14
  55. package/dist/{chunk-KDWLXVMN.js → chunk-GVZFCJHE.js} +343 -113
  56. package/dist/{chunk-633EXGZA.js → chunk-GXIWHXDB.js} +3 -3
  57. package/dist/{chunk-LUL5Z66S.js → chunk-HOX4YZ2K.js} +6 -5
  58. package/dist/chunk-HRAKUPIH.js +57 -0
  59. package/dist/{chunk-KYKNBD4Y.js → chunk-IJMW64DX.js} +978 -258
  60. package/dist/{chunk-DIMRLNIC.js → chunk-IMOD2YPV.js} +16 -9
  61. package/dist/{chunk-6CDNRHWH.js → chunk-IQCNVLO6.js} +28 -8
  62. package/dist/{chunk-UTUNT5QL.js → chunk-ISNCCX42.js} +9 -9
  63. package/dist/{chunk-RLTT5GVY.js → chunk-IZYTT3CD.js} +9 -5
  64. package/dist/{chunk-5ZMXGW7P.js → chunk-KAFMW7WM.js} +4 -85
  65. package/dist/chunk-KKEYGFX4.js +915 -0
  66. package/dist/{chunk-HHVJNVUJ.js → chunk-KS7ETA3P.js} +2 -2
  67. package/dist/{chunk-UXAC2FX4.js → chunk-L3Z5ANCV.js} +7 -7
  68. package/dist/{chunk-EHCPSZJF.js → chunk-LBFQMYS3.js} +2 -2
  69. package/dist/{chunk-QEQISF75.js → chunk-LK2FN5JY.js} +1 -1
  70. package/dist/{chunk-URBGEOH3.js → chunk-M6Z2V6YU.js} +5 -5
  71. package/dist/{chunk-DRD2A54W.js → chunk-MBJO5VNZ.js} +18 -18
  72. package/dist/chunk-MNQN3X6Y.js +595 -0
  73. package/dist/{chunk-GXCCHKN6.js → chunk-MZHXENL7.js} +7 -7
  74. package/dist/chunk-MZNWZUJM.js +1801 -0
  75. package/dist/{chunk-7YJWEF2L.js → chunk-N37QC5FV.js} +5 -5
  76. package/dist/{chunk-WLMSOT73.js → chunk-NCCQ6DVS.js} +7 -7
  77. package/dist/{chunk-TZ7MFRG4.js → chunk-NO7J45X6.js} +170 -53
  78. package/dist/chunk-OH3YYA3B.js +15 -0
  79. package/dist/{chunk-22PQ4TX4.js → chunk-P4DL2LM5.js} +16 -77
  80. package/dist/{chunk-R6MICQYU.js → chunk-PFLOULP3.js} +4 -4
  81. package/dist/{chunk-MC3JSVR6.js → chunk-QJMRYTCX.js} +7 -7
  82. package/dist/{chunk-ILJ7DWGE.js → chunk-QKWL7SYE.js} +12 -12
  83. package/dist/chunk-R2CT5YDO.js +66 -0
  84. package/dist/chunk-RFCKPS2V.js +26 -0
  85. package/dist/{chunk-ONRTXOZY.js → chunk-RTLNFZMD.js} +12 -4
  86. package/dist/{chunk-U7H5WRG5.js → chunk-RXFPB32E.js} +8 -6
  87. package/dist/{chunk-S32UQ5GL.js → chunk-SEDI5K5B.js} +18 -18
  88. package/dist/{chunk-ICO4TQ2F.js → chunk-SELG4SUR.js} +41 -25
  89. package/dist/{chunk-YEJIG7LN.js → chunk-SER7RRAE.js} +27 -832
  90. package/dist/{chunk-K2HL3GBL.js → chunk-T4TY5GG3.js} +165 -15
  91. package/dist/chunk-T7QQBNLH.js +691 -0
  92. package/dist/{chunk-HGSLRG33.js → chunk-TLTGZTXI.js} +3 -3
  93. package/dist/chunk-TZ6UVP2H.js +637 -0
  94. package/dist/{chunk-EWD5P3GK.js → chunk-TZHN5ITX.js} +13 -41
  95. package/dist/{chunk-7TKWWPD7.js → chunk-U3TPUXOQ.js} +398 -253
  96. package/dist/{chunk-GNQRWTMY.js → chunk-UA3W4FGC.js} +6 -6
  97. package/dist/{chunk-O2RQ7LCK.js → chunk-UA6W4XFJ.js} +2 -2
  98. package/dist/chunk-UWD3JD5X.js +709 -0
  99. package/dist/chunk-V4ZKOKRB.js +13433 -0
  100. package/dist/{chunk-NC4KV7EL.js → chunk-VCRVEDUC.js} +5 -5
  101. package/dist/{chunk-I7VLWRK2.js → chunk-VMATUZB6.js} +12 -10
  102. package/dist/{chunk-J2FYEQ5L.js → chunk-VTYHHQ57.js} +2 -2
  103. package/dist/chunk-WB7POC6M.js +891 -0
  104. package/dist/{chunk-GVYWZNRK.js → chunk-WBVKKTUT.js} +2 -2
  105. package/dist/{chunk-EHOSNVVM.js → chunk-WLHX3MM5.js} +6 -2
  106. package/dist/{chunk-SDWNDICN.js → chunk-WN552PKN.js} +573 -316
  107. package/dist/{chunk-TEG3RYVZ.js → chunk-WT5TRMO4.js} +51 -26
  108. package/dist/{chunk-NY6IWDVU.js → chunk-WURGVOZJ.js} +56 -12
  109. package/dist/{chunk-7WUZEB2M.js → chunk-XR3XJN2M.js} +2 -2
  110. package/dist/chunk-XW2UZICE.js +372 -0
  111. package/dist/{chunk-FSTIBAGM.js → chunk-XZ6UFQ52.js} +11 -11
  112. package/dist/chunk-Y3JU5RPK.js +8 -0
  113. package/dist/chunk-YKRJTYNP.js +1143 -0
  114. package/dist/{chunk-7HBHHVCK.js → chunk-YPRSNUTC.js} +2 -2
  115. package/dist/{chunk-PWWSIB2A.js → chunk-ZGIGW4ZG.js} +5 -5
  116. package/dist/cli/index.js +34 -36
  117. package/dist/{clio-5I2IBFYL.js → clio-L2P7S2R2.js} +9 -9
  118. package/dist/{code-nav-YXIAEZVS.js → code-nav-B5LNX4KU.js} +25 -25
  119. package/dist/{components-TNIKXCBH.js → components-63MMQKUT.js} +6 -6
  120. package/dist/{config-Y2JDJ3JJ.js → config-YXARKGTX.js} +81 -77
  121. package/dist/configure-LMVQJ46J.js +85 -0
  122. package/dist/{context-QQ53HSGJ.js → context-7HJEWTTP.js} +92 -48
  123. package/dist/{context-S2EEC3EJ.js → context-XSZKKFBW.js} +14 -14
  124. package/dist/{context-P5YSEO55.js → context-YG2LZDYZ.js} +67 -64
  125. package/dist/{context-clear-TMEQCOTH.js → context-clear-AC5NXHM2.js} +64 -61
  126. package/dist/{context-index-HP2JFUWA.js → context-index-KKTPRV5G.js} +3 -3
  127. package/dist/{context-map-INTXD54D.js → context-map-T7ROR5D5.js} +4 -4
  128. package/dist/{context-working-set-CNLSQN5K.js → context-working-set-F4Q4J3NS.js} +15 -12
  129. package/dist/{detail-5572VLBO.js → detail-H73BEF2N.js} +65 -62
  130. package/dist/{dispatch-runner-FRHD6P2O.js → dispatch-runner-3RY5FSJC.js} +83 -80
  131. package/dist/{doctor-N3LCM2LG.js → doctor-EQYJOGUG.js} +47 -32
  132. package/dist/{eval-BUU3ZOUZ.js → eval-4P7O6CCE.js} +114 -50
  133. package/dist/{evidence-DTGEN456.js → evidence-D6GUSYJW.js} +64 -61
  134. package/dist/{evidence-SQ5DNFEN.js → evidence-O76QF7TZ.js} +69 -65
  135. package/dist/{evolve-IJNUFZDS.js → evolve-H47BCETS.js} +65 -62
  136. package/dist/{extensions-YVRHX6ZI.js → extensions-NNL3ZOCU.js} +98 -20
  137. package/dist/{fleet-ZNNVSYFO.js → fleet-KMNS6NOM.js} +115 -107
  138. package/dist/{fleet-commands-5YE7NPJL.js → fleet-commands-DOWSYCBX.js} +15 -15
  139. package/dist/{fleet-decisions-3SBSCTCW.js → fleet-decisions-S3PTZV2D.js} +9 -9
  140. package/dist/{fleet-graph-6HHPWF5T.js → fleet-graph-F2DE2TME.js} +26 -24
  141. package/dist/{fleet-inspect-JEYMGCGC.js → fleet-inspect-EN2Q6IVB.js} +67 -63
  142. package/dist/{fleet-preflight-QRSHIIDE.js → fleet-preflight-FRLETDD3.js} +3 -3
  143. package/dist/{fleet-validate-4PM4GDDL.js → fleet-validate-B2XDLS57.js} +28 -29
  144. package/dist/{fleet-verify-NJDTHTO3.js → fleet-verify-4JKUWGJ7.js} +64 -61
  145. package/dist/{fleet-view-UP2BWQQY.js → fleet-view-BHJFW26B.js} +67 -63
  146. package/dist/{init-S3GZQ5ZF.js → init-XAT5N5YM.js} +86 -80
  147. package/dist/interop-FVECHFKG.js +246 -0
  148. package/dist/{inventory-K2OZ36YJ.js → inventory-7KFQGLCV.js} +67 -63
  149. package/dist/library-NY2XOT75.js +492 -0
  150. package/dist/library-QAPAO23R.js +306 -0
  151. package/dist/library-import-5Y6MAS3R.js +183 -0
  152. package/dist/library-inventory-JT6HWITQ.js +56 -0
  153. package/dist/library-validation-EQUH25DC.js +42 -0
  154. package/dist/{memory-OQOXQGYD.js → memory-DYVTTCP6.js} +65 -62
  155. package/dist/{models-3IK2Y5WE.js → models-MASFJ6Y2.js} +51 -38
  156. package/dist/{monitor-FTJLTKCQ.js → monitor-YMP4NXJJ.js} +73 -69
  157. package/dist/{orchestrator-N47O7SFD.js → orchestrator-AFQRRTEI.js} +4255 -2845
  158. package/dist/{panes-7BTYH3XQ.js → panes-D3Y2KFG5.js} +4 -4
  159. package/dist/{panes-WPOMEMRH.js → panes-NICTHQCV.js} +7 -7
  160. package/dist/{paths-J3KN7UAO.js → paths-PSFAUIGO.js} +5 -5
  161. package/dist/{preload-65U34NG6.js → preload-5Q7VXRFJ.js} +64 -61
  162. package/dist/{reset-MUVQDLNL.js → reset-7NKZK7JN.js} +11 -9
  163. package/dist/{resources-LM76COAO.js → resources-NILSIZAT.js} +94 -38
  164. package/dist/{run-3VFZQ33N.js → run-BPZGEBZV.js} +131 -114
  165. package/dist/{share-4JUB4BL7.js → share-EZ6ERBMH.js} +31 -28
  166. package/dist/skills-BTVVNYVM.js +100 -0
  167. package/dist/{skills-eval-G6T57L7M.js → skills-eval-UY34MNK7.js} +117 -78
  168. package/dist/{skills-inventory-WLM46PJH.js → skills-inventory-JDHSIA7I.js} +30 -25
  169. package/dist/{slash-commands-GBARG3Y7.js → slash-commands-K4FNQ2AT.js} +53 -49
  170. package/dist/{steer-S7D7IKPU.js → steer-2B3EQGFH.js} +4 -4
  171. package/dist/{support-5VAEC32W.js → support-L2SOL3IE.js} +7 -7
  172. package/dist/{targets-N5REUETU.js → targets-44VKGFLN.js} +69 -47
  173. package/dist/{tasks-6BVY5YZF.js → tasks-3KODKFU7.js} +14 -14
  174. package/dist/{terminal-lease-57UEOJKS.js → terminal-lease-LXA7MMPO.js} +32 -19
  175. package/dist/{tools-6OCQ6SVB.js → tools-3UB7TEVR.js} +7 -7
  176. package/dist/{trace-JHLXWUMN.js → trace-TAMIU4OJ.js} +5 -4
  177. package/dist/{tui-primitives-RCY2HN7G.js → tui-primitives-A6MUW32V.js} +3 -2
  178. package/dist/{uninstall-FXYMFFRT.js → uninstall-QYVRPEM4.js} +9 -9
  179. package/dist/{upgrade-4HD5HAIV.js → upgrade-7PMKM2JH.js} +17 -18
  180. package/dist/{usage-4GWM2WWP.js → usage-6EQV7EQK.js} +77 -73
  181. package/dist/{verifiers-GSKWKWVG.js → verifiers-JLITWSHU.js} +16 -16
  182. package/dist/{verify-3AS3ULCY.js → verify-T7NAEVIG.js} +13 -13
  183. package/dist/{web-fetch-MQN4FH3X.js → web-fetch-W4TNW4Q7.js} +4 -4
  184. package/dist/{wiki-generate-7BV7XWIY.js → wiki-generate-T2TJQJUA.js} +90 -84
  185. package/dist/{with-panes-OFTNAR4Y.js → with-panes-CHFC7HGI.js} +4 -4
  186. package/dist/worker/entry.js +297 -88
  187. package/docs/README.md +43 -0
  188. package/docs/architecture/architecture.md +8 -7
  189. package/docs/architecture/artifact-versions.md +3 -3
  190. package/docs/architecture/context-engine.md +36 -2
  191. package/docs/architecture/library.md +32 -0
  192. package/docs/architecture/middleware-and-components.md +1 -1
  193. package/docs/architecture/model-catalog.md +21 -1
  194. package/docs/architecture/pi-boundary.md +18 -0
  195. package/docs/architecture/prompt-envelope-and-tools.md +5 -5
  196. package/docs/architecture/safety-model.md +21 -2
  197. package/docs/architecture/session-lifecycle.md +12 -1
  198. package/docs/architecture/tui-design.md +153 -39
  199. package/docs/architecture/worker-context.md +106 -0
  200. package/docs/guide/authoring-plugins.md +160 -0
  201. package/docs/guide/built-in-agents.md +5 -5
  202. package/docs/guide/commands-and-modes.md +186 -80
  203. package/docs/guide/configuration-and-targets.md +123 -28
  204. package/docs/guide/configuration-reference.md +36 -38
  205. package/docs/guide/environment-variables.md +2 -2
  206. package/docs/guide/exit-codes-and-output.md +1 -1
  207. package/docs/guide/extensions-and-sharing.md +93 -53
  208. package/docs/guide/fleet-dispatch.md +32 -10
  209. package/docs/guide/glossary.md +2 -2
  210. package/docs/guide/harness-extensions.md +291 -0
  211. package/docs/guide/installation-and-lifecycle.md +53 -20
  212. package/docs/guide/interop.md +243 -0
  213. package/docs/guide/panes-and-files.md +3 -3
  214. package/docs/guide/plugins.md +80 -0
  215. package/docs/guide/resource-library.md +111 -45
  216. package/docs/guide/skills-marketplace.md +35 -72
  217. package/docs/guide/tool-usage.md +19 -7
  218. package/docs/guide/troubleshooting.md +1 -1
  219. package/docs/process/development-pipeline.md +15 -15
  220. package/docs/process/documentation-coverage.md +29 -2
  221. package/docs/process/documentation-guide.md +15 -7
  222. package/docs/process/eval-runner.md +8 -3
  223. package/docs/process/performance-methodology.md +1 -1
  224. package/docs/process/release-cut-checklist.md +22 -6
  225. package/docs/process/scientific-validation.md +23 -0
  226. package/evals/scalar-decision-machinery.ts +1 -1
  227. package/examples/extensions/README.md +67 -0
  228. package/examples/extensions/lab-status/clio-coder-extension.json +14 -0
  229. package/examples/extensions/lab-status/extension.mjs +68 -0
  230. package/examples/extensions/lab-status/jobs.synthetic.json +9 -0
  231. package/examples/extensions/measurements/clio-coder-extension.json +28 -0
  232. package/examples/extensions/measurements/summarize.cjs +23 -0
  233. package/library/README.md +109 -0
  234. package/library/_authoring/templates/agent/README.md +28 -0
  235. package/library/_authoring/templates/agent/agents/benchmark-scout.md +30 -0
  236. package/library/_authoring/templates/agent/plugin.json +23 -0
  237. package/library/_authoring/templates/fleet/README.md +29 -0
  238. package/library/_authoring/templates/fleet/fleets/pipeline-review.md +31 -0
  239. package/library/_authoring/templates/fleet/plugin.json +23 -0
  240. package/library/_authoring/templates/plugin/README.md +37 -0
  241. package/library/_authoring/templates/plugin/agents/data-curator.md +31 -0
  242. package/library/_authoring/templates/plugin/assets/curation-guide.md +22 -0
  243. package/library/_authoring/templates/plugin/plugin.json +42 -0
  244. package/library/_authoring/templates/plugin/prompts/inspect-dataset.md +15 -0
  245. package/library/_authoring/templates/plugin/skills/dataset-curation/SKILL.md +36 -0
  246. package/library/_authoring/templates/plugin/skills/dataset-curation/evals.md +17 -0
  247. package/library/_authoring/templates/prompt/README.md +28 -0
  248. package/library/_authoring/templates/prompt/plugin.json +23 -0
  249. package/library/_authoring/templates/prompt/prompts/paper-summary.md +26 -0
  250. package/library/_authoring/templates/skill/README.md +24 -0
  251. package/library/_authoring/templates/skill/SKILL.md +39 -0
  252. package/library/_authoring/templates/skill/evals.md +30 -0
  253. package/library/_authoring/templates/skill/plugin.json +23 -0
  254. package/library/agents/README.md +7 -0
  255. package/library/fleets/README.md +7 -0
  256. package/library/plugins/materio/README.md +137 -0
  257. package/library/plugins/materio/ai.iowarp.clio/agents/materio-lab-definer.md +208 -0
  258. package/library/plugins/materio/ai.iowarp.clio/agents/materio-literature-reviewer.md +308 -0
  259. package/library/plugins/materio/ai.iowarp.clio/agents/materio-research-explorer.md +249 -0
  260. package/library/plugins/materio/ai.iowarp.clio/agents/materio-task-executor.md +416 -0
  261. package/library/plugins/materio/ai.iowarp.clio/agents/materio-task-verifier.md +60 -0
  262. package/library/plugins/materio/ai.iowarp.clio/agents/materio-workflow-planner.md +238 -0
  263. package/library/plugins/materio/ai.iowarp.clio/fleets/materio-execute-task.md +50 -0
  264. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/add-task.md +66 -0
  265. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/archive-task.md +65 -0
  266. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/checkpoint.md +26 -0
  267. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/define-research-tasks.md +230 -0
  268. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/define-virtual-lab.md +181 -0
  269. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/execute-task.md +292 -0
  270. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/help.md +129 -0
  271. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/identify-research.md +206 -0
  272. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/literature-review.md +201 -0
  273. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/pause-research.md +12 -0
  274. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/progress.md +105 -0
  275. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/remove-task.md +63 -0
  276. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/resume-research.md +64 -0
  277. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/settings.md +16 -0
  278. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/status.md +92 -0
  279. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/upload-data.md +104 -0
  280. package/library/plugins/materio/ai.iowarp.clio/prompts/materio/wtfp.md +145 -0
  281. package/library/plugins/materio/ai.iowarp.clio/references/execution.md +56 -0
  282. package/library/plugins/materio/ai.iowarp.portability/provenance.json +9 -0
  283. package/library/plugins/materio/assets/actions/add-task.md +86 -0
  284. package/library/plugins/materio/assets/actions/archive-task.md +84 -0
  285. package/library/plugins/materio/assets/actions/checkpoint.md +47 -0
  286. package/library/plugins/materio/assets/actions/define-research-tasks.md +228 -0
  287. package/library/plugins/materio/assets/actions/define-virtual-lab.md +179 -0
  288. package/library/plugins/materio/assets/actions/execute-task.md +290 -0
  289. package/library/plugins/materio/assets/actions/help.md +140 -0
  290. package/library/plugins/materio/assets/actions/identify-research.md +204 -0
  291. package/library/plugins/materio/assets/actions/literature-review.md +199 -0
  292. package/library/plugins/materio/assets/actions/pause-research.md +34 -0
  293. package/library/plugins/materio/assets/actions/progress.md +125 -0
  294. package/library/plugins/materio/assets/actions/remove-task.md +82 -0
  295. package/library/plugins/materio/assets/actions/resume-research.md +84 -0
  296. package/library/plugins/materio/assets/actions/settings.md +38 -0
  297. package/library/plugins/materio/assets/actions/status.md +112 -0
  298. package/library/plugins/materio/assets/actions/upload-data.md +123 -0
  299. package/library/plugins/materio/assets/actions/wtfp.md +179 -0
  300. package/library/plugins/materio/assets/references/research-domains.md +134 -0
  301. package/library/plugins/materio/assets/references/research-policy.md +77 -0
  302. package/library/plugins/materio/assets/references/traditional-workflows.md +146 -0
  303. package/library/plugins/materio/assets/scripts/check_physics.py +271 -0
  304. package/library/plugins/materio/assets/scripts/check_scripts.py +248 -0
  305. package/library/plugins/materio/assets/scripts/project_plugin.py +165 -0
  306. package/library/plugins/materio/assets/scripts/research_state.py +400 -0
  307. package/library/plugins/materio/assets/scripts/verify_citations.py +616 -0
  308. package/library/plugins/materio/assets/templates/RESEARCH.md +39 -0
  309. package/library/plugins/materio/assets/templates/VIRTUAL-LAB.md +120 -0
  310. package/library/plugins/materio/assets/templates/WORKFLOW.md +42 -0
  311. package/library/plugins/materio/assets/templates/config.json +5 -0
  312. package/library/plugins/materio/evals/scripts.yaml +29 -0
  313. package/library/plugins/materio/plugin.json +530 -0
  314. package/library/plugins/materio/skills/materio-lab-definer/SKILL.md +74 -0
  315. package/library/plugins/materio/skills/materio-literature-reviewer/SKILL.md +64 -0
  316. package/library/plugins/materio/skills/materio-research-explorer/SKILL.md +74 -0
  317. package/library/plugins/materio/skills/materio-task-executor/SKILL.md +214 -0
  318. package/library/plugins/materio/skills/materio-task-verifier/SKILL.md +46 -0
  319. package/library/plugins/materio/skills/materio-workflow-planner/SKILL.md +79 -0
  320. package/library/plugins/materio/tests/test_check_physics.py +139 -0
  321. package/library/plugins/materio/tests/test_check_scripts.py +140 -0
  322. package/library/plugins/materio/tests/test_research_state.py +291 -0
  323. package/library/plugins/materio/tests/test_verify_citations.py +337 -0
  324. package/library/prompts/README.md +7 -0
  325. package/library/registry.yaml +921 -0
  326. package/library/skills/README.md +120 -0
  327. package/{skills → library/skills}/coding/ast-grep/SKILL.md +1 -1
  328. package/{skills → library/skills}/coding/ast-grep/evals.md +1 -1
  329. package/library/skills/coding/ast-grep/plugin.json +23 -0
  330. package/{skills → library/skills}/coding/coding-standards/SKILL.md +1 -1
  331. package/{skills → library/skills}/coding/coding-standards/evals.md +1 -1
  332. package/library/skills/coding/coding-standards/plugin.json +23 -0
  333. package/{skills → library/skills}/coding/prototype/SKILL.md +1 -1
  334. package/{skills → library/skills}/coding/prototype/evals.md +1 -1
  335. package/library/skills/coding/prototype/plugin.json +23 -0
  336. package/{skills → library/skills}/coding/tdd/SKILL.md +1 -1
  337. package/{skills → library/skills}/coding/tdd/evals.md +1 -1
  338. package/library/skills/coding/tdd/plugin.json +23 -0
  339. package/{skills → library/skills}/context/context-handoff/SKILL.md +1 -1
  340. package/{skills → library/skills}/context/context-handoff/evals.md +1 -1
  341. package/library/skills/context/context-handoff/plugin.json +23 -0
  342. package/{skills → library/skills}/context/context-prime/SKILL.md +1 -1
  343. package/{skills → library/skills}/context/context-prime/evals.md +1 -1
  344. package/library/skills/context/context-prime/plugin.json +23 -0
  345. package/{skills → library/skills}/git/branch-closeout/SKILL.md +1 -1
  346. package/library/skills/git/branch-closeout/plugin.json +23 -0
  347. package/{skills → library/skills}/git/file-ticket/SKILL.md +1 -1
  348. package/library/skills/git/file-ticket/plugin.json +23 -0
  349. package/{skills → library/skills}/git/fix-issue/SKILL.md +1 -1
  350. package/library/skills/git/fix-issue/plugin.json +23 -0
  351. package/{skills → library/skills}/git/resolve-merge-conflicts/SKILL.md +1 -1
  352. package/{skills → library/skills}/git/resolve-merge-conflicts/evals.md +1 -1
  353. package/library/skills/git/resolve-merge-conflicts/plugin.json +23 -0
  354. package/{skills → library/skills}/git/ship/SKILL.md +1 -1
  355. package/library/skills/git/ship/plugin.json +23 -0
  356. package/{skills → library/skills}/git/worktree-create/SKILL.md +1 -1
  357. package/library/skills/git/worktree-create/plugin.json +23 -0
  358. package/{skills → library/skills}/git/worktree-merge/SKILL.md +1 -1
  359. package/library/skills/git/worktree-merge/plugin.json +23 -0
  360. package/{skills → library/skills}/meta/clio-coder-dev/SKILL.md +1 -1
  361. package/{skills → library/skills}/meta/clio-coder-dev/evals.md +1 -1
  362. package/library/skills/meta/clio-coder-dev/plugin.json +23 -0
  363. package/{skills → library/skills}/meta/clio-coder-test/SKILL.md +1 -1
  364. package/{skills → library/skills}/meta/clio-coder-test/evals.md +1 -1
  365. package/library/skills/meta/clio-coder-test/plugin.json +23 -0
  366. package/{skills → library/skills}/meta/credentials/SKILL.md +1 -1
  367. package/{skills → library/skills}/meta/credentials/evals.md +1 -1
  368. package/library/skills/meta/credentials/plugin.json +23 -0
  369. package/library/skills/meta/find-skills/SKILL.md +85 -0
  370. package/library/skills/meta/find-skills/evals.md +65 -0
  371. package/library/skills/meta/find-skills/plugin.json +23 -0
  372. package/{skills → library/skills}/meta/herdr/SKILL.md +1 -1
  373. package/{skills → library/skills}/meta/herdr/evals.md +1 -1
  374. package/library/skills/meta/herdr/plugin.json +23 -0
  375. package/{skills → library/skills}/meta/skill-craft/SKILL.md +23 -9
  376. package/{skills → library/skills}/meta/skill-craft/evals.md +11 -3
  377. package/library/skills/meta/skill-craft/plugin.json +23 -0
  378. package/{skills → library/skills}/planning/archify/SKILL.md +13 -13
  379. package/library/skills/planning/archify/plugin.json +23 -0
  380. package/{skills → library/skills}/planning/architecture/SKILL.md +1 -1
  381. package/{skills → library/skills}/planning/architecture/evals.md +1 -1
  382. package/library/skills/planning/architecture/plugin.json +23 -0
  383. package/{skills → library/skills}/planning/backlog/SKILL.md +1 -1
  384. package/{skills → library/skills}/planning/backlog/evals.md +1 -1
  385. package/library/skills/planning/backlog/plugin.json +23 -0
  386. package/{skills → library/skills}/planning/prd/SKILL.md +1 -1
  387. package/{skills → library/skills}/planning/prd/evals.md +1 -1
  388. package/library/skills/planning/prd/plugin.json +23 -0
  389. package/{skills → library/skills}/planning/product-intent/SKILL.md +1 -1
  390. package/{skills → library/skills}/planning/product-intent/evals.md +1 -1
  391. package/library/skills/planning/product-intent/plugin.json +23 -0
  392. package/{skills → library/skills}/planning/tech-spec/SKILL.md +1 -1
  393. package/{skills → library/skills}/planning/tech-spec/evals.md +1 -1
  394. package/library/skills/planning/tech-spec/plugin.json +23 -0
  395. package/{skills → library/skills}/registry.yaml +7 -7
  396. package/{skills → library/skills}/remote.yaml +1 -1
  397. package/{skills → library/skills}/research/arxiv-literature/SKILL.md +1 -1
  398. package/{skills → library/skills}/research/arxiv-literature/evals.md +1 -1
  399. package/library/skills/research/arxiv-literature/plugin.json +23 -0
  400. package/{skills → library/skills}/research/experiment-protocol/SKILL.md +1 -1
  401. package/{skills → library/skills}/research/experiment-protocol/evals.md +1 -1
  402. package/library/skills/research/experiment-protocol/plugin.json +23 -0
  403. package/{skills → library/skills}/research/scientific-debugging/SKILL.md +1 -1
  404. package/{skills → library/skills}/research/scientific-debugging/evals.md +1 -1
  405. package/library/skills/research/scientific-debugging/plugin.json +23 -0
  406. package/{skills → library/skills}/research/scientific-modernization/SKILL.md +1 -1
  407. package/{skills → library/skills}/research/scientific-modernization/evals.md +1 -1
  408. package/library/skills/research/scientific-modernization/plugin.json +23 -0
  409. package/{skills → library/skills}/skill-marketplace.json +37 -37
  410. package/{skills → library/skills}/workflow/cut-it/SKILL.md +1 -1
  411. package/{skills → library/skills}/workflow/cut-it/evals.md +1 -1
  412. package/library/skills/workflow/cut-it/plugin.json +23 -0
  413. package/{skills → library/skills}/workflow/design-council/SKILL.md +1 -1
  414. package/{skills → library/skills}/workflow/design-council/evals.md +1 -1
  415. package/library/skills/workflow/design-council/plugin.json +23 -0
  416. package/{skills → library/skills}/workflow/grill-me/SKILL.md +1 -1
  417. package/{skills → library/skills}/workflow/grill-me/evals.md +1 -1
  418. package/library/skills/workflow/grill-me/plugin.json +23 -0
  419. package/{skills → library/skills}/workflow/workflow-distiller/SKILL.md +14 -11
  420. package/{skills → library/skills}/workflow/workflow-distiller/evals.md +14 -6
  421. package/library/skills/workflow/workflow-distiller/plugin.json +23 -0
  422. package/package.json +12 -5
  423. package/src/cli/agents.ts +1 -1
  424. package/src/cli/ask.ts +10 -10
  425. package/src/cli/config-inspect.ts +1 -1
  426. package/src/cli/configure-editor.ts +51 -0
  427. package/src/cli/configure-interop.ts +1 -1
  428. package/src/cli/configure-oauth.ts +1 -1
  429. package/src/cli/configure-onboarding.ts +232 -96
  430. package/src/cli/configure-prompts.ts +76 -0
  431. package/src/cli/configure-quick.ts +274 -0
  432. package/src/cli/configure-target.ts +14 -2
  433. package/src/cli/configure.ts +415 -176
  434. package/src/cli/eval.ts +40 -6
  435. package/src/cli/extensions.ts +74 -8
  436. package/src/cli/fleet-preflight.ts +2 -0
  437. package/src/cli/fleet.ts +2 -0
  438. package/src/cli/index.ts +1 -3
  439. package/src/cli/interop-inspect.ts +61 -33
  440. package/src/cli/interop.ts +79 -9
  441. package/src/cli/library-import.ts +139 -0
  442. package/src/cli/library.ts +418 -120
  443. package/src/cli/oauth-manual-input.ts +1 -1
  444. package/src/cli/reset.ts +2 -0
  445. package/src/cli/run.ts +26 -9
  446. package/src/cli/select.ts +35 -4
  447. package/src/cli/skills-eval.ts +43 -6
  448. package/src/cli/skills-inventory.ts +6 -2
  449. package/src/cli/skills.ts +44 -491
  450. package/src/cli/upgrade.ts +2 -2
  451. package/src/core/bus-events.ts +5 -0
  452. package/src/core/config.ts +6 -1
  453. package/src/core/defaults.ts +34 -12
  454. package/src/{interactive → core}/external-editor.ts +4 -4
  455. package/src/core/recent-models.ts +2 -2
  456. package/src/core/session-routing.ts +3 -3
  457. package/src/core/state-file-lock.ts +1 -1
  458. package/src/core/tool-names.ts +5 -0
  459. package/src/domains/agents/extension.ts +42 -6
  460. package/src/domains/agents/fleet-commands.ts +92 -1
  461. package/src/domains/agents/fleet-contract.ts +87 -19
  462. package/src/domains/agents/recipe.ts +5 -4
  463. package/src/domains/agents/registry.ts +80 -24
  464. package/src/domains/config/classify.ts +1 -1
  465. package/src/domains/config/keybindings.ts +156 -124
  466. package/src/domains/context/worker/contract.ts +91 -0
  467. package/src/domains/context/worker/pressure.ts +120 -0
  468. package/src/domains/context/worker/recall.ts +62 -0
  469. package/src/domains/context/worker/select.ts +164 -0
  470. package/src/domains/context/worker/snapshot.ts +35 -0
  471. package/src/domains/context/worker/store.ts +16 -0
  472. package/src/domains/context/working-set/replay/synthetic.ts +2 -1
  473. package/src/domains/dispatch/active-route-planner.ts +2 -0
  474. package/src/domains/dispatch/backoff.ts +1 -0
  475. package/src/domains/dispatch/code-step.ts +12 -2
  476. package/src/domains/dispatch/contract.ts +3 -0
  477. package/src/domains/dispatch/execution-plan.ts +2 -0
  478. package/src/domains/dispatch/extension.ts +109 -27
  479. package/src/domains/dispatch/fleet-plan.ts +10 -0
  480. package/src/domains/dispatch/fleet-run.ts +1 -0
  481. package/src/domains/dispatch/orphan-recovery.ts +1 -0
  482. package/src/domains/dispatch/receipt-integrity.ts +4 -0
  483. package/src/domains/dispatch/state.ts +1 -0
  484. package/src/domains/dispatch/types.ts +5 -0
  485. package/src/domains/dispatch/validation.ts +12 -0
  486. package/src/domains/dispatch/workspace-checkpoint.ts +1 -1
  487. package/src/domains/evidence/failure-attribution.ts +1 -0
  488. package/src/domains/evidence/trust-status.ts +22 -3
  489. package/src/domains/extensions/command-schema.ts +145 -0
  490. package/src/domains/extensions/command-tools.ts +15 -0
  491. package/src/domains/extensions/compatibility.ts +7 -0
  492. package/src/domains/extensions/contract.ts +0 -4
  493. package/src/domains/extensions/discovery.ts +69 -205
  494. package/src/domains/extensions/extension.ts +0 -4
  495. package/src/domains/extensions/index.ts +1 -5
  496. package/src/domains/extensions/manager.ts +1 -6
  497. package/src/domains/extensions/operator-commands.ts +29 -0
  498. package/src/domains/extensions/operator-runtime.ts +483 -0
  499. package/src/domains/extensions/public-api.ts +53 -0
  500. package/src/domains/extensions/runtime-child.mjs +114 -0
  501. package/src/domains/extensions/runtime-process.ts +306 -0
  502. package/src/domains/extensions/runtime-schema.ts +146 -0
  503. package/src/domains/extensions/{resources.ts → snapshot-access.ts} +1 -17
  504. package/src/domains/extensions/snapshot.ts +4 -32
  505. package/src/domains/extensions/state.ts +5 -83
  506. package/src/domains/extensions/types.ts +33 -34
  507. package/src/domains/interop/adopt.ts +546 -0
  508. package/src/domains/interop/detect.ts +50 -12
  509. package/src/domains/interop/foreign.ts +554 -0
  510. package/src/domains/interop/import.ts +277 -0
  511. package/src/domains/interop/index.ts +24 -0
  512. package/src/domains/interop/install.ts +6 -0
  513. package/src/domains/interop/inventory.ts +351 -0
  514. package/src/domains/interop/projection.ts +360 -0
  515. package/src/domains/interop/registry.ts +106 -3
  516. package/src/domains/interop/types.ts +51 -0
  517. package/src/domains/lifecycle/migrations/index.ts +0 -2
  518. package/src/domains/lifecycle/naming-resources.ts +1 -1
  519. package/src/domains/middleware/marketplace-offer.ts +1 -1
  520. package/src/domains/mux/contract.ts +1 -1
  521. package/src/domains/plugins/catalog.ts +204 -0
  522. package/src/domains/plugins/contract.ts +24 -0
  523. package/src/domains/plugins/discovery.ts +316 -0
  524. package/src/domains/plugins/extension.ts +40 -0
  525. package/src/domains/plugins/index.ts +77 -0
  526. package/src/domains/plugins/integrity.ts +6 -0
  527. package/src/domains/plugins/manifest.ts +3 -0
  528. package/src/domains/plugins/resources.ts +102 -0
  529. package/src/domains/plugins/state.ts +753 -0
  530. package/src/domains/plugins/types.ts +217 -0
  531. package/src/domains/prompts/extension.ts +9 -2
  532. package/src/domains/prompts/fragments/operating/skills.md +10 -10
  533. package/src/domains/providers/probe/fingerprint.ts +13 -6
  534. package/src/domains/providers/probe/reasoning.ts +2 -0
  535. package/src/domains/providers/runtimes/common/probe-helpers.ts +23 -7
  536. package/src/domains/providers/runtimes/protocol/anthropic-compat.ts +7 -2
  537. package/src/domains/providers/runtimes/protocol/openai-compat.ts +10 -4
  538. package/src/domains/resources/common-loader.ts +9 -6
  539. package/src/domains/resources/index.ts +67 -0
  540. package/src/domains/resources/library-actions.ts +836 -0
  541. package/src/domains/resources/library-evals.ts +38 -0
  542. package/src/domains/resources/library-inventory.ts +1048 -0
  543. package/src/domains/resources/library-types.ts +50 -0
  544. package/src/domains/resources/library-validation.ts +634 -0
  545. package/src/domains/resources/library.ts +437 -156
  546. package/src/domains/resources/package-references.ts +66 -0
  547. package/src/domains/resources/prompts/loader.ts +75 -41
  548. package/src/domains/resources/skills/install.ts +2 -2
  549. package/src/domains/resources/skills/loader.ts +77 -22
  550. package/src/domains/resources/skills/marketplace.ts +48 -57
  551. package/src/domains/resources/skills/promotion.ts +2 -2
  552. package/src/domains/resources/skills/provenance-pin.ts +17 -4
  553. package/src/domains/safety/action-classifier.ts +2 -2
  554. package/src/domains/safety/default-path-policy.ts +3 -1
  555. package/src/domains/safety/policy-engine.ts +1 -1
  556. package/src/domains/safety/protected-artifacts.ts +21 -5
  557. package/src/domains/safety/skill-authority.ts +5 -2
  558. package/src/domains/share/archive.ts +1 -1
  559. package/src/engine/apis/openai-completions.ts +52 -2
  560. package/src/engine/notices/pi-tui-LICENSE +21 -0
  561. package/src/engine/tui.ts +3 -0
  562. package/src/engine/worker-runtime.ts +58 -14
  563. package/src/engine/worker-tools.ts +5 -0
  564. package/src/entry/orchestrator.ts +26 -5
  565. package/src/entry/plugin-reload.ts +18 -0
  566. package/src/interactive/application-controller.ts +68 -52
  567. package/src/interactive/chat-loop.ts +32 -5
  568. package/src/interactive/chat-panel.ts +168 -638
  569. package/src/interactive/chat-renderer.ts +13 -30
  570. package/src/interactive/clio-editor.ts +53 -21
  571. package/src/interactive/command-output.ts +56 -1
  572. package/src/interactive/dispatch-board.ts +1 -3
  573. package/src/interactive/editor-submit.ts +73 -59
  574. package/src/interactive/fleet-run-preview.ts +2 -0
  575. package/src/interactive/follow-up-queue-panel.ts +3 -3
  576. package/src/interactive/footer/dashboard.ts +12 -4
  577. package/src/interactive/footer/notifications.ts +2 -2
  578. package/src/interactive/footer/widgets.ts +52 -93
  579. package/src/interactive/interactive-application.ts +225 -63
  580. package/src/interactive/interactive-event-projection.ts +2 -44
  581. package/src/interactive/interactive-input-runtime.ts +257 -35
  582. package/src/interactive/interactive-presentation.ts +71 -21
  583. package/src/interactive/interactive-slash-runtime.ts +40 -48
  584. package/src/interactive/keybinding-manager.ts +156 -79
  585. package/src/interactive/keyboard-owner.ts +37 -0
  586. package/src/interactive/layout.ts +29 -4
  587. package/src/interactive/leader-key.ts +49 -102
  588. package/src/interactive/leader-menu.ts +45 -0
  589. package/src/interactive/overlay-ask-user-lifecycle.ts +9 -1
  590. package/src/interactive/overlay-frame.ts +15 -0
  591. package/src/interactive/overlay-general-openers.ts +2 -0
  592. package/src/interactive/overlay-key-routing.ts +46 -47
  593. package/src/interactive/overlay-lifecycle.ts +31 -15
  594. package/src/interactive/overlay-resource-openers.ts +56 -46
  595. package/src/interactive/overlay-session-lifecycle.ts +1 -1
  596. package/src/interactive/overlays/ask-user.ts +630 -556
  597. package/src/interactive/overlays/extension-panel.ts +70 -0
  598. package/src/interactive/overlays/extensions.ts +28 -5
  599. package/src/interactive/overlays/fleet-run-approval.ts +7 -3
  600. package/src/interactive/overlays/help-reference.ts +89 -40
  601. package/src/interactive/overlays/interop.ts +122 -3
  602. package/src/interactive/overlays/keybinding-detail.ts +2 -2
  603. package/src/interactive/overlays/library-lifecycle.ts +90 -0
  604. package/src/interactive/overlays/library-model.ts +574 -0
  605. package/src/interactive/overlays/library-review.ts +557 -0
  606. package/src/interactive/overlays/library-tabs.ts +3 -15
  607. package/src/interactive/overlays/library.ts +602 -0
  608. package/src/interactive/overlays/list-overlay.ts +218 -39
  609. package/src/interactive/overlays/model-selector.ts +28 -25
  610. package/src/interactive/overlays/session-selector.ts +9 -3
  611. package/src/interactive/overlays/settings.ts +34 -26
  612. package/src/interactive/overlays/tree-selector.ts +16 -11
  613. package/src/interactive/permission-hint.ts +13 -0
  614. package/src/interactive/permission-overlay.ts +77 -28
  615. package/src/interactive/prompt-source-label.ts +21 -0
  616. package/src/interactive/renderers/preview.ts +16 -0
  617. package/src/interactive/renderers/reference-card.ts +35 -0
  618. package/src/interactive/renderers/tool-execution.ts +67 -160
  619. package/src/interactive/renderers/worker-entry.ts +90 -42
  620. package/src/interactive/slash-autocomplete.ts +100 -7
  621. package/src/interactive/slash-commands.ts +396 -105
  622. package/src/interactive/slash-spec.ts +0 -1
  623. package/src/interactive/status/controller.ts +0 -5
  624. package/src/interactive/status/state-machine.ts +44 -26
  625. package/src/interactive/status/types.ts +3 -0
  626. package/src/interactive/status/verbs.ts +13 -12
  627. package/src/interactive/terminal-lease.ts +44 -12
  628. package/src/interactive/transcript-detail.ts +50 -112
  629. package/src/interactive/turn-queues.ts +8 -7
  630. package/src/interactive/turn-runtime.ts +1 -1
  631. package/src/interactive/view/artifacts.ts +4 -0
  632. package/src/interactive/view/view-overlay.ts +58 -43
  633. package/src/interactive/welcome-dashboard.ts +525 -408
  634. package/src/tools/bootstrap.ts +8 -0
  635. package/src/tools/builtin-tool-catalog.ts +7 -2
  636. package/src/tools/context/index.ts +58 -5
  637. package/src/tools/context/library.ts +465 -0
  638. package/src/tools/context/surface.ts +20 -6
  639. package/src/tools/core-bootstrap.ts +3 -0
  640. package/src/tools/dispatch-admission.ts +24 -1
  641. package/src/tools/dispatch-arguments.ts +8 -0
  642. package/src/tools/dispatch-plan.ts +32 -0
  643. package/src/tools/dispatch-schema.ts +31 -1
  644. package/src/tools/dispatch-types.ts +3 -0
  645. package/src/tools/dispatch.ts +1 -1
  646. package/src/tools/harness-extensions.ts +169 -0
  647. package/src/tools/observation.ts +4 -0
  648. package/src/tools/policy.ts +7 -1
  649. package/src/tools/presentation.ts +1 -1
  650. package/src/tools/registry.ts +20 -2
  651. package/src/tools/verify/numeric.ts +4 -4
  652. package/src/tools/worker-evidence.ts +5 -0
  653. package/src/worker/context-seed.ts +192 -0
  654. package/src/worker/entry.ts +1 -0
  655. package/src/worker/spec-contract.ts +8 -1
  656. package/dist/chunk-3UW3KU4A.js +0 -21
  657. package/dist/chunk-6SYEGZI3.js +0 -433
  658. package/dist/chunk-CXQ37WJH.js +0 -45
  659. package/dist/chunk-EQEJJ53P.js +0 -399
  660. package/dist/chunk-KTFSFCVN.js +0 -46
  661. package/dist/chunk-QRFXEO6Y.js +0 -17
  662. package/dist/chunk-T7FDXNRU.js +0 -1257
  663. package/dist/chunk-U7VQ4NI4.js +0 -911
  664. package/dist/configure-SML6UBZ5.js +0 -55
  665. package/dist/interop-YOTGXFJM.js +0 -115
  666. package/dist/library-GJI6W6OK.js +0 -226
  667. package/dist/skills-S36AAJHU.js +0 -510
  668. package/skills/README.md +0 -418
  669. package/skills/meta/find-skills/SKILL.md +0 -78
  670. package/skills/meta/find-skills/evals.md +0 -47
  671. package/src/domains/extensions/resource-path.ts +0 -27
  672. package/src/domains/lifecycle/migrations/2026-09-01-extension-install-digests.ts +0 -27
  673. package/src/interactive/overlays/agents.ts +0 -70
  674. package/src/interactive/overlays/library-install-confirm.ts +0 -152
  675. package/src/interactive/overlays/prompts.ts +0 -89
  676. package/src/interactive/overlays/skills-hub.ts +0 -615
  677. /package/{skills → library/skills}/coding/ast-grep/references/rule_reference.md +0 -0
  678. /package/{skills → library/skills}/coding/prototype/references/LOGIC.md +0 -0
  679. /package/{skills → library/skills}/coding/prototype/references/UI.md +0 -0
  680. /package/{skills → library/skills}/coding/tdd/references/mocking.md +0 -0
  681. /package/{skills → library/skills}/coding/tdd/references/tests.md +0 -0
  682. /package/{skills → library/skills}/context/context-handoff/scripts/new-handoff.sh +0 -0
  683. /package/{skills → library/skills}/git/branch-closeout/evals.md +0 -0
  684. /package/{skills → library/skills}/git/branch-closeout/references/closeout-checklist.md +0 -0
  685. /package/{skills → library/skills}/git/file-ticket/assets/issue-template.md +0 -0
  686. /package/{skills → library/skills}/git/file-ticket/evals.md +0 -0
  687. /package/{skills → library/skills}/git/file-ticket/references/issue-discovery.md +0 -0
  688. /package/{skills → library/skills}/git/fix-issue/evals.md +0 -0
  689. /package/{skills → library/skills}/git/fix-issue/references/diagnosis-and-rca.md +0 -0
  690. /package/{skills → library/skills}/git/resolve-merge-conflicts/references/conflict-matrix.md +0 -0
  691. /package/{skills → library/skills}/git/ship/assets/pr-template.md +0 -0
  692. /package/{skills → library/skills}/git/ship/evals.md +0 -0
  693. /package/{skills → library/skills}/git/ship/references/remote-and-branch-policy.md +0 -0
  694. /package/{skills → library/skills}/git/worktree-create/evals.md +0 -0
  695. /package/{skills → library/skills}/git/worktree-create/references/worktree-setup.md +0 -0
  696. /package/{skills → library/skills}/git/worktree-merge/evals.md +0 -0
  697. /package/{skills → library/skills}/git/worktree-merge/references/merge-strategies.md +0 -0
  698. /package/{skills → library/skills}/meta/clio-coder-test/references/harness.md +0 -0
  699. /package/{skills → library/skills}/meta/clio-coder-test/references/test-map.md +0 -0
  700. /package/{skills → library/skills}/planning/archify/evals.md +0 -0
@@ -2,14 +2,25 @@ import { createRequire as __clioCreateRequire } from "node:module"; const requir
2
2
  import {
3
3
  createDelayedManualCodeInput,
4
4
  promptOAuthSelection
5
- } from "./chunk-QEQISF75.js";
5
+ } from "./chunk-LK2FN5JY.js";
6
+ import {
7
+ editTextExternally,
8
+ resolveExternalEditor
9
+ } from "./chunk-R2CT5YDO.js";
6
10
  import {
7
11
  createLifecyclePresenter,
8
12
  shortenPath
9
13
  } from "./chunk-6YA46L5A.js";
14
+ import {
15
+ column,
16
+ terminalColumns,
17
+ truncate,
18
+ twoColumnRow,
19
+ wrapPlain
20
+ } from "./chunk-ZIDFQJRB.js";
10
21
  import {
11
22
  fingerprintNativeRuntime
12
- } from "./chunk-MC3JSVR6.js";
23
+ } from "./chunk-QJMRYTCX.js";
13
24
  import {
14
25
  INHERITED_PROJECT_CONTEXT,
15
26
  acceptInteropAgents,
@@ -18,21 +29,14 @@ import {
18
29
  interopProposals,
19
30
  renderProposalEntry,
20
31
  resolveOnPath
21
- } from "./chunk-6SYEGZI3.js";
32
+ } from "./chunk-CP3HIR5H.js";
22
33
  import {
23
34
  initializeClioHome
24
- } from "./chunk-T53XI6I7.js";
25
- import {
26
- column,
27
- terminalColumns,
28
- truncate,
29
- twoColumnRow,
30
- wrapPlain
31
- } from "./chunk-ZIDFQJRB.js";
35
+ } from "./chunk-6CA2BHOR.js";
32
36
  import {
33
37
  credentialWriteFailed,
34
38
  printPlaintextCredentialWarning
35
- } from "./chunk-5VTJP36Q.js";
39
+ } from "./chunk-4N2RZ4TO.js";
36
40
  import {
37
41
  printError,
38
42
  printOk,
@@ -43,30 +47,19 @@ import {
43
47
  probeCapabilitiesForModel,
44
48
  readTargetModelSnapshot,
45
49
  recordTargetModelSnapshot
46
- } from "./chunk-TEG3RYVZ.js";
50
+ } from "./chunk-WT5TRMO4.js";
47
51
  import {
48
52
  credentialsPresent
49
- } from "./chunk-J2FYEQ5L.js";
50
- import {
51
- bindAgentProfileInSettings,
52
- readSettings,
53
- removeTargetFromSettings,
54
- settingsPath,
55
- updateSettings
56
- } from "./chunk-FKIOX6DS.js";
57
- import {
58
- warnLegacyNaming
59
- } from "./chunk-DVNAPPXU.js";
53
+ } from "./chunk-VTYHHQ57.js";
60
54
  import {
61
- getVersionInfo
62
- } from "./chunk-GD55RTIW.js";
55
+ AUTONOMY_LEVELS
56
+ } from "./chunk-EM2WNQS2.js";
63
57
  import {
64
58
  greetLmStudio,
65
- registerBuiltinRuntimes
66
- } from "./chunk-ICO4TQ2F.js";
67
- import {
68
- THINKING_LEVELS
69
- } from "./chunk-SE4ZKILO.js";
59
+ probeJson,
60
+ registerBuiltinRuntimes,
61
+ targetRootUrl
62
+ } from "./chunk-SELG4SUR.js";
70
63
  import {
71
64
  buildProviderSupportEntry,
72
65
  configuredTargetsForRuntime,
@@ -74,7 +67,7 @@ import {
74
67
  listKnownModelsForRuntime,
75
68
  listProviderSupportEntries,
76
69
  supportGroupLabel
77
- } from "./chunk-HHVJNVUJ.js";
70
+ } from "./chunk-KS7ETA3P.js";
78
71
  import {
79
72
  authStoragePath,
80
73
  openAuthStorage,
@@ -82,29 +75,57 @@ import {
82
75
  resolveAuthTarget,
83
76
  resolveRuntimeAuthTarget,
84
77
  targetRequiresAuth
85
- } from "./chunk-HXHFDHB6.js";
78
+ } from "./chunk-6TAATXXH.js";
86
79
  import {
87
80
  getRuntimeRegistry
88
81
  } from "./chunk-SRCEQKQS.js";
89
82
  import {
90
83
  getCatalogModelForRuntime
91
84
  } from "./chunk-TN5FW4XY.js";
85
+ import {
86
+ SettingsValidationError,
87
+ bindAgentProfileInSettings,
88
+ readSettings,
89
+ removeTargetFromSettings,
90
+ settingsPath,
91
+ updateSavedSettingsDocument,
92
+ updateSettings,
93
+ validateSettings,
94
+ withSettingsLock
95
+ } from "./chunk-4QKAITQT.js";
96
+ import {
97
+ warnLegacyNaming
98
+ } from "./chunk-DVNAPPXU.js";
99
+ import {
100
+ getVersionInfo
101
+ } from "./chunk-GD55RTIW.js";
102
+ import {
103
+ DEFAULT_SETTINGS_YAML,
104
+ THINKING_LEVELS
105
+ } from "./chunk-3XE4NRLF.js";
106
+ import {
107
+ require_dist
108
+ } from "./chunk-B5GGDIHT.js";
109
+ import {
110
+ safeResourceWrite
111
+ } from "./chunk-ZZFWWYLX.js";
92
112
  import {
93
113
  resolveClioDirs
94
114
  } from "./chunk-CTTI7G3T.js";
95
115
  import {
116
+ __toESM,
96
117
  init_esm_shims
97
118
  } from "./chunk-ECBHH7LU.js";
98
119
 
99
120
  // src/cli/configure.ts
100
121
  init_esm_shims();
101
- import { existsSync, readFileSync } from "node:fs";
122
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
102
123
  import { stdin as input, stdout as output2 } from "node:process";
103
- import { createInterface as createInterface2 } from "node:readline/promises";
104
124
 
105
125
  // src/cli/ask.ts
106
126
  init_esm_shims();
107
127
  async function ask(rl, label, defaultValue) {
128
+ if (rl.text) return rl.text(label, defaultValue);
108
129
  const suffix = defaultValue && defaultValue.length > 0 ? ` [${defaultValue}]` : "";
109
130
  try {
110
131
  const answer = (await rl.question(`${label}${suffix}: `)).trim();
@@ -116,6 +137,7 @@ async function ask(rl, label, defaultValue) {
116
137
  }
117
138
  }
118
139
  async function askYesNo(rl, label, defaultValue) {
140
+ if (rl.choose && rl.interactive) return await rl.choose(label, ["yes", "no"], defaultValue ? "yes" : "no") === "yes";
119
141
  const marker = defaultValue ? "Y/n" : "y/N";
120
142
  for (; ; ) {
121
143
  const answer = await ask(rl, `${label} [${marker}]`);
@@ -129,6 +151,53 @@ async function askYesNo(rl, label, defaultValue) {
129
151
  }
130
152
  }
131
153
 
154
+ // src/cli/configure-editor.ts
155
+ init_esm_shims();
156
+ var import_yaml = __toESM(require_dist(), 1);
157
+ import { existsSync, readFileSync } from "node:fs";
158
+ async function editSettings(prompts) {
159
+ const file = settingsPath();
160
+ const original = existsSync(file) ? readFileSync(file, "utf8") : null;
161
+ let draft = original ?? DEFAULT_SETTINGS_YAML;
162
+ const editor = resolveExternalEditor();
163
+ for (; ; ) {
164
+ const result = editTextExternally(draft, editor, ".yaml");
165
+ if (!result.ok || result.text === void 0) throw new Error(result.error ?? "Editor did not return a draft");
166
+ draft = `${result.text}
167
+ `;
168
+ if (draft === original) {
169
+ prompts.output.write("Settings unchanged.\n");
170
+ return false;
171
+ }
172
+ try {
173
+ const validated = validateSettings((0, import_yaml.parse)(draft));
174
+ if (validated.issues.length) throw new SettingsValidationError(validated.issues);
175
+ } catch (error) {
176
+ prompts.output.write(`${error instanceof Error ? error.message : String(error)}
177
+ `);
178
+ if (await prompts.choose("Invalid draft", ["Return to editor", "Discard draft"], "Return to editor") === "Return to editor")
179
+ continue;
180
+ return false;
181
+ }
182
+ const choice = await prompts.choose(
183
+ "Save validated settings?",
184
+ ["Save", "Return to editor", "Discard draft"],
185
+ "Save"
186
+ );
187
+ if (choice === "Return to editor") continue;
188
+ if (choice !== "Save") return false;
189
+ withSettingsLock(() => {
190
+ const current = existsSync(file) ? readFileSync(file, "utf8") : null;
191
+ if (current !== original)
192
+ throw new Error("Settings changed while the editor was open. Reopen the editor to keep those changes.");
193
+ safeResourceWrite(file, draft, { encoding: "utf8", mode: 420, backup: original !== null });
194
+ });
195
+ prompts.output.write(`Settings saved to ${file}${original === null ? "" : `; previous file: ${file}.bak`}
196
+ `);
197
+ return true;
198
+ }
199
+ }
200
+
132
201
  // src/cli/configure-interop.ts
133
202
  init_esm_shims();
134
203
  import { stdout as output } from "node:process";
@@ -226,6 +295,13 @@ function deriveTargetId(runtimeId, existing) {
226
295
  }
227
296
  return `${base}-${Date.now()}`;
228
297
  }
298
+ function targetApiKeyRef(targetId, targets) {
299
+ const taken = new Set(targets.filter((target) => target.id !== targetId).map((target) => target.auth?.apiKeyRef));
300
+ const base = `target:${targetId}`;
301
+ let ref = base;
302
+ for (let suffix = 2; taken.has(ref); suffix += 1) ref = `${base}-${suffix}`;
303
+ return ref;
304
+ }
229
305
  async function buildProbeContext(runtime, target) {
230
306
  const probeCtx = {
231
307
  credentialsPresent: credentialsPresent(),
@@ -459,8 +535,11 @@ function buildDescriptor(runtime, id, parts) {
459
535
  if (parts.litellm) descriptor.litellm = parts.litellm;
460
536
  return descriptor;
461
537
  }
462
- function describeAuthStatus(runtime) {
463
- const status = openAuthStorage().statusForTarget(resolveRuntimeAuthTarget(runtime), { includeFallback: false });
538
+ function describeAuthStatus(runtime, target) {
539
+ const status = openAuthStorage().statusForTarget(
540
+ target ? resolveAuthTarget(target, runtime) : resolveRuntimeAuthTarget(runtime),
541
+ { includeFallback: false }
542
+ );
464
543
  if (!status.available) return "none stored";
465
544
  if (status.source === "environment") return `environment${status.detail ? ` (${status.detail})` : ""}`;
466
545
  if (status.source === "stored-api-key") return "stored api key";
@@ -647,7 +726,7 @@ function viewportFor(output3, overhead, total, requested) {
647
726
  async function promptSelect(options) {
648
727
  const input2 = options.input ?? process.stdin;
649
728
  const output3 = options.output ?? process.stdout;
650
- const choices = options.choices;
729
+ let choices = options.choices;
651
730
  if (choices.length === 0) return { kind: "back" };
652
731
  const rail = options.railPrefix ?? "";
653
732
  const railWidth = 3;
@@ -655,14 +734,24 @@ async function promptSelect(options) {
655
734
  const frame = makeFrame(output3);
656
735
  let index = Math.min(Math.max(options.initialIndex ?? 0, 0), choices.length - 1);
657
736
  let windowStart = 0;
737
+ let query = "";
738
+ const filter = () => {
739
+ choices = options.choices.filter((choice) => choice.label.toLowerCase().includes(query.toLowerCase()));
740
+ index = 0;
741
+ windowStart = 0;
742
+ render();
743
+ };
658
744
  const render = () => {
659
- const viewport = viewportFor(output3, head.length + 5, choices.length, options.maxVisible);
745
+ const viewport = viewportFor(output3, head.length + (options.searchable ? 6 : 5), choices.length, options.maxVisible);
660
746
  if (index < windowStart) windowStart = index;
661
747
  else if (index >= windowStart + viewport) windowStart = index - viewport + 1;
662
748
  windowStart = Math.max(0, Math.min(windowStart, choices.length - viewport));
663
749
  const lines = [];
664
750
  for (const line of head) lines.push(`${rail}${line}`.trimEnd());
665
751
  if (head.length > 0) lines.push(rail.trimEnd());
752
+ if (options.searchable)
753
+ lines.push(`${rail}${truncate(`Filter: ${query || "(type to search)"}`, terminalColumns(output3) - railWidth)}`);
754
+ if (choices.length === 0) lines.push(`${rail}No matching models`);
666
755
  lines.push(
667
756
  ...choiceRows(
668
757
  {
@@ -681,7 +770,8 @@ async function promptSelect(options) {
681
770
  lines.push(rail.trimEnd());
682
771
  const legend = ["\u2191/\u2193 move", "enter select"];
683
772
  if (options.backLabel !== void 0 && options.backLabel !== "quit") legend.push(`esc ${options.backLabel}`);
684
- legend.push(options.backLabel === "quit" ? "esc or q quit" : "q quit");
773
+ if (options.searchable) legend.push("type to filter", "ctrl-u clear", "ctrl-c quit");
774
+ else legend.push(options.backLabel === "quit" ? "esc or q quit" : "q quit");
685
775
  lines.push(`${rail}${source_default.dim(legend.join(" \xB7 "))}`);
686
776
  frame.draw(lines);
687
777
  };
@@ -690,11 +780,29 @@ async function promptSelect(options) {
690
780
  output3,
691
781
  true,
692
782
  render,
693
- (_str, key, finish2) => {
783
+ (str, key, finish2) => {
694
784
  if (key.ctrl && (key.name === "c" || key.name === "d")) {
695
785
  finish2({ kind: "quit" });
696
786
  return;
697
787
  }
788
+ if (options.searchable) {
789
+ if (key.ctrl && key.name === "u") {
790
+ query = "";
791
+ filter();
792
+ return;
793
+ }
794
+ if (key.name === "backspace") {
795
+ query = query.slice(0, -1);
796
+ filter();
797
+ return;
798
+ }
799
+ if (!key.ctrl && !key.meta && str?.length === 1 && str >= " " && str !== "\x7F") {
800
+ query += str;
801
+ filter();
802
+ return;
803
+ }
804
+ if (choices.length === 0 && !["escape", "left"].includes(key.name ?? "")) return;
805
+ }
698
806
  switch (key.name) {
699
807
  case "up":
700
808
  case "k":
@@ -1315,18 +1423,29 @@ function allEntries() {
1315
1423
  return listProviderSupportEntries(getRuntimeRegistry().list());
1316
1424
  }
1317
1425
  function draftDescriptor(answers, runtime, withModel) {
1318
- const apiKeyRef = answers.credential === "stored" || answers.credential === "keep" ? runtime.id : void 0;
1319
- return buildDescriptor(runtime, answers.targetId ?? runtime.id, {
1426
+ const apiKeyRef = answers.credential === "stored" ? targetApiKeyRef(answers.targetId ?? runtime.id, readSettings().targets) : answers.credential === "keep" ? answers.existing?.auth?.apiKeyRef ?? runtime.id : void 0;
1427
+ const configured = buildDescriptor(runtime, answers.targetId ?? runtime.id, {
1320
1428
  ...answers.url !== void 0 ? { url: answers.url } : {},
1321
1429
  ...withModel && answers.model !== void 0 ? { model: answers.model } : {},
1322
1430
  ...answers.apiKeyEnv !== void 0 ? { apiKeyEnv: answers.apiKeyEnv } : {},
1323
1431
  ...apiKeyRef !== void 0 ? { apiKeyRef } : {},
1324
- ...runtime.auth === "oauth" ? { oauthProfile: runtime.oauthProviderId ?? runtime.id } : {}
1432
+ ...runtime.auth === "oauth" ? { oauthProfile: answers.existing?.auth?.oauthProfile ?? runtime.oauthProviderId ?? runtime.id } : {}
1325
1433
  });
1434
+ const descriptor = { ...answers.existing, ...configured };
1435
+ if (!withModel) delete descriptor.defaultModel;
1436
+ if (answers.existing?.auth || configured.auth) {
1437
+ descriptor.auth = { ...answers.existing?.auth, ...configured.auth };
1438
+ if (runtime.auth === "api-key") {
1439
+ if (answers.credential !== "env") delete descriptor.auth.apiKeyEnvVar;
1440
+ if (answers.credential !== "stored" && answers.credential !== "keep") delete descriptor.auth.apiKeyRef;
1441
+ }
1442
+ if (Object.keys(descriptor.auth).length === 0) delete descriptor.auth;
1443
+ }
1444
+ return descriptor;
1326
1445
  }
1327
1446
  var CATEGORY_STEP = {
1328
1447
  id: "category",
1329
- applies: () => true,
1448
+ applies: (answers) => answers.mode !== "edit" && !answers.fixedRuntime,
1330
1449
  run: async (wizard, answers) => {
1331
1450
  const current = CONFIGURE_CATEGORY_CHOICES.findIndex((choice2) => choice2.category === answers.category);
1332
1451
  const result = await promptSelect({
@@ -1357,12 +1476,12 @@ var CATEGORY_STEP = {
1357
1476
  };
1358
1477
  var RUNTIME_STEP = {
1359
1478
  id: "runtime",
1360
- applies: () => true,
1479
+ applies: (answers) => answers.mode !== "edit" && !answers.fixedRuntime,
1361
1480
  run: async (wizard, answers) => {
1362
1481
  const registry = getRuntimeRegistry();
1363
1482
  const chatEntries = allEntries().filter((entry) => {
1364
1483
  const runtime2 = registry.get(entry.runtimeId);
1365
- return runtime2 !== null && isOrchestratorEligibleRuntime(runtime2);
1484
+ return runtime2 !== null && (answers.mode !== "first" || isOrchestratorEligibleRuntime(runtime2));
1366
1485
  });
1367
1486
  const entries = answers.category ? runtimesForCategory(chatEntries, answers.category) : chatEntries;
1368
1487
  const usable = entries.length > 0 ? entries : chatEntries;
@@ -1390,6 +1509,9 @@ var RUNTIME_STEP = {
1390
1509
  answers.apiKeyEnv = void 0;
1391
1510
  answers.apiKeyLiteral = void 0;
1392
1511
  answers.model = void 0;
1512
+ answers.thinking = void 0;
1513
+ answers.contextWindow = void 0;
1514
+ answers.probe = void 0;
1393
1515
  answers.inventory = void 0;
1394
1516
  answers.inventoryKey = void 0;
1395
1517
  }
@@ -1400,7 +1522,7 @@ var RUNTIME_STEP = {
1400
1522
  };
1401
1523
  var TARGET_ID_STEP = {
1402
1524
  id: "target-id",
1403
- applies: () => true,
1525
+ applies: (answers) => answers.mode !== "edit",
1404
1526
  run: async (wizard, answers) => {
1405
1527
  const runtime = answers.runtime;
1406
1528
  if (!runtime) return "back";
@@ -1414,6 +1536,8 @@ var TARGET_ID_STEP = {
1414
1536
  validate: (value) => {
1415
1537
  if (value.length === 0) return "a target id is required";
1416
1538
  if (/\s/u.test(value)) return "a target id cannot contain spaces";
1539
+ if (readSettings().targets.some((target) => target.id === value))
1540
+ return "that target id already exists; choose another or use Edit a target";
1417
1541
  return null;
1418
1542
  },
1419
1543
  input: wizard.input,
@@ -1484,7 +1608,7 @@ async function reportReachability(wizard, answers, runtime, url) {
1484
1608
  }
1485
1609
  var DETECTED_RUNTIME_STEP = {
1486
1610
  id: "detected-runtime",
1487
- applies: (answers) => answers.detected !== void 0 && answers.runtime !== void 0,
1611
+ applies: (answers) => answers.mode !== "edit" && answers.detected !== void 0 && answers.runtime !== void 0,
1488
1612
  run: async (wizard, answers) => {
1489
1613
  const detected = answers.detected;
1490
1614
  const runtime = answers.runtime;
@@ -1540,10 +1664,15 @@ var CREDENTIAL_STEP = {
1540
1664
  run: async (wizard, answers) => {
1541
1665
  const runtime = answers.runtime;
1542
1666
  if (!runtime) return "back";
1543
- const stored = describeAuthStatus(runtime);
1667
+ const stored = describeAuthStatus(runtime, answers.existing);
1544
1668
  if (runtime.auth === "oauth") {
1545
1669
  const result2 = await promptSelect({
1546
- heading: ["", source_default.bold(`Sign in to ${runtime.displayName}`), source_default.dim(`credential: ${stored}`)],
1670
+ heading: [
1671
+ "",
1672
+ source_default.bold(`Sign in to ${runtime.displayName}`),
1673
+ source_default.dim(`credential: ${stored}`),
1674
+ "Sign-in stores credentials immediately; target settings wait for Save."
1675
+ ],
1547
1676
  choices: [
1548
1677
  { value: "oauth-connect", label: "Connect now", hint: "opens your browser and waits for the callback" },
1549
1678
  {
@@ -1575,7 +1704,7 @@ var CREDENTIAL_STEP = {
1575
1704
  wizard.answer("Credential", "not connected yet");
1576
1705
  return "next";
1577
1706
  }
1578
- const hasStored = stored !== "none stored";
1707
+ const hasStored = answers.existing?.auth?.apiKeyRef !== void 0 || stored !== "none stored";
1579
1708
  const choices = [
1580
1709
  {
1581
1710
  value: "env",
@@ -1609,6 +1738,7 @@ var CREDENTIAL_STEP = {
1609
1738
  if (result.kind === "back") return "back";
1610
1739
  answers.credential = result.value;
1611
1740
  if (result.value !== "env") answers.apiKeyEnv = void 0;
1741
+ answers.inventoryKey = void 0;
1612
1742
  if (result.value !== "stored") answers.apiKeyLiteral = void 0;
1613
1743
  if (result.value === "keep") wizard.answer("Credential", stored);
1614
1744
  if (result.value === "skip") wizard.answer("Credential", "none");
@@ -1627,6 +1757,7 @@ var CREDENTIAL_VALUE_STEP = {
1627
1757
  initial: wantsEnv ? answers.apiKeyEnv ?? runtime.credentialsEnvVar ?? "" : "",
1628
1758
  hint: wantsEnv ? "Clio reads it every time it calls the provider, so the key never lands on disk" : `stored at ${shortenPath(authStoragePath())}`,
1629
1759
  ...wantsEnv ? {} : { mask: true },
1760
+ validate: (value) => value.length > 0 ? null : `Enter ${wantsEnv ? "an environment variable" : "a key"}, or press Escape to choose No key.`,
1630
1761
  railPrefix: wizard.rail,
1631
1762
  backLabel: "back",
1632
1763
  clearOnExit: true,
@@ -1742,7 +1873,7 @@ var MODEL_STEP = {
1742
1873
  };
1743
1874
  async function readModelCapabilities(answers, runtime) {
1744
1875
  const descriptor = draftDescriptor(answers, runtime, true);
1745
- const probe = await runtimeProbe(runtime, descriptor);
1876
+ const probe = await runtimeProbe(runtime, descriptor, answers.apiKeyLiteral);
1746
1877
  answers.probe = probe;
1747
1878
  if (probe?.ok && probe.models) {
1748
1879
  recordTargetModelSnapshot(descriptor, probe.models, probe.modelLabels ? { modelLabels: probe.modelLabels } : {});
@@ -1760,6 +1891,7 @@ var THINKING_HINTS = {
1760
1891
  var THINKING_STEP = {
1761
1892
  id: "thinking",
1762
1893
  applies: (answers) => {
1894
+ if (answers.mode !== "first" && !PROTOCOL_COMPAT_RUNTIME_IDS.has(answers.runtime?.id ?? "")) return false;
1763
1895
  const runtime = answers.runtime;
1764
1896
  if (!runtime || answers.model === void 0) return false;
1765
1897
  if (PROTOCOL_COMPAT_RUNTIME_IDS.has(runtime.id)) return true;
@@ -1768,7 +1900,13 @@ var THINKING_STEP = {
1768
1900
  run: async (wizard, answers) => {
1769
1901
  const current = THINKING_LEVELS.indexOf(answers.thinking ?? "low");
1770
1902
  const result = await promptSelect({
1771
- heading: ["", source_default.bold("How hard should it think?"), source_default.dim("changeable any time in `clio-coder configure`")],
1903
+ heading: [
1904
+ "",
1905
+ source_default.bold("How hard should it think?"),
1906
+ source_default.dim(
1907
+ answers.mode === "first" ? "changeable any time in `clio-coder configure`" : "off disables reasoning for this target; chat and fleet thinking defaults stay unchanged"
1908
+ )
1909
+ ],
1772
1910
  choices: THINKING_LEVELS.map((level) => ({ value: level, label: level, hint: THINKING_HINTS[level] })),
1773
1911
  initialIndex: current >= 0 ? current : 0,
1774
1912
  railPrefix: wizard.rail,
@@ -1786,7 +1924,7 @@ var THINKING_STEP = {
1786
1924
  };
1787
1925
  var ANTIGRAVITY_COLLEAGUE_STEP = {
1788
1926
  id: "antigravity-colleague",
1789
- applies: (answers) => answers.runtime !== void 0 && isOrchestratorEligibleRuntime(answers.runtime) && resolveOnPath(["agy"]).presence === "present" && !readSettings().targets.some((target) => target.runtime === "antigravity-code"),
1927
+ applies: (answers) => answers.mode === "first" && answers.runtime !== void 0 && isOrchestratorEligibleRuntime(answers.runtime) && resolveOnPath(["agy"]).presence === "present" && !readSettings().targets.some((target) => target.runtime === "antigravity-code"),
1790
1928
  run: async (wizard, answers) => {
1791
1929
  const runtime = getRuntimeRegistry().get("antigravity-code");
1792
1930
  if (!runtime) return "next";
@@ -1845,22 +1983,54 @@ var ANTIGRAVITY_COLLEAGUE_STEP = {
1845
1983
  return "next";
1846
1984
  }
1847
1985
  };
1848
- var PEERS_STEP = {
1849
- id: "peers",
1850
- applies: () => true,
1986
+ var CONTEXT_STEP = {
1987
+ id: "context-window",
1988
+ applies: (answers) => PROTOCOL_COMPAT_RUNTIME_IDS.has(answers.runtime?.id ?? "") || answers.mode === "edit",
1851
1989
  run: async (wizard, answers) => {
1852
- const outcome = await reviewInteropAgents({
1853
- rl: null,
1854
- streams: wizard.streams,
1855
- presenter: wizard.presenter,
1856
- rail: wizard.rail,
1857
- quiet: true
1990
+ const result = await promptText({
1991
+ heading: ["", source_default.bold("Context window in tokens")],
1992
+ initial: answers.contextWindow === void 0 ? "" : String(answers.contextWindow),
1993
+ hint: "optional override; blank uses detected capabilities or the runtime default",
1994
+ validate: (value) => value === "" || Number.isSafeInteger(Number(value)) && Number(value) > 0 ? null : "enter a positive whole number, or leave blank",
1995
+ railPrefix: wizard.rail,
1996
+ backLabel: "back",
1997
+ clearOnExit: true,
1998
+ input: wizard.input,
1999
+ output: wizard.output
1858
2000
  });
1859
- if (outcome.back) return "back";
1860
- answers.wiredPeers = outcome.wired;
2001
+ if (result.kind !== "value") return result.kind;
2002
+ answers.contextWindow = result.value ? Number(result.value) : void 0;
2003
+ wizard.answer("Context", result.value || "detected / runtime default");
1861
2004
  return "next";
1862
2005
  }
1863
2006
  };
2007
+ var REVIEW_STEP = {
2008
+ id: "review",
2009
+ applies: () => true,
2010
+ run: async (wizard, answers) => {
2011
+ const result = await promptSelect({
2012
+ heading: [
2013
+ "",
2014
+ source_default.bold("Review target"),
2015
+ `${answers.targetId} \xB7 ${answers.runtime?.id} \xB7 ${answers.model}`,
2016
+ answers.mode === "first" ? "Use for chat and fleet." : "Existing chat, fleet, memory, and profile defaults stay in place.",
2017
+ "Escape returns to the previous step; settings are saved only when you choose Save."
2018
+ ],
2019
+ choices: [
2020
+ { value: "save", label: "Save target" },
2021
+ { value: "back", label: "Back" },
2022
+ { value: "cancel", label: "Cancel setup" }
2023
+ ],
2024
+ railPrefix: wizard.rail,
2025
+ backLabel: "back",
2026
+ clearOnExit: true,
2027
+ input: wizard.input,
2028
+ output: wizard.output
2029
+ });
2030
+ if (result.kind !== "selected") return result.kind;
2031
+ return result.value === "save" ? "next" : result.value === "back" ? "back" : "cancel";
2032
+ }
2033
+ };
1864
2034
  var STEPS = [
1865
2035
  CATEGORY_STEP,
1866
2036
  RUNTIME_STEP,
@@ -1871,31 +2041,37 @@ var STEPS = [
1871
2041
  DETECTED_RUNTIME_STEP,
1872
2042
  MODEL_STEP,
1873
2043
  THINKING_STEP,
2044
+ CONTEXT_STEP,
1874
2045
  ANTIGRAVITY_COLLEAGUE_STEP,
1875
- PEERS_STEP
2046
+ REVIEW_STEP
1876
2047
  ];
1877
- function persist(answers, descriptor, chatEligible) {
1878
- updateSettings((settings) => {
1879
- applyTarget(settings, descriptor);
1880
- if (chatEligible) setOrchestratorPointer(settings, descriptor, answers.model ?? null);
1881
- setWorkerDefaultPointer(settings, descriptor, answers.model ?? null);
1882
- if (answers.thinking !== void 0) {
1883
- settings.chat.thinkingLevel = answers.thinking;
1884
- settings.fleet.default.thinkingLevel = answers.thinking;
1885
- }
1886
- if (answers.antigravity !== void 0) {
1887
- const antigravityRuntime = getRuntimeRegistry().get("antigravity-code");
1888
- if (!antigravityRuntime) throw new Error("Antigravity runtime disappeared before settings were written");
1889
- const external = buildDescriptor(antigravityRuntime, answers.antigravity.targetId, {
1890
- model: answers.antigravity.model
1891
- });
1892
- applyTarget(settings, external);
1893
- setWorkerProfilePointer(settings, "world-knowledge-external", external, answers.antigravity.model);
1894
- bindAgentProfileInSettings(settings, "world-knowledge", "world-knowledge-external");
1895
- }
1896
- });
2048
+ function applyAnswers(settings, answers, descriptor, chatEligible) {
2049
+ const current = settings.targets.find((target) => target.id === descriptor.id);
2050
+ if (answers.mode === "edit") {
2051
+ if (JSON.stringify(current) !== JSON.stringify(answers.existing))
2052
+ throw new Error("This target changed during setup; reopen Edit to keep those changes.");
2053
+ } else if (current) throw new Error(`Target '${descriptor.id}' already exists; use Edit a target.`);
2054
+ applyTarget(settings, descriptor);
2055
+ if (answers.mode === "first" && chatEligible) setOrchestratorPointer(settings, descriptor, answers.model ?? null);
2056
+ if (answers.mode === "first") setWorkerDefaultPointer(settings, descriptor, answers.model ?? null);
2057
+ if (answers.mode === "first" && answers.thinking !== void 0) {
2058
+ settings.chat.thinkingLevel = answers.thinking;
2059
+ settings.fleet.default.thinkingLevel = answers.thinking;
2060
+ }
2061
+ if (answers.antigravity !== void 0) {
2062
+ const antigravityRuntime = getRuntimeRegistry().get("antigravity-code");
2063
+ if (!antigravityRuntime) throw new Error("Antigravity runtime disappeared before settings were written");
2064
+ const external = buildDescriptor(antigravityRuntime, answers.antigravity.targetId, {
2065
+ model: answers.antigravity.model
2066
+ });
2067
+ applyTarget(settings, external);
2068
+ setWorkerProfilePointer(settings, "world-knowledge-external", external, answers.antigravity.model);
2069
+ bindAgentProfileInSettings(settings, "world-knowledge", "world-knowledge-external");
2070
+ }
1897
2071
  }
1898
- async function runOnboardingWizard(streams) {
2072
+ async function runOnboardingWizard(streams, options = {
2073
+ mode: "first"
2074
+ }) {
1899
2075
  const writer = railWriter(streams.out);
1900
2076
  const presenter = createLifecyclePresenter({ stream: writer.stream });
1901
2077
  const rail = railPrefix(presenter.isPlain());
@@ -1910,10 +2086,30 @@ async function runOnboardingWizard(streams) {
1910
2086
  presenter.fields([[label.padEnd(LABEL_WIDTH), truncate(value, Math.max(12, columns - LABEL_WIDTH - 6))]]);
1911
2087
  }
1912
2088
  };
1913
- presenter.header("Welcome to Clio Coder", "configure");
1914
- presenter.note("Pick the model you want Clio to talk to; escape goes back a step and changes nothing.");
2089
+ presenter.header(
2090
+ options.mode === "edit" ? `Edit target: ${options.target.id}` : options.mode === "first" ? "Welcome to Clio Coder" : "Add a target",
2091
+ "configure"
2092
+ );
2093
+ presenter.note("Pick a model; escape goes back. Review and save when ready.");
1915
2094
  presenter.note(`Result: ${shortenPath(settingsPath())}`);
1916
- const answers = {};
2095
+ const existing = options.mode === "edit" ? options.target : void 0;
2096
+ const answers = {
2097
+ mode: options.mode,
2098
+ existing,
2099
+ runtime: existing ? getRuntimeRegistry().get(existing.runtime) ?? void 0 : options.mode !== "edit" ? options.runtime : void 0,
2100
+ fixedRuntime: options.mode !== "edit" && options.runtime !== void 0,
2101
+ targetId: existing?.id,
2102
+ url: existing?.url,
2103
+ model: existing?.defaultModel,
2104
+ credential: existing?.auth?.apiKeyEnvVar ? "env" : existing?.auth?.apiKeyRef ? "keep" : void 0,
2105
+ apiKeyEnv: existing?.auth?.apiKeyEnvVar,
2106
+ contextWindow: existing?.capabilities?.contextWindow,
2107
+ thinking: existing?.capabilities?.reasoning === false ? "off" : void 0
2108
+ };
2109
+ if (existing && !answers.runtime) {
2110
+ presenter.fail(`Unknown runtime: ${existing.runtime}`);
2111
+ return 2;
2112
+ }
1917
2113
  const marks = new Array(STEPS.length).fill(writer.mark());
1918
2114
  let cursor = 0;
1919
2115
  let direction = 1;
@@ -1922,70 +2118,76 @@ async function runOnboardingWizard(streams) {
1922
2118
  if (step === void 0) break;
1923
2119
  if (!step.applies(answers)) {
1924
2120
  cursor += direction;
1925
- if (cursor < 0) return cancel(presenter);
2121
+ if (cursor < 0) return cancel(presenter, answers);
1926
2122
  continue;
1927
2123
  }
1928
2124
  marks[cursor] = writer.mark();
1929
2125
  const outcome = await step.run(wizard, answers);
1930
- if (outcome === "quit") return cancel(presenter);
2126
+ if (outcome === "quit" || outcome === "cancel") return cancel(presenter, answers, outcome === "quit");
1931
2127
  if (outcome === "back") {
1932
2128
  direction = -1;
1933
2129
  cursor -= 1;
1934
2130
  while (cursor >= 0 && !(STEPS[cursor]?.applies(answers) ?? false)) cursor -= 1;
1935
- if (cursor < 0) return cancel(presenter);
2131
+ if (cursor < 0) return cancel(presenter, answers);
1936
2132
  writer.rewindTo(marks[cursor] ?? writer.mark());
1937
2133
  continue;
1938
2134
  }
1939
2135
  direction = 1;
1940
2136
  cursor += 1;
1941
2137
  }
1942
- return finish(wizard, answers);
2138
+ const code = finish(wizard, answers);
2139
+ if (code === 0 && answers.mode === "first") {
2140
+ await reviewInteropAgents({ rl: null, streams, presenter, rail, quiet: true });
2141
+ }
2142
+ return code;
1943
2143
  }
1944
- function cancel(presenter) {
1945
- presenter.done("Cancelled, nothing written");
1946
- printError("configuration cancelled");
1947
- return 130;
2144
+ function cancel(presenter, answers, quit = false) {
2145
+ presenter.done("Cancelled; target settings not saved");
2146
+ if (answers.mode === "first") printError("configuration cancelled");
2147
+ return answers.mode === "first" || quit ? 130 : 0;
1948
2148
  }
1949
2149
  function finish(wizard, answers) {
1950
2150
  const runtime = answers.runtime;
1951
2151
  const targetId = answers.targetId;
1952
- if (!runtime || targetId === void 0) return cancel(wizard.presenter);
2152
+ if (!runtime || targetId === void 0) return cancel(wizard.presenter, answers);
1953
2153
  const presenter = wizard.presenter;
1954
- if (answers.apiKeyLiteral !== void 0) {
1955
- const auth = openAuthStorage();
1956
- auth.setApiKey(runtime.id, answers.apiKeyLiteral);
1957
- if (credentialWriteFailed(auth, `credential for ${runtime.id} was not stored; target '${targetId}' not saved`)) {
1958
- presenter.done("Nothing written");
1959
- return 1;
1960
- }
1961
- printPlaintextCredentialWarning();
1962
- }
1963
2154
  const reasoning = PROTOCOL_COMPAT_RUNTIME_IDS.has(runtime.id) && answers.thinking !== void 0 ? answers.thinking !== "off" : void 0;
1964
- const descriptor = buildDescriptor(runtime, targetId, {
1965
- ...answers.url !== void 0 ? { url: answers.url } : {},
1966
- ...answers.model !== void 0 ? { model: answers.model } : {},
1967
- ...answers.apiKeyEnv !== void 0 ? { apiKeyEnv: answers.apiKeyEnv } : {},
1968
- ...answers.credential === "stored" || answers.credential === "keep" ? { apiKeyRef: runtime.id } : {},
1969
- ...runtime.auth === "oauth" ? { oauthProfile: runtime.oauthProviderId ?? runtime.id } : {},
1970
- ...reasoning === void 0 ? {} : { reasoning }
1971
- });
2155
+ const descriptor = draftDescriptor(answers, runtime, true);
2156
+ descriptor.capabilities = { ...descriptor.capabilities };
2157
+ if (reasoning !== void 0) descriptor.capabilities.reasoning = reasoning;
2158
+ if (answers.contextWindow === void 0) delete descriptor.capabilities.contextWindow;
2159
+ else descriptor.capabilities.contextWindow = answers.contextWindow;
1972
2160
  const chatEligible = isOrchestratorEligibleRuntime(runtime);
1973
2161
  try {
1974
- persist(answers, descriptor, chatEligible);
2162
+ const preview = readSettings();
2163
+ applyAnswers(preview, answers, descriptor, chatEligible);
2164
+ const validated = validateSettings(preview);
2165
+ if (validated.issues.length) throw new SettingsValidationError(validated.issues);
2166
+ initializeClioHome();
2167
+ if (answers.apiKeyLiteral !== void 0 && descriptor.auth?.apiKeyRef) {
2168
+ const auth = openAuthStorage();
2169
+ auth.setApiKey(descriptor.auth.apiKeyRef, answers.apiKeyLiteral);
2170
+ if (credentialWriteFailed(auth, `credential for ${runtime.id} was not stored; target '${targetId}' not saved`)) {
2171
+ presenter.done("Nothing written");
2172
+ return 1;
2173
+ }
2174
+ printPlaintextCredentialWarning();
2175
+ }
2176
+ updateSettings((settings) => applyAnswers(settings, answers, descriptor, chatEligible));
1975
2177
  } catch (error) {
1976
2178
  presenter.fail("settings were not written", error instanceof Error ? error.message : String(error));
1977
- presenter.done("Nothing written");
2179
+ presenter.done("Target settings not saved");
1978
2180
  return 1;
1979
2181
  }
1980
2182
  presenter.completedStep(`target ${targetId} saved, runtime ${runtime.id}`);
1981
- if (chatEligible)
2183
+ if (answers.mode === "first" && chatEligible)
1982
2184
  presenter.completedStep(`chat runs on ${targetId}${answers.model ? `, model ${answers.model}` : ""}`);
1983
- else presenter.completedStep(`${runtime.id} cannot answer chat; ${targetId} is registered for dispatch only`);
1984
- presenter.completedStep(`fleet default is ${targetId}`);
1985
- if (answers.thinking !== void 0) presenter.completedStep(`thinking level ${answers.thinking}`);
1986
- for (const peer of answers.wiredPeers ?? []) {
1987
- presenter.completedStep(`delegation agent ${peer} added; use \`/delegate ${peer} <task>\``);
1988
- }
2185
+ else if (!chatEligible)
2186
+ presenter.completedStep(`${runtime.id} cannot answer chat; ${targetId} is registered for dispatch only`);
2187
+ if (answers.mode === "first") presenter.completedStep(`fleet default is ${targetId}`);
2188
+ else presenter.note("Use Targets & Auth to change chat, fleet, or background defaults.");
2189
+ if (answers.mode === "first" && answers.thinking !== void 0)
2190
+ presenter.completedStep(`thinking level ${answers.thinking}`);
1989
2191
  if (answers.antigravity !== void 0) {
1990
2192
  presenter.completedStep(
1991
2193
  `world-knowledge bound read-only to ${answers.antigravity.targetId}/${answers.antigravity.model}`
@@ -2003,19 +2205,318 @@ function finish(wizard, answers) {
2003
2205
  return 0;
2004
2206
  }
2005
2207
 
2208
+ // src/cli/configure-prompts.ts
2209
+ init_esm_shims();
2210
+ import { createInterface as createInterface2 } from "node:readline/promises";
2211
+ var ConfigureNavigation = class extends Error {
2212
+ constructor(kind) {
2213
+ super(kind);
2214
+ this.kind = kind;
2215
+ }
2216
+ kind;
2217
+ };
2218
+ var ConfigurePrompts = class {
2219
+ constructor(input2, output3) {
2220
+ this.input = input2;
2221
+ this.output = output3;
2222
+ }
2223
+ input;
2224
+ output;
2225
+ get interactive() {
2226
+ return canSelect(this.input, this.output);
2227
+ }
2228
+ clearScreen() {
2229
+ if (this.interactive) this.output.write("\x1B[H\x1B[2J");
2230
+ }
2231
+ async question(query, options) {
2232
+ const rl = createInterface2({ input: this.input, output: this.output });
2233
+ try {
2234
+ return await new Promise((resolve, reject) => {
2235
+ rl.once("close", () => reject(new ConfigureNavigation("quit")));
2236
+ rl.once("SIGINT", () => reject(new ConfigureNavigation("quit")));
2237
+ rl.question(query, options ?? {}).then(resolve, reject);
2238
+ });
2239
+ } finally {
2240
+ rl.close();
2241
+ }
2242
+ }
2243
+ async text(label, initial = "", mask = false) {
2244
+ if (!this.interactive) {
2245
+ const value = (await this.question(`${label}${initial ? ` [${initial}]` : ""}: `)).trim();
2246
+ if (/^(q|quit)$/iu.test(value)) throw new ConfigureNavigation("quit");
2247
+ return value || initial;
2248
+ }
2249
+ const result = await promptText({
2250
+ heading: ["", label],
2251
+ railPrefix: railPrefix(createLifecyclePresenter({ stream: this.output }).isPlain()),
2252
+ initial,
2253
+ mask,
2254
+ backLabel: "back",
2255
+ clearOnExit: true,
2256
+ input: this.input,
2257
+ output: this.output
2258
+ });
2259
+ if (result.kind !== "value") throw new ConfigureNavigation(result.kind);
2260
+ return result.value;
2261
+ }
2262
+ async choose(label, choices, current, searchable = false) {
2263
+ if (!this.interactive) return this.text(`${label} [${choices.join("|")}]`, current);
2264
+ const result = await promptSelect({
2265
+ heading: ["", label],
2266
+ railPrefix: railPrefix(createLifecyclePresenter({ stream: this.output }).isPlain()),
2267
+ choices: choices.map((value) => ({ value, label: value })),
2268
+ initialIndex: Math.max(0, choices.indexOf(current)),
2269
+ ...searchable ? { searchable: true, maxVisible: 8 } : {},
2270
+ backLabel: "back",
2271
+ clearOnExit: true,
2272
+ input: this.input,
2273
+ output: this.output
2274
+ });
2275
+ if (result.kind !== "selected") throw new ConfigureNavigation(result.kind);
2276
+ return result.value;
2277
+ }
2278
+ };
2279
+
2280
+ // src/cli/configure-quick.ts
2281
+ init_esm_shims();
2282
+ function endpointUrl(value) {
2283
+ const url = new URL(value.includes("://") ? value : `http://${value}`);
2284
+ if (!["http:", "https:"].includes(url.protocol) || !url.hostname)
2285
+ throw new Error("Use an http:// or https:// endpoint URL.");
2286
+ if (url.username || url.password)
2287
+ throw new Error("Enter the endpoint without credentials; Clio asks for a key when needed.");
2288
+ return url.toString().replace(/\/$/u, "");
2289
+ }
2290
+ async function connect(url, key) {
2291
+ const settings = readSettings();
2292
+ const registry = getRuntimeRegistry();
2293
+ const matches = settings.targets.filter((target2) => {
2294
+ const runtime2 = registry.get(target2.runtime);
2295
+ if (!target2.url || !runtime2 || !isOrchestratorEligibleRuntime(runtime2)) return false;
2296
+ try {
2297
+ return endpointUrl(target2.url) === url;
2298
+ } catch {
2299
+ return false;
2300
+ }
2301
+ });
2302
+ const existing = matches.find((target2) => target2.id === settings.chat.target) ?? matches[0];
2303
+ let runtime = existing ? registry.get(existing.runtime) : null;
2304
+ let token = key;
2305
+ if (existing && runtime && token === void 0) {
2306
+ const auth = await openAuthStorage().resolveForTarget(resolveAuthTarget(existing, runtime), {
2307
+ includeFallback: false
2308
+ });
2309
+ token = auth.apiKey;
2310
+ }
2311
+ const ctx = { credentialsPresent: /* @__PURE__ */ new Set(), httpTimeoutMs: 5e3, authToken: token ?? "" };
2312
+ if (!runtime) {
2313
+ const root = targetRootUrl({ id: "quick", runtime: "openai-compat", url }) ?? url;
2314
+ const headers = token ? { Authorization: `Bearer ${token}` } : {};
2315
+ const native = await fingerprintNativeRuntime(root, headers);
2316
+ let id = native?.runtimeId ?? "openai-compat";
2317
+ if (!native) {
2318
+ const info = await probeJson({
2319
+ url: `${root}/v1/model/info`,
2320
+ headers,
2321
+ timeoutMs: 1e3
2322
+ });
2323
+ if (info.ok && info.data?.data?.some((row) => typeof row.model_name === "string" && row.model_info !== void 0))
2324
+ id = "litellm";
2325
+ }
2326
+ runtime = registry.get(id);
2327
+ }
2328
+ if (!runtime) throw new Error("No compatible runtime is available. Open Settings \u2192 Targets & Auth.");
2329
+ const target = existing ? structuredClone(existing) : {
2330
+ id: deriveTargetId(runtime.id, settings.targets),
2331
+ runtime: runtime.id,
2332
+ url
2333
+ };
2334
+ let probe = await runtime.probe?.(target, ctx) ?? {
2335
+ ok: false,
2336
+ error: "This connection does not support endpoint checks."
2337
+ };
2338
+ let models = probe.ok ? probe.models ?? await runtime.probeModels?.(target, ctx) ?? [] : [];
2339
+ if (!existing && runtime.id === "openai-compat" && !probe.ok && /HTTP (401|403|404)/u.test(probe.error ?? "")) {
2340
+ const anthropic = registry.get("anthropic-compat");
2341
+ if (anthropic) {
2342
+ const candidate = { ...target, runtime: anthropic.id };
2343
+ const catalog = await anthropic.probeModels?.(candidate, ctx) ?? [];
2344
+ if (catalog.length > 0) {
2345
+ runtime = anthropic;
2346
+ target.runtime = anthropic.id;
2347
+ target.id = deriveTargetId(anthropic.id, settings.targets);
2348
+ models = catalog;
2349
+ probe = { ok: true, models };
2350
+ }
2351
+ }
2352
+ }
2353
+ models = [...new Set(models)].filter((id) => probe.modelCapabilities?.[id]?.chat !== false);
2354
+ return { runtime, target, existing, probe, models };
2355
+ }
2356
+ async function runQuickConnect(prompts) {
2357
+ const initial = readSettings();
2358
+ const first = initial.targets.length === 0;
2359
+ const current = initial.targets.find((target) => target.id === initial.chat.target);
2360
+ let url = current?.url ?? "";
2361
+ let key;
2362
+ let connection;
2363
+ let model = "";
2364
+ let step = "url";
2365
+ let askedKey = false;
2366
+ let optionalKey = false;
2367
+ let notice = "";
2368
+ const presenter = createLifecyclePresenter({ stream: prompts.output });
2369
+ for (; ; ) {
2370
+ prompts.clearScreen();
2371
+ presenter.header("Quick Connect", "configure");
2372
+ presenter.note("Connect one model to power Clio. Change other settings whenever you need them.");
2373
+ if (notice) {
2374
+ presenter.warn(notice);
2375
+ notice = "";
2376
+ }
2377
+ try {
2378
+ if (step === "url") {
2379
+ presenter.note("LM Studio: localhost:1234 \xB7 Ollama: localhost:11434");
2380
+ const answer = await prompts.text("Endpoint URL", url);
2381
+ if (!answer) {
2382
+ notice = "Enter the endpoint URL shown by your model server or API provider.";
2383
+ continue;
2384
+ }
2385
+ try {
2386
+ url = endpointUrl(answer);
2387
+ } catch (error) {
2388
+ notice = error instanceof Error ? error.message : String(error);
2389
+ continue;
2390
+ }
2391
+ key = void 0;
2392
+ askedKey = false;
2393
+ connection = void 0;
2394
+ } else if (step === "key") {
2395
+ presenter.note(`Endpoint: ${url}`);
2396
+ if (optionalKey)
2397
+ presenter.note("Some APIs publish models publicly but require a key for chat. Leave blank for a keyless server.");
2398
+ key = await prompts.text("API key (saved locally when you choose Connect)", "", true) || void 0;
2399
+ if (!key && !optionalKey) {
2400
+ notice = "Enter a key, or press Escape to change the endpoint.";
2401
+ continue;
2402
+ }
2403
+ askedKey = true;
2404
+ }
2405
+ if (step === "url" || step === "key") {
2406
+ presenter.note("Checking the endpoint and reading its model list\u2026");
2407
+ connection = await connect(url, key);
2408
+ if (!connection.probe.ok) {
2409
+ if (connection.probe.authFailed || /HTTP (401|403)/u.test(connection.probe.error ?? "")) {
2410
+ optionalKey = false;
2411
+ notice = key ? "The endpoint rejected that key. Try again, or Escape to go back." : "This endpoint needs an API key.";
2412
+ step = "key";
2413
+ } else {
2414
+ notice = `Could not connect: ${connection.probe.error ?? "no reply"}. Check the URL and that the server is running.`;
2415
+ step = "url";
2416
+ }
2417
+ continue;
2418
+ }
2419
+ if (!connection.existing && !askedKey && connection.runtime.auth === "api-key" && connection.runtime.tier !== "local-native") {
2420
+ optionalKey = true;
2421
+ step = "key";
2422
+ continue;
2423
+ }
2424
+ if (connection.models.length === 0) {
2425
+ notice = "The endpoint offered no chat models. Load a model and retry. Servers without model discovery can use Settings \u2192 Targets & Auth.";
2426
+ step = "url";
2427
+ continue;
2428
+ }
2429
+ const preferred = connection.existing?.id === initial.chat.target ? initial.chat.model : connection.target.defaultModel;
2430
+ model = preferred && connection.models.includes(preferred) ? preferred : connection.models[0] ?? "";
2431
+ step = connection.models.length === 1 ? "save" : "model";
2432
+ continue;
2433
+ }
2434
+ if (!connection) {
2435
+ step = "url";
2436
+ continue;
2437
+ }
2438
+ if (step === "model") {
2439
+ presenter.note(`Connected: ${url} (${connection.runtime.displayName})`);
2440
+ model = await prompts.choose("Choose the model for Clio", connection.models, model, true);
2441
+ if (!connection.models.includes(model)) {
2442
+ notice = "Choose a model from the endpoint's live list.";
2443
+ continue;
2444
+ }
2445
+ step = "save";
2446
+ continue;
2447
+ }
2448
+ presenter.fields([
2449
+ ["Endpoint", url],
2450
+ ["Model", model],
2451
+ ["Connection", "live model discovery passed"]
2452
+ ]);
2453
+ presenter.note(
2454
+ first ? "Ready with recommended defaults: workspace edits, approval for unrecognized commands, one worker, $5 tracked session budget." : "Use this model for chat. Your other settings and role assignments stay in place."
2455
+ );
2456
+ const choice = await prompts.choose("Ready to connect", ["Connect", "Back"], "Connect");
2457
+ if (choice !== "Connect") throw new ConfigureNavigation("back");
2458
+ const descriptor = structuredClone(connection.target);
2459
+ if (!connection.existing) descriptor.defaultModel = model;
2460
+ if (key) {
2461
+ descriptor.auth = { ...descriptor.auth, apiKeyRef: targetApiKeyRef(descriptor.id, readSettings().targets) };
2462
+ delete descriptor.auth.apiKeyEnvVar;
2463
+ }
2464
+ const apply = (settings) => {
2465
+ const target = settings.targets.find((entry) => entry.id === descriptor.id);
2466
+ if (JSON.stringify(target) !== JSON.stringify(connection?.existing))
2467
+ throw new Error("This target changed during setup. Reopen Quick Connect to keep those changes.");
2468
+ applyTarget(settings, descriptor);
2469
+ setOrchestratorPointer(settings, descriptor, model);
2470
+ if (first && !settings.fleet.default.target) setWorkerDefaultPointer(settings, descriptor, model);
2471
+ };
2472
+ const preview = readSettings();
2473
+ apply(preview);
2474
+ const validated = validateSettings(preview);
2475
+ if (validated.issues.length) throw new SettingsValidationError(validated.issues);
2476
+ initializeClioHome();
2477
+ if (key && descriptor.auth?.apiKeyRef) {
2478
+ const auth = openAuthStorage();
2479
+ auth.setApiKey(descriptor.auth.apiKeyRef, key);
2480
+ if (credentialWriteFailed(auth, "The key was not saved; connection settings were not changed."))
2481
+ throw new Error("The key could not be saved. Check permissions on the credentials file and retry.");
2482
+ printPlaintextCredentialWarning();
2483
+ }
2484
+ updateSettings(apply);
2485
+ presenter.done(`Connected: ${descriptor.id} / ${model}`);
2486
+ presenter.commandAdvice("Start Clio:", "clio-coder");
2487
+ return "connected";
2488
+ } catch (error) {
2489
+ if (!(error instanceof ConfigureNavigation)) {
2490
+ notice = error instanceof Error ? error.message : String(error);
2491
+ step = "url";
2492
+ continue;
2493
+ }
2494
+ if (error.kind === "quit" || step === "url") {
2495
+ presenter.done("Quick Connect cancelled; connection settings not saved.");
2496
+ return error.kind;
2497
+ }
2498
+ step = step === "save" && (connection?.models.length ?? 0) > 1 ? "model" : step === "model" || step === "save" ? askedKey ? "key" : "url" : "url";
2499
+ }
2500
+ }
2501
+ }
2502
+
2006
2503
  // src/cli/configure.ts
2007
2504
  var HELP = `clio-coder configure
2008
2505
 
2009
2506
  Configure model targets and runtime settings for chat and fleet dispatch.
2010
2507
 
2011
2508
  Usage:
2012
- clio-coder configure interactive configuration wizard
2509
+ clio-coder configure Quick Connect, Settings, or Diagnostics
2510
+ clio-coder configure --quick connect an endpoint with recommended defaults
2511
+ clio-coder configure --settings open the complete settings menu
2013
2512
  clio-coder configure --section <name> open one section directly:
2014
2513
  targets, models, chat, fleet,
2015
- permissions, panes, skills, diagnostics
2514
+ permissions, panes, skills, diagnostics, advanced
2016
2515
  Without a terminal this prints the
2017
2516
  section's values and exits.
2018
2517
  clio-coder configure --json emit the effective settings as JSON
2518
+ clio-coder configure --edit edit all user settings in VISUAL/EDITOR;
2519
+ validate and review before saving
2019
2520
  clio-coder configure --interop review detected coding agents as delegation peers
2020
2521
  clio-coder configure --list list target runtimes (user-facing only)
2021
2522
  clio-coder configure --list --all list every registered runtime including aliases
@@ -2060,6 +2561,9 @@ function parseSetupArgs(argv) {
2060
2561
  all: false,
2061
2562
  interop: false,
2062
2563
  json: false,
2564
+ edit: false,
2565
+ quick: false,
2566
+ settings: false,
2063
2567
  force: false,
2064
2568
  gateway: false,
2065
2569
  setOrchestrator: false,
@@ -2082,6 +2586,15 @@ function parseSetupArgs(argv) {
2082
2586
  case "--json":
2083
2587
  out.json = true;
2084
2588
  break;
2589
+ case "--edit":
2590
+ out.edit = true;
2591
+ break;
2592
+ case "--quick":
2593
+ out.quick = true;
2594
+ break;
2595
+ case "--settings":
2596
+ out.settings = true;
2597
+ break;
2085
2598
  case "--section":
2086
2599
  out.section = need();
2087
2600
  break;
@@ -2197,7 +2710,9 @@ function printRuntimeList(includeHidden) {
2197
2710
  const rows = [];
2198
2711
  for (const entry of listProviderSupportEntries(getRuntimeRegistry().list(), { includeHidden })) {
2199
2712
  const runtime = getRuntimeRegistry().get(entry.runtimeId);
2200
- const status = runtime && entry.connectable ? auth.statusForTarget(resolveRuntimeAuthTarget(runtime), { includeFallback: false }) : null;
2713
+ const status = runtime && entry.connectable ? auth.statusForTarget(resolveRuntimeAuthTarget(runtime), {
2714
+ includeFallback: false
2715
+ }) : null;
2201
2716
  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";
2202
2717
  rows.push({
2203
2718
  group: supportGroupLabel(entry.group),
@@ -2292,6 +2807,7 @@ async function runNonInteractive(runtime, args) {
2292
2807
  );
2293
2808
  return 2;
2294
2809
  }
2810
+ initializeClioHome();
2295
2811
  const settings = readSettings();
2296
2812
  const auth = openAuthStorage();
2297
2813
  const support = buildProviderSupportEntry(runtime);
@@ -2323,24 +2839,32 @@ async function runNonInteractive(runtime, args) {
2323
2839
  );
2324
2840
  }
2325
2841
  }
2326
- const authStatus = auth.statusForTarget(resolveRuntimeAuthTarget(runtime), { includeFallback: false });
2842
+ const authStatus = auth.statusForTarget(
2843
+ existing ? resolveAuthTarget(existing, runtime) : resolveRuntimeAuthTarget(runtime),
2844
+ { includeFallback: false }
2845
+ );
2327
2846
  const apiKeyEnv = args.apiKeyEnv ?? existing?.auth?.apiKeyEnvVar;
2328
- const apiKeyRef = runtime.auth === "api-key" && (args.apiKey || existing?.auth?.apiKeyRef || authStatus.source === "stored-api-key") ? runtime.id : void 0;
2847
+ 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;
2329
2848
  const oauthProfile = runtime.auth === "oauth" ? existing?.auth?.oauthProfile ?? runtime.oauthProviderId ?? runtime.id : void 0;
2330
- const seed = buildDescriptor(runtime, args.id, {
2331
- ...url !== void 0 ? { url } : {},
2332
- ...args.model !== void 0 ? { model: args.model } : existing?.defaultModel ? { model: existing.defaultModel } : support.defaultModel ? { model: support.defaultModel } : {},
2333
- ...apiKeyEnv !== void 0 ? { apiKeyEnv } : {},
2334
- ...apiKeyRef !== void 0 ? { apiKeyRef } : {},
2335
- ...oauthProfile !== void 0 ? { oauthProfile } : {},
2336
- gateway: args.gateway || existing?.gateway === true,
2337
- ...args.lifecycle !== void 0 ? { lifecycle: args.lifecycle } : existing?.lifecycle !== void 0 ? { lifecycle: existing.lifecycle } : {},
2338
- ...args.contextWindow !== void 0 ? { contextWindow: args.contextWindow } : {},
2339
- ...args.maxTokens !== void 0 ? { maxTokens: args.maxTokens } : {},
2340
- ...args.reasoning !== void 0 ? { reasoning: args.reasoning } : {},
2341
- ...existing?.lmstudio ? { lmstudio: existing.lmstudio } : {},
2342
- ...existing?.litellm ? { litellm: existing.litellm } : {}
2343
- });
2849
+ const seed = {
2850
+ ...existing,
2851
+ ...buildDescriptor(runtime, args.id, {
2852
+ ...url !== void 0 ? { url } : {},
2853
+ ...args.model !== void 0 ? { model: args.model } : existing?.defaultModel ? { model: existing.defaultModel } : support.defaultModel ? { model: support.defaultModel } : {},
2854
+ ...apiKeyEnv !== void 0 ? { apiKeyEnv } : {},
2855
+ ...apiKeyRef !== void 0 ? { apiKeyRef } : {},
2856
+ ...oauthProfile !== void 0 ? { oauthProfile } : {},
2857
+ gateway: args.gateway || existing?.gateway === true,
2858
+ ...args.lifecycle !== void 0 ? { lifecycle: args.lifecycle } : existing?.lifecycle !== void 0 ? { lifecycle: existing.lifecycle } : {},
2859
+ ...args.contextWindow !== void 0 ? { contextWindow: args.contextWindow } : {},
2860
+ ...args.maxTokens !== void 0 ? { maxTokens: args.maxTokens } : {},
2861
+ ...args.reasoning !== void 0 ? { reasoning: args.reasoning } : {},
2862
+ ...existing?.lmstudio ? { lmstudio: existing.lmstudio } : {},
2863
+ ...existing?.litellm ? { litellm: existing.litellm } : {}
2864
+ })
2865
+ };
2866
+ seed.capabilities = { ...existing?.capabilities, ...seed.capabilities };
2867
+ if (seed.auth) seed.auth = { ...existing?.auth, ...seed.auth };
2344
2868
  const inventory = await resolveSupportedWireModels(runtime, seed, existing, args.apiKey);
2345
2869
  const wireModels = inventory.models;
2346
2870
  const model = args.model ?? existing?.defaultModel ?? (inventory.source === "probe" ? wireModels[0] : support.defaultModel) ?? (support.modelSource === "catalog" ? void 0 : wireModels[0]);
@@ -2350,20 +2874,25 @@ async function runNonInteractive(runtime, args) {
2350
2874
  }
2351
2875
  if (!validateResolvedModel(runtime, seed, model, args.force, inventory)) return 2;
2352
2876
  if (!validateContextWindowOverride(runtime, model, args.contextWindow, args.force)) return 2;
2353
- const descriptor = buildDescriptor(runtime, args.id, {
2354
- ...url !== void 0 ? { url } : {},
2355
- ...model ? { model } : {},
2356
- ...apiKeyEnv !== void 0 ? { apiKeyEnv } : {},
2357
- ...apiKeyRef !== void 0 ? { apiKeyRef } : {},
2358
- ...oauthProfile !== void 0 ? { oauthProfile } : {},
2359
- gateway: args.gateway || existing?.gateway === true,
2360
- ...args.lifecycle !== void 0 ? { lifecycle: args.lifecycle } : existing?.lifecycle !== void 0 ? { lifecycle: existing.lifecycle } : {},
2361
- ...args.contextWindow !== void 0 ? { contextWindow: args.contextWindow } : {},
2362
- ...args.maxTokens !== void 0 ? { maxTokens: args.maxTokens } : {},
2363
- ...args.reasoning !== void 0 ? { reasoning: args.reasoning } : {},
2364
- ...existing?.lmstudio ? { lmstudio: existing.lmstudio } : {},
2365
- ...existing?.litellm ? { litellm: existing.litellm } : {}
2366
- });
2877
+ const descriptor = {
2878
+ ...existing,
2879
+ ...buildDescriptor(runtime, args.id, {
2880
+ ...url !== void 0 ? { url } : {},
2881
+ ...model ? { model } : {},
2882
+ ...apiKeyEnv !== void 0 ? { apiKeyEnv } : {},
2883
+ ...apiKeyRef !== void 0 ? { apiKeyRef } : {},
2884
+ ...oauthProfile !== void 0 ? { oauthProfile } : {},
2885
+ gateway: args.gateway || existing?.gateway === true,
2886
+ ...args.lifecycle !== void 0 ? { lifecycle: args.lifecycle } : existing?.lifecycle !== void 0 ? { lifecycle: existing.lifecycle } : {},
2887
+ ...args.contextWindow !== void 0 ? { contextWindow: args.contextWindow } : {},
2888
+ ...args.maxTokens !== void 0 ? { maxTokens: args.maxTokens } : {},
2889
+ ...args.reasoning !== void 0 ? { reasoning: args.reasoning } : {},
2890
+ ...existing?.lmstudio ? { lmstudio: existing.lmstudio } : {},
2891
+ ...existing?.litellm ? { litellm: existing.litellm } : {}
2892
+ })
2893
+ };
2894
+ descriptor.capabilities = { ...existing?.capabilities, ...descriptor.capabilities };
2895
+ if (descriptor.auth) descriptor.auth = { ...existing?.auth, ...descriptor.auth };
2367
2896
  const setOrchestrator = args.setOrchestrator || args.orchestratorModel !== void 0;
2368
2897
  const setBackground = args.setBackground || args.backgroundModel !== void 0;
2369
2898
  if ((setOrchestrator || setBackground) && !isOrchestratorEligibleRuntime(runtime)) {
@@ -2378,8 +2907,8 @@ async function runNonInteractive(runtime, args) {
2378
2907
  printError(error instanceof Error ? error.message : String(error));
2379
2908
  return 1;
2380
2909
  }
2381
- if (args.apiKey) {
2382
- auth.setApiKey(runtime.id, args.apiKey);
2910
+ if (args.apiKey && apiKeyRef) {
2911
+ auth.setApiKey(apiKeyRef, args.apiKey);
2383
2912
  if (credentialWriteFailed(auth, `credential for ${runtime.id} was not stored; target '${descriptor.id}' not saved`))
2384
2913
  return 1;
2385
2914
  printPlaintextCredentialWarning();
@@ -2404,12 +2933,14 @@ async function runNonInteractive(runtime, args) {
2404
2933
  };
2405
2934
  applyConfiguration(settings);
2406
2935
  updateSettings(applyConfiguration);
2407
- const probe = await runtimeProbe(runtime, descriptor);
2936
+ const probe = await runtimeProbe(runtime, descriptor, args.apiKey);
2408
2937
  if (probe?.ok && probe.models) {
2409
2938
  recordTargetModelSnapshot(descriptor, probe.models, probe.modelLabels ? { modelLabels: probe.modelLabels } : {});
2410
2939
  }
2411
2940
  printSummary(settings, descriptor, probe);
2412
- if (runtime.auth === "oauth" && !auth.statusForTarget(resolveRuntimeAuthTarget(runtime), { includeFallback: false }).available) {
2941
+ if (runtime.auth === "oauth" && !auth.statusForTarget(existing ? resolveAuthTarget(existing, runtime) : resolveRuntimeAuthTarget(runtime), {
2942
+ includeFallback: false
2943
+ }).available) {
2413
2944
  process.stdout.write(
2414
2945
  `note: authenticate ${runtime.id} with \`clio-coder auth login ${runtime.id}\` before using this target
2415
2946
  `
@@ -2541,7 +3072,7 @@ async function runTargetSetupInteractive(rl, runtime, defaults) {
2541
3072
  let support = buildProviderSupportEntry(runtime);
2542
3073
  const initialRuntimeId = runtime.id;
2543
3074
  const existingForRuntime = configuredTargetsForRuntime(settings, initialRuntimeId);
2544
- const existing = (defaults.id ? settings.targets.find((entry) => entry.id === defaults.id && entry.runtime === initialRuntimeId) : null) ?? existingForRuntime[0] ?? null;
3075
+ const existing = defaults.id ? settings.targets.find((entry) => entry.id === defaults.id && entry.runtime === initialRuntimeId) ?? null : null;
2545
3076
  if (existingForRuntime.length > 0) {
2546
3077
  process.stdout.write(`
2547
3078
  Existing targets for ${runtime.id}:
@@ -2554,7 +3085,7 @@ Existing targets for ${runtime.id}:
2554
3085
  process.stdout.write(`
2555
3086
  Selected runtime: ${runtime.id} (${support.summary})
2556
3087
  `);
2557
- process.stdout.write(`Credentials: ${describeAuthStatus(runtime)}
3088
+ process.stdout.write(`Credentials: ${describeAuthStatus(runtime, existing ?? void 0)}
2558
3089
  `);
2559
3090
  if (support.modelHints.length > 0) {
2560
3091
  process.stdout.write(`Known models: ${describeRuntimeModels(support, 4)}
@@ -2601,10 +3132,13 @@ Selected runtime: ${runtime.id} (${support.summary})
2601
3132
  let apiKeyLiteral;
2602
3133
  let apiKeyRef = existing?.auth?.apiKeyRef;
2603
3134
  let oauthProfile = runtime.auth === "oauth" ? existing?.auth?.oauthProfile ?? runtime.oauthProviderId ?? runtime.id : void 0;
2604
- const authStatus = auth.statusForTarget(resolveRuntimeAuthTarget(runtime), { includeFallback: false });
3135
+ const authStatus = auth.statusForTarget(
3136
+ existing ? resolveAuthTarget(existing, runtime) : resolveRuntimeAuthTarget(runtime),
3137
+ { includeFallback: false }
3138
+ );
2605
3139
  if (runtime.auth === "api-key") {
2606
3140
  const needsCredential = targetRequiresAuth({ id: targetId, runtime: runtime.id }, runtime);
2607
- const defaultSource = authStatus.source === "stored-api-key" ? "keep" : authStatus.source === "environment" || existing?.auth?.apiKeyEnvVar || needsCredential ? "env" : "skip";
3141
+ const defaultSource = existing?.auth?.apiKeyRef || authStatus.source === "stored-api-key" ? "keep" : authStatus.source === "environment" || existing?.auth?.apiKeyEnvVar || needsCredential ? "env" : "skip";
2608
3142
  process.stdout.write(
2609
3143
  "\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"
2610
3144
  );
@@ -2612,10 +3146,10 @@ Selected runtime: ${runtime.id} (${support.summary})
2612
3146
  if (choice === null) return 0;
2613
3147
  const normalized = choice.trim().toLowerCase();
2614
3148
  if (normalized === "stored") {
2615
- const literal = await ask(rl, "API key literal (stored in credentials.yaml, mode 0600)");
3149
+ const literal = await rl.text("API key literal (stored in credentials.yaml, mode 0600)", "", true);
2616
3150
  if (literal !== null && literal.length > 0) {
2617
3151
  apiKeyLiteral = literal;
2618
- apiKeyRef = runtime.id;
3152
+ apiKeyRef = targetApiKeyRef(targetId, settings.targets);
2619
3153
  }
2620
3154
  } else if (normalized === "env") {
2621
3155
  const envDefault = defaults.apiKeyEnv ?? existing?.auth?.apiKeyEnvVar ?? runtime.credentialsEnvVar ?? "";
@@ -2637,7 +3171,7 @@ Selected runtime: ${runtime.id} (${support.summary})
2637
3171
  const connected = await loginOAuthRuntime(rl, runtime);
2638
3172
  if (!connected) return 1;
2639
3173
  }
2640
- oauthProfile = runtime.oauthProviderId ?? runtime.id;
3174
+ oauthProfile = existing?.auth?.oauthProfile ?? runtime.oauthProviderId ?? runtime.id;
2641
3175
  }
2642
3176
  let model = defaults.model;
2643
3177
  let inventory = { models: [], source: "none" };
@@ -2654,8 +3188,9 @@ Selected runtime: ${runtime.id} (${support.summary})
2654
3188
  ...existing?.lmstudio ? { lmstudio: existing.lmstudio } : {},
2655
3189
  ...existing?.litellm ? { litellm: existing.litellm } : {}
2656
3190
  });
3191
+ if (existing?.auth?.headers) tentative.auth = { ...tentative.auth, headers: existing.auth.headers };
2657
3192
  if (runtime.kind === "http" || runtime.externalAgentLoop?.modelCatalog === "live-authoritative") {
2658
- inventory = await resolveSupportedWireModels(runtime, tentative, existing ?? void 0);
3193
+ inventory = await resolveSupportedWireModels(runtime, tentative, existing ?? void 0, apiKeyLiteral);
2659
3194
  }
2660
3195
  const wireModels = inventory.models;
2661
3196
  const catalogOrdered = support.modelSource === "catalog";
@@ -2721,7 +3256,7 @@ Selected runtime: ${runtime.id} (${support.summary})
2721
3256
  if (!validateContextWindowOverride(runtime, model, contextWindowChoice, defaults.force)) return 2;
2722
3257
  const gatewayDefault = defaults.gateway || existing?.gateway === true;
2723
3258
  const gatewayAnswer = gatewayDefault ? true : await askYesNo(rl, "Mark as gateway?", false);
2724
- const descriptor = buildDescriptor(runtime, targetId, {
3259
+ const configured = buildDescriptor(runtime, targetId, {
2725
3260
  ...url !== void 0 ? { url } : {},
2726
3261
  ...model !== void 0 ? { model } : {},
2727
3262
  ...apiKeyEnv !== void 0 ? { apiKeyEnv } : {},
@@ -2735,19 +3270,20 @@ Selected runtime: ${runtime.id} (${support.summary})
2735
3270
  ...existing?.lmstudio ? { lmstudio: existing.lmstudio } : {},
2736
3271
  ...existing?.litellm ? { litellm: existing.litellm } : {}
2737
3272
  });
3273
+ const descriptor = {
3274
+ ...existing,
3275
+ ...configured,
3276
+ capabilities: { ...existing?.capabilities, ...configured.capabilities }
3277
+ };
3278
+ if (existing?.auth?.headers) descriptor.auth = { ...configured.auth, headers: existing.auth.headers };
3279
+ else if (!configured.auth) delete descriptor.auth;
2738
3280
  try {
2739
3281
  assertOrchestratorReplacementEligible(settings, descriptor);
2740
3282
  } catch (error) {
2741
3283
  printError(error instanceof Error ? error.message : String(error));
2742
3284
  return 1;
2743
3285
  }
2744
- if (apiKeyLiteral) {
2745
- auth.setApiKey(runtime.id, apiKeyLiteral);
2746
- if (credentialWriteFailed(auth, `credential for ${runtime.id} was not stored; target '${descriptor.id}' not saved`))
2747
- return 1;
2748
- printPlaintextCredentialWarning();
2749
- }
2750
- const probe = await runtimeProbe(runtime, descriptor);
3286
+ const probe = await runtimeProbe(runtime, descriptor, apiKeyLiteral);
2751
3287
  if (probe?.ok && probe.models) recordTargetModelSnapshot(descriptor, probe.models);
2752
3288
  if (probe) {
2753
3289
  process.stdout.write("\n");
@@ -2785,6 +3321,12 @@ Selected runtime: ${runtime.id} (${support.summary})
2785
3321
  settings.context.memory.target === targetId ? settings.context.memory.model ?? model : model
2786
3322
  ) : void 0;
2787
3323
  if (backgroundModel === null) return 0;
3324
+ if (apiKeyLiteral && apiKeyRef) {
3325
+ auth.setApiKey(apiKeyRef, apiKeyLiteral);
3326
+ if (credentialWriteFailed(auth, `credential for ${runtime.id} was not stored; target '${descriptor.id}' not saved`))
3327
+ return 1;
3328
+ printPlaintextCredentialWarning();
3329
+ }
2788
3330
  const applyWizardChoice = (target) => {
2789
3331
  applyTarget(target, descriptor);
2790
3332
  if (setOrchestrator) setOrchestratorPointer(target, descriptor, orchestratorModel);
@@ -2833,11 +3375,16 @@ function runTargetRename(oldId, newId) {
2833
3375
  for (const profile of Object.values(settings.fleet.profiles)) {
2834
3376
  if (profile.target === oldId) profile.target = newId;
2835
3377
  }
2836
- settings.chat.modelPicker.cycleSet = settings.chat.modelPicker.cycleSet.map((entry) => {
3378
+ for (const roster of Object.values(settings.fleet.rosters)) {
3379
+ for (const member of roster.members) if (member.target === oldId) member.target = newId;
3380
+ }
3381
+ const renameRef = (entry) => {
2837
3382
  const [head, ...rest] = entry.split("/");
2838
3383
  if (head !== oldId) return entry;
2839
3384
  return rest.length === 0 ? newId : `${newId}/${rest.join("/")}`;
2840
- });
3385
+ };
3386
+ settings.chat.modelPicker.cycleSet = settings.chat.modelPicker.cycleSet.map(renameRef);
3387
+ settings.chat.modelPicker.favorites = settings.chat.modelPicker.favorites.map(renameRef);
2841
3388
  });
2842
3389
  printOk(`renamed ${oldId} to ${newId}`);
2843
3390
  return 0;
@@ -2849,27 +3396,42 @@ async function askInteger(io, label, current, apply, min = 0) {
2849
3396
  const answer = await ask(io.rl, label, String(current));
2850
3397
  if (answer === null) return;
2851
3398
  const parsed = Number(answer);
2852
- if (!Number.isFinite(parsed) || parsed < min) {
2853
- io.out.write(` ${label} must be a number of at least ${min}; left at ${current}
3399
+ if (!Number.isSafeInteger(parsed) || parsed < min) {
3400
+ io.warn(`${label} must be a whole number of at least ${min}; left at ${current}
2854
3401
  `);
2855
3402
  return;
2856
3403
  }
2857
- const value = Math.floor(parsed);
3404
+ const value = parsed;
2858
3405
  apply(value);
2859
3406
  io.ok(`${label} set to ${value}`);
2860
3407
  }
2861
3408
  async function askChoice(io, label, allowed, current, apply) {
2862
- const answer = await ask(io.rl, `${label} [${allowed.join("|")}]`, current);
3409
+ const answer = await io.rl.choose(label, allowed, current);
2863
3410
  if (answer === null) return;
2864
3411
  const value = answer.trim().toLowerCase();
2865
3412
  if (!allowed.includes(value)) {
2866
- io.out.write(` ${label} must be one of ${allowed.join(", ")}; left at ${current}
3413
+ io.warn(`${label} must be one of ${allowed.join(", ")}; left at ${current}
2867
3414
  `);
2868
3415
  return;
2869
3416
  }
2870
3417
  apply(value);
2871
3418
  io.ok(`${label} set to ${value}`);
2872
3419
  }
3420
+ async function runTargetWizard(io, options) {
3421
+ const before = readSettings().targets;
3422
+ io.rl.clearScreen();
3423
+ const code = await runOnboardingWizard(io.streams, options);
3424
+ if (code === 130) throw new ConfigureNavigation("quit");
3425
+ if (code !== 0) {
3426
+ await io.rl.text("Press Enter to return");
3427
+ io.warn("Target settings were not saved.");
3428
+ return;
3429
+ }
3430
+ const changed = readSettings().targets.find(
3431
+ (target) => JSON.stringify(target) !== JSON.stringify(before.find((entry) => entry.id === target.id))
3432
+ );
3433
+ if (changed) io.ok(`Target ${changed.id} saved`);
3434
+ }
2873
3435
  var SECTIONS = [
2874
3436
  {
2875
3437
  id: "targets",
@@ -2900,6 +3462,10 @@ var SECTIONS = [
2900
3462
  label: "Add a target",
2901
3463
  hint: "register a provider endpoint",
2902
3464
  run: async (io) => {
3465
+ if (canRunOnboarding(io.streams)) {
3466
+ await runTargetWizard(io, { mode: readSettings().targets.length === 0 ? "first" : "add" });
3467
+ return;
3468
+ }
2903
3469
  const runtime = await pickRuntimeViaCategory(io.rl);
2904
3470
  if (runtime) await runTargetSetupInteractive(io.rl, runtime, emptyArgs());
2905
3471
  }
@@ -2924,17 +3490,59 @@ var SECTIONS = [
2924
3490
  const settings = readSettings();
2925
3491
  const ids = settings.targets.map((target) => target.id);
2926
3492
  if (ids.length === 0) {
2927
- io.out.write(" No targets to remove.\n");
3493
+ io.warn("No targets to remove.");
2928
3494
  return;
2929
3495
  }
2930
3496
  io.out.write(` Registered: ${ids.join(", ")}
2931
3497
  `);
2932
- const chosen = await ask(io.rl, "Target id to remove");
3498
+ const chosen = await io.rl.choose("Target to remove", ids, ids[0] ?? "");
2933
3499
  if (chosen === null || !ids.includes(chosen)) return;
2934
3500
  if (await askYesNo(io.rl, `Remove target '${chosen}'?`, false)) {
2935
- runTargetRemove(chosen);
3501
+ if (runTargetRemove(chosen) === 0) io.ok(`Removed target ${chosen}`);
3502
+ else io.warn(`Could not remove target ${chosen}`);
2936
3503
  }
2937
3504
  }
3505
+ },
3506
+ {
3507
+ label: "Edit a target",
3508
+ hint: "endpoint, credentials, model, capabilities",
3509
+ run: async (io) => {
3510
+ const targets = readSettings().targets;
3511
+ if (targets.length === 0) return;
3512
+ const id = await io.rl.choose(
3513
+ "Target to edit",
3514
+ targets.map((target2) => target2.id),
3515
+ targets[0]?.id ?? ""
3516
+ );
3517
+ const target = targets.find((entry) => entry.id === id);
3518
+ if (!target) return;
3519
+ if (canRunOnboarding(io.streams)) {
3520
+ await runTargetWizard(io, { mode: "edit", target });
3521
+ } else {
3522
+ const runtime = getRuntimeRegistry().get(target.runtime);
3523
+ if (runtime) await runTargetSetupInteractive(io.rl, runtime, { ...emptyArgs(), id });
3524
+ }
3525
+ }
3526
+ },
3527
+ {
3528
+ label: "Rename a target",
3529
+ run: async (io) => {
3530
+ const ids = readSettings().targets.map((target) => target.id);
3531
+ if (ids.length === 0) return;
3532
+ const id = await io.rl.choose("Target to rename", ids, ids[0] ?? "");
3533
+ const name = await ask(io.rl, "New target id", id);
3534
+ if (!name || name === id) return;
3535
+ if (ids.includes(name)) {
3536
+ io.warn(`Target id already exists: ${name}`);
3537
+ return;
3538
+ }
3539
+ if (runTargetRename(id, name) === 0) io.ok(`Renamed ${id} to ${name}`);
3540
+ else io.warn(`Could not rename target ${id}`);
3541
+ }
3542
+ },
3543
+ {
3544
+ label: "Set the background memory target",
3545
+ run: async (io) => assignTarget(io, "memory")
2938
3546
  }
2939
3547
  ]
2940
3548
  },
@@ -2950,7 +3558,7 @@ var SECTIONS = [
2950
3558
  ["Chat thinking", settings.chat.thinkingLevel],
2951
3559
  ["Fleet thinking", settings.fleet.default.thinkingLevel],
2952
3560
  ["Favorites", listOr(settings.chat.modelPicker.favorites)],
2953
- ["Cycle set (Alt+J/K)", listOr(settings.chat.modelPicker.cycleSet)]
3561
+ ["Model cycle set", listOr(settings.chat.modelPicker.cycleSet)]
2954
3562
  ];
2955
3563
  },
2956
3564
  actions: [
@@ -2992,8 +3600,10 @@ var SECTIONS = [
2992
3600
  readSettings().chat.model ?? ""
2993
3601
  );
2994
3602
  if (model === null) return;
2995
- updateSettings((draft) => {
2996
- draft.chat.model = model.length > 0 ? model : null;
3603
+ updateSavedSettingsDocument((saved) => {
3604
+ const document = saved;
3605
+ document.chat = { ...document.chat, model: model.length > 0 ? model : null };
3606
+ return document;
2997
3607
  });
2998
3608
  io.ok(model.length > 0 ? `Chat default model set to ${model}` : "Chat default model cleared");
2999
3609
  }
@@ -3011,7 +3621,7 @@ var SECTIONS = [
3011
3621
  },
3012
3622
  {
3013
3623
  label: "Cycle set",
3014
- hint: "comma-separated, Alt+J/K walks it",
3624
+ hint: "comma-separated models for the scoped cycle actions",
3015
3625
  run: async (io) => {
3016
3626
  await askList(io, "Cycle set", readSettings().chat.modelPicker.cycleSet, (values) => {
3017
3627
  updateSettings((draft) => {
@@ -3149,7 +3759,7 @@ var SECTIONS = [
3149
3759
  }
3150
3760
  const parsed = Number(answer);
3151
3761
  if (!Number.isFinite(parsed) || parsed < 1) {
3152
- io.out.write(` Concurrency limit must be auto or at least 1; left at ${current}
3762
+ io.warn(`Concurrency limit must be auto or at least 1; left at ${current}
3153
3763
  `);
3154
3764
  return;
3155
3765
  }
@@ -3194,7 +3804,7 @@ var SECTIONS = [
3194
3804
  if (answer === null) return;
3195
3805
  const parsed = Number(answer);
3196
3806
  if (!Number.isFinite(parsed) || parsed < 1) {
3197
- io.out.write(` Run timeout must be at least 1 second; left at ${current}s
3807
+ io.warn(`Run timeout must be at least 1 second; left at ${current}s
3198
3808
  `);
3199
3809
  return;
3200
3810
  }
@@ -3224,22 +3834,16 @@ var SECTIONS = [
3224
3834
  actions: [
3225
3835
  {
3226
3836
  label: "Autonomy level",
3227
- hint: "interactive | assisted | auto-edit | full",
3837
+ hint: AUTONOMY_LEVELS.join(" | "),
3228
3838
  run: async (io) => {
3229
3839
  io.out.write(
3230
- " interactive prompts for everything, assisted auto-reads and confirms writes,\n auto-edit confirms only bash, full runs unattended.\n"
3231
- );
3232
- await askChoice(
3233
- io,
3234
- "Autonomy level",
3235
- ["interactive", "assisted", "auto-edit", "full"],
3236
- readSettings().safety.autonomy,
3237
- (value) => {
3238
- updateSettings((draft) => {
3239
- draft.safety.autonomy = value;
3240
- });
3241
- }
3840
+ " read-only inspects; suggest asks before changes; auto-edit permits workspace\n edits; full-auto skips autonomy prompts. Safety rules still apply at every level.\n"
3242
3841
  );
3842
+ await askChoice(io, "Autonomy level", AUTONOMY_LEVELS, readSettings().safety.autonomy, (value) => {
3843
+ updateSettings((draft) => {
3844
+ draft.safety.autonomy = value;
3845
+ });
3846
+ });
3243
3847
  }
3244
3848
  },
3245
3849
  {
@@ -3268,7 +3872,7 @@ var SECTIONS = [
3268
3872
  if (answer === null) return;
3269
3873
  const parsed = Number(answer);
3270
3874
  if (!Number.isFinite(parsed) || parsed <= 0) {
3271
- io.out.write(` Session cost limit must be greater than 0; left at $${current}
3875
+ io.warn(`Session cost limit must be greater than 0; left at $${current}
3272
3876
  `);
3273
3877
  return;
3274
3878
  }
@@ -3319,7 +3923,7 @@ var SECTIONS = [
3319
3923
  ["Panes capability", settings.interface.panes.enabled],
3320
3924
  ["Startup layout", settings.interface.panes.layout],
3321
3925
  ["TUI mode", settings.interface.mode],
3322
- ["Output detail", settings.interface.outputDetail],
3926
+ ["Output style", settings.interface.outputDetail],
3323
3927
  ["Desktop notifications", onOff(settings.interface.desktopNotifications)],
3324
3928
  ["Git commit attribution", onOff(settings.integrations.git.commitAttribution)]
3325
3929
  ];
@@ -3371,13 +3975,13 @@ var SECTIONS = [
3371
3975
  }
3372
3976
  },
3373
3977
  {
3374
- label: "Output detail",
3375
- hint: "minimal | default | verbose",
3978
+ label: "Output style",
3979
+ hint: "compact | standard | detailed",
3376
3980
  run: async (io) => {
3377
3981
  await askChoice(
3378
3982
  io,
3379
- "Output detail",
3380
- ["minimal", "default", "verbose"],
3983
+ "Output style",
3984
+ ["compact", "standard", "detailed"],
3381
3985
  readSettings().interface.outputDetail,
3382
3986
  (value) => {
3383
3987
  updateSettings((draft) => {
@@ -3489,23 +4093,44 @@ var SECTIONS = [
3489
4093
  {
3490
4094
  label: "Run doctor",
3491
4095
  hint: "read-only health check",
3492
- run: async () => {
3493
- const { runDoctorCommand } = await import("./doctor-N3LCM2LG.js");
4096
+ run: async (io) => {
4097
+ const { runDoctorCommand } = await import("./doctor-EQYJOGUG.js");
3494
4098
  await runDoctorCommand([]);
4099
+ await io.rl.text("Press Enter to return");
3495
4100
  }
3496
4101
  },
3497
4102
  {
3498
4103
  label: "Show raw settings.yaml",
3499
4104
  run: async (io) => {
3500
4105
  const file = settingsPath();
3501
- if (!existsSync(file)) {
4106
+ if (!existsSync2(file)) {
3502
4107
  io.out.write(" settings.yaml does not exist yet.\n");
3503
4108
  return;
3504
4109
  }
3505
4110
  io.out.write(`
3506
4111
  --- ${shortenPath(file)} ---
3507
- ${readFileSync(file, "utf8")}--- end ---
4112
+ ${readFileSync2(file, "utf8")}--- end ---
3508
4113
  `);
4114
+ await io.rl.text("Press Enter to return");
4115
+ }
4116
+ }
4117
+ ]
4118
+ },
4119
+ {
4120
+ id: "advanced",
4121
+ title: "All Settings",
4122
+ summary: "validated editor for every setting",
4123
+ aliases: ["all", "settings"],
4124
+ fields: () => [
4125
+ ["Settings file", shortenPath(settingsPath())],
4126
+ ["Reference", "clio-coder docs configuration-reference"]
4127
+ ],
4128
+ actions: [
4129
+ {
4130
+ label: "Edit all settings",
4131
+ hint: "VISUAL / EDITOR; validate before saving",
4132
+ run: async (io) => {
4133
+ if (await editSettings(io.rl)) io.ok("Settings saved; previous file kept at settings.yaml.bak");
3509
4134
  }
3510
4135
  }
3511
4136
  ]
@@ -3519,6 +4144,9 @@ function emptyArgs() {
3519
4144
  all: false,
3520
4145
  interop: false,
3521
4146
  json: false,
4147
+ edit: false,
4148
+ quick: false,
4149
+ settings: false,
3522
4150
  force: false,
3523
4151
  gateway: false,
3524
4152
  setOrchestrator: false,
@@ -3535,39 +4163,47 @@ async function askList(io, label, current, apply) {
3535
4163
  }
3536
4164
  async function assignTarget(io, role) {
3537
4165
  const settings = readSettings();
3538
- const ids = settings.targets.map((target2) => target2.id);
4166
+ const ids = settings.targets.filter((target2) => {
4167
+ const runtime = getRuntimeRegistry().get(target2.runtime);
4168
+ return role === "fleet" || runtime !== null && isOrchestratorEligibleRuntime(runtime);
4169
+ }).map((target2) => target2.id);
3539
4170
  if (ids.length === 0) {
3540
- io.out.write(" No targets registered yet. Add one first.\n");
4171
+ io.warn("No eligible targets registered yet. Add one first.");
3541
4172
  return;
3542
4173
  }
3543
4174
  io.out.write(` Registered: ${ids.join(", ")}
3544
4175
  `);
3545
- const currentTarget = role === "chat" ? settings.chat.target : settings.fleet.default.target;
3546
- const chosen = await ask(io.rl, `${role === "chat" ? "Chat" : "Fleet"} target id`, currentTarget ?? ids[0] ?? "");
4176
+ const currentTarget = role === "chat" ? settings.chat.target : role === "fleet" ? settings.fleet.default.target : settings.context.memory.target;
4177
+ const label = role === "chat" ? "Chat" : role === "fleet" ? "Fleet" : "Background memory";
4178
+ const chosen = await io.rl.choose(`${label} target`, ids, currentTarget ?? ids[0] ?? "");
3547
4179
  if (chosen === null) return;
3548
4180
  if (!ids.includes(chosen)) {
3549
- io.out.write(` ${chosen} is not a registered target; nothing changed.
3550
- `);
4181
+ io.warn(`${chosen} is not a registered target; nothing changed.`);
3551
4182
  return;
3552
4183
  }
3553
4184
  const target = settings.targets.find((entry) => entry.id === chosen);
3554
- const model = await ask(io.rl, "Model (blank for the target default)", target?.defaultModel ?? "");
4185
+ const model = await ask(io.rl, `Model override (blank uses ${target?.defaultModel ?? "the target default"})`, "");
3555
4186
  if (model === null) return;
3556
4187
  updateSettings((draft) => {
3557
4188
  if (role === "chat") {
3558
4189
  draft.chat.target = chosen;
3559
4190
  draft.chat.model = model.length > 0 ? model : null;
3560
- } else {
4191
+ } else if (role === "fleet") {
3561
4192
  draft.fleet.default.target = chosen;
3562
4193
  draft.fleet.default.model = model.length > 0 ? model : null;
4194
+ } else {
4195
+ draft.context.memory.target = chosen;
4196
+ draft.context.memory.model = model.length > 0 ? model : null;
3563
4197
  }
3564
4198
  });
3565
- io.ok(`${role === "chat" ? "Chat" : "Fleet"} target set to ${chosen}`);
4199
+ io.ok(`${label} target set to ${chosen}`);
3566
4200
  }
3567
- async function pickEntry(rl, io, entries, backLabel, plain) {
4201
+ async function pickEntry(rl, io, entries, backLabel, plain, initialIndex = 0) {
3568
4202
  const out = io.out;
3569
4203
  if (canSelect(io.in, out)) {
3570
4204
  const result = await promptSelect({
4205
+ initialIndex,
4206
+ clearOnExit: true,
3571
4207
  choices: entries.map((entry, index2) => ({
3572
4208
  value: index2,
3573
4209
  label: entry.label,
@@ -3608,40 +4244,98 @@ function renderSection(spec, out) {
3608
4244
  return presenter;
3609
4245
  }
3610
4246
  async function runSection(rl, streams, spec, backLabel) {
4247
+ let selected = 0;
4248
+ let notice;
3611
4249
  for (; ; ) {
4250
+ rl.clearScreen();
3612
4251
  const presenter = renderSection(spec, streams.out);
4252
+ if (notice) {
4253
+ if (notice.warning) presenter.warn(notice.text);
4254
+ else presenter.completedStep(notice.text);
4255
+ notice = void 0;
4256
+ }
3613
4257
  const io = {
3614
4258
  rl,
3615
4259
  out: streams.out,
3616
4260
  streams,
3617
4261
  ok: (text) => {
3618
- presenter.completedStep(text);
4262
+ notice = { text, warning: false };
4263
+ },
4264
+ warn: (text) => {
4265
+ notice = { text: text.trim(), warning: true };
3619
4266
  }
3620
4267
  };
3621
4268
  presenter.blank();
3622
- const choice = await pickEntry(rl, streams, spec.actions, backLabel, presenter.isPlain());
4269
+ const choice = await pickEntry(rl, streams, spec.actions, backLabel, presenter.isPlain(), selected);
3623
4270
  if (choice.kind !== "index") return choice.kind;
3624
- const action = spec.actions[choice.index];
3625
- if (action !== void 0) await action.run(io);
4271
+ selected = choice.index;
4272
+ const action = spec.actions[selected];
4273
+ try {
4274
+ if (action !== void 0) await action.run(io);
4275
+ } catch (error) {
4276
+ if (error instanceof ConfigureNavigation) {
4277
+ if (error.kind === "quit") return "quit";
4278
+ } else
4279
+ notice = { text: `Change not saved: ${error instanceof Error ? error.message : String(error)}`, warning: true };
4280
+ }
3626
4281
  }
3627
4282
  }
3628
- async function runConfigSectionsMenu(rl, streams) {
4283
+ async function runConfigSectionsMenu(rl, streams, backLabel = "quit") {
4284
+ let selected = 0;
3629
4285
  for (; ; ) {
4286
+ rl.clearScreen();
3630
4287
  const presenter = createLifecyclePresenter({ stream: streams.out });
3631
- presenter.header("Clio Coder Configuration", "configure");
4288
+ presenter.header("Clio Coder Settings", "configure");
3632
4289
  presenter.note(`Source: ${shortenPath(settingsPath())}`);
3633
4290
  presenter.blank();
3634
4291
  const choice = await pickEntry(
3635
4292
  rl,
3636
4293
  streams,
3637
4294
  SECTIONS.map((section) => ({ label: section.title, hint: section.summary })),
3638
- "quit",
3639
- presenter.isPlain()
4295
+ backLabel,
4296
+ presenter.isPlain(),
4297
+ selected
3640
4298
  );
3641
- if (choice.kind !== "index") return 0;
3642
- const spec = SECTIONS[choice.index];
4299
+ if (choice.kind !== "index") return choice.kind;
4300
+ selected = choice.index;
4301
+ const spec = SECTIONS[selected];
3643
4302
  if (spec === void 0) continue;
3644
- if (await runSection(rl, streams, spec, "back") === "quit") return 0;
4303
+ if (await runSection(rl, streams, spec, "back") === "quit") return "quit";
4304
+ }
4305
+ }
4306
+ async function runConfigLauncher(rl, streams) {
4307
+ let selected = 0;
4308
+ const exitCode = () => readSettings().chat.target ? 0 : 130;
4309
+ for (; ; ) {
4310
+ rl.clearScreen();
4311
+ const presenter = createLifecyclePresenter({ stream: streams.out });
4312
+ presenter.header("Clio Coder", "configure");
4313
+ presenter.note("Connect a model and start coding. Everything else is optional.");
4314
+ presenter.blank();
4315
+ const choice = await pickEntry(
4316
+ rl,
4317
+ streams,
4318
+ [
4319
+ { label: "Quick Connect", hint: "endpoint \u2192 model \u2192 ready" },
4320
+ { label: "Settings", hint: "all configuration options" },
4321
+ { label: "Diagnostics", hint: "check an existing installation" }
4322
+ ],
4323
+ "quit",
4324
+ presenter.isPlain(),
4325
+ selected
4326
+ );
4327
+ if (choice.kind !== "index") return exitCode();
4328
+ selected = choice.index;
4329
+ if (selected === 0) {
4330
+ const result = await runQuickConnect(rl);
4331
+ if (result === "connected") return 0;
4332
+ if (result === "quit") return exitCode();
4333
+ } else if (selected === 1) {
4334
+ if (await runConfigSectionsMenu(rl, streams, "back") === "quit") return exitCode();
4335
+ } else {
4336
+ const section = findSection("diagnostics");
4337
+ if (section && await runSection(rl, streams, section, "back") === "quit") return exitCode();
4338
+ }
3645
4339
  }
3646
4340
  }
3647
4341
  function findSection(name) {
@@ -3650,7 +4344,23 @@ function findSection(name) {
3650
4344
  }
3651
4345
  var SECTION_IDS = SECTIONS.map((section) => section.id);
3652
4346
  async function runInteractive(rl, preselectedRuntime, defaults, streams) {
4347
+ if (defaults.quick) {
4348
+ if (!canRunOnboarding(streams)) {
4349
+ printError("--quick needs a terminal; use --id and --runtime for unattended setup");
4350
+ return 2;
4351
+ }
4352
+ return await runQuickConnect(rl) === "connected" ? 0 : 130;
4353
+ }
4354
+ if (defaults.settings) {
4355
+ await runConfigSectionsMenu(rl, streams);
4356
+ return 0;
4357
+ }
3653
4358
  if (preselectedRuntime) {
4359
+ if (canRunOnboarding(streams))
4360
+ return runOnboardingWizard(streams, {
4361
+ mode: readSettings().targets.length === 0 ? "first" : "add",
4362
+ runtime: preselectedRuntime
4363
+ });
3654
4364
  return await runTargetSetupInteractive(rl, preselectedRuntime, defaults);
3655
4365
  }
3656
4366
  if (defaults.section !== void 0) {
@@ -3666,11 +4376,8 @@ async function runInteractive(rl, preselectedRuntime, defaults, streams) {
3666
4376
  await runSection(rl, streams, spec, "quit");
3667
4377
  return 0;
3668
4378
  }
4379
+ if (canRunOnboarding(streams)) return runConfigLauncher(rl, streams);
3669
4380
  if (readSettings().targets.length === 0) {
3670
- if (canRunOnboarding(streams)) {
3671
- rl.close();
3672
- return await runOnboardingWizard(streams);
3673
- }
3674
4381
  const runtime = await pickRuntimeViaCategory(rl);
3675
4382
  if (!runtime) {
3676
4383
  printError("configuration cancelled");
@@ -3678,7 +4385,8 @@ async function runInteractive(rl, preselectedRuntime, defaults, streams) {
3678
4385
  }
3679
4386
  return await runTargetSetupInteractive(rl, runtime, defaults);
3680
4387
  }
3681
- return await runConfigSectionsMenu(rl, streams);
4388
+ await runConfigSectionsMenu(rl, streams);
4389
+ return 0;
3682
4390
  }
3683
4391
  async function runConfigureCommand(argv, inStream = input, outStream = output2) {
3684
4392
  let args;
@@ -3693,8 +4401,21 @@ async function runConfigureCommand(argv, inStream = input, outStream = output2)
3693
4401
  process.stdout.write(HELP);
3694
4402
  return 0;
3695
4403
  }
3696
- initializeClioHome();
3697
4404
  ensureRegistryPopulated();
4405
+ if (args.edit) {
4406
+ if (!inStream.isTTY || !outStream.isTTY) {
4407
+ printError("--edit needs a terminal; use configure --json to inspect settings without one");
4408
+ return 2;
4409
+ }
4410
+ try {
4411
+ await editSettings(new ConfigurePrompts(inStream, outStream));
4412
+ return 0;
4413
+ } catch (error) {
4414
+ if (error instanceof ConfigureNavigation) return 0;
4415
+ printError(error instanceof Error ? error.message : String(error));
4416
+ return 1;
4417
+ }
4418
+ }
3698
4419
  if (args.json) {
3699
4420
  const settings = readSettings();
3700
4421
  outStream.write(`${JSON.stringify(settings, null, 2)}
@@ -3706,13 +4427,9 @@ async function runConfigureCommand(argv, inStream = input, outStream = output2)
3706
4427
  return 0;
3707
4428
  }
3708
4429
  if (args.interop) {
3709
- if (!input.isTTY) return runInteropReview({ rl: null });
3710
- const rl2 = createInterface2({ input, output: output2 });
3711
- try {
3712
- return await runInteropReview({ rl: rl2, streams: { in: input, out: output2 } });
3713
- } finally {
3714
- rl2.close();
3715
- }
4430
+ if (!inStream.isTTY) return runInteropReview({ rl: null });
4431
+ const rl2 = new ConfigurePrompts(inStream, outStream);
4432
+ return runInteropReview({ rl: rl2, streams: { in: inStream, out: outStream } });
3716
4433
  }
3717
4434
  if (args.remove) return runTargetRemove(args.remove);
3718
4435
  if (args.renameOld && args.renameNew) return runTargetRename(args.renameOld, args.renameNew);
@@ -3735,23 +4452,26 @@ async function runConfigureCommand(argv, inStream = input, outStream = output2)
3735
4452
  warnLegacyNaming(runtimeId, runtime.id);
3736
4453
  }
3737
4454
  }
3738
- 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.setWorkerDefault || args.contextWindow !== void 0 || args.maxTokens !== void 0 || args.reasoning !== void 0;
4455
+ 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;
3739
4456
  const nonInteractive = runtime !== null && hasTargetSetupFlag;
3740
4457
  if (nonInteractive && runtime) return runNonInteractive(runtime, args);
3741
- if ((runtimeId !== void 0 || hasTargetSetupFlag) && !input.isTTY) {
4458
+ if ((runtimeId !== void 0 || hasTargetSetupFlag) && !inStream.isTTY) {
3742
4459
  printError(
3743
4460
  runtime === null ? "--runtime is required when configuring a target non-interactively" : "--id is required when passing flags non-interactively"
3744
4461
  );
3745
4462
  return 2;
3746
4463
  }
3747
- const rl = createInterface2({ input: inStream, output: outStream });
4464
+ const rl = new ConfigurePrompts(inStream, outStream);
3748
4465
  try {
3749
4466
  return await runInteractive(rl, runtime, args, { in: inStream, out: outStream });
3750
4467
  } catch (err) {
4468
+ if (err instanceof ConfigureNavigation) {
4469
+ if (readSettings().targets.length > 0) return 0;
4470
+ printError("configuration cancelled");
4471
+ return 130;
4472
+ }
3751
4473
  printError(err instanceof Error ? err.message : String(err));
3752
4474
  return 1;
3753
- } finally {
3754
- rl.close();
3755
4475
  }
3756
4476
  }
3757
4477
 
@@ -3761,4 +4481,4 @@ export {
3761
4481
  runTargetRename,
3762
4482
  runConfigureCommand
3763
4483
  };
3764
- //# sourceMappingURL=chunk-KYKNBD4Y.js.map
4484
+ //# sourceMappingURL=chunk-IJMW64DX.js.map