@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
@@ -6,7 +6,7 @@ import type { SessionContract, SessionEntry } from "../domains/session/index.js"
6
6
  import { toolPresentationPolicy } from "../tools/presentation.js";
7
7
  import type { ChatLoop } from "./chat-loop.js";
8
8
  import type { ChatPanel } from "./chat-panel.js";
9
- import { bashExecutionEntryInput, parseEditorBashCommand } from "./editor-bash.js";
9
+ import { bashExecutionEntryInput, parseEditorBashCommand, unguardPastedEditorOperator } from "./editor-bash.js";
10
10
  import {
11
11
  formatSteerCandidates,
12
12
  parseEditorSteerMention,
@@ -57,6 +57,8 @@ export interface EditorSubmitExpansion {
57
57
 
58
58
  export interface EditorSubmitEditor {
59
59
  getText(): string;
60
+ /** Draft spelling for an immediate send, including any editor provenance envelope. */
61
+ getTextForSubmit(): string;
60
62
  setText(text: string): void;
61
63
  addToHistory(text: string): void;
62
64
  }
@@ -318,18 +320,19 @@ export function createEditorSubmitController(deps: EditorSubmitDeps): EditorSubm
318
320
  submitEditorSteerMention(mention) !== "unhandled";
319
321
 
320
322
  const submitEditorText = (text: string): void => {
321
- const trimmed = text.trim();
323
+ const literalText = unguardPastedEditorOperator(text);
324
+ const trimmed = literalText.trim();
322
325
  if (trimmed.length === 0) return;
323
326
  deps.collapseLaunchpadBeforeSubmit?.();
324
327
  if (parseEditorBashCommand(text)) {
325
328
  if (!deps.chat.isStreaming() && !activeEditorBash) {
326
- deps.editor.addToHistory(text);
329
+ deps.editor.addToHistory(literalText);
327
330
  deps.editor.setText("");
328
331
  } else {
329
332
  // Pi Editor clears the buffer before invoking onSubmit. A command
330
333
  // refused by either admission guard is still a draft, so put it back
331
334
  // for the operator instead of silently discarding it.
332
- deps.editor.setText(text);
335
+ deps.editor.setText(literalText);
333
336
  }
334
337
  if (runEditorBash(text)) deps.ui.requestRender();
335
338
  return;
@@ -339,12 +342,12 @@ export function createEditorSubmitController(deps: EditorSubmitDeps): EditorSubm
339
342
  const submission = submitEditorSteerMention(steerMention);
340
343
  if (submission !== "unhandled") {
341
344
  if (submission === "accepted") {
342
- deps.editor.addToHistory(text);
345
+ deps.editor.addToHistory(literalText);
343
346
  deps.editor.setText("");
344
347
  } else {
345
348
  // Resolution and dispatch failures are correctable rejections. Pi
346
349
  // has already cleared the editor, so explicitly restore the draft.
347
- deps.editor.setText(text);
350
+ deps.editor.setText(literalText);
348
351
  }
349
352
  deps.ui.requestRender();
350
353
  return;
@@ -352,18 +355,18 @@ export function createEditorSubmitController(deps: EditorSubmitDeps): EditorSubm
352
355
  }
353
356
  const command = parseSlashCommand(trimmed);
354
357
  if (isRejectedCommand(command)) {
355
- deps.editor.setText(text);
358
+ deps.editor.setText(literalText);
356
359
  deps.dispatchCommand(trimmed);
357
360
  } else if (command.kind === "unknown-command") {
358
361
  const result = deps.dispatchCommand(trimmed);
359
362
  if (result === "rejected") {
360
- deps.editor.setText(text);
363
+ deps.editor.setText(literalText);
361
364
  } else {
362
- deps.editor.addToHistory(text);
365
+ deps.editor.addToHistory(literalText);
363
366
  deps.editor.setText("");
364
367
  }
365
368
  } else {
366
- deps.editor.addToHistory(text);
369
+ deps.editor.addToHistory(literalText);
367
370
  deps.editor.setText("");
368
371
  deps.dispatchCommand(trimmed);
369
372
  }
@@ -388,7 +391,8 @@ export function createEditorSubmitController(deps: EditorSubmitDeps): EditorSubm
388
391
  };
389
392
 
390
393
  const admitCapturedText = async (text: string, signal?: AbortSignal): Promise<void> => {
391
- const trimmed = text.trim();
394
+ const literalText = unguardPastedEditorOperator(text);
395
+ const trimmed = literalText.trim();
392
396
  if (trimmed.length === 0) return;
393
397
  signal?.throwIfAborted();
394
398
  deps.collapseLaunchpadBeforeSubmit?.();
@@ -396,7 +400,7 @@ export function createEditorSubmitController(deps: EditorSubmitDeps): EditorSubm
396
400
  while (deps.chat.isStreaming()) await awaitWithAbort(deps.chat.whenSettled(), signal);
397
401
  while (activeEditorBashSettlement) await awaitWithAbort(activeEditorBashSettlement, signal);
398
402
  signal?.throwIfAborted();
399
- deps.editor.addToHistory(text);
403
+ deps.editor.addToHistory(literalText);
400
404
  runEditorBash(text);
401
405
  deps.ui.requestRender();
402
406
  return;
@@ -408,7 +412,7 @@ export function createEditorSubmitController(deps: EditorSubmitDeps): EditorSubm
408
412
  if (submission === "rejected") {
409
413
  throw new Error("queued boot steer was not admitted; preserving it for recovery");
410
414
  }
411
- deps.editor.addToHistory(text);
415
+ deps.editor.addToHistory(literalText);
412
416
  deps.ui.requestRender();
413
417
  return;
414
418
  }
@@ -421,7 +425,7 @@ export function createEditorSubmitController(deps: EditorSubmitDeps): EditorSubm
421
425
  deps.ui.requestRender();
422
426
  throw new Error("queued boot command needs correction; preserving it for recovery");
423
427
  }
424
- deps.editor.addToHistory(text);
428
+ deps.editor.addToHistory(literalText);
425
429
  signal?.throwIfAborted();
426
430
  if (deps.dispatchCommandAsync) await deps.dispatchCommandAsync(trimmed, signal);
427
431
  else deps.dispatchCommand(trimmed);
@@ -429,9 +433,10 @@ export function createEditorSubmitController(deps: EditorSubmitDeps): EditorSubm
429
433
  };
430
434
 
431
435
  const queueFollowUpFromEditor = (): void => {
432
- const text = deps.editor.getText().trim();
436
+ const streaming = deps.chat.isStreaming();
437
+ const text = (streaming ? deps.editor.getText() : deps.editor.getTextForSubmit()).trim();
433
438
  if (text.length === 0) return;
434
- if (!deps.chat.isStreaming()) {
439
+ if (!streaming) {
435
440
  deps.editor.setText("");
436
441
  submitEditorText(text);
437
442
  deps.ui.requestRender();
@@ -458,9 +463,10 @@ export function createEditorSubmitController(deps: EditorSubmitDeps): EditorSubm
458
463
  };
459
464
 
460
465
  const interruptFromEditor = (): void => {
461
- const text = deps.editor.getText().trim();
466
+ const streaming = deps.chat.isStreaming();
467
+ const text = (streaming ? deps.editor.getText() : deps.editor.getTextForSubmit()).trim();
462
468
  if (text.length === 0) return;
463
- if (!deps.chat.isStreaming()) {
469
+ if (!streaming) {
464
470
  deps.editor.setText("");
465
471
  submitEditorText(text);
466
472
  deps.ui.requestRender();
@@ -50,7 +50,7 @@ export function resolveExternalEditor(
50
50
 
51
51
  export function editTextExternally(initialText: string, command: string | null): ExternalEditResult {
52
52
  if (!command) return { ok: false, error: "no external editor configured; set VISUAL or EDITOR" };
53
- const tmpFile = join(tmpdir(), `clio-editor-${process.pid}-${randomUUID()}.md`);
53
+ const tmpFile = join(tmpdir(), `clio-coder-editor-${process.pid}-${randomUUID()}.md`);
54
54
  try {
55
55
  writeFileSync(tmpFile, initialText, "utf8");
56
56
  const result = runEditor(command, tmpFile);
@@ -0,0 +1,360 @@
1
+ import { execFile } from "node:child_process";
2
+ import { open, readdir, stat } from "node:fs/promises";
3
+ import { homedir } from "node:os";
4
+ import { basename, dirname, join, relative, resolve, sep } from "node:path";
5
+ import { enumerateWorkspaceFilesAsync } from "../core/workspace-files.js";
6
+ import { fuzzyFilter, stripTerminalSequences } from "../engine/tui.js";
7
+ import { isEditorSteerTargetToken } from "./editor-steer.js";
8
+
9
+ const MAX_COMPLETION_ROWS = 40;
10
+ const PREVIEW_BYTES = 2048;
11
+ const PREVIEW_CHARS = 120;
12
+ const SNAPSHOT_TTL_MS = 2_000;
13
+ const GIT_OUTPUT_LIMIT_BYTES = 128 * 1024 * 1024;
14
+
15
+ export interface FileReferenceCompletionRequest {
16
+ /** Text after the active `@`, decoded when the reference is quoted. */
17
+ query: string;
18
+ signal: AbortSignal;
19
+ }
20
+
21
+ export interface FileReferenceCompletionValue {
22
+ id: string;
23
+ /** Complete inline reference spelling, including `@` and any quotes. */
24
+ value: string;
25
+ /** Workspace/path spelling without the leading `@` or a trailing slash. */
26
+ path: string;
27
+ label: string;
28
+ description: string;
29
+ isDirectory: boolean;
30
+ tracked: boolean;
31
+ }
32
+
33
+ export type FileReferenceCompletionSource = (
34
+ request: FileReferenceCompletionRequest,
35
+ ) => Promise<ReadonlyArray<FileReferenceCompletionValue>>;
36
+
37
+ export interface FileReferenceCompletionOptions {
38
+ basePath: string;
39
+ cacheTtlMs?: number;
40
+ /** Test/runtime seam; defaults to the repository's authoritative visible-file enumerator. */
41
+ listWorkspaceFiles?: (basePath: string) => Promise<ReadonlyArray<string>>;
42
+ /** Test/runtime seam; defaults to `git ls-files --cached`. */
43
+ listTrackedFiles?: (basePath: string) => Promise<ReadonlySet<string>>;
44
+ }
45
+
46
+ interface FileCandidate {
47
+ path: string;
48
+ absolutePath: string;
49
+ isDirectory: boolean;
50
+ tracked: boolean;
51
+ descendantFiles: number;
52
+ workspace: boolean;
53
+ }
54
+
55
+ interface WorkspaceSnapshot {
56
+ candidates: FileCandidate[];
57
+ directories: ReadonlySet<string>;
58
+ trackedFiles: ReadonlySet<string>;
59
+ }
60
+
61
+ function posixPath(path: string): string {
62
+ return sep === "\\" ? path.replaceAll("\\", "/") : path;
63
+ }
64
+
65
+ function safeRelativePath(path: string): string | null {
66
+ const normalized = posixPath(path).replace(/^\.\//u, "").replace(/\/$/u, "");
67
+ if (normalized.length === 0 || normalized.startsWith("/") || normalized.includes("\0") || /[\r\n]/u.test(normalized)) {
68
+ return null;
69
+ }
70
+ const segments = normalized.split("/");
71
+ if (segments.some((segment) => segment.length === 0 || segment === "." || segment === "..")) return null;
72
+ return segments.join("/");
73
+ }
74
+
75
+ function gitTrackedFiles(basePath: string): Promise<ReadonlySet<string>> {
76
+ return new Promise((resolveTracked) => {
77
+ execFile(
78
+ "git",
79
+ ["--literal-pathspecs", "ls-files", "-z", "--cached"],
80
+ { cwd: basePath, encoding: "utf8", maxBuffer: GIT_OUTPUT_LIMIT_BYTES },
81
+ (error, stdout) => {
82
+ if (error) {
83
+ resolveTracked(new Set());
84
+ return;
85
+ }
86
+ const tracked = new Set<string>();
87
+ for (const raw of stdout.split("\0")) {
88
+ const normalized = safeRelativePath(raw);
89
+ if (normalized) tracked.add(normalized);
90
+ }
91
+ resolveTracked(tracked);
92
+ },
93
+ );
94
+ });
95
+ }
96
+
97
+ function buildWorkspaceSnapshot(
98
+ basePath: string,
99
+ visibleFiles: ReadonlyArray<string>,
100
+ trackedFiles: ReadonlySet<string>,
101
+ ): WorkspaceSnapshot {
102
+ const files: FileCandidate[] = [];
103
+ const directoryFacts = new Map<string, { tracked: boolean; descendantFiles: number }>();
104
+ for (const raw of visibleFiles) {
105
+ const path = safeRelativePath(raw);
106
+ if (!path) continue;
107
+ const tracked = trackedFiles.has(path);
108
+ files.push({
109
+ path,
110
+ absolutePath: join(basePath, path),
111
+ isDirectory: false,
112
+ tracked,
113
+ descendantFiles: 0,
114
+ workspace: true,
115
+ });
116
+ const segments = path.split("/");
117
+ for (let index = 1; index < segments.length; index += 1) {
118
+ const directory = segments.slice(0, index).join("/");
119
+ const facts = directoryFacts.get(directory) ?? { tracked: false, descendantFiles: 0 };
120
+ facts.tracked ||= tracked;
121
+ facts.descendantFiles += 1;
122
+ directoryFacts.set(directory, facts);
123
+ }
124
+ }
125
+ const directories = [...directoryFacts].map(
126
+ ([path, facts]): FileCandidate => ({
127
+ path,
128
+ absolutePath: join(basePath, path),
129
+ isDirectory: true,
130
+ tracked: facts.tracked,
131
+ descendantFiles: facts.descendantFiles,
132
+ workspace: true,
133
+ }),
134
+ );
135
+ return {
136
+ candidates: [...directories, ...files],
137
+ directories: new Set(directoryFacts.keys()),
138
+ trackedFiles,
139
+ };
140
+ }
141
+
142
+ function candidateParent(path: string): string {
143
+ const parent = posixPath(dirname(path));
144
+ return parent === "." ? "" : parent;
145
+ }
146
+
147
+ function fuzzyOrdered(candidates: ReadonlyArray<FileCandidate>, query: string): FileCandidate[] {
148
+ const buckets: FileCandidate[][] = [[], [], [], []];
149
+ for (const candidate of candidates) {
150
+ const bucket = candidate.tracked ? (candidate.isDirectory ? 0 : 1) : candidate.isDirectory ? 2 : 3;
151
+ buckets[bucket]?.push(candidate);
152
+ }
153
+ return buckets.flatMap((bucket) =>
154
+ fuzzyFilter(bucket, query, (candidate) => `${basename(candidate.path)} ${candidate.path}`),
155
+ );
156
+ }
157
+
158
+ function workspaceCandidates(snapshot: WorkspaceSnapshot, rawQuery: string): FileCandidate[] {
159
+ const explicitDot = rawQuery.startsWith("./");
160
+ const query = explicitDot ? rawQuery.slice(2) : rawQuery;
161
+ const slash = query.lastIndexOf("/");
162
+ if (query.length === 0) {
163
+ return fuzzyOrdered(
164
+ snapshot.candidates
165
+ .filter((candidate) => candidateParent(candidate.path) === "")
166
+ .map((candidate) => (explicitDot ? { ...candidate, path: `./${candidate.path}` } : candidate)),
167
+ "",
168
+ );
169
+ }
170
+ if (slash >= 0) {
171
+ const parent = query.slice(0, slash);
172
+ const fragment = query.slice(slash + 1);
173
+ if (parent.length === 0 || snapshot.directories.has(parent)) {
174
+ const displayPrefix = explicitDot ? "./" : "";
175
+ return fuzzyOrdered(
176
+ snapshot.candidates
177
+ .filter((candidate) => candidateParent(candidate.path) === parent)
178
+ .map((candidate) => ({ ...candidate, path: `${displayPrefix}${candidate.path}` })),
179
+ fragment,
180
+ );
181
+ }
182
+ }
183
+ return fuzzyOrdered(
184
+ snapshot.candidates.map((candidate) => (explicitDot ? { ...candidate, path: `./${candidate.path}` } : candidate)),
185
+ query,
186
+ );
187
+ }
188
+
189
+ function explicitPathQuery(query: string): boolean {
190
+ return query.startsWith("../") || query.startsWith("~/") || query.startsWith("/");
191
+ }
192
+
193
+ function resolveDisplayBase(basePath: string, displayBase: string): string {
194
+ if (displayBase.startsWith("~/")) return resolve(homedir(), displayBase.slice(2));
195
+ if (displayBase.startsWith("/")) return resolve(displayBase);
196
+ return resolve(basePath, displayBase);
197
+ }
198
+
199
+ function workspaceRelative(basePath: string, absolutePath: string): string | null {
200
+ const candidate = posixPath(relative(basePath, absolutePath));
201
+ if (candidate.length === 0 || candidate === ".." || candidate.startsWith("../")) return null;
202
+ return safeRelativePath(candidate);
203
+ }
204
+
205
+ async function explicitCandidates(
206
+ basePath: string,
207
+ query: string,
208
+ trackedFiles: ReadonlySet<string>,
209
+ ): Promise<FileCandidate[]> {
210
+ const slash = query.lastIndexOf("/");
211
+ if (slash < 0) return [];
212
+ const displayBase = query.slice(0, slash + 1);
213
+ const fragment = query.slice(slash + 1);
214
+ const directory = resolveDisplayBase(basePath, displayBase);
215
+ const candidates: FileCandidate[] = [];
216
+ for (const entry of await readdir(directory, { withFileTypes: true })) {
217
+ if (entry.name === ".git" || /[\r\n\0]/u.test(entry.name)) continue;
218
+ const absolutePath = join(directory, entry.name);
219
+ let isDirectory = entry.isDirectory();
220
+ let isFile = entry.isFile();
221
+ if (!isDirectory && !isFile && entry.isSymbolicLink()) {
222
+ try {
223
+ const facts = await stat(absolutePath);
224
+ isDirectory = facts.isDirectory();
225
+ isFile = facts.isFile();
226
+ } catch {
227
+ continue;
228
+ }
229
+ }
230
+ if (!isDirectory && !isFile) continue;
231
+ const relativePath = workspaceRelative(basePath, absolutePath);
232
+ candidates.push({
233
+ path: `${displayBase}${entry.name}`,
234
+ absolutePath,
235
+ isDirectory,
236
+ tracked: relativePath !== null && trackedFiles.has(relativePath),
237
+ descendantFiles: 0,
238
+ workspace: relativePath !== null,
239
+ });
240
+ }
241
+ return fuzzyOrdered(candidates, fragment);
242
+ }
243
+
244
+ function formatBytes(bytes: number): string {
245
+ if (bytes < 1024) return `${bytes}B`;
246
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(bytes < 10 * 1024 ? 1 : 0)}KB`;
247
+ return `${(bytes / (1024 * 1024)).toFixed(bytes < 10 * 1024 * 1024 ? 1 : 0)}MB`;
248
+ }
249
+
250
+ function cleanPreview(bytes: Buffer): string | null {
251
+ if (bytes.includes(0)) return "binary file";
252
+ const text = stripTerminalSequences(bytes.toString("utf8"));
253
+ const line = text
254
+ .split(/\r?\n/u)
255
+ .map((candidate) =>
256
+ Array.from(candidate, (character) => {
257
+ const code = character.codePointAt(0) ?? 0;
258
+ return code < 32 || code === 127 ? " " : character;
259
+ })
260
+ .join("")
261
+ .trim(),
262
+ )
263
+ .find((candidate) => candidate.length > 0);
264
+ if (!line) return null;
265
+ return line.length > PREVIEW_CHARS ? `${line.slice(0, PREVIEW_CHARS - 1)}…` : line;
266
+ }
267
+
268
+ async function candidateDescription(candidate: FileCandidate): Promise<string> {
269
+ const provenance = candidate.tracked ? "git tracked" : candidate.workspace ? "untracked" : "filesystem";
270
+ if (candidate.isDirectory) {
271
+ const count = candidate.descendantFiles > 0 ? ` · ${candidate.descendantFiles} files` : "";
272
+ return `${provenance} directory${count} · Tab/Enter opens`;
273
+ }
274
+ try {
275
+ const facts = await stat(candidate.absolutePath);
276
+ const handle = await open(candidate.absolutePath, "r");
277
+ let preview: string | null = null;
278
+ try {
279
+ const buffer = Buffer.alloc(Math.min(PREVIEW_BYTES, Math.max(0, facts.size)));
280
+ if (buffer.length > 0) {
281
+ const { bytesRead } = await handle.read(buffer, 0, buffer.length, 0);
282
+ preview = cleanPreview(buffer.subarray(0, bytesRead));
283
+ }
284
+ } finally {
285
+ await handle.close();
286
+ }
287
+ return `${provenance} · ${formatBytes(facts.size)}${preview ? ` · ${preview}` : ""}`;
288
+ } catch {
289
+ return `${provenance} · preview unavailable`;
290
+ }
291
+ }
292
+
293
+ /** Quote a completion exactly the way the inline-reference scanner accepts. */
294
+ function formatInlineFileReference(path: string, isDirectory: boolean): string {
295
+ const completionPath = isDirectory ? `${path.replace(/\/$/u, "")}/` : path;
296
+ if (!/[\s"'\\]/u.test(completionPath) && !isEditorSteerTargetToken(completionPath)) return `@${completionPath}`;
297
+ return `@"${completionPath.replaceAll("\\", "\\\\").replaceAll('"', '\\"')}"`;
298
+ }
299
+
300
+ function completionId(candidate: FileCandidate): string {
301
+ return `file-reference:${candidate.isDirectory ? "directory" : "file"}:${candidate.absolutePath}`;
302
+ }
303
+
304
+ /**
305
+ * Workspace-aware `@` source for Clio's one grammar-aware composer provider.
306
+ * A bare `@` is a top-level tree; text without a slash fuzzes the whole
307
+ * workspace; a real directory prefix becomes its child submenu. Explicit
308
+ * `../`, `~/`, and absolute prefixes stay scoped filesystem navigation.
309
+ */
310
+ export function createFileReferenceCompletionSource(
311
+ options: FileReferenceCompletionOptions,
312
+ ): FileReferenceCompletionSource {
313
+ const basePath = resolve(options.basePath);
314
+ const listWorkspaceFiles = options.listWorkspaceFiles ?? ((cwd: string) => enumerateWorkspaceFilesAsync(cwd));
315
+ const listTrackedFiles = options.listTrackedFiles ?? gitTrackedFiles;
316
+ const cacheTtlMs = options.cacheTtlMs ?? SNAPSHOT_TTL_MS;
317
+ let cached: { expiresAt: number; snapshot: WorkspaceSnapshot } | null = null;
318
+ let loading: Promise<WorkspaceSnapshot> | null = null;
319
+
320
+ const snapshot = async (): Promise<WorkspaceSnapshot> => {
321
+ const now = Date.now();
322
+ if (cached && cached.expiresAt > now) return cached.snapshot;
323
+ loading ??= Promise.all([listWorkspaceFiles(basePath), listTrackedFiles(basePath)]).then(([visible, tracked]) =>
324
+ buildWorkspaceSnapshot(basePath, visible, tracked),
325
+ );
326
+ try {
327
+ const next = await loading;
328
+ cached = { expiresAt: now + cacheTtlMs, snapshot: next };
329
+ return next;
330
+ } finally {
331
+ loading = null;
332
+ }
333
+ };
334
+
335
+ return async (request) => {
336
+ if (request.signal.aborted) return [];
337
+ try {
338
+ const workspace = await snapshot();
339
+ if (request.signal.aborted) return [];
340
+ const candidates = explicitPathQuery(request.query)
341
+ ? await explicitCandidates(basePath, request.query, workspace.trackedFiles)
342
+ : workspaceCandidates(workspace, request.query);
343
+ if (request.signal.aborted) return [];
344
+ const top = candidates.slice(0, MAX_COMPLETION_ROWS);
345
+ const descriptions = await Promise.all(top.map(candidateDescription));
346
+ if (request.signal.aborted) return [];
347
+ return top.map((candidate, index) => ({
348
+ id: completionId(candidate),
349
+ value: formatInlineFileReference(candidate.path, candidate.isDirectory),
350
+ path: candidate.path,
351
+ label: `${candidate.path}${candidate.isDirectory ? "/" : ""}`,
352
+ description: descriptions[index] ?? "preview unavailable",
353
+ isDirectory: candidate.isDirectory,
354
+ tracked: candidate.tracked,
355
+ }));
356
+ } catch {
357
+ return [];
358
+ }
359
+ };
360
+ }
@@ -208,7 +208,7 @@ function renderFooterDashboardLines(
208
208
  * Widths from 80 to 119 columns use a two by two grid.
209
209
  * Widths below 80 columns use a vertical stack with all sections retained.
210
210
  */
211
- export function renderFooterStatusLines(state: FooterDashboardRenderState, width: number): string[] {
211
+ function renderFooterStatusLines(state: FooterDashboardRenderState, width: number): string[] {
212
212
  const theme = clioTheme();
213
213
  const safeWidth = Math.max(1, Math.floor(width));
214
214
  const header = headerLine(state.session, safeWidth);
@@ -297,7 +297,7 @@ export function renderFooterStatusLines(state: FooterDashboardRenderState, width
297
297
  * current work the strongest column; surplus is shared by urgency until the
298
298
  * lower-priority sections reach their caps, then spills into Activity.
299
299
  */
300
- export function expandedWideColumnWidths(width: number, totalSepWidth: number): [number, number, number, number] {
300
+ function expandedWideColumnWidths(width: number, totalSepWidth: number): [number, number, number, number] {
301
301
  const available = Math.max(0, width - totalSepWidth);
302
302
  const widths: [number, number, number, number] = [32, 31, 27, 21];
303
303
  let remaining = Math.max(0, available - widths.reduce((sum, item) => sum + item, 0));
@@ -392,33 +392,31 @@ export function buildFooterDashboard(deps: FooterDashboardDeps): FooterDashboard
392
392
  const tokensLabel = tokens || (usage?.totalTokens ? `Σ${formatFooterTokens(usage.totalTokens)}` : null);
393
393
 
394
394
  const statuses = deps.providers.list();
395
- const current = settings?.orchestrator?.target
396
- ? (statuses.find((s) => s.target.id === settings.orchestrator?.target) ?? null)
397
- : null;
395
+ const current = settings?.chat?.target ? (statuses.find((s) => s.target.id === settings.chat?.target) ?? null) : null;
398
396
 
399
- const target = formatTargetLabel(settings?.orchestrator?.target, settings?.orchestrator?.model);
397
+ const target = formatTargetLabel(settings?.chat?.target, settings?.chat?.model);
400
398
 
401
399
  const resolution = resolveModelRuntimeCapabilitiesForProviders(
402
400
  deps.providers,
403
- settings?.orchestrator?.target,
404
- settings?.orchestrator?.model,
405
- settings?.orchestrator?.thinkingLevel ?? "off",
401
+ settings?.chat?.target,
402
+ settings?.chat?.model,
403
+ settings?.chat?.thinkingLevel ?? "off",
406
404
  );
407
405
 
408
- const thinking = resolution?.thinking.display ?? settings?.orchestrator?.thinkingLevel ?? "off";
406
+ const thinking = resolution?.thinking.display ?? settings?.chat?.thinkingLevel ?? "off";
409
407
 
410
- const wireModelId = settings?.orchestrator?.model ?? current?.target.defaultModel ?? null;
408
+ const wireModelId = settings?.chat?.model ?? current?.target.defaultModel ?? null;
411
409
  const detectedReasoning =
412
410
  wireModelId && typeof deps.providers.getDetectedReasoning === "function"
413
- ? deps.providers.getDetectedReasoning(settings?.orchestrator?.target ?? "", wireModelId)
411
+ ? deps.providers.getDetectedReasoning(settings?.chat?.target ?? "", wireModelId)
414
412
  : null;
415
413
  const caps = current
416
414
  ? resolveModelCapabilities(current, wireModelId, deps.providers.knowledgeBase, { detectedReasoning })
417
415
  : null;
418
416
  const capabilities = capabilityLabels(caps);
419
417
 
420
- const safety = settings?.autonomy ?? "auto-edit";
421
- const toolProfile = settings?.delegation?.defaults?.toolGovernance ?? "clio-policy";
418
+ const safety = settings?.safety.autonomy ?? "auto-edit";
419
+ const toolProfile = settings?.integrations.externalAgents?.defaults?.toolGovernance ?? "clio-coder-policy";
422
420
 
423
421
  return {
424
422
  workspace: workspaceFacts(deps, branchSlot),
@@ -436,7 +434,7 @@ export function buildFooterDashboard(deps: FooterDashboardDeps): FooterDashboard
436
434
  capabilities,
437
435
  safety,
438
436
  toolProfile,
439
- outputVerbosity: settings?.terminal.outputVerbosity ?? "default",
437
+ outputVerbosity: settings?.interface.outputDetail ?? "default",
440
438
  leaderArmed: deps.getLeaderArmed?.() ?? false,
441
439
  shutdownArmed: deps.getShutdownArmed?.() ?? false,
442
440
  memoryIntervention: taskMemory
@@ -454,8 +452,8 @@ export function buildFooterDashboard(deps: FooterDashboardDeps): FooterDashboard
454
452
  used: contextUsage?.tokens ?? null,
455
453
  contextWindow: contextUsage?.contextWindow ?? null,
456
454
  toolSchemaTokens: contextUsage?.breakdown?.toolSchemaTokens ?? null,
457
- compactionThreshold: settings?.compaction?.threshold ?? null,
458
- compactionAuto: settings?.compaction?.auto ?? null,
455
+ compactionThreshold: settings?.context.compaction?.threshold ?? null,
456
+ compactionAuto: settings?.context.compaction?.auto ?? null,
459
457
  compactionActive,
460
458
  clioMd: formatClioMdState(contextState?.clioMd),
461
459
  memory: formatMemoryState(contextState?.memoryCount),
@@ -14,7 +14,7 @@
14
14
  * color lives in `theme/**`; every emitted line is width-clamped.
15
15
  */
16
16
 
17
- import { truncateToWidth, visibleWidth } from "../../engine/tui.js";
17
+ import { truncateToWidth, visibleWidth, wrapTextWithAnsi } from "../../engine/tui.js";
18
18
  import { fitFooterText } from "../footer-panel.js";
19
19
  import { type ClioTheme, type ClioToken, clioTheme, GLYPH, rule } from "../theme/index.js";
20
20
 
@@ -152,7 +152,7 @@ function boundNotifyBytes(text: string, maxBytes: number): string {
152
152
  }
153
153
 
154
154
  /** The closed-vocabulary body for one event. */
155
- export function desktopNotifyBody(event: DesktopNotifyEvent): string {
155
+ function desktopNotifyBody(event: DesktopNotifyEvent): string {
156
156
  if (event.kind === "turn-finished") return "turn finished";
157
157
  if (event.kind === "approval-needed") return "approval needed";
158
158
  const shortId = boundNotifyBytes(sanitizeNotifyText(event.shortId), 32);
@@ -160,7 +160,7 @@ export function desktopNotifyBody(event: DesktopNotifyEvent): string {
160
160
  }
161
161
 
162
162
  /** True when the environment names a terminal that answers OSC 9 rather than OSC 777. */
163
- export function prefersOsc9(env: Readonly<Record<string, string | undefined>>): boolean {
163
+ function prefersOsc9(env: Readonly<Record<string, string | undefined>>): boolean {
164
164
  if (typeof env.WT_SESSION === "string" && env.WT_SESSION.length > 0) return true;
165
165
  const program = (env.TERM_PROGRAM ?? "").trim().toLowerCase();
166
166
  if (program.length === 0) return false;
@@ -173,7 +173,7 @@ export function prefersOsc9(env: Readonly<Record<string, string | undefined>>):
173
173
  * chosen for the terminals that implement it instead. Exactly one sequence is
174
174
  * returned, so a single event can never produce two notifications.
175
175
  */
176
- export function buildDesktopNotifySequence(
176
+ function buildDesktopNotifySequence(
177
177
  event: DesktopNotifyEvent,
178
178
  env: Readonly<Record<string, string | undefined>> = process.env,
179
179
  ): string {
@@ -208,7 +208,7 @@ export interface DesktopNotifier {
208
208
  * events. Every call re-checks the setting and the surface, so turning
209
209
  * `terminal.notify` off mid-session silences the next event.
210
210
  */
211
- export function createDesktopNotifier(deps: DesktopNotifierDeps): DesktopNotifier {
211
+ function createDesktopNotifier(deps: DesktopNotifierDeps): DesktopNotifier {
212
212
  const env = deps.env ?? process.env;
213
213
  return {
214
214
  notify(event) {
@@ -470,8 +470,9 @@ export function formatNotificationBadge(
470
470
  }
471
471
 
472
472
  /**
473
- * Expanded notices panel for the dashboard. Header rule + one styled line per
474
- * entry, capped so a noisy boot cannot push the dashboard off-screen.
473
+ * Expanded notices panel for the dashboard. The entry count is capped so a
474
+ * noisy boot cannot take over the dashboard, but every included notice wraps
475
+ * in full: this is the detail surface that the compact badge points toward.
475
476
  */
476
477
  export function formatNotificationPanel(
477
478
  entries: ReadonlyArray<Notification>,
@@ -485,7 +486,12 @@ export function formatNotificationPanel(
485
486
  const lines: string[] = [rule(theme, width, { left: "notices" })];
486
487
  for (const entry of entries.slice(0, maxRows)) {
487
488
  const glyph = theme.fg(notificationToken(entry.level), notificationGlyph(entry.level));
488
- lines.push(fitFooterText(`${glyph} ${theme.fg("muted", entry.text)}`, width, GLYPH.ellipsis));
489
+ const prefix = `${glyph} `;
490
+ const prefixWidth = visibleWidth(prefix);
491
+ const wrapped = wrapTextWithAnsi(theme.fg("muted", entry.text), Math.max(1, width - prefixWidth));
492
+ lines.push(
493
+ ...wrapped.map((line, index) => fitFooterText(`${index === 0 ? prefix : " ".repeat(prefixWidth)}${line}`, width)),
494
+ );
489
495
  }
490
496
  const overflow = entries.length - maxRows;
491
497
  const hint = overflow > 0 ? `+${overflow} more · ${dismiss} dismiss` : `${dismiss} dismiss`;