@iowarp/clio-coder 0.3.9 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (416) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/NOTICE +33 -0
  3. package/README.md +7 -2
  4. package/dist/{acp-7LOELQFP.js → acp-G5WJBNCT.js} +13 -12
  5. package/dist/{agents-FIBG2SHA.js → agents-FMV2Q5G4.js} +39 -36
  6. package/dist/assets/codewiki.json +1 -1
  7. package/dist/{auth-OI4LIH2I.js → auth-3IDSJEIK.js} +16 -15
  8. package/dist/{builtins-AD25UL3C.js → builtins-XCZWXSC7.js} +3 -3
  9. package/dist/{chunk-IFBNV6H6.js → chunk-2ANTL7MR.js} +3 -3
  10. package/dist/{chunk-56KB5IJP.js → chunk-2OQE55CK.js} +3 -3
  11. package/dist/{chunk-N3PBVRTZ.js → chunk-32KWKNSF.js} +9 -7
  12. package/dist/{chunk-VKBMFOYV.js → chunk-36EJLSQQ.js} +23 -27
  13. package/dist/{chunk-465CC7FK.js → chunk-3BT2XMV4.js} +16 -13
  14. package/dist/{chunk-NQ6UCCOD.js → chunk-3URVFKWK.js} +7 -7
  15. package/dist/{chunk-WIE7ZOSW.js → chunk-3XML7CDN.js} +2 -2
  16. package/dist/chunk-42FMPA75.js +101 -0
  17. package/dist/{chunk-A2NJGIB3.js → chunk-5LXZXPKX.js} +2 -2
  18. package/dist/{chunk-HAY4ZE2P.js → chunk-5PSMVOLM.js} +2 -2
  19. package/dist/{chunk-JEQQR47K.js → chunk-6DB53AJS.js} +168 -9
  20. package/dist/{chunk-KV2AOLDF.js → chunk-76ONBSIA.js} +5 -25
  21. package/dist/{chunk-FALJGAWU.js → chunk-7MCTRUCE.js} +2 -2
  22. package/dist/{chunk-5T7RBWN2.js → chunk-AB44T6BB.js} +5 -5
  23. package/dist/chunk-B7OBL7PK.js +1405 -0
  24. package/dist/{chunk-B5CSFE7B.js → chunk-BBVJUZHB.js} +2 -2
  25. package/dist/{chunk-EQ63NRB7.js → chunk-BBVYXMFO.js} +2 -2
  26. package/dist/{chunk-O6I4CIEU.js → chunk-BKFJHQCA.js} +6 -6
  27. package/dist/chunk-BKFM6EJV.js +462 -0
  28. package/dist/chunk-BMS5RKQY.js +27 -0
  29. package/dist/{chunk-MV2VUEJC.js → chunk-BPKCPIL7.js} +2 -2
  30. package/dist/{chunk-TEO2TLVN.js → chunk-BUMFYQFY.js} +964 -1120
  31. package/dist/{chunk-BNAZZHFG.js → chunk-BYP5D4HI.js} +1 -1
  32. package/dist/chunk-C2LTL2W6.js +2447 -0
  33. package/dist/{chunk-EBOC7MT3.js → chunk-CODPRO7Q.js} +8 -8
  34. package/dist/{chunk-HPCTNZM2.js → chunk-CTJ4RNAA.js} +4 -4
  35. package/dist/{chunk-ODFEOB4F.js → chunk-CY6FY24N.js} +26 -8
  36. package/dist/{chunk-MIX5N5AC.js → chunk-DQITNCXG.js} +394 -154
  37. package/dist/{chunk-S4COXYBG.js → chunk-DYJP44XW.js} +129 -106
  38. package/dist/{chunk-N5XKWMDW.js → chunk-F4CKPOEQ.js} +6 -6
  39. package/dist/{chunk-AMKHQW3C.js → chunk-FEFIFZTL.js} +3 -3
  40. package/dist/{chunk-MV3K5QF2.js → chunk-GCSMB2KY.js} +2 -2
  41. package/dist/{chunk-7C6RYZGQ.js → chunk-GKF55TAZ.js} +3 -3
  42. package/dist/{chunk-B5XRQOLB.js → chunk-GR5G2PVF.js} +9 -8
  43. package/dist/{chunk-XDOQXGFO.js → chunk-GXNLGKAB.js} +64 -8
  44. package/dist/chunk-HHV2GANA.js +88 -0
  45. package/dist/{chunk-774ILSRL.js → chunk-HI63TFOG.js} +4 -3
  46. package/dist/{chunk-R7LNVMCS.js → chunk-HJJTYUHX.js} +64 -72
  47. package/dist/{chunk-RKRLDWD3.js → chunk-HLW2MRKE.js} +1 -1
  48. package/dist/{chunk-CA42X6KT.js → chunk-HWHKMHUA.js} +6 -6
  49. package/dist/chunk-HZHHCK24.js +1631 -0
  50. package/dist/{chunk-HJB5IUKP.js → chunk-I5VEOC6I.js} +12 -12
  51. package/dist/chunk-IBEBSCYA.js +564 -0
  52. package/dist/chunk-IQ7KR472.js +362 -0
  53. package/dist/{chunk-4H6ULJ3H.js → chunk-J4W7KFM7.js} +921 -990
  54. package/dist/{chunk-4LJX2PUC.js → chunk-JDG2WCRO.js} +5 -5
  55. package/dist/{chunk-NZU6YDNV.js → chunk-K5C3NCBD.js} +4 -4
  56. package/dist/{chunk-CGKSTWHD.js → chunk-K6BSR66V.js} +2 -1
  57. package/dist/{chunk-NNNWO6F2.js → chunk-KFZI4NIL.js} +93 -3
  58. package/dist/chunk-KMVISBZR.js +132 -0
  59. package/dist/{chunk-BVDVID7E.js → chunk-LDQ2ZF2M.js} +2 -2
  60. package/dist/{chunk-OEDBCISO.js → chunk-LQ3DZAMX.js} +2 -2
  61. package/dist/{chunk-PZ4I4JE2.js → chunk-LY4S7GJC.js} +124 -116
  62. package/dist/{chunk-3DUR4WUA.js → chunk-MLKNTWH2.js} +19 -19
  63. package/dist/chunk-NEKRRTYW.js +56 -0
  64. package/dist/{chunk-5DQRIYDZ.js → chunk-NHCZP4K7.js} +2 -2
  65. package/dist/chunk-NHLBIGRH.js +1506 -0
  66. package/dist/chunk-NQQH3YT7.js +302 -0
  67. package/dist/chunk-NYS75XW5.js +15 -0
  68. package/dist/{chunk-TD7UE2L5.js → chunk-O4XIVISU.js} +7 -7
  69. package/dist/{chunk-WXCJ7VME.js → chunk-O6TL7WWY.js} +6 -6
  70. package/dist/chunk-OQBA45DZ.js +97 -0
  71. package/dist/{chunk-LU7P4LHA.js → chunk-P3FOHJT4.js} +2 -2
  72. package/dist/chunk-PMZCIOCJ.js +25 -0
  73. package/dist/{chunk-I4HZDVNP.js → chunk-PQEFIJ36.js} +2 -2
  74. package/dist/{chunk-HKO36JWF.js → chunk-QBJA7R7N.js} +31 -3
  75. package/dist/chunk-QDC3K2U3.js +262 -0
  76. package/dist/{chunk-5HFBWUMU.js → chunk-QLFS5GO2.js} +4 -4
  77. package/dist/{chunk-GAYUJ7LE.js → chunk-QLL7ILRG.js} +41 -32
  78. package/dist/{chunk-LXPJXFM5.js → chunk-QREDIESB.js} +7 -7
  79. package/dist/chunk-QSNYB6ZV.js +195 -0
  80. package/dist/chunk-R346GLFC.js +31 -0
  81. package/dist/{chunk-VPTUJU4P.js → chunk-SJ5ZKQ4S.js} +2 -2
  82. package/dist/{chunk-QQ7EKM72.js → chunk-SP2RXXYO.js} +6 -54
  83. package/dist/chunk-SUCTJL45.js +45 -0
  84. package/dist/{chunk-5QKCQQ3E.js → chunk-SUW5DORT.js} +2 -2
  85. package/dist/chunk-T56WDKA5.js +183 -0
  86. package/dist/chunk-TVHHYFHE.js +255 -0
  87. package/dist/{chunk-IHKBWSXF.js → chunk-TZ3SGWZZ.js} +2 -2
  88. package/dist/{chunk-ECUO3KDP.js → chunk-U77AMWDL.js} +47 -7
  89. package/dist/{chunk-3UUY7R3Z.js → chunk-ULC6OTWO.js} +7 -7
  90. package/dist/{chunk-AEYBF3TB.js → chunk-UM7N4G5A.js} +2 -2
  91. package/dist/{chunk-3V5AYSEQ.js → chunk-UXMFQ54G.js} +43 -36
  92. package/dist/{chunk-YW7UVM5V.js → chunk-V5DHCITQ.js} +34 -1
  93. package/dist/{chunk-47CMYGET.js → chunk-VAZSBTKF.js} +2 -2
  94. package/dist/{chunk-3MRC2YSQ.js → chunk-VEO4AP2K.js} +2 -2
  95. package/dist/{chunk-PNY46YEY.js → chunk-VFA6GDY5.js} +47 -3
  96. package/dist/chunk-VO67MWHC.js +75 -0
  97. package/dist/{chunk-XK56QHLX.js → chunk-VPKWYKEY.js} +19 -5
  98. package/dist/{chunk-AD7Y7STJ.js → chunk-VYMXRQI6.js} +36 -22
  99. package/dist/{chunk-T3Z6VAAF.js → chunk-W5VSYASO.js} +19 -17
  100. package/dist/{chunk-5PVQ4SRS.js → chunk-WZR7K7ZX.js} +7 -123
  101. package/dist/{chunk-DG4M6ZUE.js → chunk-X3YGUTOB.js} +4 -4
  102. package/dist/chunk-X75E3D2N.js +686 -0
  103. package/dist/{chunk-P3JGPQFL.js → chunk-YDFRH54B.js} +4 -4
  104. package/dist/chunk-YJX4SHTD.js +40 -0
  105. package/dist/{chunk-ZI647VB5.js → chunk-YPI3QQCF.js} +2 -2
  106. package/dist/{chunk-YSEHGPCT.js → chunk-Z2RR6MAK.js} +3 -3
  107. package/dist/{chunk-HCBCAYZU.js → chunk-Z4TXYIEG.js} +5 -5
  108. package/dist/cli/index.js +47 -36
  109. package/dist/{clio-LT5V7SSZ.js → clio-2JXHBBY5.js} +7 -7
  110. package/dist/{code-nav-LMW275PA.js → code-nav-3YYRMYNF.js} +6 -6
  111. package/dist/{compile-cache-CVJMMODC.js → compile-cache-7FPE6PS3.js} +3 -3
  112. package/dist/{components-ZFA3SAER.js → components-RYZV4JGP.js} +5 -5
  113. package/dist/{config-RXS5T3JT.js → config-QZPCMYSO.js} +58 -50
  114. package/dist/{configure-2WYWSCSD.js → configure-TEGEBYCA.js} +21 -19
  115. package/dist/{context-I3BTOTCS.js → context-AV7OEZ4D.js} +11 -11
  116. package/dist/{context-MVOORGMF.js → context-E6H5RNMC.js} +49 -41
  117. package/dist/{context-PALKKQYL.js → context-GSXUE4CT.js} +25 -23
  118. package/dist/{context-clear-N2WOYZ2K.js → context-clear-SHIBYK6T.js} +48 -40
  119. package/dist/{context-working-set-MIEVECVZ.js → context-working-set-5ZGKPGZQ.js} +11 -10
  120. package/dist/{dispatch-runner-VVA4SRRH.js → dispatch-runner-EFMJT4LD.js} +88 -60
  121. package/dist/{docs-7LQ23DLM.js → docs-23KQS3XK.js} +5 -5
  122. package/dist/doctor-QOA5FNY5.js +313 -0
  123. package/dist/{eval-IJ5VEZDJ.js → eval-TFBYQH4H.js} +66 -64
  124. package/dist/eval-inventory-SXH7PDKX.js +316 -0
  125. package/dist/{evidence-L5APPXNV.js → evidence-ERGESKGN.js} +198 -44
  126. package/dist/{evolve-RGNKFJ52.js → evolve-VDXTSYCJ.js} +46 -38
  127. package/dist/{extensions-7WYWUX5A.js → extensions-7BGBHN57.js} +6 -6
  128. package/dist/{fleet-6CNVBZZP.js → fleet-2RRVDF2V.js} +189 -101
  129. package/dist/{fleet-commands-L2SXSYEI.js → fleet-commands-VJ726XIA.js} +10 -10
  130. package/dist/fleet-decisions-EPAPM3XJ.js +157 -0
  131. package/dist/{fleet-graph-2J3OOIPO.js → fleet-graph-JF5QOATM.js} +16 -15
  132. package/dist/fleet-inspect-VLY4S7QM.js +442 -0
  133. package/dist/{fleet-preflight-CZRJ4JP5.js → fleet-preflight-AIZUEJOY.js} +6 -5
  134. package/dist/{fleet-validate-C5RI6DP7.js → fleet-validate-AJRPDMDV.js} +20 -18
  135. package/dist/fleet-verify-JFEL2L3H.js +175 -0
  136. package/dist/fleet-view-ZCON35AG.js +102 -0
  137. package/dist/{init-VBN2ACVA.js → init-DN2WWLFE.js} +64 -56
  138. package/dist/install-XGLBQY5E.js +13 -0
  139. package/dist/interop-OZBKXAYL.js +114 -0
  140. package/dist/{library-JHGUMLY2.js → library-YWZG7IMW.js} +19 -18
  141. package/dist/{memory-K4OQIYWG.js → memory-I4C4HMLW.js} +48 -40
  142. package/dist/{models-2NCZUWDD.js → models-CEYXJBO6.js} +30 -28
  143. package/dist/{monitor-MMVTJABD.js → monitor-NZ6GCI3P.js} +53 -47
  144. package/dist/{orchestrator-ZKBPCHW6.js → orchestrator-GCGQ4N5I.js} +6311 -7145
  145. package/dist/panes-HMABYVO4.js +58 -0
  146. package/dist/panes-KY6W3V2E.js +103 -0
  147. package/dist/{paths-DBXMZMDU.js → paths-II4K7DNR.js} +5 -5
  148. package/dist/{reset-DD5JGOY3.js → reset-DQ6FGCSH.js} +13 -11
  149. package/dist/resources-BB3MVJMD.js +111 -0
  150. package/dist/{run-QEGNX7FL.js → run-H2GQDUER.js} +113 -82
  151. package/dist/{share-JKD3BQMW.js → share-GTJN6A5O.js} +18 -17
  152. package/dist/{skills-LMQIKDOZ.js → skills-L55TEW6R.js} +31 -24
  153. package/dist/{skills-eval-I7X2774U.js → skills-eval-XVXPH2JI.js} +61 -52
  154. package/dist/skills-inventory-S4MXPJFV.js +126 -0
  155. package/dist/slash-commands-ZSGASKJC.js +77 -0
  156. package/dist/{steer-CF5TDANS.js → steer-RZGSCY4R.js} +3 -3
  157. package/dist/{support-I7LOJLIF.js → support-PKEUNNQL.js} +4 -4
  158. package/dist/{targets-RUSR6B5Z.js → targets-NCPZ644J.js} +31 -29
  159. package/dist/{terminal-lease-QYVORFR4.js → terminal-lease-44SV3YCN.js} +4 -4
  160. package/dist/tools-DAF3DI3C.js +27 -0
  161. package/dist/{trace-ODOQIVIW.js → trace-FYVW2MQA.js} +149 -7
  162. package/dist/tui-primitives-2AKXQNZK.js +13 -0
  163. package/dist/{uninstall-ZJF5H5ZN.js → uninstall-DW2PNOIC.js} +5 -5
  164. package/dist/{upgrade-XANW3FXB.js → upgrade-3XPP6OQL.js} +26 -24
  165. package/dist/{usage-4H7ZRXQT.js → usage-3NLHGTU2.js} +57 -49
  166. package/dist/{verifiers-UZXNBZEB.js → verifiers-SSQONKRT.js} +171 -12
  167. package/dist/{verify-BVKWTNDL.js → verify-3U6J7FZI.js} +9 -9
  168. package/dist/{web-fetch-2YHJ3KTG.js → web-fetch-S7RR6GZ7.js} +3 -3
  169. package/dist/{wiki-generate-MY7WV2QI.js → wiki-generate-CEHYGPGQ.js} +67 -59
  170. package/dist/with-panes-MKB46MPQ.js +782 -0
  171. package/dist/worker/entry.js +101 -66
  172. package/docs/README.md +3 -2
  173. package/docs/acp.md +24 -3
  174. package/docs/alcf-provider.md +1 -1
  175. package/docs/architecture.md +2 -2
  176. package/docs/artifact-versions.md +4 -1
  177. package/docs/built-in-agents.md +1 -1
  178. package/docs/capacity-and-scheduling.md +43 -5
  179. package/docs/commands-and-modes.md +31 -2
  180. package/docs/configuration-and-targets.md +40 -10
  181. package/docs/context-engine.md +1 -1
  182. package/docs/development-pipeline.md +19 -0
  183. package/docs/dispatch-typed-intent.md +385 -0
  184. package/docs/documentation-coverage.md +2 -2
  185. package/docs/documentation-guide.md +1 -1
  186. package/docs/environment-variables.md +1 -0
  187. package/docs/eval-runner.md +1 -1
  188. package/docs/evals-internal.md +1 -1
  189. package/docs/evidence-and-memory.md +2 -2
  190. package/docs/evolution.md +1 -1
  191. package/docs/exit-codes-and-output.md +1 -1
  192. package/docs/extensions-and-sharing.md +25 -1
  193. package/docs/fleet-dispatch.md +22 -1
  194. package/docs/installation-and-lifecycle.md +15 -2
  195. package/docs/middleware-and-components.md +1 -1
  196. package/docs/model-catalog.md +10 -1
  197. package/docs/observability.md +3 -3
  198. package/docs/proactive-memory.md +1 -1
  199. package/docs/prompt-envelope-and-tools.md +1 -1
  200. package/docs/provider-adapter-cookbook.md +1 -1
  201. package/docs/safety-model.md +2 -2
  202. package/docs/scientific-validation.md +3 -3
  203. package/docs/session-lifecycle.md +1 -1
  204. package/docs/skills-marketplace.md +1 -1
  205. package/docs/tool-usage.md +18 -8
  206. package/docs/trace-store.md +1 -1
  207. package/docs/troubleshooting.md +1 -1
  208. package/docs/tui-design.md +1 -1
  209. package/docs/worker-dispatch-mechanics.md +1 -1
  210. package/package.json +4 -2
  211. package/src/cli/acp.ts +6 -2
  212. package/src/cli/argv.ts +25 -0
  213. package/src/cli/configure.ts +23 -21
  214. package/src/cli/doctor-panes.ts +124 -0
  215. package/src/cli/doctor-toolchain.ts +57 -0
  216. package/src/cli/doctor.ts +20 -1
  217. package/src/cli/eval-inventory.ts +436 -0
  218. package/src/cli/eval.ts +13 -0
  219. package/src/cli/evidence-detail.ts +88 -0
  220. package/src/cli/evidence-inventory.ts +183 -0
  221. package/src/cli/evidence.ts +30 -5
  222. package/src/cli/fleet-decisions.ts +69 -0
  223. package/src/cli/fleet-inspect.ts +334 -0
  224. package/src/cli/fleet-verify.ts +133 -0
  225. package/src/cli/fleet-view.ts +810 -0
  226. package/src/cli/fleet.ts +148 -37
  227. package/src/cli/index.ts +14 -2
  228. package/src/cli/interop-inspect.ts +128 -0
  229. package/src/cli/interop.ts +34 -0
  230. package/src/cli/panes.ts +35 -0
  231. package/src/cli/reset.ts +5 -2
  232. package/src/cli/run.ts +58 -0
  233. package/src/cli/skills-inventory.ts +185 -0
  234. package/src/cli/skills.ts +16 -13
  235. package/src/cli/tools.ts +321 -0
  236. package/src/cli/trace-inspect.ts +252 -0
  237. package/src/cli/trace.ts +23 -2
  238. package/src/cli/verifiers-inspect.ts +347 -0
  239. package/src/cli/verifiers.ts +9 -0
  240. package/src/core/bus-events.ts +4 -0
  241. package/src/core/config.ts +49 -0
  242. package/src/core/defaults.ts +93 -7
  243. package/src/core/response-schema.ts +44 -4
  244. package/src/core/theme-token-hex.ts +43 -0
  245. package/src/core/tool-names.ts +2 -1
  246. package/src/core/xdg.ts +1 -1
  247. package/src/domains/agents/fleets/build-review.md +0 -3
  248. package/src/domains/agents/fleets/build-test.md +0 -3
  249. package/src/domains/agents/result-contract-filesystem.ts +32 -0
  250. package/src/domains/agents/result-contract.ts +164 -35
  251. package/src/domains/config/classify.ts +3 -0
  252. package/src/domains/dispatch/admission-error.ts +9 -0
  253. package/src/domains/dispatch/admission.ts +22 -21
  254. package/src/domains/dispatch/capacity-lease.ts +21 -1
  255. package/src/domains/dispatch/council-topology.ts +398 -0
  256. package/src/domains/dispatch/extension.ts +222 -50
  257. package/src/domains/dispatch/fleet-node-prompt.ts +62 -0
  258. package/src/domains/dispatch/fleet-plan.ts +7 -2
  259. package/src/domains/dispatch/fleet-run.ts +64 -1
  260. package/src/domains/dispatch/gate-decisions.ts +11 -1
  261. package/src/domains/dispatch/gate-role-prompts.ts +9 -0
  262. package/src/domains/dispatch/gate-topology.ts +289 -0
  263. package/src/domains/dispatch/index.ts +19 -0
  264. package/src/domains/dispatch/intent-compatibility.ts +330 -0
  265. package/src/domains/dispatch/intent.ts +85 -1
  266. package/src/domains/dispatch/reservation-store.ts +24 -4
  267. package/src/domains/dispatch/run-event-journal-bridge.ts +149 -0
  268. package/src/domains/dispatch/run-event-journal.ts +598 -0
  269. package/src/domains/dispatch/state.ts +45 -1
  270. package/src/domains/dispatch/types.ts +13 -0
  271. package/src/domains/dispatch/validation.ts +33 -8
  272. package/src/domains/eval/compare/compare.ts +3 -16
  273. package/src/domains/eval/inventory.ts +113 -0
  274. package/src/domains/eval/schema/serving.ts +31 -0
  275. package/src/domains/evidence/store.ts +6 -0
  276. package/src/domains/memory/index.ts +0 -1
  277. package/src/domains/memory/task-memory-policy.ts +6 -10
  278. package/src/domains/memory/task-memory-telemetry.ts +1 -0
  279. package/src/domains/middleware/memory-intervention.ts +33 -21
  280. package/src/domains/mux/contract.ts +434 -0
  281. package/src/domains/mux/detect.ts +158 -0
  282. package/src/domains/mux/extension.ts +47 -0
  283. package/src/domains/mux/index.ts +96 -0
  284. package/src/domains/mux/manifest.ts +6 -0
  285. package/src/domains/mux/operations.ts +164 -0
  286. package/src/domains/mux/pane-registry.ts +90 -0
  287. package/src/domains/mux/protocol.ts +49 -0
  288. package/src/domains/mux/socket-client.ts +816 -0
  289. package/src/domains/mux/types.ts +222 -0
  290. package/src/domains/mux/viewer-command.ts +59 -0
  291. package/src/domains/mux/yazi/assets/init.lua +2 -0
  292. package/src/domains/mux/yazi/assets/plugins/git.yazi/LICENSE +21 -0
  293. package/src/domains/mux/yazi/assets/plugins/git.yazi/README.md +78 -0
  294. package/src/domains/mux/yazi/assets/plugins/git.yazi/main.lua +255 -0
  295. package/src/domains/mux/yazi/assets/plugins/git.yazi/types.lua +12 -0
  296. package/src/domains/mux/yazi/assets/yazi.toml +17 -0
  297. package/src/domains/mux/yazi/event-stream.ts +180 -0
  298. package/src/domains/mux/yazi/profile.ts +299 -0
  299. package/src/domains/mux/yazi/session.ts +228 -0
  300. package/src/domains/mux/yazi/theme.ts +30 -0
  301. package/src/domains/observability/cost.ts +21 -0
  302. package/src/domains/observability/index.ts +2 -0
  303. package/src/domains/observability/trace-store.ts +42 -0
  304. package/src/domains/providers/endpoint-capacity.ts +154 -22
  305. package/src/domains/providers/endpoint-slots-store.ts +189 -0
  306. package/src/domains/providers/extension.ts +20 -3
  307. package/src/domains/providers/index.ts +22 -0
  308. package/src/domains/providers/model-runtime-capabilities.ts +32 -0
  309. package/src/domains/providers/runtimes/boot-manifest.ts +1 -0
  310. package/src/domains/providers/runtimes/builtins.ts +2 -0
  311. package/src/domains/providers/runtimes/protocol/litellm.ts +375 -0
  312. package/src/domains/providers/support.ts +1 -0
  313. package/src/domains/providers/target-model-cache.ts +124 -0
  314. package/src/domains/resources/index.ts +3 -0
  315. package/src/domains/resources/skills/loader.ts +33 -0
  316. package/src/domains/safety/action-classifier.ts +6 -0
  317. package/src/domains/toolchain/archive.ts +175 -0
  318. package/src/domains/toolchain/contract.ts +28 -0
  319. package/src/domains/toolchain/extension.ts +47 -0
  320. package/src/domains/toolchain/index.ts +39 -0
  321. package/src/domains/toolchain/install.ts +327 -0
  322. package/src/domains/toolchain/manifest.ts +8 -0
  323. package/src/domains/toolchain/paths.ts +34 -0
  324. package/src/domains/toolchain/registry.ts +265 -0
  325. package/src/domains/toolchain/remove.ts +218 -0
  326. package/src/domains/toolchain/resolve.ts +182 -0
  327. package/src/domains/toolchain/types.ts +113 -0
  328. package/src/domains/toolchain/version.ts +88 -0
  329. package/src/engine/acp/server.ts +413 -70
  330. package/src/engine/acp/types.ts +19 -1
  331. package/src/engine/claude/sdk-module.ts +98 -0
  332. package/src/engine/claude/sdk-runtime.ts +19 -11
  333. package/src/engine/tui-primitives.ts +21 -0
  334. package/src/engine/tui.ts +1 -0
  335. package/src/engine/worker-runtime.ts +2 -13
  336. package/src/entry/boot-options.ts +2 -0
  337. package/src/entry/orchestrator.ts +103 -5
  338. package/src/entry/panes-activation.ts +31 -0
  339. package/src/entry/with-panes.ts +20 -0
  340. package/src/interactive/context-overlay.ts +1 -0
  341. package/src/interactive/cost-overlay.ts +2 -0
  342. package/src/interactive/council-grid.ts +1 -3
  343. package/src/interactive/council.ts +11 -0
  344. package/src/interactive/dispatch-board.ts +26 -16
  345. package/src/interactive/interactive-application.ts +153 -6
  346. package/src/interactive/interactive-input-runtime.ts +7 -0
  347. package/src/interactive/interactive-slash-runtime.ts +36 -6
  348. package/src/interactive/memory-overlay.ts +1 -0
  349. package/src/interactive/modal-marker.ts +170 -0
  350. package/src/interactive/mux-bridge.ts +214 -0
  351. package/src/interactive/overlay-frame.ts +58 -2
  352. package/src/interactive/overlay-general-openers.ts +1 -0
  353. package/src/interactive/overlay-key-routing.ts +14 -3
  354. package/src/interactive/overlay-lifecycle.ts +19 -3
  355. package/src/interactive/overlay-model-selectors.ts +40 -3
  356. package/src/interactive/overlay-permission-lifecycle.ts +90 -22
  357. package/src/interactive/overlay-transitions.ts +18 -4
  358. package/src/interactive/overlays/agents.ts +1 -0
  359. package/src/interactive/overlays/ask-user.ts +136 -30
  360. package/src/interactive/overlays/auth-dialog.ts +1 -0
  361. package/src/interactive/overlays/context-reset.ts +1 -0
  362. package/src/interactive/overlays/cwd-fallback.ts +1 -0
  363. package/src/interactive/overlays/decisions.ts +11 -11
  364. package/src/interactive/overlays/extensions.ts +1 -0
  365. package/src/interactive/overlays/fleet-run-approval.ts +1 -0
  366. package/src/interactive/overlays/handoff-review.ts +1 -0
  367. package/src/interactive/overlays/help-reference.ts +2 -0
  368. package/src/interactive/overlays/interop.ts +1 -0
  369. package/src/interactive/overlays/library-install-confirm.ts +1 -0
  370. package/src/interactive/overlays/library-tabs.ts +28 -0
  371. package/src/interactive/overlays/list-overlay.ts +10 -1
  372. package/src/interactive/overlays/message-picker.ts +1 -0
  373. package/src/interactive/overlays/model-scope.ts +86 -0
  374. package/src/interactive/overlays/model-selector.ts +1 -0
  375. package/src/interactive/overlays/prompts.ts +1 -0
  376. package/src/interactive/overlays/session-selector.ts +1 -0
  377. package/src/interactive/overlays/settings-sections.ts +30 -0
  378. package/src/interactive/overlays/settings.ts +579 -44
  379. package/src/interactive/overlays/side-question.ts +1 -0
  380. package/src/interactive/overlays/skills-hub.ts +3 -11
  381. package/src/interactive/overlays/tree-selector.ts +1 -0
  382. package/src/interactive/pane-policy.ts +46 -0
  383. package/src/interactive/panes-runtime.ts +292 -0
  384. package/src/interactive/renderers/compaction-summary.ts +29 -0
  385. package/src/interactive/renderers/worker-entry.ts +122 -14
  386. package/src/interactive/slash-commands.ts +251 -15
  387. package/src/interactive/tasks-overlay.ts +1 -0
  388. package/src/interactive/theme/tokens.ts +3 -14
  389. package/src/interactive/turn-context.ts +47 -2
  390. package/src/interactive/view/artifacts.ts +109 -1
  391. package/src/interactive/view/view-overlay.ts +1 -0
  392. package/src/interactive/watch-pane.ts +152 -0
  393. package/src/interactive/worker-progress.ts +7 -1
  394. package/src/interactive/worker-receipts.ts +19 -1
  395. package/src/interactive/worker-stream.ts +5 -0
  396. package/src/interactive/yazi-bridge.ts +444 -0
  397. package/src/tools/bootstrap.ts +26 -2
  398. package/src/tools/builtin-tool-catalog.ts +15 -0
  399. package/src/tools/compete-worktrees.ts +83 -2
  400. package/src/tools/core-bootstrap.ts +2 -1
  401. package/src/tools/dispatch-admission.ts +14 -3
  402. package/src/tools/dispatch-arguments.ts +20 -20
  403. package/src/tools/dispatch-run-events.ts +134 -19
  404. package/src/tools/dispatch-runner.ts +29 -7
  405. package/src/tools/dispatch-types.ts +15 -3
  406. package/src/tools/dispatch.ts +1 -1
  407. package/src/tools/executables.ts +17 -14
  408. package/src/tools/observation.ts +54 -4
  409. package/src/tools/panes-surface.ts +38 -0
  410. package/src/tools/panes.ts +112 -0
  411. package/src/tools/policy.ts +10 -1
  412. package/src/tools/presentation.ts +1 -0
  413. package/dist/chunk-D73KXYPF.js +0 -37
  414. package/dist/chunk-MLOK6ZOS.js +0 -2888
  415. package/dist/chunk-YKOFT37S.js +0 -279
  416. package/dist/doctor-TWBWFK5V.js +0 -165
@@ -4,6 +4,7 @@ import type { SafeEventBus } from "../core/event-bus.js";
4
4
  import { parseCouncilReport, parseOracleResult } from "../domains/agents/index.js";
5
5
  import type { AgentSpec } from "../domains/agents/spec.js";
6
6
  import type { ContextInitOptions } from "../domains/context/init-options.js";
7
+ import { AdmissionCanceledError } from "../domains/dispatch/admission-error.js";
7
8
  import type { DispatchContract, DispatchRequest } from "../domains/dispatch/contract.js";
8
9
  import { type AgentRoleFactsResolver, requestExecutionRole } from "../domains/dispatch/execution-role.js";
9
10
  import type { RunReceipt } from "../domains/dispatch/types.js";
@@ -11,6 +12,14 @@ import type { JobThinkingLevel } from "../domains/dispatch/validation.js";
11
12
  import type { ReceiptIntegrityOutcome } from "../domains/evidence/trust-status.js";
12
13
  import type { InstalledExtension } from "../domains/extensions/index.js";
13
14
  import type { InteropAgentId, InteropProposal, InteropReport } from "../domains/interop/index.js";
15
+ import {
16
+ isPanesPresetId,
17
+ PANES_PRESET_IDS,
18
+ PANES_PRESETS,
19
+ type PanesOperations,
20
+ type PanesPresetId,
21
+ type PanesStatus,
22
+ } from "../domains/mux/operations.js";
14
23
  import type { ProvidersContract, ResolvedModelRef } from "../domains/providers/index.js";
15
24
  import { resolveModelReference } from "../domains/providers/index.js";
16
25
  import type {
@@ -27,13 +36,13 @@ import type { NoticeLevel } from "./command-output.js";
27
36
  import {
28
37
  buildCouncilDispatchArgs,
29
38
  COUNCIL_MAX_ROUNDS,
39
+ COUNCIL_SYNTHESIS_LABEL,
30
40
  COUNCIL_SYNTHESIS_MODES,
31
41
  type CouncilCommandOptions,
32
42
  type CouncilRosters,
33
43
  isCouncilSynthesisMode,
34
44
  resolveCouncilRoster,
35
45
  } from "./council.js";
36
- import { COUNCIL_SYNTHESIS_LABEL } from "./council-grid.js";
37
46
  import {
38
47
  formatOracleAnswer,
39
48
  ORACLE_AGENT_ID,
@@ -41,8 +50,9 @@ import {
41
50
  type OracleDigestSources,
42
51
  packOracleDigest,
43
52
  } from "./oracle.js";
44
- import { SETTINGS_SECTIONS, type SettingsCenterRowId, type SettingsSectionId } from "./overlays/settings.js";
45
- import { isLibraryTab, LIBRARY_TABS } from "./overlays/skills-hub.js";
53
+ import { isLibraryTab, LIBRARY_TABS } from "./overlays/library-tabs.js";
54
+ import type { SettingsCenterRowId } from "./overlays/settings.js";
55
+ import { SETTINGS_SECTIONS, type SettingsSectionId } from "./overlays/settings-sections.js";
46
56
  import type { CommandArgsSpec, CommandPositionalSpec, ParsedArgs } from "./slash-spec.js";
47
57
  import { matchFromSpec, usageLine } from "./slash-spec.js";
48
58
  import {
@@ -60,6 +70,25 @@ import type { WorkerEntryState } from "./worker-stream.js";
60
70
  * one user-facing slash command: how it parses, which SlashCommand kinds it
61
71
  * produces, and how those kinds execute. Adding a new command is one entry
62
72
  * rather than extending two parallel switches.
73
+ *
74
+ * This module is a CLI seam, which constrains what it may import.
75
+ * `src/cli/run.ts` reaches `parseSlashCommand` here so a headless
76
+ * `clio-coder run "/typo"` refuses the token by the same shape test and the same
77
+ * registry membership the editor uses; a second copy of the parser would drift
78
+ * from this one on the first command added. That makes the CLI a reacher of
79
+ * everything this file statically imports, so nothing here may reach the
80
+ * interactive render graph: no theme, no overlay frame, no overlay module, no
81
+ * `../engine/tui.js`. Those modules share one bundle chunk with the instant
82
+ * shell's Stage 0 closure, and a second, disjoint reacher makes esbuild split
83
+ * it, which is a startup-latency regression rather than a style problem. The
84
+ * parse-time data tables the registry needs live in leaves for that reason:
85
+ * `./overlays/settings-sections.js`, `./overlays/library-tabs.js`, and
86
+ * `COUNCIL_SYNTHESIS_LABEL` in `./council.js`. Import from those, not from the
87
+ * overlays that re-export them.
88
+ *
89
+ * Boundaries rule6 in `tests/boundaries/check-boundaries.ts` refuses a violation
90
+ * at lint time; `tests/contracts/instant-shell-import-graph.test.ts` is the
91
+ * measurement it protects.
63
92
  */
64
93
 
65
94
  type ShareCommandVariant =
@@ -116,6 +145,13 @@ type SlashCommandVariant =
116
145
  | { kind: "view"; filter?: string }
117
146
  | { kind: "view-verify"; runId: string }
118
147
  | { kind: "view-usage" }
148
+ /** `/panes`: mode, health, pane inventory, effective settings. */
149
+ | { kind: "panes" }
150
+ | { kind: "panes-show"; target: string }
151
+ /** A preset the model may also ask for, or operator-only argv. Never both. */
152
+ | { kind: "panes-open"; preset?: PanesPresetId; argv?: ReadonlyArray<string>; once?: boolean }
153
+ | { kind: "panes-close"; target: string }
154
+ | { kind: "panes-usage"; reason?: string }
119
155
  | { kind: "thinking-set"; level: string }
120
156
  | { kind: "output-set"; verbosity: string }
121
157
  | { kind: "model" }
@@ -258,14 +294,20 @@ async function runAttributed(
258
294
  progressBus?.emit(BusChannels.DispatchProgress, { runId: handle.runId, agentId: request.agentId, event });
259
295
  }
260
296
  const receipt = await handle.finalPromise;
261
- if (receipt.exitCode !== 0 || receipt.failureMessage) {
297
+ if (receipt.outcome === "canceled") {
298
+ notice("warn", `${command} aborted: ${receipt.outcomeDetail ?? "operator abort"}`);
299
+ } else if (receipt.exitCode !== 0 || receipt.failureMessage) {
262
300
  const failure = receipt.failureMessage ? ` ${receipt.failureMessage}` : "";
263
301
  notice("error", `${command} failed: exit=${receipt.exitCode}${failure}`);
264
302
  }
265
303
  if (share) shareReceipt(request.agentId, receipt, deps);
266
304
  } catch (err) {
267
305
  const msg = err instanceof Error ? err.message : String(err);
268
- notice("error", `${command} failed: ${msg}`);
306
+ if (err instanceof AdmissionCanceledError) {
307
+ notice("warn", `${command} aborted: ${msg.replace(/^dispatch:\s*/u, "")}`);
308
+ } else {
309
+ notice("error", `${command} failed: ${msg}`);
310
+ }
269
311
  }
270
312
  }
271
313
 
@@ -629,6 +671,14 @@ export interface SlashCommandContext {
629
671
  seedTaskMemory?: () => TaskMemorySeedCommandResult;
630
672
  /** Open `/view`, the full observability artifact viewer. */
631
673
  openView: (filter?: string) => void;
674
+ /**
675
+ * The pane layer's operator surface. It remains present when mux resolves to
676
+ * `none` because the Yazi preset can borrow the terminal for one selection;
677
+ * absent only when the host did not compose pane operations at all.
678
+ */
679
+ panes?: PanesOperations;
680
+ /** Serialize a local async command so the next admitted slash command observes its committed state. */
681
+ runLocalOperation?: (operation: () => Promise<void>) => void;
632
682
  /**
633
683
  * Apply a thinking level named on the command line. Returns why it was
634
684
  * refused so the caller can say so, because the level the operator typed may
@@ -640,8 +690,12 @@ export interface SlashCommandContext {
640
690
  openModel: () => void;
641
691
  /** Live providers contract used by `/model <pattern>` to resolve directly. */
642
692
  providers: ProvidersContract;
643
- /** Apply a resolved model reference to settings (and optionally thinking level). */
644
- applyModelRef: (ref: ResolvedModelRef) => void;
693
+ /**
694
+ * Apply a resolved model reference, or hand it to the scope dialog. "pending"
695
+ * means the operator has yet to choose session or global and nothing has
696
+ * changed; the dialog reports the outcome itself.
697
+ */
698
+ applyModelRef: (ref: ResolvedModelRef) => "applied" | "pending";
645
699
  openSettings: (section?: SettingsSectionId, rowId?: SettingsCenterRowId) => void;
646
700
  openResume: () => void;
647
701
  startNewSession: () => void;
@@ -662,10 +716,16 @@ export interface SlashCommandContext {
662
716
  runCompact: (instructions: string | undefined) => void;
663
717
  /**
664
718
  * Escape hatch for the `view verify` entry: verify a receipt file on disk
665
- * and emit a single status line. Kept on the context so the registry does
719
+ * and emit an actionable verification block. Kept on the context so the registry does
666
720
  * not import the overlay module.
667
721
  */
668
- verifyReceipt: (runId: string) => ReceiptIntegrityOutcome;
722
+ verifyReceipt: (runId: string) => ReceiptIntegrityOutcome & {
723
+ receiptPath?: string;
724
+ sealedDigest?: string | null;
725
+ trustSummary?: string | null;
726
+ compromised?: boolean;
727
+ checks?: ReadonlyArray<{ name: string; ok: boolean; evidence: string }>;
728
+ };
669
729
  /**
670
730
  * Handles the "unknown" case: append the text to the chat panel as a user
671
731
  * turn, submit to the chat loop, and schedule a re-render. Handlers for
@@ -677,6 +737,24 @@ export interface SlashCommandContext {
677
737
  render: () => void;
678
738
  }
679
739
 
740
+ type SlashReceiptVerification = ReturnType<SlashCommandContext["verifyReceipt"]>;
741
+
742
+ /** Compact multiline receipt verification for the composer notice surface. */
743
+ export function formatReceiptVerificationBlock(runId: string, result: SlashReceiptVerification): string {
744
+ const status = result.ok ? (result.compromised ? "compromised" : "ok") : result.retired ? "retired" : "fail";
745
+ const lines = [
746
+ `verify ${status} ${runId}`,
747
+ `receipt ${result.receiptPath ?? "unavailable"}`,
748
+ `digest ${result.sealedDigest ?? "unavailable"}`,
749
+ `evidence ${result.trustSummary ?? (!result.ok ? result.reason : "trust status unavailable")}`,
750
+ ];
751
+ if (result.checks && result.checks.length > 0) {
752
+ lines.push("checks");
753
+ for (const check of result.checks) lines.push(` ${check.ok ? "✓" : "✗"} ${check.name}: ${check.evidence}`);
754
+ }
755
+ return lines.join("\n");
756
+ }
757
+
680
758
  /** The one operator-authored turn used by slash and overlay handoff paths. */
681
759
  export function formatUserTaskHandoff(task: Pick<UserTask, "id" | "title" | "note">): string {
682
760
  const note = task.note ? ` ${task.note}.` : "";
@@ -765,6 +843,35 @@ function usageNotice(entry: BuiltinSlashCommand, subcommand?: string): string {
765
843
  return usageLine(entry, subcommand).trim();
766
844
  }
767
845
 
846
+ /**
847
+ * `/panes` output, as plain lines. Pure so the contract test asserts the text
848
+ * an operator reads rather than the object behind it, and so the registry keeps
849
+ * its promise not to reach a renderer.
850
+ */
851
+ export function formatPanesStatus(status: PanesStatus): ReadonlyArray<string> {
852
+ const server = status.server ? `pane host ${status.server.version}, protocol ${status.server.protocol}` : "no server";
853
+ const lines = [
854
+ `panes: mode=${status.mode} ${status.available ? "available" : "unavailable"} (${server})`,
855
+ ` ${status.reason}`,
856
+ ...(status.socketPath ? [` socket ${status.socketPath}`] : []),
857
+ ` settings: enabled=${status.settings.enabled} notifications=${status.settings.notifications} journal=${status.settings.journal}`,
858
+ ` files: enabled=${status.settings.yazi.enabled} mode=${status.settings.yazi.mode} profile=${status.settings.yazi.profile} followCwd=${status.settings.yazi.followCwd}`,
859
+ ` file pane: mode=${status.yazi.mode} pane=${status.yazi.paneId ?? "none"} cwd=${status.yazi.paneCwd ?? "unknown"} lastLine=${status.yazi.lastLineAt === null ? "never" : new Date(status.yazi.lastLineAt).toISOString()} dropped=${status.yazi.droppedLines}`,
860
+ ];
861
+ if (status.panes.length === 0) {
862
+ lines.push(" no Clio-owned panes");
863
+ } else {
864
+ lines.push(` ${status.panes.length} Clio-owned pane(s):`);
865
+ for (const pane of status.panes) {
866
+ const adopted = pane.adopted ? " adopted" : "";
867
+ const pending = pane.pending ? " opening" : "";
868
+ lines.push(` ${pane.paneId} ${pane.purpose} ${pane.label}${adopted}${pending}`);
869
+ }
870
+ }
871
+ lines.push(` presets: ${PANES_PRESETS.map((preset) => `${preset.id} (${preset.summary})`).join(", ")}`);
872
+ return lines;
873
+ }
874
+
768
875
  export const BUILTIN_SLASH_COMMANDS: ReadonlyArray<BuiltinSlashCommand> = [
769
876
  {
770
877
  name: "quit",
@@ -1505,16 +1612,141 @@ export const BUILTIN_SLASH_COMMANDS: ReadonlyArray<BuiltinSlashCommand> = [
1505
1612
  }
1506
1613
  if (command.kind !== "view-verify") return;
1507
1614
  const result = ctx.verifyReceipt(command.runId);
1615
+ const block = formatReceiptVerificationBlock(command.runId, result);
1508
1616
  if (result.ok) {
1509
- ctx.notice("success", `verify ok ${command.runId}`);
1617
+ ctx.notice(result.compromised ? "warn" : "success", block);
1510
1618
  } else if (result.retired !== undefined) {
1511
1619
  // A retired seal is the expected state of a run from the previous
1512
1620
  // release, so it is a warning that names the versions, never the
1513
1621
  // failure a tampered receipt gets.
1514
- ctx.notice("warn", `verify retired ${command.runId} ${result.reason}`);
1622
+ ctx.notice("warn", block);
1515
1623
  } else {
1516
- ctx.notice("error", `verify fail ${command.runId} ${result.reason}`);
1624
+ ctx.notice("error", block);
1625
+ }
1626
+ },
1627
+ },
1628
+ {
1629
+ name: "panes",
1630
+ description: "Inspect the pane layer, watch a live run in a pane, or open a utility pane",
1631
+ group: "Inspect",
1632
+ kinds: ["panes", "panes-show", "panes-open", "panes-close", "panes-usage"],
1633
+ args: {
1634
+ subcommands: {
1635
+ show: { positionals: [{ name: "run-or-agent", required: true }] },
1636
+ // A rest positional, so an argv pane keeps its own flags: the parser
1637
+ // would otherwise refuse `--follow` as an unknown flag of `/panes`.
1638
+ open: { positionals: [{ name: "preset-or-argv", required: true, rest: true }] },
1639
+ close: { positionals: [{ name: "target", required: false }] },
1640
+ },
1641
+ },
1642
+ subcommandDescriptions: {
1643
+ show: "watch a live run or agent in the watch pane",
1644
+ open: `open a utility pane (${PANES_PRESET_IDS.join(", ")}, or a command)`,
1645
+ close: "close a Clio-owned pane, or all of them",
1646
+ },
1647
+ fromArgs(parsed) {
1648
+ if (parsed.error) return { kind: "panes-usage", reason: parsed.error };
1649
+ if (parsed.subcommand === "show") {
1650
+ return { kind: "panes-show", target: parsed.positionals[0] ?? "" };
1651
+ }
1652
+ if (parsed.subcommand === "open") {
1653
+ const rest = (parsed.rest ?? "").trim();
1654
+ if (rest.length === 0) return { kind: "panes-usage", reason: "Missing required argument: preset-or-argv" };
1655
+ const argv = rest.split(/\s+/).filter((token) => token.length > 0);
1656
+ const first = argv[0] ?? "";
1657
+ // A bare preset name is a preset; anything else is operator argv,
1658
+ // which the tool surface deliberately cannot ask for.
1659
+ if (argv.length === 1 && isPanesPresetId(first)) return { kind: "panes-open", preset: first };
1660
+ if (argv.length === 2 && first === "yazi" && argv[1] === "--once") {
1661
+ return { kind: "panes-open", preset: "yazi", once: true };
1662
+ }
1663
+ return { kind: "panes-open", argv };
1664
+ }
1665
+ if (parsed.subcommand === "close") {
1666
+ return { kind: "panes-close", target: parsed.positionals[0] ?? "all" };
1667
+ }
1668
+ if (parsed.positionals.length > 0) {
1669
+ return { kind: "panes-usage", reason: `Unexpected argument: ${parsed.positionals[0]}` };
1670
+ }
1671
+ return { kind: "panes" };
1672
+ },
1673
+ handle(command, ctx) {
1674
+ const entry = BUILTIN_SLASH_COMMANDS.find((candidate) => candidate.name === "panes");
1675
+ if (command.kind === "panes-usage") {
1676
+ // usageNotice trims the leading newline usageLine carries, so the reason
1677
+ // and the usage line need their own separator or they run together as
1678
+ // `Missing required argument: run-or-agentusage: /panes show ...`.
1679
+ if (entry) ctx.notice("info", command.reason ? `${command.reason}\n${usageNotice(entry)}` : usageNotice(entry));
1680
+ return;
1681
+ }
1682
+ const panes = ctx.panes;
1683
+ if (!panes) {
1684
+ // Inactive by choice, not unavailable: the operations object exists in
1685
+ // every `--with-panes` session, even one where no pane host answered.
1686
+ ctx.notice(
1687
+ "info",
1688
+ "panes are inactive: this session started without them. Restart with `clio-coder --with-panes`, or set panes.enabled=auto",
1689
+ );
1690
+ return;
1691
+ }
1692
+ const runLocal = ctx.runLocalOperation ?? ((operation: () => Promise<void>) => void operation());
1693
+ if (command.kind === "panes") {
1694
+ runLocal(async () => {
1695
+ for (const line of formatPanesStatus(panes.status())) ctx.io.stdout(`${line}\n`);
1696
+ ctx.render();
1697
+ });
1698
+ return;
1699
+ }
1700
+ if (command.kind === "panes-show") {
1701
+ runLocal(async () => {
1702
+ const result = await panes.show(command.target);
1703
+ if (result.status === "watching") {
1704
+ ctx.notice("success", `watching ${result.agentId} (${result.runId})${result.opened ? " in a new pane" : ""}`);
1705
+ } else if (result.status === "not-found") {
1706
+ const known = result.candidates.length > 0 ? `; live runs: ${result.candidates.join(", ")}` : "";
1707
+ ctx.notice("warn", `no live run matches ${result.target}${known}`);
1708
+ } else {
1709
+ ctx.notice("warn", result.reason);
1710
+ }
1711
+ });
1712
+ return;
1517
1713
  }
1714
+ if (command.kind === "panes-open") {
1715
+ runLocal(async () => {
1716
+ const result = await panes.open({
1717
+ ...(command.preset ? { preset: command.preset } : {}),
1718
+ ...(command.argv ? { argv: command.argv } : {}),
1719
+ ...(command.once ? { once: true } : {}),
1720
+ });
1721
+ if (result.status === "opened") {
1722
+ // The in-terminal chooser has already restored the TUI by the
1723
+ // time this resolves. A pick emitted its composer notice; an empty
1724
+ // chooser was cancellation and deliberately stays silent.
1725
+ if (result.paneId !== null) ctx.notice("success", `opened pane ${result.label} (${result.paneId})`);
1726
+ } else if (result.status === "missing-binary") {
1727
+ // This is a synchronous slash-surface line, not a transient pane-host
1728
+ // notification. It remains visible when no pane was ever created and
1729
+ // reuses the exact doctor/tools diagnostic including the install hint.
1730
+ ctx.io.stdout(`${result.detail}\n`);
1731
+ ctx.render();
1732
+ } else {
1733
+ ctx.notice("warn", result.reason);
1734
+ }
1735
+ });
1736
+ return;
1737
+ }
1738
+ if (command.kind !== "panes-close") return;
1739
+ runLocal(async () => {
1740
+ const result = await panes.close(command.target);
1741
+ if (result.status === "closed") {
1742
+ const what = result.labels.length > 0 ? `: ${result.labels.join(", ")}` : "";
1743
+ ctx.notice(result.closed > 0 ? "success" : "info", `closed ${result.closed} pane(s)${what}`);
1744
+ } else if (result.status === "not-found") {
1745
+ ctx.notice("warn", `no Clio-owned pane matches ${result.target}`);
1746
+ } else {
1747
+ ctx.notice("warn", result.reason);
1748
+ }
1749
+ });
1518
1750
  },
1519
1751
  },
1520
1752
  {
@@ -1604,9 +1836,13 @@ export const BUILTIN_SLASH_COMMANDS: ReadonlyArray<BuiltinSlashCommand> = [
1604
1836
  return;
1605
1837
  }
1606
1838
  if (result.warning) ctx.notice("warn", result.warning);
1607
- ctx.applyModelRef(result.ref);
1608
- const suffix = result.ref.thinkingLevel ? ` thinking=${result.ref.thinkingLevel}` : "";
1609
- ctx.notice("success", `active: ${result.ref.target}/${result.ref.model}${suffix}`);
1839
+ // "pending" means the scope dialog is up: it says what landed and
1840
+ // where, so announcing a swap here would be announcing a choice the
1841
+ // operator has not made yet.
1842
+ if (ctx.applyModelRef(result.ref) === "applied") {
1843
+ const suffix = result.ref.thinkingLevel ? ` thinking=${result.ref.thinkingLevel}` : "";
1844
+ ctx.notice("success", `active this session: ${result.ref.target}/${result.ref.model}${suffix}`);
1845
+ }
1610
1846
  ctx.render();
1611
1847
  })();
1612
1848
  },
@@ -523,6 +523,7 @@ export function openTasksOverlay(
523
523
  const handle = showClioOverlayFrame(tui, body, {
524
524
  anchor: "center",
525
525
  width: TASKS_OVERLAY_WIDTH,
526
+ markerId: "tasks",
526
527
  title: () => "Tasks",
527
528
  footerHint: () => body.footerHint(),
528
529
  });
@@ -1,17 +1,6 @@
1
- export type ClioToken =
2
- | "accent"
3
- | "accentDeep"
4
- | "action"
5
- | "success"
6
- | "warning"
7
- | "error"
8
- | "info"
9
- | "reason"
10
- | "dim"
11
- | "muted"
12
- | "title"
13
- | "frame"
14
- | "frameStrong";
1
+ import type { ClioToken } from "../../core/theme-token-hex.js";
2
+
3
+ export type { ClioToken } from "../../core/theme-token-hex.js";
15
4
 
16
5
  interface TokenColor {
17
6
  rgb: readonly [number, number, number];
@@ -26,6 +26,7 @@ import { residencyTargetKey } from "../core/residency-target-key.js";
26
26
  import type { ToolName } from "../core/tool-names.js";
27
27
  import { buildEvictionFields, planEviction } from "../domains/context/working-set/engine.js";
28
28
  import { foldWorkingSet } from "../domains/context/working-set/fold.js";
29
+ import { isTurnStart } from "../domains/context/working-set/horizon.js";
29
30
  import { resolveWorkingSetPolicy } from "../domains/context/working-set/policies/index.js";
30
31
  import { selectVisibleEntries } from "../domains/context/working-set/visible.js";
31
32
  import type { ObservabilityContract } from "../domains/observability/contract.js";
@@ -89,7 +90,7 @@ import {
89
90
  toolNamesFromAgentState,
90
91
  } from "./chat-loop-messages.js";
91
92
  import { buildModelReplayAgentMessagesFromTurns } from "./model-session-replay.js";
92
- import { renderCompactionSummaryLine } from "./renderers/compaction-summary.js";
93
+ import { renderCompactionSummaryLine, renderEvictionSkipLine } from "./renderers/compaction-summary.js";
93
94
  import type { TurnMiddleware } from "./turn-middleware.js";
94
95
  import type { AgentRuntime, ChatTurnState } from "./turn-state.js";
95
96
 
@@ -218,6 +219,27 @@ export interface TurnContext {
218
219
  dispose(): void;
219
220
  }
220
221
 
222
+ /**
223
+ * Why the working-set stage declined, said in the terms the operator can act
224
+ * on. The two cases are worth separating: a session whose every turn is inside
225
+ * `protectLastTurns` was never offered a candidate, while a longer one was
226
+ * offered candidates the policy refused. The first is the shape smoke pass 2
227
+ * found (G1), and the setting it names is the one that changes it.
228
+ */
229
+ function evictionSkipMessage(
230
+ visibleEntries: ReadonlyArray<SessionEntry>,
231
+ workingSet: Readonly<{ protectLastTurns: number; policy: string }>,
232
+ policyId: string,
233
+ ): string {
234
+ const turns = visibleEntries.filter(isTurnStart).length;
235
+ return renderEvictionSkipLine({
236
+ reason: turns <= workingSet.protectLastTurns ? "all-protected" : "nothing-evictable",
237
+ turns,
238
+ protectLastTurns: workingSet.protectLastTurns,
239
+ policyId,
240
+ });
241
+ }
242
+
221
243
  export function createTurnContext(deps: TurnContextDeps): TurnContext {
222
244
  const { state, middleware } = deps;
223
245
  const compactionTrigger = new AutoCompactionTrigger<CompactResult | null>();
@@ -661,6 +683,12 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
661
683
  const autoEnabled = cfg?.auto !== false;
662
684
  if (!force && !autoEnabled) return false;
663
685
  let preSummaryStageActed = false;
686
+ // G1 from smoke pass 2: a short session generates all its pressure inside
687
+ // the protection window, the non-destructive layer finds nothing, and the
688
+ // destructive summary ran with nothing in the transcript saying eviction
689
+ // was considered and declined. Held here and emitted only if a summary
690
+ // actually follows.
691
+ let evictionSkipNotice: string | null = null;
664
692
  const rememberEmptyAutomaticAttempt = (): void => {
665
693
  if (!force && !preSummaryStageActed && activeAutoTurnId) emptyAutoCompactTurnId = activeAutoTurnId;
666
694
  };
@@ -743,12 +771,16 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
743
771
  }
744
772
  } else if (settings.context.workingSet.enabled) {
745
773
  let planned: ReturnType<typeof planEviction>;
774
+ let visibleEntries: ReadonlyArray<SessionEntry> = [];
775
+ let policyId = settings.context.workingSet.policy;
746
776
  try {
747
777
  const entries = deps.readSessionEntries() ?? [];
748
778
  const view = foldWorkingSet(entries, state.lastTurnId ?? undefined);
749
779
  const policy = resolveWorkingSetPolicy(settings.context.workingSet.policy);
780
+ policyId = policy.id;
781
+ visibleEntries = selectVisibleEntries(entries, state.lastTurnId ?? undefined);
750
782
  planned = (deps.planEviction ?? planEviction)(policy, {
751
- entries: selectVisibleEntries(entries, state.lastTurnId ?? undefined),
783
+ entries: visibleEntries,
752
784
  view,
753
785
  cwd: deps.session.current()?.cwd ?? null,
754
786
  settings: settings.context.workingSet,
@@ -830,7 +862,16 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
830
862
  emitCompactionActivity("failed", compactionFailureMessage(error));
831
863
  throw error;
832
864
  }
865
+ } else {
866
+ evictionSkipNotice = evictionSkipMessage(visibleEntries, settings.context.workingSet, policyId);
833
867
  }
868
+ } else {
869
+ evictionSkipNotice = renderEvictionSkipLine({
870
+ reason: "disabled",
871
+ turns: 0,
872
+ protectLastTurns: settings.context.workingSet.protectLastTurns,
873
+ policyId: settings.context.workingSet.policy,
874
+ });
834
875
  }
835
876
  }
836
877
  }
@@ -847,6 +888,10 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
847
888
  summaryLifecycleStarted = true;
848
889
  };
849
890
  if (force) startSummaryLifecycle();
891
+ // Said before the summary call, not after it: the operator is about to wait
892
+ // on a destructive stage, and the reason the cheap one was skipped is only
893
+ // useful ahead of it.
894
+ if (evictionSkipNotice) deps.emitNotice(evictionSkipNotice);
850
895
  let result: CompactResult | null = null;
851
896
  const beforeSnapshotId = currentContextSnapshot?.snapshotId ?? null;
852
897
  try {
@@ -5,12 +5,14 @@ import type { DispatchContract } from "../../domains/dispatch/contract.js";
5
5
  import { isReceiptIntegrity, verifyReceiptIntegrity } from "../../domains/dispatch/receipt-integrity.js";
6
6
  import type { RunEnvelope, RunReceipt } from "../../domains/dispatch/types.js";
7
7
  import { evidenceDirectory, inspectEvidence, listEvidenceOverviews } from "../../domains/evidence/store.js";
8
- import { formatTrustSummaryLine } from "../../domains/evidence/trust-projection.js";
8
+ import { formatTrustSummaryLine, trustStateWord } from "../../domains/evidence/trust-projection.js";
9
9
  import {
10
10
  inspectRunReceiptTrustStatus,
11
11
  type ReceiptIntegrityOutcome,
12
12
  retiredReceiptIntegrity,
13
13
  retiredReceiptIntegrityReason,
14
+ TRUST_STATUS_AXES,
15
+ type TrustStatusAxis,
14
16
  } from "../../domains/evidence/trust-status.js";
15
17
  import type { EvidenceFinding, EvidenceOverview, EvidenceSource } from "../../domains/evidence/types.js";
16
18
  import { type AccountabilitySummary, readAccountabilitySummary } from "../../domains/observability/index.js";
@@ -113,6 +115,20 @@ const JSON_PRETTY_MAX_BYTES = 10 * 1024 * 1024;
113
115
 
114
116
  export type ReceiptVerifyResult = ReceiptIntegrityOutcome;
115
117
 
118
+ export interface ReceiptVerificationCheck {
119
+ name: string;
120
+ ok: boolean;
121
+ evidence: string;
122
+ }
123
+
124
+ export type ReceiptVerificationReport = ReceiptIntegrityOutcome & {
125
+ receiptPath: string;
126
+ sealedDigest: string | null;
127
+ trustSummary: string | null;
128
+ compromised: boolean;
129
+ checks: ReceiptVerificationCheck[];
130
+ };
131
+
116
132
  /**
117
133
  * What a verify action reports. `retired` marks a seal this build does not
118
134
  * verify because its integrity version was retired: not a pass, and not the
@@ -435,6 +451,98 @@ export function verifyReceiptFile(stateDir: string, runId: string): ReceiptVerif
435
451
  return verifyReceiptIntegrity(r as unknown as RunReceipt, ledger.envelope);
436
452
  }
437
453
 
454
+ const RECEIPT_FILE_FAILURE = /^(?:receipt file not found|read error:)/u;
455
+ const RECEIPT_CONTRACT_FAILURE =
456
+ /^(?:invalid json:|receipt is not an object|missing field:|runId invalid:|runId mismatch:|agentId invalid:|task invalid:|targetId invalid:|wireModelId invalid:|runtimeId invalid:|runtimeKind invalid:|exitCode out of range:|tokenCount out of range:|inputTokenCount out of range:|outputTokenCount out of range:|cacheReadTokenCount out of range:|cacheWriteTokenCount out of range:|costUsd out of range:|reasoningTokenCount out of range:|startedAt not ISO-8601:|endedAt not ISO-8601:|clioVersion empty|piMonoVersion invalid:|platform invalid:|nodeVersion invalid:|toolCalls out of range:|toolStats\[|compiledPromptHash invalid:|staticCompositionHash invalid:|sessionId invalid:|integrity invalid|execution role invalid|routing intent invalid|route decision invalid)/u;
457
+ const LEDGER_FAILURE = /^(?:run ledger not found|run not found in ledger|ledger mismatch:)/u;
458
+
459
+ function receiptIntegrityDigest(value: unknown): string | null {
460
+ if (!isRecord(value) || value.algorithm !== "sha256" || !isNonEmptyString(value.digest)) return null;
461
+ return `sha256:${value.digest}`;
462
+ }
463
+
464
+ function trustCheckEvidence(status: ReturnType<typeof inspectRunReceiptTrustStatus>["status"], axis: string): string {
465
+ const entry = status[axis as keyof typeof status];
466
+ if (typeof entry !== "object" || entry === null || !("state" in entry)) return "canonical trust projection";
467
+ if (entry.state === "absent") return `reason=${entry.reason}`;
468
+ const refs = entry.artifacts.map((artifact) => `${artifact.kind}:${artifact.id}`);
469
+ return refs.length > 0 ? refs.join(", ") : `${entry.authority.kind}:${entry.authority.id}`;
470
+ }
471
+
472
+ function compromisedTrustAxes(status: ReturnType<typeof inspectRunReceiptTrustStatus>["status"]): TrustStatusAxis[] {
473
+ return TRUST_STATUS_AXES.filter((axis) => {
474
+ const state = status[axis].state;
475
+ if (axis === "artifactIntegrity") return state === "failed";
476
+ if (axis === "validationGrounding") return state === "failed" || state === "ungrounded";
477
+ if (axis === "independentReview") return state === "failed" || state === "not_independent";
478
+ if (axis === "contextProvenance") return state === "invalid";
479
+ if (axis === "autonomyEnforcement") return state === "bypassed";
480
+ return false;
481
+ });
482
+ }
483
+
484
+ /** Actionable `/view verify` report without changing the low-level verifier contract. */
485
+ export function verifyReceiptFileReport(stateDir: string, runId: string): ReceiptVerificationReport {
486
+ const receiptPath = receiptFilePath(stateDir, runId);
487
+ const result = verifyReceiptFile(stateDir, runId);
488
+ let receipt: RunReceipt | null = null;
489
+ try {
490
+ receipt = JSON.parse(readFileSync(receiptPath, "utf8")) as RunReceipt;
491
+ } catch {
492
+ // The verifier's named file or JSON check below retains the actionable error.
493
+ }
494
+ const sealedDigest = receiptIntegrityDigest(receipt?.integrity);
495
+ const ledger = readRunEnvelope(stateDir, runId);
496
+ const inspection = receipt === null ? null : inspectRunReceiptTrustStatus(receipt, ledger.ok ? ledger.envelope : null);
497
+ const trustSummary = inspection === null ? null : formatTrustSummaryLine(inspection.status);
498
+ const compromiseAxes = inspection === null ? [] : compromisedTrustAxes(inspection.status);
499
+ const checks: ReceiptVerificationCheck[] = [];
500
+
501
+ if (!result.ok && RECEIPT_FILE_FAILURE.test(result.reason)) {
502
+ checks.push({ name: "receipt file", ok: false, evidence: `${receiptPath}: ${result.reason}` });
503
+ } else {
504
+ checks.push({ name: "receipt file", ok: true, evidence: receiptPath });
505
+ if (!result.ok && (RECEIPT_CONTRACT_FAILURE.test(result.reason) || result.retired !== undefined)) {
506
+ checks.push({ name: "receipt contract", ok: false, evidence: result.reason });
507
+ } else {
508
+ checks.push({
509
+ name: "receipt contract",
510
+ ok: true,
511
+ evidence: `current integrity v${receipt?.integrity.version ?? "unknown"}`,
512
+ });
513
+ if (!result.ok && LEDGER_FAILURE.test(result.reason)) {
514
+ checks.push({ name: "run ledger", ok: false, evidence: result.reason });
515
+ } else {
516
+ checks.push({ name: "run ledger", ok: true, evidence: `run ${runId} fields match` });
517
+ checks.push({
518
+ name: "sealed digest",
519
+ ok: result.ok,
520
+ evidence: result.ok ? `${sealedDigest ?? "digest unavailable"} matches receipt and ledger` : result.reason,
521
+ });
522
+ }
523
+ }
524
+ }
525
+
526
+ if (inspection !== null) {
527
+ for (const axis of compromiseAxes) {
528
+ checks.push({
529
+ name: `trust ${axis}`,
530
+ ok: false,
531
+ evidence: `${trustStateWord(axis, inspection.status[axis].state)}; ${trustCheckEvidence(inspection.status, axis)}`,
532
+ });
533
+ }
534
+ }
535
+
536
+ return {
537
+ ...result,
538
+ receiptPath,
539
+ sealedDigest,
540
+ trustSummary,
541
+ compromised: compromiseAxes.length > 0,
542
+ checks,
543
+ };
544
+ }
545
+
438
546
  function pushCapped(lines: string[], line: string, maxLines: number): boolean {
439
547
  if (lines.length >= maxLines) return false;
440
548
  lines.push(line);
@@ -764,6 +764,7 @@ export function openViewOverlay(
764
764
  width: VIEW_OVERLAY_WIDTH,
765
765
  maxHeight: VIEW_OVERLAY_MAX_HEIGHT,
766
766
  margin: VIEW_OVERLAY_MARGIN,
767
+ markerId: "view",
767
768
  title: "View",
768
769
  footerHint: (innerWidth) => view.getHint(innerWidth),
769
770
  });