@iowarp/clio-coder 0.4.0 → 0.4.1

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 (581) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +116 -16
  3. package/dist/{acp-G5WJBNCT.js → acp-ZILU3AUO.js} +14 -14
  4. package/dist/{agents-FMV2Q5G4.js → agents-HYWGBGQR.js} +40 -29
  5. package/dist/assets/codewiki.json +1 -1
  6. package/dist/{auth-3IDSJEIK.js → auth-N3QT7CBO.js} +21 -19
  7. package/dist/{builtins-XCZWXSC7.js → builtins-UJLMOVOV.js} +6 -6
  8. package/dist/{chunk-PQEFIJ36.js → chunk-2LEAKD4C.js} +1 -2
  9. package/dist/{chunk-3BT2XMV4.js → chunk-2NM363SV.js} +50 -57
  10. package/dist/{chunk-J4W7KFM7.js → chunk-2VG7KLYV.js} +24 -279
  11. package/dist/{chunk-SST6Z5JA.js → chunk-336NSSKI.js} +1 -1
  12. package/dist/{chunk-K5C3NCBD.js → chunk-3I5NY75V.js} +5 -5
  13. package/dist/{chunk-VAZSBTKF.js → chunk-3QSOM6PA.js} +2 -2
  14. package/dist/{chunk-TZ3SGWZZ.js → chunk-5QIAJV2D.js} +2 -2
  15. package/dist/{chunk-OQBA45DZ.js → chunk-5YHDIDBP.js} +2 -2
  16. package/dist/{chunk-NHLBIGRH.js → chunk-6CCS4G3W.js} +40 -17
  17. package/dist/{chunk-2JDWVJND.js → chunk-6DWBAZ5U.js} +2 -2
  18. package/dist/{chunk-LDQ2ZF2M.js → chunk-6FN3E6KX.js} +5 -5
  19. package/dist/{chunk-X3YGUTOB.js → chunk-6HMJX2VU.js} +59 -59
  20. package/dist/{chunk-VEO4AP2K.js → chunk-6I5ILFOF.js} +3 -2
  21. package/dist/{chunk-B7OBL7PK.js → chunk-6NJQITNH.js} +18 -11
  22. package/dist/{chunk-IQ7KR472.js → chunk-6VC4OV3Z.js} +6 -3
  23. package/dist/{chunk-P3FOHJT4.js → chunk-72GZI5EV.js} +2 -2
  24. package/dist/{chunk-AB44T6BB.js → chunk-74YWRRU5.js} +8 -7
  25. package/dist/{chunk-SJ5ZKQ4S.js → chunk-7EPLI7VL.js} +2 -2
  26. package/dist/{chunk-HWHKMHUA.js → chunk-7OBGU7UB.js} +3 -3
  27. package/dist/{chunk-2OQE55CK.js → chunk-7PWAODYW.js} +2 -2
  28. package/dist/{chunk-IBEBSCYA.js → chunk-7RY5VZPH.js} +42 -33
  29. package/dist/{chunk-LQ3DZAMX.js → chunk-ABLSQ6JX.js} +2 -2
  30. package/dist/{chunk-QLFS5GO2.js → chunk-AFKWHWXF.js} +12 -22
  31. package/dist/{chunk-FWDFM5ZU.js → chunk-AK5XEFVZ.js} +3 -3
  32. package/dist/{chunk-O6TL7WWY.js → chunk-AKB4GYDL.js} +4 -4
  33. package/dist/chunk-AP73CFDC.js +308 -0
  34. package/dist/{chunk-JDG2WCRO.js → chunk-BBTJOK6Y.js} +5 -5
  35. package/dist/{chunk-SP2RXXYO.js → chunk-BDPT6GTK.js} +10 -10
  36. package/dist/{chunk-NQQH3YT7.js → chunk-BJGUKIG4.js} +3 -3
  37. package/dist/{chunk-O4XIVISU.js → chunk-BTGG6BG2.js} +79 -38
  38. package/dist/chunk-BTK3SSSK.js +67 -0
  39. package/dist/{chunk-M6L6IDJG.js → chunk-BWH6N36D.js} +1 -1
  40. package/dist/chunk-BWW4HLO4.js +301 -0
  41. package/dist/{chunk-I5VEOC6I.js → chunk-C537JADH.js} +10 -10
  42. package/dist/{chunk-HI63TFOG.js → chunk-CDNVLKUX.js} +3 -3
  43. package/dist/{chunk-UM7N4G5A.js → chunk-CWVRRIEI.js} +2 -2
  44. package/dist/{chunk-BKFM6EJV.js → chunk-D4CJV46V.js} +2 -2
  45. package/dist/chunk-D7E7WCDF.js +27 -0
  46. package/dist/{chunk-WZR7K7ZX.js → chunk-E67WX76H.js} +6 -6
  47. package/dist/{chunk-FQ4SKYE4.js → chunk-EBY63B7G.js} +2 -5
  48. package/dist/chunk-EIMVLWB3.js +1842 -0
  49. package/dist/{chunk-RAPCMZL4.js → chunk-FSP7CMNU.js} +9 -1
  50. package/dist/{chunk-MLKNTWH2.js → chunk-FYUN5KZ3.js} +21 -21
  51. package/dist/{chunk-YJX4SHTD.js → chunk-GIZNH63R.js} +1 -1
  52. package/dist/{chunk-X75E3D2N.js → chunk-GPPB3JBE.js} +18 -16
  53. package/dist/{chunk-GR5G2PVF.js → chunk-GVQJ5CCZ.js} +15 -10
  54. package/dist/chunk-HJWWJ6IL.js +184 -0
  55. package/dist/{chunk-VO67MWHC.js → chunk-HRQMFLJP.js} +3 -3
  56. package/dist/{chunk-VYMXRQI6.js → chunk-HUAS7ITX.js} +89 -93
  57. package/dist/{chunk-BKFJHQCA.js → chunk-I66EAJFY.js} +2 -2
  58. package/dist/{chunk-DYJP44XW.js → chunk-IG7BCQBA.js} +1 -1
  59. package/dist/{chunk-32KWKNSF.js → chunk-IXJT6DCX.js} +3 -3
  60. package/dist/{chunk-C2LTL2W6.js → chunk-J4HBWF6Y.js} +360 -172
  61. package/dist/chunk-J5LZHVIT.js +284 -0
  62. package/dist/{chunk-QLL7ILRG.js → chunk-JA5QWE4Z.js} +510 -202
  63. package/dist/{chunk-BBVJUZHB.js → chunk-JIEGK6UF.js} +5 -173
  64. package/dist/{chunk-36EJLSQQ.js → chunk-JZWT5J3Y.js} +4 -4
  65. package/dist/{chunk-HZHHCK24.js → chunk-K6BF4U2H.js} +476 -322
  66. package/dist/{chunk-Z2RR6MAK.js → chunk-MA3H6DM5.js} +6 -6
  67. package/dist/{chunk-CODPRO7Q.js → chunk-MOPSG2X7.js} +6 -6
  68. package/dist/{chunk-76ONBSIA.js → chunk-MQXIVJ35.js} +14 -5
  69. package/dist/{chunk-YDFRH54B.js → chunk-N5UK64DP.js} +4 -4
  70. package/dist/chunk-NDDGJUXD.js +81 -0
  71. package/dist/{chunk-4ZG3XFUR.js → chunk-NLFAQR7Z.js} +12 -1
  72. package/dist/{chunk-VO2LKSTM.js → chunk-O42A54GG.js} +2 -2
  73. package/dist/{chunk-W5VSYASO.js → chunk-OJTRZGR3.js} +46 -87
  74. package/dist/{chunk-NHCZP4K7.js → chunk-PBP4B7XR.js} +2 -2
  75. package/dist/{chunk-3URVFKWK.js → chunk-PJJ6MY27.js} +5 -5
  76. package/dist/{chunk-ZGVHUX3M.js → chunk-PMZVFWSR.js} +2 -2
  77. package/dist/{chunk-GKF55TAZ.js → chunk-PVAMAVBB.js} +3 -2
  78. package/dist/{chunk-6DB53AJS.js → chunk-QKIFBZKT.js} +7 -7
  79. package/dist/{chunk-HJJTYUHX.js → chunk-QMXC4JB7.js} +20 -20
  80. package/dist/chunk-QTFGO774.js +644 -0
  81. package/dist/{chunk-CY6FY24N.js → chunk-R23Z6K6I.js} +2 -2
  82. package/dist/{chunk-ULC6OTWO.js → chunk-R32CLGZ6.js} +13 -13
  83. package/dist/{chunk-KMVISBZR.js → chunk-RKSR6VSF.js} +1 -1
  84. package/dist/{chunk-F4CKPOEQ.js → chunk-SCYB3HA4.js} +72 -26
  85. package/dist/{chunk-LY4S7GJC.js → chunk-SINK3QR6.js} +18 -16
  86. package/dist/{chunk-U77AMWDL.js → chunk-TD3PGPQA.js} +43 -22
  87. package/dist/{chunk-QBJA7R7N.js → chunk-THYWACCR.js} +2 -2
  88. package/dist/{chunk-QREDIESB.js → chunk-TVH4ONAM.js} +14 -8
  89. package/dist/chunk-U2WB7TZS.js +271 -0
  90. package/dist/{chunk-KFZI4NIL.js → chunk-UAPGZHYC.js} +145 -31
  91. package/dist/{chunk-DQITNCXG.js → chunk-UEDMSP56.js} +29 -14
  92. package/dist/{chunk-3XML7CDN.js → chunk-UXN6JT4W.js} +2 -2
  93. package/dist/{chunk-CMZWFGD2.js → chunk-VAVR4IJY.js} +19 -15
  94. package/dist/{chunk-BPKCPIL7.js → chunk-VEGN6WIQ.js} +2 -2
  95. package/dist/chunk-VKFQTNDV.js +66 -0
  96. package/dist/{chunk-7MCTRUCE.js → chunk-VKRH2TCS.js} +2 -2
  97. package/dist/{chunk-5LXZXPKX.js → chunk-VN3SHNBN.js} +2 -2
  98. package/dist/{chunk-UOSL25KY.js → chunk-VXMFAE2W.js} +1 -1
  99. package/dist/{chunk-BBVYXMFO.js → chunk-WNP7O5WZ.js} +2 -2
  100. package/dist/{chunk-SUCTJL45.js → chunk-WR6U3OVP.js} +3 -3
  101. package/dist/{chunk-BUMFYQFY.js → chunk-XKA2ICR3.js} +124 -113
  102. package/dist/{chunk-UXMFQ54G.js → chunk-Y45G3AXC.js} +39 -39
  103. package/dist/{chunk-J5Q24KAG.js → chunk-Y4CAGMM6.js} +2 -2
  104. package/dist/{chunk-NYS75XW5.js → chunk-YAKGTXEV.js} +5 -3
  105. package/dist/{chunk-V5DHCITQ.js → chunk-ZAZB4JMW.js} +23 -12
  106. package/dist/{chunk-Z4TXYIEG.js → chunk-ZJLUDYFY.js} +9 -9
  107. package/dist/{chunk-HKIYEGME.js → chunk-ZTJUVLTU.js} +2 -2
  108. package/dist/{chunk-2ANTL7MR.js → chunk-ZW55JB7N.js} +2 -2
  109. package/dist/cli/index.js +36 -36
  110. package/dist/{clio-2JXHBBY5.js → clio-IT3G3VQH.js} +12 -13
  111. package/dist/{code-nav-3YYRMYNF.js → code-nav-RK6S7F6E.js} +5 -5
  112. package/dist/codewiki/build-worker.js +1 -1
  113. package/dist/{compile-cache-7FPE6PS3.js → compile-cache-OQAVB7Y5.js} +2 -4
  114. package/dist/{components-RYZV4JGP.js → components-UBWCQSRW.js} +4 -4
  115. package/dist/{config-QZPCMYSO.js → config-3QZRWZJF.js} +53 -49
  116. package/dist/{configure-TEGEBYCA.js → configure-FL7Y3KJF.js} +25 -22
  117. package/dist/{context-E6H5RNMC.js → context-5HE7ODYK.js} +47 -43
  118. package/dist/{context-AV7OEZ4D.js → context-KYQFRVDC.js} +11 -11
  119. package/dist/{context-GSXUE4CT.js → context-XNHL75JV.js} +32 -19
  120. package/dist/{context-clear-SHIBYK6T.js → context-clear-N545L53A.js} +47 -43
  121. package/dist/{context-working-set-5ZGKPGZQ.js → context-working-set-QHKXSV2F.js} +10 -9
  122. package/dist/{dispatch-runner-EFMJT4LD.js → dispatch-runner-RGIE5PCT.js} +56 -47
  123. package/dist/{docs-23KQS3XK.js → docs-5NAF6AU7.js} +5 -11
  124. package/dist/doctor-ZGPEGHIP.js +772 -0
  125. package/dist/{eval-TFBYQH4H.js → eval-GXLL44RD.js} +63 -45
  126. package/dist/{eval-inventory-SXH7PDKX.js → eval-inventory-HBWSWQOK.js} +7 -8
  127. package/dist/{evidence-ERGESKGN.js → evidence-HWLBRH3Q.js} +44 -40
  128. package/dist/{evolve-VDXTSYCJ.js → evolve-FTZBMNVW.js} +43 -39
  129. package/dist/{extensions-7BGBHN57.js → extensions-VHRBEID7.js} +4 -4
  130. package/dist/{fleet-2RRVDF2V.js → fleet-CKZHJWZJ.js} +86 -73
  131. package/dist/{fleet-commands-VJ726XIA.js → fleet-commands-EXDXBMV6.js} +10 -9
  132. package/dist/{fleet-decisions-EPAPM3XJ.js → fleet-decisions-OTHB6KRL.js} +5 -5
  133. package/dist/{fleet-graph-JF5QOATM.js → fleet-graph-YTEZUCUT.js} +13 -11
  134. package/dist/{fleet-inspect-VLY4S7QM.js → fleet-inspect-SS6YMDCK.js} +44 -41
  135. package/dist/{fleet-preflight-AIZUEJOY.js → fleet-preflight-PBY4VYOM.js} +5 -9
  136. package/dist/{fleet-validate-AJRPDMDV.js → fleet-validate-KMEM5L3S.js} +16 -13
  137. package/dist/{fleet-verify-JFEL2L3H.js → fleet-verify-QD5M7E7Q.js} +42 -39
  138. package/dist/{fleet-view-ZCON35AG.js → fleet-view-WAMJYNDT.js} +44 -52
  139. package/dist/{init-DN2WWLFE.js → init-5XQRBOFV.js} +63 -58
  140. package/dist/{install-XGLBQY5E.js → install-NKNG7KD4.js} +2 -2
  141. package/dist/{interop-OZBKXAYL.js → interop-34TVO25M.js} +13 -11
  142. package/dist/{library-YWZG7IMW.js → library-3QY6KF57.js} +17 -14
  143. package/dist/{memory-I4C4HMLW.js → memory-L4UTIIIW.js} +45 -41
  144. package/dist/{models-CEYXJBO6.js → models-ZVX3QOWE.js} +39 -31
  145. package/dist/{monitor-NZ6GCI3P.js → monitor-CEKVSYTS.js} +50 -46
  146. package/dist/{orchestrator-GCGQ4N5I.js → orchestrator-77BAP6BC.js} +1807 -1039
  147. package/dist/{panes-KY6W3V2E.js → panes-7STHOAUJ.js} +4 -4
  148. package/dist/{panes-HMABYVO4.js → panes-SHAUIRXY.js} +10 -8
  149. package/dist/{paths-II4K7DNR.js → paths-L7LGY6RN.js} +4 -4
  150. package/dist/{reset-DQ6FGCSH.js → reset-EOLM7GVE.js} +7 -8
  151. package/dist/{resources-BB3MVJMD.js → resources-74GKTLSF.js} +17 -13
  152. package/dist/{run-H2GQDUER.js → run-HBAUJNNZ.js} +86 -76
  153. package/dist/{share-GTJN6A5O.js → share-G3APVLVP.js} +17 -14
  154. package/dist/{skills-L55TEW6R.js → skills-35HHUKCR.js} +19 -16
  155. package/dist/{skills-eval-XVXPH2JI.js → skills-eval-QN4HSHDC.js} +55 -57
  156. package/dist/{skills-inventory-S4MXPJFV.js → skills-inventory-J357J34F.js} +15 -12
  157. package/dist/{slash-commands-ZSGASKJC.js → slash-commands-JZZCQA32.js} +31 -29
  158. package/dist/{steer-RZGSCY4R.js → steer-XAVHJM22.js} +3 -3
  159. package/dist/{support-PKEUNNQL.js → support-U7QOWY26.js} +6 -6
  160. package/dist/{targets-NCPZ644J.js → targets-DSM6CY3M.js} +59 -53
  161. package/dist/{terminal-lease-44SV3YCN.js → terminal-lease-JOPFUVEM.js} +14 -9
  162. package/dist/{tools-DAF3DI3C.js → tools-MKNWVPBH.js} +10 -8
  163. package/dist/{trace-FYVW2MQA.js → trace-ECQ7TIYZ.js} +48 -3
  164. package/dist/{tui-primitives-2AKXQNZK.js → tui-primitives-K5PASC3O.js} +8 -4
  165. package/dist/{uninstall-DW2PNOIC.js → uninstall-N34PCTGJ.js} +4 -6
  166. package/dist/{upgrade-3XPP6OQL.js → upgrade-H7TOM7YL.js} +35 -62
  167. package/dist/{usage-3NLHGTU2.js → usage-X52N3IDJ.js} +51 -48
  168. package/dist/{verifiers-SSQONKRT.js → verifiers-EJTVVSMA.js} +10 -9
  169. package/dist/{verify-3U6J7FZI.js → verify-YJL6XET2.js} +9 -8
  170. package/dist/{web-fetch-S7RR6GZ7.js → web-fetch-MPIFL3LL.js} +1 -2
  171. package/dist/{wiki-generate-CEHYGPGQ.js → wiki-generate-4NDZTQ4B.js} +66 -63
  172. package/dist/{with-panes-MKB46MPQ.js → with-panes-OBOBFIIR.js} +62 -26
  173. package/dist/worker/entry.js +57 -52
  174. package/docs/acp.md +1 -1
  175. package/docs/built-in-agents.md +40 -32
  176. package/docs/commands-and-modes.md +9 -3
  177. package/docs/config-knobs-audit.md +3 -0
  178. package/docs/configuration-and-targets.md +105 -164
  179. package/docs/environment-variables.md +2 -1
  180. package/docs/exit-codes-and-output.md +2 -0
  181. package/docs/fleet-demo-runbook.md +6 -3
  182. package/docs/fleet-dispatch.md +8 -6
  183. package/docs/installation-and-lifecycle.md +1 -1
  184. package/docs/release-cut-checklist.md +164 -177
  185. package/docs/trace-store.md +15 -10
  186. package/docs/troubleshooting.md +1 -1
  187. package/evals/README.md +5 -0
  188. package/evals/behavioral-corpus-grader.mjs +103 -0
  189. package/evals/behavioral-machinery-baseline.json +2276 -0
  190. package/evals/behavioral-machinery-driver.ts +250 -0
  191. package/evals/behavioral-machinery-support.ts +253 -0
  192. package/evals/behavioral-machinery.yaml +614 -0
  193. package/evals/behavioral-model-negative-control.yaml +68 -0
  194. package/evals/behavioral-model.yaml +216 -0
  195. package/evals/fixtures/behavioral-facts.txt +3 -0
  196. package/evals/fixtures/behavioral-main.ts +7 -0
  197. package/evals/fixtures/decoy/note.txt +2 -0
  198. package/evals/fixtures/private/credentials.txt +1 -0
  199. package/evals/tracked-metrics-baseline.yaml +229 -0
  200. package/evals/tracked-metrics-grader.mjs +129 -0
  201. package/package.json +5 -15
  202. package/skills/README.md +6 -6
  203. package/skills/coding/ast-grep/SKILL.md +8 -2
  204. package/skills/coding/coding-standards/SKILL.md +8 -2
  205. package/skills/coding/prototype/SKILL.md +8 -2
  206. package/skills/coding/tdd/SKILL.md +8 -2
  207. package/skills/context/context-handoff/SKILL.md +12 -3
  208. package/skills/context/context-handoff/evals.md +3 -3
  209. package/skills/context/context-prime/SKILL.md +8 -2
  210. package/skills/context/context-prime/evals.md +2 -2
  211. package/skills/git/file-ticket/SKILL.md +9 -4
  212. package/skills/git/file-ticket/evals.md +2 -2
  213. package/skills/git/fix-issue/SKILL.md +12 -5
  214. package/skills/git/fix-issue/evals.md +4 -4
  215. package/skills/git/resolve-merge-conflicts/SKILL.md +8 -2
  216. package/skills/git/resolve-merge-conflicts/evals.md +2 -2
  217. package/skills/git/ship/SKILL.md +9 -3
  218. package/skills/git/ship/evals.md +4 -4
  219. package/skills/git/worktree-create/SKILL.md +7 -2
  220. package/skills/git/worktree-create/evals.md +6 -6
  221. package/skills/git/worktree-merge/SKILL.md +7 -2
  222. package/skills/git/worktree-merge/evals.md +6 -6
  223. package/skills/meta/{clio-dev → clio-coder-dev}/SKILL.md +14 -8
  224. package/skills/meta/{clio-dev → clio-coder-dev}/evals.md +3 -3
  225. package/skills/meta/{clio-test → clio-coder-test}/SKILL.md +11 -5
  226. package/skills/meta/{clio-test → clio-coder-test}/evals.md +1 -1
  227. package/skills/meta/credentials/SKILL.md +9 -2
  228. package/skills/meta/find-skills/SKILL.md +8 -2
  229. package/skills/meta/herdr/SKILL.md +8 -2
  230. package/skills/meta/skill-craft/SKILL.md +21 -4
  231. package/skills/planning/architecture/SKILL.md +9 -3
  232. package/skills/planning/backlog/SKILL.md +8 -2
  233. package/skills/planning/prd/SKILL.md +8 -2
  234. package/skills/planning/product-intent/SKILL.md +8 -2
  235. package/skills/planning/tech-spec/SKILL.md +9 -3
  236. package/skills/registry.yaml +66 -66
  237. package/skills/research/arxiv-literature/SKILL.md +8 -2
  238. package/skills/research/experiment-protocol/SKILL.md +9 -2
  239. package/skills/research/scientific-debugging/SKILL.md +9 -2
  240. package/skills/research/scientific-debugging/evals.md +2 -2
  241. package/skills/research/scientific-modernization/SKILL.md +9 -2
  242. package/skills/skill-marketplace.json +257 -38
  243. package/skills/workflow/cut-it/SKILL.md +10 -2
  244. package/skills/workflow/design-council/SKILL.md +11 -2
  245. package/skills/workflow/grill-me/SKILL.md +8 -2
  246. package/skills/workflow/workflow-distiller/SKILL.md +8 -2
  247. package/src/cli/acp.ts +2 -2
  248. package/src/cli/auth.ts +2 -2
  249. package/src/cli/bootstrap-generate.ts +5 -5
  250. package/src/cli/clio.ts +6 -1
  251. package/src/cli/config-inspect.ts +3 -3
  252. package/src/cli/configure-interop.ts +1 -1
  253. package/src/cli/configure.ts +27 -27
  254. package/src/cli/default-target.ts +1 -1
  255. package/src/cli/docs.ts +6 -6
  256. package/src/cli/doctor-naming.ts +323 -0
  257. package/src/cli/doctor-panes.ts +46 -14
  258. package/src/cli/doctor-toolchain.ts +29 -8
  259. package/src/cli/doctor.ts +15 -1
  260. package/src/cli/eval-inventory.ts +8 -8
  261. package/src/cli/evidence-detail.ts +1 -1
  262. package/src/cli/evidence-inventory.ts +1 -1
  263. package/src/cli/fleet-decisions.ts +1 -1
  264. package/src/cli/fleet-inspect.ts +1 -1
  265. package/src/cli/fleet-preflight.ts +1 -1
  266. package/src/cli/fleet-verify.ts +1 -1
  267. package/src/cli/fleet-view.ts +40 -23
  268. package/src/cli/fleet.ts +8 -5
  269. package/src/cli/interop-inspect.ts +2 -2
  270. package/src/cli/models.ts +3 -3
  271. package/src/cli/modes/print.ts +1 -1
  272. package/src/cli/reset.ts +1 -1
  273. package/src/cli/run.ts +11 -15
  274. package/src/cli/share.ts +1 -1
  275. package/src/cli/skills-eval.ts +11 -11
  276. package/src/cli/targets.ts +23 -24
  277. package/src/cli/trace-inspect.ts +1 -1
  278. package/src/cli/trace.ts +41 -0
  279. package/src/cli/uninstall.ts +2 -2
  280. package/src/cli/upgrade.ts +29 -34
  281. package/src/cli/usage.ts +2 -2
  282. package/src/cli/validate-model.ts +1 -1
  283. package/src/cli/verifiers-inspect.ts +1 -1
  284. package/src/cli/wiki-generate.ts +5 -5
  285. package/src/core/bash-exec.ts +1 -1
  286. package/src/core/boot-trace.ts +3 -3
  287. package/src/core/bus-trace.ts +2 -2
  288. package/src/core/compile-cache.ts +1 -1
  289. package/src/core/config.ts +1062 -886
  290. package/src/core/defaults.ts +321 -528
  291. package/src/core/domain-loader.ts +6 -4
  292. package/src/core/event-bus.ts +1 -1
  293. package/src/core/file-references.ts +78 -88
  294. package/src/core/git-commit-attribution.ts +3 -9
  295. package/src/core/guardrails.ts +24 -4
  296. package/src/core/naming-compat.ts +45 -0
  297. package/src/core/naming-events.ts +62 -0
  298. package/src/core/recent-models.ts +1 -7
  299. package/src/core/residency-protection.ts +4 -8
  300. package/src/core/resolve-config-value.ts +1 -1
  301. package/src/core/response-model-id.ts +0 -14
  302. package/src/core/session-routing.ts +84 -74
  303. package/src/core/skill-activation.ts +18 -0
  304. package/src/core/termination.ts +4 -4
  305. package/src/core/timers.ts +2 -12
  306. package/src/domains/agents/catalog.ts +2 -12
  307. package/src/domains/agents/extension.ts +3 -3
  308. package/src/domains/agents/registry.ts +7 -7
  309. package/src/domains/agents/result-contract.ts +1 -1
  310. package/src/domains/agents/spec.ts +0 -11
  311. package/src/domains/config/classify.ts +35 -47
  312. package/src/domains/config/extension.ts +5 -5
  313. package/src/domains/config/keybindings.ts +48 -47
  314. package/src/domains/config/watcher.ts +1 -1
  315. package/src/domains/context/codewiki/indexer.ts +1 -1
  316. package/src/domains/context/extension.ts +3 -3
  317. package/src/domains/context/prompt-context.ts +1 -1
  318. package/src/domains/context/wiki/assemble.ts +2 -2
  319. package/src/domains/context/working-set/replay/metrics.ts +0 -4
  320. package/src/domains/context/working-set/replay/report.ts +1 -1
  321. package/src/domains/context/working-set/replay/synthetic.ts +2 -2
  322. package/src/domains/dispatch/active-route-planner.ts +2 -2
  323. package/src/domains/dispatch/agent-candidates.ts +1 -1
  324. package/src/domains/dispatch/agent-ledger-store.ts +1 -1
  325. package/src/domains/dispatch/agent-ledger.ts +1 -1
  326. package/src/domains/dispatch/assignment.ts +5 -5
  327. package/src/domains/dispatch/capacity-lease.ts +2 -5
  328. package/src/domains/dispatch/code-step.ts +1 -1
  329. package/src/domains/dispatch/contract.ts +2 -2
  330. package/src/domains/dispatch/extension.ts +65 -61
  331. package/src/domains/dispatch/fleet-node-prompt.ts +1 -1
  332. package/src/domains/dispatch/fleet-preflight.ts +8 -17
  333. package/src/domains/dispatch/fleet-run.ts +0 -7
  334. package/src/domains/dispatch/gate-decisions.ts +25 -14
  335. package/src/domains/dispatch/joint-route-resolver.ts +1 -1
  336. package/src/domains/dispatch/path-scope.ts +0 -61
  337. package/src/domains/dispatch/placement.ts +2 -2
  338. package/src/domains/dispatch/receipt-findings.ts +1 -1
  339. package/src/domains/dispatch/receipt-integrity.ts +20 -8
  340. package/src/domains/dispatch/reservation-store.ts +0 -23
  341. package/src/domains/dispatch/route-decision.ts +1 -1
  342. package/src/domains/dispatch/route-history.ts +1 -1
  343. package/src/domains/dispatch/route-policy.ts +1 -1
  344. package/src/domains/dispatch/route-readiness.ts +0 -28
  345. package/src/domains/dispatch/run-event-journal.ts +6 -5
  346. package/src/domains/dispatch/tool-stats.ts +1 -1
  347. package/src/domains/dispatch/transport.ts +2 -19
  348. package/src/domains/dispatch/types.ts +3 -3
  349. package/src/domains/dispatch/worker-protocol.ts +2 -2
  350. package/src/domains/eval/artifacts/store.ts +5 -4
  351. package/src/domains/eval/compare/thresholds.ts +0 -8
  352. package/src/domains/eval/execution-provenance.ts +1 -1
  353. package/src/domains/eval/metrics/token-stream.ts +0 -7
  354. package/src/domains/eval/report.ts +1 -1
  355. package/src/domains/eval/runner.ts +1 -1
  356. package/src/domains/eval/runners/clio-run.ts +7 -6
  357. package/src/domains/eval/runners/external-command.ts +4 -3
  358. package/src/domains/eval/schema/artifact.ts +1 -1
  359. package/src/domains/eval/schema/behavioral-metrics.ts +3 -2
  360. package/src/domains/eval/schema/behavioral.ts +7 -6
  361. package/src/domains/eval/schema/execution-envelope.ts +4 -2
  362. package/src/domains/eval/schema/naming.ts +10 -0
  363. package/src/domains/eval/schema/suite.ts +2 -2
  364. package/src/domains/eval/schema/validate.ts +9 -5
  365. package/src/domains/eval/schema/verdict.ts +4 -2
  366. package/src/domains/eval/store.ts +12 -2
  367. package/src/domains/eval/suites/run.ts +12 -6
  368. package/src/domains/eval/types.ts +1 -1
  369. package/src/domains/eval/workspaces/git.ts +1 -1
  370. package/src/domains/eval/workspaces/temp-copy.ts +1 -1
  371. package/src/domains/evidence/build.ts +13 -5
  372. package/src/domains/interop/consent.ts +7 -7
  373. package/src/domains/interop/extension.ts +1 -1
  374. package/src/domains/lifecycle/doctor.ts +27 -21
  375. package/src/domains/lifecycle/migrations/2026-09-01-clio-coder-naming.ts +155 -0
  376. package/src/domains/lifecycle/migrations/2026-09-01-retire-panes-knobs.ts +59 -0
  377. package/src/domains/lifecycle/migrations/2026-09-01-settings-v2.ts +338 -0
  378. package/src/domains/lifecycle/migrations/index.ts +20 -1
  379. package/src/domains/lifecycle/naming-history.ts +153 -0
  380. package/src/domains/lifecycle/naming-mutable-state.ts +104 -0
  381. package/src/domains/lifecycle/naming-resources.ts +261 -0
  382. package/src/domains/lifecycle/naming-tool-markers.ts +139 -0
  383. package/src/domains/lifecycle/naming-yazi.ts +81 -0
  384. package/src/domains/lifecycle/upgrade-notice.ts +1 -1
  385. package/src/domains/memory/task-memory-handoff.ts +6 -3
  386. package/src/domains/middleware/index.ts +7 -0
  387. package/src/domains/middleware/marketplace-offer.ts +339 -0
  388. package/src/domains/middleware/runtime.ts +2 -2
  389. package/src/domains/mux/contract.ts +157 -25
  390. package/src/domains/mux/detect.ts +29 -5
  391. package/src/domains/mux/dock-controller.ts +365 -0
  392. package/src/domains/mux/extension.ts +7 -1
  393. package/src/domains/mux/index.ts +20 -0
  394. package/src/domains/mux/operations.ts +28 -0
  395. package/src/domains/mux/protocol.ts +19 -6
  396. package/src/domains/mux/socket-client.ts +167 -19
  397. package/src/domains/mux/types.ts +49 -6
  398. package/src/domains/mux/yazi/event-stream.ts +6 -4
  399. package/src/domains/mux/yazi/profile.ts +1 -1
  400. package/src/domains/mux/yazi/session.ts +26 -3
  401. package/src/domains/observability/extension.ts +1 -1
  402. package/src/domains/observability/out-of-turn-usage.ts +2 -2
  403. package/src/domains/observability/projection.ts +1 -1
  404. package/src/domains/observability/trace-store.ts +22 -12
  405. package/src/domains/prompts/compiler.ts +2 -2
  406. package/src/domains/prompts/extension.ts +3 -3
  407. package/src/domains/prompts/fragments/identity/clio-worker.md +1 -1
  408. package/src/domains/prompts/fragments/operating/skills.md +25 -18
  409. package/src/domains/providers/extension.ts +5 -5
  410. package/src/domains/providers/knowledge-base-path.ts +1 -1
  411. package/src/domains/providers/model-runtime-capabilities.ts +14 -2
  412. package/src/domains/providers/models/cloud-models/alcf.yaml +1 -1
  413. package/src/domains/providers/models/local-models/{clio-local-coding-targets.yaml → clio-coder-local-coding-targets.yaml} +4 -4
  414. package/src/domains/providers/plugins.ts +1 -1
  415. package/src/domains/providers/resolver.ts +1 -1
  416. package/src/domains/providers/runtimes/cloud/alcf.ts +4 -4
  417. package/src/domains/providers/runtimes/common/lmstudio-http.ts +1 -5
  418. package/src/domains/providers/runtimes/common/local-synth.ts +3 -3
  419. package/src/domains/providers/runtimes/common/probe-helpers.ts +2 -2
  420. package/src/domains/providers/runtimes/local-native/llamacpp-completion.ts +1 -1
  421. package/src/domains/providers/runtimes/local-native/lmstudio.ts +2 -9
  422. package/src/domains/providers/runtimes/protocol/litellm.ts +1 -91
  423. package/src/domains/providers/types/knowledge-base.ts +13 -0
  424. package/src/domains/providers/types/local-model-quirks.ts +2 -2
  425. package/src/domains/providers/types/target-descriptor.ts +3 -3
  426. package/src/domains/resources/extension.ts +1 -1
  427. package/src/domains/resources/library.ts +6 -6
  428. package/src/domains/resources/prompts/loader.ts +1 -1
  429. package/src/domains/resources/skills/content-hash.ts +7 -6
  430. package/src/domains/resources/skills/evals.ts +1 -1
  431. package/src/domains/resources/skills/install.ts +36 -12
  432. package/src/domains/resources/skills/loader.ts +39 -13
  433. package/src/domains/resources/skills/marketplace.ts +21 -2
  434. package/src/domains/resources/skills/promotion.ts +214 -0
  435. package/src/domains/safety/audit.ts +2 -2
  436. package/src/domains/safety/finish-contract.ts +2 -1
  437. package/src/domains/safety/run-effects.ts +1 -1
  438. package/src/domains/scheduling/extension.ts +4 -4
  439. package/src/domains/session/archive-readers.ts +9 -1
  440. package/src/domains/session/compaction/branch-summary.ts +4 -0
  441. package/src/domains/session/compaction/compact.ts +1 -1
  442. package/src/domains/session/compaction/tokens.ts +4 -0
  443. package/src/domains/session/context-accounting.ts +1 -1
  444. package/src/domains/session/decision-board.ts +1 -1
  445. package/src/domains/session/extension.ts +1 -1
  446. package/src/domains/session/handoff.ts +2 -2
  447. package/src/domains/session/prompt-manifest.ts +0 -5
  448. package/src/domains/session/protected-artifact-journal.ts +12 -6
  449. package/src/domains/session/retry.ts +1 -1
  450. package/src/domains/share/archive.ts +85 -36
  451. package/src/domains/toolchain/install.ts +1 -1
  452. package/src/engine/acp/adapter.ts +3 -3
  453. package/src/engine/acp/event-mapper.ts +3 -3
  454. package/src/engine/acp/server.ts +27 -26
  455. package/src/engine/acp/tool-mediator.ts +2 -2
  456. package/src/engine/acp/types.ts +1 -1
  457. package/src/engine/alcf-oauth.ts +5 -5
  458. package/src/engine/antigravity/subprocess-runtime.ts +2 -2
  459. package/src/engine/api-registry.ts +1 -1
  460. package/src/engine/apis/llamacpp-residency.ts +1 -19
  461. package/src/engine/apis/lmstudio.ts +1 -6
  462. package/src/engine/apis/ollama-native.ts +3 -3
  463. package/src/engine/apis/openai-completions.ts +2 -2
  464. package/src/engine/apis/residency.ts +3 -9
  465. package/src/engine/claude/sdk-module.ts +1 -12
  466. package/src/engine/claude/sdk-runtime.ts +6 -6
  467. package/src/engine/claude/subprocess-runtime.ts +1 -1
  468. package/src/engine/claude/tool-safety.ts +4 -4
  469. package/src/engine/loop-guard.ts +0 -5
  470. package/src/engine/session.ts +14 -7
  471. package/src/engine/tui-primitives.ts +1 -1
  472. package/src/engine/worker-events.ts +6 -6
  473. package/src/engine/worker-runtime.ts +14 -13
  474. package/src/entry/orchestrator.ts +107 -88
  475. package/src/interactive/application-controller.ts +21 -21
  476. package/src/interactive/bus-notices.ts +2 -2
  477. package/src/interactive/chat-loop.ts +8 -8
  478. package/src/interactive/chat-panel.ts +1 -1
  479. package/src/interactive/clio-editor.ts +105 -1
  480. package/src/interactive/context-activity.ts +8 -6
  481. package/src/interactive/context-meter.ts +3 -6
  482. package/src/interactive/context-overlay.ts +1 -1
  483. package/src/interactive/cost-overlay.ts +1 -1
  484. package/src/interactive/council-grid.ts +2 -2
  485. package/src/interactive/dispatch-board.ts +30 -33
  486. package/src/interactive/editor-bash.ts +21 -0
  487. package/src/interactive/editor-steer.ts +9 -4
  488. package/src/interactive/editor-submit.ts +24 -18
  489. package/src/interactive/external-editor.ts +1 -1
  490. package/src/interactive/file-reference-completion.ts +360 -0
  491. package/src/interactive/footer/dashboard.ts +15 -17
  492. package/src/interactive/footer/notifications.ts +14 -8
  493. package/src/interactive/footer/widgets.ts +2 -44
  494. package/src/interactive/interactive-application.ts +79 -59
  495. package/src/interactive/interactive-event-projection.ts +1 -1
  496. package/src/interactive/interactive-input-runtime.ts +2 -2
  497. package/src/interactive/interactive-presentation.ts +21 -16
  498. package/src/interactive/interactive-shell.ts +2 -2
  499. package/src/interactive/interactive-slash-runtime.ts +63 -17
  500. package/src/interactive/interactive-subscriptions.ts +1 -1
  501. package/src/interactive/interactive-tickers.ts +1 -1
  502. package/src/interactive/keybinding-manager.ts +4 -4
  503. package/src/interactive/layout.ts +1 -1
  504. package/src/interactive/memory-overlay.ts +2 -2
  505. package/src/interactive/modal-marker.ts +2 -21
  506. package/src/interactive/mutation-preview.ts +1 -1
  507. package/src/interactive/overlay-frame.ts +4 -12
  508. package/src/interactive/overlay-general-openers.ts +6 -2
  509. package/src/interactive/overlay-key-routing.ts +7 -7
  510. package/src/interactive/overlay-lifecycle.ts +1 -1
  511. package/src/interactive/overlay-model-selectors.ts +3 -3
  512. package/src/interactive/overlays/agents.ts +2 -2
  513. package/src/interactive/overlays/ask-user.ts +25 -11
  514. package/src/interactive/overlays/context-reset.ts +28 -4
  515. package/src/interactive/overlays/cwd-fallback.ts +28 -4
  516. package/src/interactive/overlays/decisions.ts +4 -2
  517. package/src/interactive/overlays/fleet-run-approval.ts +3 -3
  518. package/src/interactive/overlays/handoff-review.ts +2 -2
  519. package/src/interactive/overlays/interop.ts +1 -1
  520. package/src/interactive/overlays/library-install-confirm.ts +1 -1
  521. package/src/interactive/overlays/message-picker.ts +1 -1
  522. package/src/interactive/overlays/model-selector.ts +39 -31
  523. package/src/interactive/overlays/prompts.ts +10 -4
  524. package/src/interactive/overlays/session-selector.ts +2 -2
  525. package/src/interactive/overlays/settings.ts +339 -293
  526. package/src/interactive/overlays/side-question.ts +2 -2
  527. package/src/interactive/overlays/skills-hub.ts +8 -8
  528. package/src/interactive/overlays/tree-selector.ts +2 -2
  529. package/src/interactive/panes-runtime.ts +36 -10
  530. package/src/interactive/permission-overlay.ts +2 -2
  531. package/src/interactive/renderers/retry-status.ts +12 -4
  532. package/src/interactive/renderers/tool-execution.ts +4 -4
  533. package/src/interactive/session-transcript.ts +3 -3
  534. package/src/interactive/slash-autocomplete.ts +454 -165
  535. package/src/interactive/slash-commands.ts +279 -183
  536. package/src/interactive/slash-spec.ts +160 -17
  537. package/src/interactive/status/controller.ts +2 -2
  538. package/src/interactive/stream-pacing-policy.ts +1 -1
  539. package/src/interactive/tasks-overlay.ts +20 -13
  540. package/src/interactive/terminal-lease.ts +6 -7
  541. package/src/interactive/turn-context.ts +11 -11
  542. package/src/interactive/turn-persistence.ts +2 -2
  543. package/src/interactive/turn-prewarm.ts +2 -2
  544. package/src/interactive/turn-runtime.ts +8 -8
  545. package/src/interactive/turn-state.ts +1 -1
  546. package/src/interactive/view/artifacts.ts +12 -9
  547. package/src/interactive/view/view-overlay.ts +13 -10
  548. package/src/interactive/watch-pane.ts +38 -10
  549. package/src/interactive/welcome-dashboard.ts +15 -15
  550. package/src/interactive/worker-progress.ts +4 -4
  551. package/src/interactive/worker-receipts.ts +1 -1
  552. package/src/interactive/worker-stream.ts +1 -4
  553. package/src/interactive/yazi-bridge.ts +12 -5
  554. package/src/tools/ask-user.ts +3 -3
  555. package/src/tools/bash.ts +1 -1
  556. package/src/tools/builtin-tool-catalog.ts +1 -1
  557. package/src/tools/compete-worktrees.ts +27 -17
  558. package/src/tools/context/index.ts +15 -1
  559. package/src/tools/dispatch-admission.ts +4 -2
  560. package/src/tools/dispatch-arguments.ts +1 -1
  561. package/src/tools/dispatch-plan.ts +0 -11
  562. package/src/tools/dispatch-run-events.ts +12 -10
  563. package/src/tools/dispatch-runner.ts +11 -6
  564. package/src/tools/dispatch.ts +1 -1
  565. package/src/tools/find.ts +1 -6
  566. package/src/tools/monitor.ts +4 -4
  567. package/src/tools/observers.ts +0 -33
  568. package/src/tools/task-worktree.ts +28 -7
  569. package/src/tools/verify/authoring.ts +3 -6
  570. package/src/tools/verify/frontend.ts +1 -1
  571. package/src/tools/web-fetch.ts +1 -1
  572. package/src/worker/entry.ts +4 -3
  573. package/src/worker/protocol.ts +16 -14
  574. package/src/worker/spec-contract.ts +2 -2
  575. package/src/worker/stdin-demux.ts +2 -2
  576. package/dist/chunk-GXNLGKAB.js +0 -571
  577. package/dist/chunk-VFA6GDY5.js +0 -1625
  578. package/dist/doctor-QOA5FNY5.js +0 -313
  579. package/src/engine/apis/degraded-inference.ts +0 -95
  580. /package/skills/meta/{clio-test → clio-coder-test}/references/harness.md +0 -0
  581. /package/skills/meta/{clio-test → clio-coder-test}/references/test-map.md +0 -0
@@ -38,7 +38,6 @@ import { renderSessionHtml } from "./export-html/index.js";
38
38
  import { dateLocal } from "./format-time.js";
39
39
  import type { OracleDigestSources } from "./oracle.js";
40
40
  import type { PendingModelScope } from "./overlays/model-scope.js";
41
- import type { SettingsCenterRowId, SettingsSectionId } from "./overlays/settings.js";
42
41
  import {
43
42
  type ContextClearCommandOptions,
44
43
  type CouncilDispatchOutcome,
@@ -46,6 +45,7 @@ import {
46
45
  type InitCommandOptions,
47
46
  parseSlashCommand,
48
47
  type RunIo,
48
+ type SettingsAreaId,
49
49
  type SlashCommandContext,
50
50
  type SlashCommandDispatchResult,
51
51
  type TaskMemorySeedCommandResult,
@@ -145,7 +145,8 @@ export interface InteractiveSlashRuntimeDeps {
145
145
  * Absent on a host with no overlay layer, where the swap stays session-scoped.
146
146
  */
147
147
  openModelScope?: (ref: PendingModelScope) => void;
148
- openSettings: (section?: SettingsSectionId, rowId?: SettingsCenterRowId) => void;
148
+ openSettings: (area?: SettingsAreaId, group?: string) => void;
149
+ openFleetRuns?: () => void;
149
150
  openResume: () => void;
150
151
  startNewSession: () => void;
151
152
  openTree: () => void;
@@ -174,11 +175,7 @@ export interface InteractiveSlashRuntime {
174
175
  }
175
176
 
176
177
  /** Owns slash-command context construction and its asynchronous command state. */
177
- const OUTPUT_VERBOSITIES: ReadonlyArray<ClioSettings["terminal"]["outputVerbosity"]> = [
178
- "minimal",
179
- "default",
180
- "verbose",
181
- ];
178
+ const OUTPUT_VERBOSITIES: ReadonlyArray<ClioSettings["interface"]["outputDetail"]> = ["minimal", "default", "verbose"];
182
179
 
183
180
  /** Thinking capability of the active orchestrator target and model, or null when unresolved. */
184
181
  export function resolveThinkingCapability(
@@ -187,9 +184,9 @@ export function resolveThinkingCapability(
187
184
  ): ResolvedThinkingCapability | null {
188
185
  const resolved = resolveModelRuntimeCapabilitiesForProviders(
189
186
  providers,
190
- settings.orchestrator.target,
191
- settings.orchestrator.model,
192
- settings.orchestrator.thinkingLevel ?? "off",
187
+ settings.chat.target,
188
+ settings.chat.model,
189
+ settings.chat.thinkingLevel ?? "off",
193
190
  );
194
191
  return resolved?.thinking ?? null;
195
192
  }
@@ -370,7 +367,8 @@ export function createInteractiveSlashRuntime(deps: InteractiveSlashRuntimeDeps)
370
367
  deps.requestRender();
371
368
  }
372
369
  };
373
- const context: SlashCommandContext = {
370
+ let context: SlashCommandContext;
371
+ context = {
374
372
  io: deps.io,
375
373
  notice: appendCommandNotice,
376
374
  echoOperatorCommand: (text) => {
@@ -392,7 +390,7 @@ export function createInteractiveSlashRuntime(deps: InteractiveSlashRuntimeDeps)
392
390
  openSkillsHub: deps.openSkillsHub,
393
391
  listExtensions: () => deps.extensions?.list(cwd(), { all: true }) ?? [],
394
392
  listAgents: () => deps.agents?.listSpecs().filter((spec) => spec.audience !== "internal") ?? [],
395
- listDelegationAgents: () => deps.getSettings?.().delegation.agents ?? [],
393
+ listDelegationAgents: () => deps.getSettings?.().integrations.externalAgents.entries ?? [],
396
394
  exportShareArchive: (outPath) => {
397
395
  if (!deps.share) throw new Error("share domain is not loaded");
398
396
  const path = resolve(outPath);
@@ -423,7 +421,8 @@ export function createInteractiveSlashRuntime(deps: InteractiveSlashRuntimeDeps)
423
421
  oracleBriefing: oracleBriefingSources,
424
422
  startHandoff: deps.startHandoff,
425
423
  ...(deps.startFleetRun ? { startFleetRun: deps.startFleetRun } : {}),
426
- ...(deps.getSettings ? { getWorkerRosters: () => deps.getSettings?.().workers.rosters ?? {} } : {}),
424
+ ...(deps.openFleetRuns ? { openFleetRuns: deps.openFleetRuns } : {}),
425
+ ...(deps.getSettings ? { getWorkerRosters: () => deps.getSettings?.().fleet.rosters ?? {} } : {}),
427
426
  ...(deps.runCouncilDispatch ? { runCouncilDispatch: deps.runCouncilDispatch } : {}),
428
427
  openContextView: deps.openContextView,
429
428
  openTasks: deps.openTasks,
@@ -467,24 +466,53 @@ export function createInteractiveSlashRuntime(deps: InteractiveSlashRuntimeDeps)
467
466
  // has no mandate to do.
468
467
  if (deps.commitSetting) {
469
468
  const next = structuredClone(settings) as ClioSettings;
470
- next.orchestrator.thinkingLevel = match;
471
- deps.commitSetting("orchestrator.thinkingLevel", next, "session");
469
+ next.chat.thinkingLevel = match;
470
+ deps.commitSetting("chat.thinkingLevel", next, "session");
472
471
  } else {
473
472
  deps.onSetThinkingLevel(match);
474
473
  }
475
474
  deps.refreshFooter();
476
475
  return { status: "applied", level: match, display: labelFor(match) };
477
476
  },
477
+ thinkingLevelChoices: () => {
478
+ const settings = deps.getSettings?.();
479
+ if (!settings) return [];
480
+ const thinking = resolveThinkingCapability(deps.providers, settings);
481
+ return (thinking?.supportedLevels ?? (["off"] as ReadonlyArray<ThinkingLevel>)).map((value) => ({
482
+ value,
483
+ label: thinkingLevelChoiceLabel(thinking?.mechanism ?? null, value),
484
+ }));
485
+ },
486
+ openThinkingPicker: () => {
487
+ const choices = context.thinkingLevelChoices?.() ?? [];
488
+ if (choices.length === 0) {
489
+ appendCommandNotice("error", "thinking level cannot be set right now");
490
+ return;
491
+ }
492
+ void deps
493
+ .openAskUser([
494
+ {
495
+ question: "Choose the thinking level for this chat.",
496
+ header: "Thinking",
497
+ options: choices.map(({ label }) => ({ label })),
498
+ },
499
+ ])
500
+ .then((result) => {
501
+ const answer = result.cancelled ? undefined : result.answers[0]?.answer;
502
+ const selected = choices.find(({ label }) => label === answer);
503
+ if (selected) dispatchSlashCommand({ kind: "thinking-set", level: selected.value }, context);
504
+ });
505
+ },
478
506
  setOutputVerbosity: (verbosity) => {
479
507
  if (!deps.getSettings || !(deps.commitSetting || deps.writeSettings)) return { status: "unavailable" };
480
508
  const requested = verbosity.trim().toLowerCase();
481
509
  const match = OUTPUT_VERBOSITIES.find((candidate) => candidate === requested);
482
510
  if (!match) return { status: "unsupported", verbosity, supported: OUTPUT_VERBOSITIES };
483
511
  const next = structuredClone(deps.getSettings()) as ClioSettings;
484
- next.terminal.outputVerbosity = match;
512
+ next.interface.outputDetail = match;
485
513
  // Session scope: /output changes this session and leaves settings.yaml
486
514
  // alone. Saving it as the default is what Settings → Terminal is for.
487
- if (deps.commitSetting) deps.commitSetting("terminal.outputVerbosity", next, "session");
515
+ if (deps.commitSetting) deps.commitSetting("interface.outputDetail", next, "session");
488
516
  else deps.writeSettings?.(next);
489
517
  // `/output` is also the explicit reset action for transcript folds. Do
490
518
  // this even when the requested level already matches the current one;
@@ -493,6 +521,24 @@ export function createInteractiveSlashRuntime(deps: InteractiveSlashRuntimeDeps)
493
521
  deps.refreshFooter();
494
522
  return { status: "applied", verbosity: match };
495
523
  },
524
+ openOutputPicker: () => {
525
+ void deps
526
+ .openAskUser([
527
+ {
528
+ question: "Choose transcript detail for this session.",
529
+ header: "Output",
530
+ options: OUTPUT_VERBOSITIES.map((value) => ({
531
+ label: `${value[0]?.toUpperCase()}${value.slice(1)}`,
532
+ })),
533
+ },
534
+ ])
535
+ .then((result) => {
536
+ if (result.cancelled) return;
537
+ const answer = result.answers[0]?.answer.toLowerCase();
538
+ const selected = OUTPUT_VERBOSITIES.find((value) => value === answer);
539
+ if (selected) dispatchSlashCommand({ kind: "output-set", verbosity: selected }, context);
540
+ });
541
+ },
496
542
  openModel: deps.openModel,
497
543
  providers: deps.providers,
498
544
  applyModelRef: (ref) => {
@@ -88,7 +88,7 @@ export function createInteractiveSubscriptions(deps: InteractiveSubscriptionsDep
88
88
  BusChannels.DispatchProgress,
89
89
  folded((payload) => {
90
90
  const workerEvent = payload.event as { type?: unknown } | null | undefined;
91
- if (workerEvent?.type === "clio_steer_received") {
91
+ if (workerEvent?.type === "clio_coder_steer_received") {
92
92
  deps.notify("success", `steer received by ${payload.agentId} (${payload.runId})`, `steer:${payload.runId}`);
93
93
  }
94
94
  return workers.progress(payload);
@@ -34,7 +34,7 @@ export interface InteractiveTickersDeps {
34
34
  clearScheduledInterval?: (handle: InteractiveTickerHandle) => void;
35
35
  }
36
36
 
37
- export function formatTaskBoardIslandLines(board: TaskBoardSnapshot): string[] {
37
+ function formatTaskBoardIslandLines(board: TaskBoardSnapshot): string[] {
38
38
  const theme = clioTheme();
39
39
  const counts = taskBoardCounts(board);
40
40
  const active = board.tasks.find((task) => task.status === "active");
@@ -18,7 +18,7 @@
18
18
  * so editor/select components honor overrides out of the box.
19
19
  *
20
20
  * User overrides go through `validateKeybindings` first. Unmappable strings
21
- * (e.g. `clio.exit: "banana"`) are dropped so they cannot silently replace
21
+ * (e.g. `clio-coder.exit: "banana"`) are dropped so they cannot silently replace
22
22
  * the default binding; they still surface through `invalidBindings()` so
23
23
  * `/settings` and the boot stderr notice can point at the offending entry.
24
24
  */
@@ -184,7 +184,7 @@ interface ValidationResult {
184
184
  }
185
185
 
186
186
  /**
187
- * Normalize and validate the raw `settings.keybindings` block. Invalid
187
+ * Normalize and validate the raw `settings.interface.keybindings` block. Invalid
188
188
  * entries are dropped from the returned `valid` config so pi-tui keeps
189
189
  * the default binding in effect; callers render `invalid` as a diagnostic.
190
190
  */
@@ -472,14 +472,14 @@ function buildManager(
472
472
  * Build a `ClioKeybindingManager` from the provided settings snapshot. The
473
473
  * resulting manager is also installed as pi-tui's global so editor and
474
474
  * select components pick up the same overrides. Callers are expected to
475
- * recreate the manager if `settings.keybindings` is replaced wholesale;
475
+ * recreate the manager if `settings.interface.keybindings` is replaced wholesale;
476
476
  * partial live updates should instead go through `manager` state.
477
477
  */
478
478
  export function createKeybindingManager(
479
479
  settings: Readonly<ClioSettings>,
480
480
  env: NodeJS.ProcessEnv | Readonly<Record<string, string | undefined>> = process.env,
481
481
  ): ClioKeybindingManager {
482
- const { valid, invalid } = validateKeybindings(settings.keybindings ?? {});
482
+ const { valid, invalid } = validateKeybindings(settings.interface.keybindings ?? {});
483
483
  const inner = new KeybindingsManager(CLIO_KEYBINDINGS, valid);
484
484
  setKeybindings(inner);
485
485
  return buildManager(inner, invalid, detectPlatformKeybindingWarnings(valid, detectTerminalKeySupport(env)));
@@ -20,7 +20,7 @@ export interface FullscreenLayout {
20
20
  transcript: ScrollView;
21
21
  }
22
22
 
23
- export function buildFullscreenLayout(
23
+ function buildFullscreenLayout(
24
24
  parts: LayoutParts,
25
25
  options: Pick<LayoutOptions, "fullscreenScrollbar"> = {},
26
26
  ): FullscreenLayout {
@@ -29,7 +29,7 @@ const EMPTY_MESSAGE = "no approved lessons, task-bank entries, or memory steps c
29
29
  * row of its own until it finishes, and an operator who cannot see it in flight
30
30
  * reads an unchanged bank as an idle memory agent.
31
31
  */
32
- export function formatMemoryStatusLine(status: TaskMemoryOperatorStatus, contentWidth: number): string {
32
+ function formatMemoryStatusLine(status: TaskMemoryOperatorStatus, contentWidth: number): string {
33
33
  const theme = clioTheme();
34
34
  const width = Math.max(1, Math.floor(contentWidth));
35
35
  const units = [
@@ -145,7 +145,7 @@ function activityItems(events: ReadonlyArray<TaskMemoryActivityEvent>, group: st
145
145
  * section titles and they are the only place a reader learns that a class is
146
146
  * empty: a group with no rows renders no header at all.
147
147
  */
148
- export function buildMemoryOverlayItems(
148
+ function buildMemoryOverlayItems(
149
149
  status: TaskMemoryOperatorStatus,
150
150
  records: ReadonlyArray<MemoryRecord>,
151
151
  ): ListOverlayItem[] {
@@ -49,22 +49,13 @@ export const MODAL_MARKER_BASE_TITLE = "clio";
49
49
  export const MODAL_MARKER_TITLE_PATTERN = /^clio \[modal:([a-z0-9][a-z0-9-]*)(?:\+([1-9]\d*))?\]$/u;
50
50
 
51
51
  /** Render the title for a modal stack, outermost first. */
52
- export function formatModalMarkerTitle(stack: readonly string[]): string {
52
+ function formatModalMarkerTitle(stack: readonly string[]): string {
53
53
  const top = stack.at(-1);
54
54
  if (top === undefined) return MODAL_MARKER_BASE_TITLE;
55
55
  const beneath = stack.length - 1;
56
56
  return `${MODAL_MARKER_BASE_TITLE} [modal:${top}${beneath > 0 ? `+${beneath}` : ""}]`;
57
57
  }
58
58
 
59
- /** Read a marker title back. Returns null for the base title and for anything else. */
60
- export function parseModalMarkerTitle(title: string): { id: string; depth: number } | null {
61
- const match = MODAL_MARKER_TITLE_PATTERN.exec(title);
62
- const id = match?.[1];
63
- if (id === undefined) return null;
64
- const beneath = match?.[2];
65
- return { id, depth: beneath === undefined ? 1 : 1 + Number.parseInt(beneath, 10) };
66
- }
67
-
68
59
  /** One modal's claim on the keyboard, released when the overlay goes away. */
69
60
  export interface ModalMarkerHandle {
70
61
  /** Drop this modal from the stack. Idempotent; a second call is inert. */
@@ -152,19 +143,9 @@ function createModalMarkerRegistry(): ModalMarkerRegistry {
152
143
  return { enter, stack: (): readonly string[] => activeIds() };
153
144
  }
154
145
 
155
- let registry = createModalMarkerRegistry();
146
+ const registry = createModalMarkerRegistry();
156
147
 
157
148
  /** Push a modal onto the process-wide stack. See {@link ModalMarkerRegistry.enter}. */
158
149
  export function enterModal(id: string, sink?: ModalMarkerSink | null): ModalMarkerHandle {
159
150
  return registry.enter(id, sink);
160
151
  }
161
-
162
- /** The ids that currently own keys, outermost first. */
163
- export function modalMarkerStack(): readonly string[] {
164
- return registry.stack();
165
- }
166
-
167
- /** Drop every claim and forget the sink. Tests use it to isolate; nothing in the app does. */
168
- export function resetModalMarker(): void {
169
- registry = createModalMarkerRegistry();
170
- }
@@ -96,7 +96,7 @@ function canonicalJson(value: unknown): string {
96
96
  * anything else about the arguments does, which is the point: a call that
97
97
  * differs from the previewed one cannot inherit its preview.
98
98
  */
99
- export function callArgumentsDigest(args: Record<string, unknown> | undefined): string {
99
+ function callArgumentsDigest(args: Record<string, unknown> | undefined): string {
100
100
  return createHash("sha256")
101
101
  .update(canonicalJson(args ?? {}), "utf8")
102
102
  .digest("hex")
@@ -133,7 +133,7 @@ export interface HintEntry {
133
133
  * dropped `[Enter] use`, which is the only way to commit. The commit key and
134
134
  * the way out are what a narrow footer is for.
135
135
  */
136
- export function isCriticalHintKey(key: string): boolean {
136
+ function isCriticalHintKey(key: string): boolean {
137
137
  const canonical = canonicalizeKey(key);
138
138
  // `type` joins the commit key and the way out because on a list of a hundred
139
139
  // models, typing is how a reader reaches the row they want at all; the
@@ -190,7 +190,7 @@ export function fitHintEntries(entries: ReadonlyArray<HintEntry>, maxWidth: numb
190
190
  */
191
191
  export const FILTER_HINT: HintEntry = { key: "type", verb: "filter" };
192
192
 
193
- export function canonicalizeKey(key: string): string {
193
+ function canonicalizeKey(key: string): string {
194
194
  const trimmed = key.trim();
195
195
  if (trimmed === "R") return "R";
196
196
  const lower = trimmed.toLowerCase();
@@ -240,7 +240,7 @@ export function buildResponsiveHint(
240
240
  * labels but recovers the key, which is all the critical-key classification
241
241
  * needs, so a plain-string overlay gets the same protection as a structured one.
242
242
  */
243
- export function elideHint(hint: string, maxCleanWidth: number): string {
243
+ function elideHint(hint: string, maxCleanWidth: number): string {
244
244
  const parts = hint.split(" · ");
245
245
  if (parts.length <= 2) return hint;
246
246
  const entries: HintEntry[] = parts.map((part) => {
@@ -297,14 +297,6 @@ export function diagnosticSeverityToken(severity: RuntimeResolutionDiagnostic["s
297
297
  return severity === "error" ? "error" : severity === "warning" ? "warning" : "muted";
298
298
  }
299
299
 
300
- export function runtimeResolutionDiagnosticLine(diagnostic: RuntimeResolutionDiagnostic, width: number): string {
301
- return clioTheme().fg(diagnosticSeverityToken(diagnostic.severity), fitDiagnosticLine(diagnostic, width));
302
- }
303
-
304
- function fitDiagnosticLine(diagnostic: RuntimeResolutionDiagnostic, width: number): string {
305
- return padAnsi(formatRuntimeResolutionDiagnostic(diagnostic), Math.max(1, width));
306
- }
307
-
308
300
  export type FrameAlign = "left" | "center" | "right";
309
301
 
310
302
  /**
@@ -313,7 +305,7 @@ export type FrameAlign = "left" | "center" | "right";
313
305
  * row and places the box itself; this is what the box would have been anchored
314
306
  * to if the engine were still doing the placing.
315
307
  */
316
- export function frameAlignForAnchor(anchor: OverlayOptions["anchor"]): FrameAlign {
308
+ function frameAlignForAnchor(anchor: OverlayOptions["anchor"]): FrameAlign {
317
309
  if (anchor === undefined) return "center";
318
310
  if (anchor === "left-center" || anchor.endsWith("-left")) return "left";
319
311
  if (anchor === "right-center" || anchor.endsWith("-right")) return "right";
@@ -12,6 +12,7 @@ import {
12
12
  proposeMemoryPromotion,
13
13
  } from "../domains/memory/index.js";
14
14
  import type { ObservabilityContract } from "../domains/observability/index.js";
15
+ import { renderCostAggregate } from "../domains/observability/index.js";
15
16
  import { foregroundStreamUsage } from "../domains/providers/index.js";
16
17
  import type { ContextLedger } from "../domains/session/context-ledger.js";
17
18
  import type { SessionMeta } from "../domains/session/index.js";
@@ -486,7 +487,7 @@ export function createOverlayGeneralOpeners(deps: OverlayGeneralOpenersDeps): Ov
486
487
  fleetRootId,
487
488
  dispatch: deps.dispatch,
488
489
  agents: { getSpec: (agentId) => agents.getSpec(agentId) },
489
- attributionEnabled: deps.getSettings?.().attribution.gitCommits ?? true,
490
+ attributionEnabled: deps.getSettings?.().integrations.git.commitAttribution ?? true,
490
491
  vars: preview.vars,
491
492
  onStepDispatched: (event) => {
492
493
  deps.setFleetRunPhase?.(event.assignmentId, { wave: event.waveIndex, stepId: event.stepId });
@@ -496,7 +497,10 @@ export function createOverlayGeneralOpeners(deps: OverlayGeneralOpenersDeps): Ov
496
497
  .then((outcome) => {
497
498
  deps.notify(
498
499
  outcome.cleanRun ? "success" : "warning",
499
- `fleet ${preview.name}: ${outcome.succeededStepCount}/${outcome.requiredStepCount} steps succeeded, cost $${outcome.totalCostUsd.toFixed(4)}`,
500
+ // `totalCost` rather than the bare `totalCostUsd` sum: a run whose
501
+ // receipts were all unpriced reads as not measured instead of as a
502
+ // measured $0.0000 nobody put a number on.
503
+ `fleet ${preview.name}: ${outcome.succeededStepCount}/${outcome.requiredStepCount} steps succeeded, cost ${renderCostAggregate(outcome.totalCost)}`,
500
504
  "fleet-run:settled",
501
505
  );
502
506
  })
@@ -111,7 +111,7 @@ function mutationScrollDelta(data: string): number {
111
111
  }
112
112
 
113
113
  /** Pure permission overlay key router: returns true when the input was consumed. */
114
- export function routePermissionOverlayKey(data: string, deps: PermissionOverlayKeyDeps): boolean {
114
+ function routePermissionOverlayKey(data: string, deps: PermissionOverlayKeyDeps): boolean {
115
115
  if (matchesKey(data, "enter") && !isKeyRelease(data)) {
116
116
  // Consumed either way: with a draft the press changes nothing, and the
117
117
  // composer rail says what clears it. Letting it fall through would hand
@@ -158,7 +158,7 @@ export function routePermissionOverlayKey(data: string, deps: PermissionOverlayK
158
158
  }
159
159
 
160
160
  /** Pure overlay key router for the dispatch board. */
161
- export function routeDispatchBoardOverlayKey(data: string, deps: DispatchBoardOverlayKeyDeps): boolean {
161
+ function routeDispatchBoardOverlayKey(data: string, deps: DispatchBoardOverlayKeyDeps): boolean {
162
162
  if (isEscapeKey(data)) {
163
163
  deps.closeOverlay();
164
164
  return true;
@@ -247,11 +247,11 @@ export function routeOverlayKey(
247
247
  ): boolean {
248
248
  if (overlayState === "closed") return false;
249
249
  if (
250
- (overlayState === "dispatch-board" && matches(data, "clio.dispatchBoard.toggle")) ||
251
- (overlayState === "tasks" && matches(data, "clio.tasks.open")) ||
252
- (overlayState === "tree" && matches(data, "clio.session.tree")) ||
253
- (overlayState === "model" && matches(data, "clio.model.select")) ||
254
- (overlayState === "help" && matches(data, "clio.leader"))
250
+ (overlayState === "dispatch-board" && matches(data, "clio-coder.dispatchBoard.toggle")) ||
251
+ (overlayState === "tasks" && matches(data, "clio-coder.tasks.open")) ||
252
+ (overlayState === "tree" && matches(data, "clio-coder.session.tree")) ||
253
+ (overlayState === "model" && matches(data, "clio-coder.model.select")) ||
254
+ (overlayState === "help" && matches(data, "clio-coder.leader"))
255
255
  ) {
256
256
  deps.closeOverlay();
257
257
  return true;
@@ -272,7 +272,7 @@ export function createOverlayLifecycle(deps: OverlayLifecycleRuntimeDeps): Overl
272
272
  ...(deps.app.toolRegistry ? { toolRegistry: deps.app.toolRegistry } : {}),
273
273
  bus: deps.app.bus,
274
274
  dispatch: deps.app.dispatch,
275
- getAutonomy: () => deps.app.getSettings?.().autonomy ?? "auto-edit",
275
+ getAutonomy: () => deps.app.getSettings?.().safety.autonomy ?? "auto-edit",
276
276
  getOverlayState: () => overlayTransitions.state,
277
277
  openPermissionOverlay: (view, inspect) => {
278
278
  if (overlayTransitions.state === "permission-confirm") return false;
@@ -76,11 +76,11 @@ export function createOverlayModelSelectors(deps: OverlayModelSelectorsDeps): Ov
76
76
  if (!deps.getSettings || !deps.writeSettings) return;
77
77
  const next = structuredClone(deps.getSettings()) as ClioSettings;
78
78
  const value = `${ref.target}/${ref.model}`;
79
- const current = new Set(next.modelSelector?.favorites ?? []);
79
+ const current = new Set(next.chat.modelPicker?.favorites ?? []);
80
80
  if (favorite) current.add(value);
81
81
  else current.delete(value);
82
- next.modelSelector = {
83
- ...(next.modelSelector ?? { recentLimit: 12, favorites: [] }),
82
+ next.chat.modelPicker = {
83
+ ...(next.chat.modelPicker ?? { recentLimit: 12, favorites: [] }),
84
84
  favorites: [...current],
85
85
  };
86
86
  deps.writeSettings(next);
@@ -34,7 +34,7 @@ export function openAgentsOverlay(tui: TUI, ctx: SlashCommandContext, onClose: (
34
34
  const delegationItems: ListOverlayItem[] = delegationAgents.map((agent) => {
35
35
  const fullCmd = [agent.command, ...agent.args].join(" ");
36
36
  const label = `${agent.id.padEnd(18)}${fullCmd}`;
37
- const meta = `governance=${agent.toolGovernance ?? "clio-policy"}`;
37
+ const meta = `governance=${agent.toolGovernance ?? "clio-coder-policy"}`;
38
38
  return {
39
39
  id: agent.id,
40
40
  label,
@@ -44,7 +44,7 @@ export function openAgentsOverlay(tui: TUI, ctx: SlashCommandContext, onClose: (
44
44
  const lines = [
45
45
  `# ACP Delegation Agent: ${agent.id}`,
46
46
  `**Command:** \`${fullCmd}\``,
47
- `**Governance:** ${agent.toolGovernance ?? "clio-policy"}`,
47
+ `**Governance:** ${agent.toolGovernance ?? "clio-coder-policy"}`,
48
48
  ];
49
49
  if (agent.labels && Object.keys(agent.labels).length > 0) {
50
50
  lines.push(`**Labels:**`);
@@ -110,7 +110,7 @@ const ELLIPSIS = "…";
110
110
  * should not take the screen. A round that follows an answered one has captured
111
111
  * answers to keep on screen, which is the full surface's whole job.
112
112
  */
113
- export function askUserSurface(questions: ReadonlyArray<AskUserQuestion>, priorRounds = 0): AskUserSurface {
113
+ function askUserSurface(questions: ReadonlyArray<AskUserQuestion>, priorRounds = 0): AskUserSurface {
114
114
  if (priorRounds > 0 || questions.length !== 1) return "interview";
115
115
  const question = questions[0];
116
116
  if (!question) return "interview";
@@ -245,6 +245,16 @@ function fitLine(text: string, width: number): string {
245
245
  return truncateToWidth(text, safeWidth, ELLIPSIS, true);
246
246
  }
247
247
 
248
+ /** Wrap a prose value inside the columns left by its one-time row label. */
249
+ function wrapLabeledValue(prefix: string, value: string, width: number): string[] {
250
+ const safeWidth = Math.max(1, width);
251
+ const prefixWidth = visibleWidth(prefix);
252
+ const valueWidth = Math.max(1, safeWidth - prefixWidth);
253
+ return wrapTextWithAnsi(value, valueWidth).map((line, index) =>
254
+ fitLine(`${index === 0 ? prefix : " ".repeat(prefixWidth)}${line}`, safeWidth),
255
+ );
256
+ }
257
+
248
258
  function compactTitle(question: AskUserQuestion): string {
249
259
  return (question.header ?? question.question).replace(/\s+/g, " ").trim();
250
260
  }
@@ -398,7 +408,8 @@ class AskUserOverlayView implements Component {
398
408
 
399
409
  this.contentOverflows = false;
400
410
  const controlLines = this.renderControlLines(safeWidth);
401
- const statusLines = this.status.length > 0 ? ["", fitLine(clioTheme().fg("dim", this.status), safeWidth)] : [];
411
+ const statusLines =
412
+ this.status.length > 0 ? ["", ...wrapTextWithAnsi(clioTheme().fg("dim", this.status), safeWidth)] : [];
402
413
  const headerLine = this.renderQuestionHeader(question, safeWidth);
403
414
  const headerLines = headerLine.length > 0 ? [headerLine] : [];
404
415
  const bottom = [...statusLines, "", ...controlLines];
@@ -426,7 +437,7 @@ class AskUserOverlayView implements Component {
426
437
  private renderInterview(question: AskUserQuestion, width: number, maxRows: number): string[] {
427
438
  const theme = clioTheme();
428
439
  const controlLines = this.renderControlLines(width);
429
- const statusLines = this.status.length > 0 ? ["", fitLine(theme.fg("dim", this.status), width)] : [];
440
+ const statusLines = this.status.length > 0 ? ["", ...wrapTextWithAnsi(theme.fg("dim", this.status), width)] : [];
430
441
  const headerLine = this.renderQuestionHeader(question, width);
431
442
  const headerLines = headerLine.length > 0 ? [headerLine] : [];
432
443
  const stripLines = [this.renderQuestionStrip(width), ""];
@@ -606,11 +617,14 @@ class AskUserOverlayView implements Component {
606
617
  const lines = [
607
618
  screenTitle(theme, "Interview"),
608
619
  "",
609
- theme.fg(
610
- "muted",
611
- this.history.length > 0
612
- ? "Answer sent. Waiting for Clio to prepare the next interview question."
613
- : "Waiting for Clio to prepare the interview.",
620
+ ...wrapTextWithAnsi(
621
+ theme.fg(
622
+ "muted",
623
+ this.history.length > 0
624
+ ? "Answer sent. Waiting for Clio to prepare the next interview question."
625
+ : "Waiting for Clio to prepare the interview.",
626
+ ),
627
+ width,
614
628
  ),
615
629
  ];
616
630
  if (this.history.length > 0) {
@@ -618,7 +632,7 @@ class AskUserOverlayView implements Component {
618
632
  for (let index = 0; index < this.history.length; index += 1) {
619
633
  const answer = this.history[index];
620
634
  if (!answer) continue;
621
- lines.push(fitLine(`${theme.fg("dim", `${index + 1}.`)} ${theme.fg("muted", answer.answer)}`, width));
635
+ lines.push(...wrapLabeledValue(`${theme.fg("dim", `${index + 1}.`)} `, theme.fg("muted", answer.answer), width));
622
636
  }
623
637
  }
624
638
  return lines.map((line) => fitLine(line, width)).slice(0, maxRows);
@@ -767,7 +781,7 @@ class AskUserOverlayView implements Component {
767
781
  for (let index = 0; index < this.history.length; index += 1) {
768
782
  const answer = this.history[index];
769
783
  if (!answer) continue;
770
- rows.push(fitLine(`${theme.fg("dim", `${index + 1}.`)} ${theme.fg("muted", answer.answer)}`, width));
784
+ rows.push(...wrapLabeledValue(`${theme.fg("dim", `${index + 1}.`)} `, theme.fg("muted", answer.answer), width));
771
785
  }
772
786
  // A round of one question needs no per-question roll: the strip already
773
787
  // names the round and the question is on screen above this.
@@ -775,7 +789,7 @@ class AskUserOverlayView implements Component {
775
789
  for (let index = 0; index < this.questions.length; index += 1) {
776
790
  const answer = this.states[index]?.answer.trim();
777
791
  const value = answer && answer.length > 0 ? theme.fg("muted", answer) : theme.fg("dim", "pending");
778
- rows.push(fitLine(`${theme.fg("dim", `Q${index + 1}`)} ${value}`, width));
792
+ rows.push(...wrapLabeledValue(`${theme.fg("dim", `Q${index + 1}`)} `, value, width));
779
793
  }
780
794
  }
781
795
  if (rows.length === 0) return [];
@@ -1,4 +1,5 @@
1
1
  import {
2
+ type Component,
2
3
  type OverlayHandle,
3
4
  type SelectItem,
4
5
  SelectList,
@@ -6,6 +7,7 @@ import {
6
7
  type TUI,
7
8
  truncateToWidth,
8
9
  visibleWidth,
10
+ wrapTextWithAnsi,
9
11
  } from "../../engine/tui.js";
10
12
  import { buildHint, DEFAULT_SELECT_THEME, FocusBox, showClioOverlayFrame } from "../overlay-frame.js";
11
13
  import type { ContextClearCommandOptions } from "../slash-commands.js";
@@ -29,7 +31,7 @@ export function contextResetOptions(choice: ContextResetMutationChoice): Context
29
31
  }
30
32
 
31
33
  /** Three intentional outcomes, ordered with the least destructive action first. */
32
- export function buildContextResetItems(): SelectItem[] {
34
+ function buildContextResetItems(): SelectItem[] {
33
35
  return [
34
36
  {
35
37
  value: "preserve-clio-md",
@@ -67,6 +69,10 @@ function buildSelectPresentation(items: ReadonlyArray<SelectItem>): {
67
69
  truncatePrimary: ({ text, maxWidth, item, isSelected }) => {
68
70
  const label = singleLine(text);
69
71
  const description = descriptions.get(item.value) ?? "";
72
+ // The focused description is rendered in full below the list. Keeping
73
+ // only its label here prevents the same explanation appearing once cut
74
+ // and once wrapped on the same decision surface.
75
+ if (isSelected) return truncateToWidth(label, maxWidth, ELLIPSIS, true);
70
76
  if (description.length === 0 || maxWidth < 44) {
71
77
  return truncateToWidth(label, maxWidth, ELLIPSIS, true);
72
78
  }
@@ -76,13 +82,31 @@ function buildSelectPresentation(items: ReadonlyArray<SelectItem>): {
76
82
  const spacing = " ".repeat(Math.max(1, labelWidth + 2 - visibleWidth(fittedLabel)));
77
83
  const descriptionWidth = Math.max(1, maxWidth - visibleWidth(fittedLabel) - visibleWidth(spacing));
78
84
  const fittedDescription = truncateToWidth(description, descriptionWidth, ELLIPSIS, true);
79
- const body = `${fittedLabel}${spacing}${fittedDescription}`;
80
- return isSelected ? body : `${fittedLabel}${clioTheme().fg("muted", `${spacing}${fittedDescription}`)}`;
85
+ return `${fittedLabel}${clioTheme().fg("muted", `${spacing}${fittedDescription}`)}`;
81
86
  },
82
87
  },
83
88
  };
84
89
  }
85
90
 
91
+ function describedSelect(list: SelectList, choices: ReadonlyArray<SelectItem>): Component {
92
+ return {
93
+ render(width: number): string[] {
94
+ const rows = list.render(width);
95
+ const selected = list.getSelectedItem();
96
+ const description = choices.find((choice) => choice.value === selected?.value)?.description;
97
+ if (!description) return rows;
98
+ const indent = " ";
99
+ const wrapped = wrapTextWithAnsi(
100
+ clioTheme().fg("muted", singleLine(description)),
101
+ Math.max(1, width - visibleWidth(indent)),
102
+ ).map((line) => `${indent}${line}`);
103
+ return [...rows, ...wrapped];
104
+ },
105
+ handleInput: (data: string) => list.handleInput(data),
106
+ invalidate: () => list.invalidate(),
107
+ };
108
+ }
109
+
86
110
  /** Open the `/context reset` choice dialog. Cancel paths never reach onReset. */
87
111
  export function openContextResetOverlay(tui: TUI, deps: OpenContextResetOverlayDeps): OverlayHandle {
88
112
  const choices = buildContextResetItems();
@@ -99,7 +123,7 @@ export function openContextResetOverlay(tui: TUI, deps: OpenContextResetOverlayD
99
123
  deps.onCancel();
100
124
  };
101
125
 
102
- return showClioOverlayFrame(tui, new FocusBox(list), {
126
+ return showClioOverlayFrame(tui, new FocusBox(describedSelect(list, choices)), {
103
127
  anchor: "center",
104
128
  width: CONTEXT_RESET_OVERLAY_WIDTH,
105
129
  markerId: "context-reset",