@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
@@ -215,7 +215,7 @@ export interface ChatSubmitOptions {
215
215
  * the turn runtime's own local fallback, so a `/btw` round against a local
216
216
  * server authenticates exactly the way a turn against it does.
217
217
  */
218
- const LOCAL_SIDE_QUESTION_API_KEY = "clio-local-target";
218
+ const LOCAL_SIDE_QUESTION_API_KEY = "clio-coder-local-target";
219
219
 
220
220
  /** Closing notice an operator interrupt leaves in the transcript and the ledger. */
221
221
  const INTERRUPT_CANCEL_REASON = "[Clio Coder] run interrupted by operator; delivering the new message now.";
@@ -372,7 +372,7 @@ export interface CreateChatLoopDeps {
372
372
  /**
373
373
  * Whitelist of target ids that the chat-loop is allowed to drive. The
374
374
  * orchestrator composes this from `providers.list()` so an unknown
375
- * `settings.orchestrator.target` surfaces a configuration error before
375
+ * `settings.chat.target` surfaces a configuration error before
376
376
  * the agent is constructed.
377
377
  */
378
378
  knownTargets: () => ReadonlySet<string>;
@@ -527,7 +527,7 @@ export interface CreateChatLoopDeps {
527
527
  registerPrewarmEndpointSlot?: (runtime: AgentRuntime) => (() => void) | null;
528
528
  }
529
529
 
530
- export function reloadProtectedArtifactsForSession(
530
+ function reloadProtectedArtifactsForSession(
531
531
  protectedArtifacts: NonNullable<CreateChatLoopDeps["protectedArtifacts"]>,
532
532
  readSessionEntries: (() => ReadonlyArray<SessionEntry>) | undefined,
533
533
  ): void {
@@ -547,7 +547,7 @@ export function createChatLoop(deps: CreateChatLoopDeps): ChatLoop {
547
547
  const sideQuestionRound = deps.runSideQuestion ?? runSideQuestion;
548
548
  const handoffRound = deps.runHandoffRound ?? runHandoffRound;
549
549
  const middlewareToolChoice = deps.middlewareToolChoice ?? createMiddlewareToolChoiceControl();
550
- const state = createTurnState(deps.getSettings().orchestrator.thinkingLevel ?? "off");
550
+ const state = createTurnState(deps.getSettings().chat.thinkingLevel ?? "off");
551
551
  const toolStartTimes = new Map<string, number>();
552
552
 
553
553
  const preparationListeners = new Set<(phase: TurnPreparationPhase) => void>();
@@ -639,13 +639,13 @@ export function createChatLoop(deps: CreateChatLoopDeps): ChatLoop {
639
639
  * collapsing them sent a client with a configured target to the wrong fix.
640
640
  */
641
641
  const nullRuntimeAdmissionReason = (): string => {
642
- const orchestrator = deps.getSettings().orchestrator;
642
+ const orchestrator = deps.getSettings().chat;
643
643
  const target = orchestrator.target?.trim() ?? "";
644
644
  const model = orchestrator.model?.trim() ?? "";
645
645
  return target.length > 0 && model.length === 0 ? "model-not-configured" : "orchestrator-not-configured";
646
646
  };
647
647
 
648
- const retrySettings = (): RetrySettings => normalizeRetrySettings(deps.getSettings().retry);
648
+ const retrySettings = (): RetrySettings => normalizeRetrySettings(deps.getSettings().chat.retry);
649
649
 
650
650
  const currentToolInvokeOptions = (): Partial<ToolInvokeOptions> => {
651
651
  const options: Partial<ToolInvokeOptions> = {};
@@ -1088,7 +1088,7 @@ export function createChatLoop(deps: CreateChatLoopDeps): ChatLoop {
1088
1088
  // 4. Preflight overflow check, before the user turn is committed.
1089
1089
  // A blocked request must not leave a dangling user entry that the
1090
1090
  // next replay would treat as an unanswered turn.
1091
- const compactionThreshold = deps.getSettings().compaction?.threshold ?? null;
1091
+ const compactionThreshold = deps.getSettings().context.compaction?.threshold ?? null;
1092
1092
  const captureTurnSnapshot = (turnId: string): ContextSnapshot =>
1093
1093
  context.captureRuntimeContextSnapshot(agentRuntime, turnId, compactionThreshold, {
1094
1094
  promptSegments: compiledPrompt
@@ -1179,7 +1179,7 @@ export function createChatLoop(deps: CreateChatLoopDeps): ChatLoop {
1179
1179
  runtimeId: agentRuntime.runtimeId,
1180
1180
  runtimeKind: agentRuntime.runtimeResolution.runtimeKind,
1181
1181
  wireModelId: agentRuntime.wireModelId,
1182
- autonomy: deps.getSettings().autonomy,
1182
+ autonomy: deps.getSettings().safety.autonomy,
1183
1183
  compiledPromptHash: promptHash,
1184
1184
  staticCompositionHash: promptHash,
1185
1185
  promptSignature: promptHash,
@@ -384,7 +384,7 @@ export interface ChatPanel extends Component {
384
384
 
385
385
  export interface ChatPanelOptions {
386
386
  /**
387
- * Resolves the user-visible key string for the `clio.tool.expand`
387
+ * Resolves the user-visible key string for the `clio-coder.tool.expand`
388
388
  * action, which folds and unfolds the newest tool call or worker block.
389
389
  * Returning a non-empty string surfaces a dim ` (<key>)` hint on the one
390
390
  * surface the key would act on: the latest finished collapsed tool subline,
@@ -1,4 +1,12 @@
1
- import { Editor, stripTerminalSequences, type TUI, truncateToWidth, visibleWidth } from "../engine/tui.js";
1
+ import {
2
+ Editor,
3
+ getKeybindings,
4
+ stripTerminalSequences,
5
+ type TUI,
6
+ truncateToWidth,
7
+ visibleWidth,
8
+ } from "../engine/tui.js";
9
+ import { guardPastedEditorOperator } from "./editor-bash.js";
2
10
  import { fitHintEntries } from "./overlay-frame.js";
3
11
  import { type PermissionInspectionHint, permissionHintEntries } from "./permission-hint.js";
4
12
  import type { ClioTheme } from "./theme/index.js";
@@ -154,7 +162,50 @@ function findBottomRail(lines: readonly string[], width: number): number {
154
162
  return -1;
155
163
  }
156
164
 
165
+ function cursorEndsDirectoryPath(editor: Editor): boolean {
166
+ const cursor = editor.getCursor();
167
+ const line = editor.getLines()[cursor.line] ?? "";
168
+ return line.slice(0, cursor.col).endsWith("/");
169
+ }
170
+
171
+ function remapPastedBangOffsets(
172
+ before: string,
173
+ after: string,
174
+ offsets: ReadonlySet<number>,
175
+ markInsertedAsPasted: boolean,
176
+ ): Set<number> {
177
+ let prefix = 0;
178
+ while (prefix < before.length && prefix < after.length && before[prefix] === after[prefix]) prefix += 1;
179
+ let beforeEnd = before.length;
180
+ let afterEnd = after.length;
181
+ while (beforeEnd > prefix && afterEnd > prefix && before[beforeEnd - 1] === after[afterEnd - 1]) {
182
+ beforeEnd -= 1;
183
+ afterEnd -= 1;
184
+ }
185
+
186
+ const next = new Set<number>();
187
+ const shift = afterEnd - prefix - (beforeEnd - prefix);
188
+ for (const offset of offsets) {
189
+ if (offset < prefix) next.add(offset);
190
+ else if (offset >= beforeEnd) next.add(offset + shift);
191
+ }
192
+ if (markInsertedAsPasted) {
193
+ for (let offset = prefix; offset < afterEnd; offset += 1) {
194
+ if (after[offset] === "!") next.add(offset);
195
+ }
196
+ }
197
+ return next;
198
+ }
199
+
200
+ function startsWithPastedOperator(text: string, pastedBangOffsets: ReadonlySet<number>): boolean {
201
+ const first = text.search(/\S/u);
202
+ return first >= 0 && text[first] === "!" && pastedBangOffsets.has(first);
203
+ }
204
+
157
205
  export class ClioEditor extends Editor {
206
+ private pastedBangOffsets = new Set<number>();
207
+ private bracketedPasteActive = false;
208
+
158
209
  constructor(
159
210
  tui: TUI,
160
211
  private readonly chrome: EditorChrome,
@@ -213,6 +264,15 @@ export class ClioEditor extends Editor {
213
264
  return lines;
214
265
  }
215
266
 
267
+ /**
268
+ * Preserve paste provenance for every immediate-send binding, including the
269
+ * alternate paths that invoke the submit controller without an Editor Enter.
270
+ */
271
+ getTextForSubmit(): string {
272
+ const text = this.getExpandedText();
273
+ return startsWithPastedOperator(this.getText(), this.pastedBangOffsets) ? guardPastedEditorOperator(text) : text;
274
+ }
275
+
216
276
  /**
217
277
  * pi-tui's bracketed-paste handling inserts pasted text (including a
218
278
  * trailing newline the paste carried) without submitting: a pasted
@@ -222,8 +282,46 @@ export class ClioEditor extends Editor {
222
282
  * through the same handler the typed-Enter path uses.
223
283
  */
224
284
  override handleInput(data: string): void {
285
+ const openedPaste = data.includes("\x1b[200~");
225
286
  const closedPaste = data.includes("\x1b[201~");
287
+ const pasteMutation = this.bracketedPasteActive || openedPaste;
288
+ const textBeforeInput = this.getText();
289
+ const keybindings = getKeybindings();
290
+ // Pi expands and trims the buffer immediately before onSubmit. Envelope a
291
+ // pasted bang draft for that synchronous handoff so the Bash parser can
292
+ // distinguish it from a typed operator; the submit controller unwraps it
293
+ // before sending the literal prompt onward.
294
+ if (
295
+ startsWithPastedOperator(textBeforeInput, this.pastedBangOffsets) &&
296
+ keybindings.matches(data, "tui.input.submit")
297
+ ) {
298
+ const pastedText = this.getTextForSubmit();
299
+ this.pastedBangOffsets.clear();
300
+ this.bracketedPasteActive = false;
301
+ super.setText(pastedText);
302
+ super.handleInput(data);
303
+ return;
304
+ }
305
+ const completingDirectory =
306
+ this.isShowingAutocomplete() &&
307
+ (keybindings.matches(data, "tui.input.tab") || keybindings.matches(data, "tui.select.confirm"));
308
+ const textBeforeCompletion = completingDirectory ? this.getText() : "";
226
309
  super.handleInput(data);
310
+ if (completingDirectory && this.getText() !== textBeforeCompletion && cursorEndsDirectoryPath(this)) {
311
+ // Directory rows are submenus on the same provider. Re-open immediately
312
+ // after acceptance so ↑/↓ continues in the child tree without requiring
313
+ // a second Tab. Pi's provider request remains the only completion path.
314
+ super.handleInput("\t");
315
+ }
316
+ const textAfterInput = this.getText();
317
+ this.pastedBangOffsets = remapPastedBangOffsets(
318
+ textBeforeInput,
319
+ textAfterInput,
320
+ this.pastedBangOffsets,
321
+ pasteMutation,
322
+ );
323
+ if (openedPaste) this.bracketedPasteActive = true;
324
+ if (closedPaste) this.bracketedPasteActive = false;
227
325
  if (!closedPaste) return;
228
326
  const text = this.getText();
229
327
  if (!text.endsWith("\n")) return;
@@ -232,4 +330,10 @@ export class ClioEditor extends Editor {
232
330
  this.setText("");
233
331
  this.onSubmit?.(command);
234
332
  }
333
+
334
+ override setText(text: string): void {
335
+ this.pastedBangOffsets.clear();
336
+ this.bracketedPasteActive = false;
337
+ super.setText(text);
338
+ }
235
339
  }
@@ -6,6 +6,7 @@ import {
6
6
  type ContextActivityStatus,
7
7
  } from "../core/bus-events.js";
8
8
  import type { SafeEventBus } from "../core/event-bus.js";
9
+ import { wrapTextWithAnsi } from "../engine/tui.js";
9
10
  import { type ClioTheme, clioTheme, formatCompactMs, frame, GLYPH, padAnsi, spinnerFrame } from "./theme/index.js";
10
11
 
11
12
  export interface ContextActivitySnapshot {
@@ -152,17 +153,18 @@ export function formatContextActivityIslandLines(
152
153
  const percent = `${Math.round(activityProgress(activity) * 100)}%`.padStart(4);
153
154
  const progressLine = `${progressBar(theme, activity, barWidth)} ${theme.fg("dim", percent)}`;
154
155
  const message = theme.fg(activity.status === "failed" ? "error" : "muted", activity.message);
155
- // Every row here can outrun a narrow island: at 40 columns the trail stopped
156
- // at "sta" and the message at "refreshed pr", each reading as the whole
157
- // value. padAnsi's default marker is empty, so the marker is passed
158
- // explicitly. The progress bar is sized to fit and never cuts.
156
+ // The trail is compact navigation chrome and marks its cut. The message and
157
+ // detail are the only explanation of this operation, so they wrap in full.
158
+ // The progress bar is sized to fit and never cuts.
159
159
  const body = [
160
160
  padAnsi(topLine, bodyWidth, GLYPH.ellipsis),
161
161
  padAnsi(progressLine, bodyWidth),
162
162
  phaseTrail(theme, activity, bodyWidth),
163
- padAnsi(message, bodyWidth, GLYPH.ellipsis),
163
+ ...wrapTextWithAnsi(message, bodyWidth).map((line) => padAnsi(line, bodyWidth)),
164
164
  ];
165
- if (activity.detail) body.push(padAnsi(theme.fg("dim", activity.detail), bodyWidth, GLYPH.ellipsis));
165
+ if (activity.detail) {
166
+ body.push(...wrapTextWithAnsi(theme.fg("dim", activity.detail), bodyWidth).map((line) => padAnsi(line, bodyWidth)));
167
+ }
166
168
  return frame(theme, "Context", body, width);
167
169
  }
168
170
 
@@ -23,7 +23,7 @@ export const CONTEXT_CATEGORY_TOKEN: Readonly<Record<ContextLedgerCategory, Clio
23
23
  streaming: "accent",
24
24
  };
25
25
 
26
- export function contextCategoryGlyph(category: ContextLedgerCategory): string {
26
+ function contextCategoryGlyph(category: ContextLedgerCategory): string {
27
27
  const filled = visibleSingle(GLYPH.contextFull) ? GLYPH.contextFull : GLYPH.barFull;
28
28
  const free = visibleSingle(GLYPH.contextFree) ? GLYPH.contextFree : GLYPH.barEmpty;
29
29
  // The autocompact reserve is held-back headroom, not consumed context; it
@@ -187,7 +187,7 @@ export type WorkerContextSeverity = "healthy" | "warn" | "critical";
187
187
  export const WORKER_CONTEXT_WARN_PCT = 80;
188
188
  export const WORKER_CONTEXT_CRITICAL_PCT = 95;
189
189
 
190
- export function workerContextSeverity(pct: number): WorkerContextSeverity {
190
+ function workerContextSeverity(pct: number): WorkerContextSeverity {
191
191
  if (pct >= WORKER_CONTEXT_CRITICAL_PCT) return "critical";
192
192
  if (pct >= WORKER_CONTEXT_WARN_PCT) return "warn";
193
193
  return "healthy";
@@ -211,10 +211,7 @@ export interface WorkerContextView {
211
211
  * usage has been observed yet. The percentage is capped at 100: a provider
212
212
  * report past the window is a full window, not a >100% claim.
213
213
  */
214
- export function workerContextView(
215
- usedTokens: number,
216
- contextWindow: number | undefined | null,
217
- ): WorkerContextView | null {
214
+ function workerContextView(usedTokens: number, contextWindow: number | undefined | null): WorkerContextView | null {
218
215
  if (contextWindow === undefined || contextWindow === null || contextWindow <= 0) return null;
219
216
  if (!Number.isFinite(usedTokens) || usedTokens <= 0) return null;
220
217
  const pct = Math.min(100, Math.round((usedTokens / contextWindow) * 100));
@@ -166,7 +166,7 @@ function renderWorkingSetLines(view: WorkingSetView, config: WorkingSetConfigVie
166
166
  ];
167
167
  }
168
168
 
169
- export function renderContextLedgerLines(
169
+ function renderContextLedgerLines(
170
170
  ledger: ContextLedger,
171
171
  contentWidth: number,
172
172
  workingSet?: WorkingSetView | null,
@@ -271,7 +271,7 @@ function modelBlock(row: CostRow): string[] {
271
271
  ]);
272
272
  }
273
273
 
274
- export function formatCostOverlayBodyLines(
274
+ function formatCostOverlayBodyLines(
275
275
  totalCost: CostAggregate,
276
276
  totalTokens: number,
277
277
  rows: ReadonlyArray<CostRow>,
@@ -78,7 +78,7 @@ export type CouncilLayout = { mode: "grid"; columnWidth: number } | { mode: "sta
78
78
  * moment one column would fall under {@link COUNCIL_COLUMN_MIN_WIDTH}: a grid
79
79
  * where only some columns are readable is worse than no grid at all.
80
80
  */
81
- export function councilGridLayout(memberCount: number, contentWidth: number): CouncilLayout {
81
+ function councilGridLayout(memberCount: number, contentWidth: number): CouncilLayout {
82
82
  const count = Math.max(1, memberCount);
83
83
  const usable = contentWidth - COUNCIL_COLUMN_GUTTER * (count - 1);
84
84
  const columnWidth = Math.floor(usable / count);
@@ -124,7 +124,7 @@ function answerRows(theme: ClioTheme, member: CouncilMemberView, width: number,
124
124
  * answer. Every line is clipped to the column so a long model id or a long
125
125
  * answer line can never push a neighbouring column out of position.
126
126
  */
127
- export function councilMemberLines(
127
+ function councilMemberLines(
128
128
  theme: ClioTheme,
129
129
  member: CouncilMemberView,
130
130
  width: number,
@@ -182,10 +182,7 @@ export interface DispatchBoardPhase {
182
182
  * the column lines up across rows; a long step id is clipped with a marker
183
183
  * rather than pushing the row's other facts out of position.
184
184
  */
185
- export function formatDispatchPhaseCell(
186
- phase: DispatchBoardPhase | undefined,
187
- width = PHASE_COLUMN_WIDTH,
188
- ): string | null {
185
+ function formatDispatchPhaseCell(phase: DispatchBoardPhase | undefined, width = PHASE_COLUMN_WIDTH): string | null {
189
186
  if (phase === undefined) return null;
190
187
  return truncateToWidth(`w${phase.wave} ${phase.stepId}`, Math.max(1, width), "…", false);
191
188
  }
@@ -294,9 +291,7 @@ export interface AgentAudiencePresentation {
294
291
  * machinery. Returns null for base/custom agents, which the operator asked for
295
292
  * directly and which therefore render like any other row.
296
293
  */
297
- export function agentAudiencePresentation(
298
- row: Pick<DispatchBoardRow, "agentAudience">,
299
- ): AgentAudiencePresentation | null {
294
+ function agentAudiencePresentation(row: Pick<DispatchBoardRow, "agentAudience">): AgentAudiencePresentation | null {
300
295
  if (row.agentAudience === "shadow") return { glyph: GLYPH.subProcess, token: "muted" };
301
296
  if (row.agentAudience === "internal") return { glyph: GLYPH.subProcess, token: "dim" };
302
297
  return null;
@@ -439,10 +434,7 @@ function latestEvidenceFailureReason(notices: readonly ObservabilityNotice[], ru
439
434
  * summary with an evidence bundle is ready; the latest error-level evidence
440
435
  * notice for the run marks it failed.
441
436
  */
442
- export function deriveRunEvidenceState(
443
- snapshot: ObservabilitySnapshot | undefined,
444
- runId: string,
445
- ): RunEvidencePresentation {
437
+ function deriveRunEvidenceState(snapshot: ObservabilitySnapshot | undefined, runId: string): RunEvidencePresentation {
446
438
  if (!snapshot || runId.length === 0) return { state: "none", viewFilter: `dispatch:${runId}` };
447
439
  if (snapshot.pendingEvidenceBuildRunIds.includes(runId)) {
448
440
  return { state: "pending", viewFilter: `evidence:${runId}` };
@@ -497,6 +489,16 @@ function cardUnitsLine(theme: ClioTheme, key: string, units: ReadonlyArray<strin
497
489
  return visibleWidth(full) <= contentWidth ? full : fitUnits(theme, prefix, units, contentWidth);
498
490
  }
499
491
 
492
+ /** A prose card value, wrapped inside the columns left by its one-time key. */
493
+ function cardWrappedValueLines(theme: ClioTheme, key: string, value: string, contentWidth: number): string[] {
494
+ const prefix = cardKvKey(theme, key);
495
+ const prefixWidth = visibleWidth(prefix);
496
+ const valueWidth = Math.max(1, contentWidth - prefixWidth);
497
+ return wrapTextWithAnsi(value, valueWidth).map(
498
+ (line, index) => `${index === 0 ? prefix : " ".repeat(prefixWidth)}${line}`,
499
+ );
500
+ }
501
+
500
502
  // The `proof` row: the colored state marker, an optional failure reason, then
501
503
  // the dim `/view` filter an operator would type.
502
504
  function evidenceCardLine(theme: ClioTheme, evidence: RunEvidencePresentation, contentWidth: number): string | null {
@@ -509,7 +511,7 @@ function evidenceCardLine(theme: ClioTheme, evidence: RunEvidencePresentation, c
509
511
  }
510
512
 
511
513
  /** Sanitize lifecycle task text at the terminal boundary and collapse it to one bounded line. */
512
- export function sanitizeDispatchTaskSummary(value: unknown): string | undefined {
514
+ function sanitizeDispatchTaskSummary(value: unknown): string | undefined {
513
515
  if (typeof value !== "string") return undefined;
514
516
  const sanitized = sanitizeCallTargetText(value);
515
517
  if (sanitized.length === 0) return undefined;
@@ -622,7 +624,7 @@ function trustCardLines(theme: ClioTheme, row: DispatchBoardRow, contentWidth: n
622
624
  );
623
625
  }
624
626
 
625
- export function renderDispatchCard(
627
+ function renderDispatchCard(
626
628
  row: DispatchBoardRow,
627
629
  width: number,
628
630
  evidence?: RunEvidencePresentation,
@@ -715,24 +717,22 @@ export function renderDispatchCard(
715
717
  contentWidth,
716
718
  ),
717
719
  targetLine,
718
- ...(row.taskSummary
719
- ? [truncateToWidth(`${cardKvKey(theme, "task")}${theme.fg("muted", row.taskSummary)}`, contentWidth, "…", false)]
720
- : []),
720
+ ...(row.taskSummary ? cardWrappedValueLines(theme, "task", theme.fg("muted", row.taskSummary), contentWidth) : []),
721
721
  cardUnitsLine(theme, "status", statusUnits, contentWidth),
722
722
  ...trustCardLines(theme, row, contentWidth),
723
723
  ...(row.budget !== undefined
724
724
  ? [
725
- truncateToWidth(
726
- `${cardKvKey(theme, "policy")}${theme.fg("muted", `${formatBudgetPolicy(row.budget)}; requested ${formatBudgetRequest(row.budget)}`)}`,
725
+ ...cardWrappedValueLines(
726
+ theme,
727
+ "policy",
728
+ theme.fg("muted", `${formatBudgetPolicy(row.budget)}; requested ${formatBudgetRequest(row.budget)}`),
727
729
  contentWidth,
728
- "…",
729
- false,
730
730
  ),
731
- truncateToWidth(
732
- `${cardKvKey(theme, "budget")}${theme.fg("muted", `${formatEffectiveBudget(row.budget)}; reason ${formatBudgetReasons(row.budget)}`)}`,
731
+ ...cardWrappedValueLines(
732
+ theme,
733
+ "budget",
734
+ theme.fg("muted", `${formatEffectiveBudget(row.budget)}; reason ${formatBudgetReasons(row.budget)}`),
733
735
  contentWidth,
734
- "…",
735
- false,
736
736
  ),
737
737
  ]
738
738
  : []),
@@ -797,7 +797,7 @@ export function renderDispatchCard(
797
797
  const proofLine = evidenceCardLine(theme, evidence, contentWidth);
798
798
  if (proofLine !== null) bodyLines.push(proofLine);
799
799
  }
800
- if (detail !== null) bodyLines.push(`${cardKvKey(theme, "detail")}${theme.fg("dim", detail)}`);
800
+ if (detail !== null) bodyLines.push(...cardWrappedValueLines(theme, "detail", theme.fg("dim", detail), contentWidth));
801
801
 
802
802
  return frame(theme, cardTitle, bodyLines, width, { rightMeta: elapsed });
803
803
  }
@@ -956,10 +956,7 @@ export type DispatchBoardItem = { kind: "run"; row: DispatchBoardRow } | { kind:
956
956
  * its first row and its remaining rows are consumed, so the board never shows a
957
957
  * member both inside its group and beside it.
958
958
  */
959
- export function dispatchBoardItems(
960
- rows: ReadonlyArray<DispatchBoardRow>,
961
- selectedRunId?: string | null,
962
- ): DispatchBoardItem[] {
959
+ function dispatchBoardItems(rows: ReadonlyArray<DispatchBoardRow>, selectedRunId?: string | null): DispatchBoardItem[] {
963
960
  const byGroup = new Map<string, DispatchBoardRow[]>();
964
961
  for (const row of rows) {
965
962
  const group = row.council?.group;
@@ -984,14 +981,14 @@ export function dispatchBoardItems(
984
981
  }
985
982
 
986
983
  /** The framed council card: the member grid or stack, with the synthesis run full width under it. */
987
- export function renderCouncilCard(group: CouncilGroupView, width: number): string[] {
984
+ function renderCouncilCard(group: CouncilGroupView, width: number): string[] {
988
985
  const theme = clioTheme();
989
986
  const contentWidth = Math.max(0, width - 4);
990
987
  const title = `${theme.fg("info", "council")} ${theme.paint(group.group, { bold: true })}`;
991
988
  return frame(theme, title, councilGroupBody(theme, group, contentWidth), width, { rightMeta: group.elapsed });
992
989
  }
993
990
 
994
- export function formatDispatchBoardLines(
991
+ function formatDispatchBoardLines(
995
992
  rows: ReadonlyArray<DispatchBoardRow>,
996
993
  width = 76,
997
994
  observability?: ObservabilitySnapshot,
@@ -1722,7 +1719,7 @@ export function createDispatchBoardStore(
1722
1719
  entry.ttftMs = Math.round(performance.now() - entry.startedAtClockMs);
1723
1720
  }
1724
1721
  }
1725
- if (type === "clio_write_record_downgraded") {
1722
+ if (type === "clio_coder_write_record_downgraded") {
1726
1723
  const rawPayload = (workerEvent as { payload?: unknown }).payload;
1727
1724
  const payload =
1728
1725
  typeof rawPayload === "object" && rawPayload !== null ? (rawPayload as Record<string, unknown>) : null;
@@ -1740,7 +1737,7 @@ export function createDispatchBoardStore(
1740
1737
  // board says about what a worker is saying or touching comes from here,
1741
1738
  // so the board and the transcript block cannot tell two stories.
1742
1739
  entry.progress.observe(payload.event);
1743
- if (type === "clio_steer_received") {
1740
+ if (type === "clio_coder_steer_received") {
1744
1741
  const steerPayload = (workerEvent as { payload?: { chars?: unknown } }).payload;
1745
1742
  entry.steerAcknowledgement = {
1746
1743
  receivedAtMs: Date.now(),
@@ -6,7 +6,28 @@ export interface EditorBashCommand {
6
6
  excludeFromContext: boolean;
7
7
  }
8
8
 
9
+ /**
10
+ * Invisible one-shot envelope used only between ClioEditor and its submit
11
+ * callback. Pi trims submitted text before invoking that callback, so a
12
+ * whitespace guard would disappear and re-arm a pasted `!` command. The
13
+ * controller removes this envelope before routing the text as an ordinary
14
+ * prompt; it is never persisted or sent to a model.
15
+ */
16
+ export const PASTED_EDITOR_OPERATOR_GUARD = "\u2063";
17
+
18
+ export function guardPastedEditorOperator(text: string): string {
19
+ return `${PASTED_EDITOR_OPERATOR_GUARD}${text}`;
20
+ }
21
+
22
+ export function unguardPastedEditorOperator(text: string): string {
23
+ return text.startsWith(PASTED_EDITOR_OPERATOR_GUARD) ? text.slice(PASTED_EDITOR_OPERATOR_GUARD.length) : text;
24
+ }
25
+
9
26
  export function parseEditorBashCommand(text: string): EditorBashCommand | null {
27
+ // Commands are an editor-line operator, not a shell-script paste surface.
28
+ // The paste guard also makes a bracketed-pasted one-liner literal until it
29
+ // has crossed the editor submit boundary and been routed as a normal prompt.
30
+ if (text.startsWith(PASTED_EDITOR_OPERATOR_GUARD) || text.includes("\n") || text.includes("\r")) return null;
10
31
  if (!text.startsWith("!")) return null;
11
32
  const excludeFromContext = text.startsWith("!!");
12
33
  const command = (excludeFromContext ? text.slice(2) : text.slice(1)).trim();
@@ -4,8 +4,8 @@
4
4
  * `!` intercept in the editor submit path.
5
5
  *
6
6
  * The target token is deliberately a bare word (letters, digits, underscore,
7
- * hyphen). Inline file references (`@package.json`, `@src/x.ts`) contain dots
8
- * or slashes and never match, so prompt file expansion keeps working.
7
+ * hyphen). File completion consults the same predicate and quotes an otherwise
8
+ * ambiguous root-level extensionless reference before it reaches this parser.
9
9
  */
10
10
 
11
11
  export interface EditorSteerMention {
@@ -23,11 +23,16 @@ export type SteerTargetResolution =
23
23
  | { kind: "ambiguous"; candidates: RunningDispatchRef[] }
24
24
  | { kind: "none" };
25
25
 
26
- const STEER_MENTION = /^@([A-Za-z0-9][A-Za-z0-9_-]*)\s+(\S[\s\S]*)$/;
26
+ const STEER_TARGET_TOKEN = /^[A-Za-z0-9][A-Za-z0-9_-]*$/;
27
+ const STEER_MENTION = /^@(\S+)\s+(\S[\s\S]*)$/;
28
+
29
+ export function isEditorSteerTargetToken(value: string): boolean {
30
+ return STEER_TARGET_TOKEN.test(value);
31
+ }
27
32
 
28
33
  export function parseEditorSteerMention(text: string): EditorSteerMention | null {
29
34
  const match = STEER_MENTION.exec(text.trim());
30
- if (!match?.[1] || !match[2]) return null;
35
+ if (!match?.[1] || !match[2] || !isEditorSteerTargetToken(match[1])) return null;
31
36
  return { target: match[1], text: match[2].trim() };
32
37
  }
33
38