@iowarp/clio-coder 0.3.8 → 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 (552) hide show
  1. package/CHANGELOG.md +102 -0
  2. package/NOTICE +33 -0
  3. package/README.md +12 -3
  4. package/dist/{acp-U67UHUK2.js → acp-G5WJBNCT.js} +13 -12
  5. package/dist/{agents-YU6SGALZ.js → agents-FMV2Q5G4.js} +41 -36
  6. package/dist/assets/codewiki.json +1 -1
  7. package/dist/{auth-5ZPJOIVG.js → auth-3IDSJEIK.js} +18 -18
  8. package/dist/{builtins-C6JMZVV6.js → builtins-XCZWXSC7.js} +5 -5
  9. package/dist/{chunk-IFBNV6H6.js → chunk-2ANTL7MR.js} +3 -3
  10. package/dist/{chunk-5FR74PWO.js → chunk-2JDWVJND.js} +2 -2
  11. package/dist/{chunk-XWSF374K.js → chunk-2OQE55CK.js} +3 -3
  12. package/dist/{chunk-5H3GB5BO.js → chunk-32KWKNSF.js} +8 -384
  13. package/dist/{chunk-KTYTFRMB.js → chunk-36EJLSQQ.js} +34 -36
  14. package/dist/{chunk-FHJEP5SW.js → chunk-3BT2XMV4.js} +19 -13
  15. package/dist/chunk-3DPEIQKN.js +113 -0
  16. package/dist/{chunk-GU2UIAFZ.js → chunk-3URVFKWK.js} +7 -7
  17. package/dist/{chunk-WEH5XRJQ.js → chunk-3XML7CDN.js} +3 -3
  18. package/dist/chunk-42FMPA75.js +101 -0
  19. package/dist/{chunk-A2NJGIB3.js → chunk-5LXZXPKX.js} +2 -2
  20. package/dist/{chunk-VCBR6CU7.js → chunk-5PSMVOLM.js} +2 -2
  21. package/dist/{chunk-NMPKI6XL.js → chunk-6DB53AJS.js} +203 -25
  22. package/dist/{chunk-3BINW3FP.js → chunk-76ONBSIA.js} +2 -2
  23. package/dist/{chunk-26LEYJZH.js → chunk-7MCTRUCE.js} +2 -2
  24. package/dist/{chunk-TYPGUK6W.js → chunk-AB44T6BB.js} +111 -5
  25. package/dist/{chunk-K4XHGFR5.js → chunk-B7OBL7PK.js} +317 -721
  26. package/dist/{chunk-B5CSFE7B.js → chunk-BBVJUZHB.js} +2 -2
  27. package/dist/{chunk-EQ63NRB7.js → chunk-BBVYXMFO.js} +2 -2
  28. package/dist/{chunk-ZVJ5BLO2.js → chunk-BKFJHQCA.js} +154 -16
  29. package/dist/chunk-BKFM6EJV.js +462 -0
  30. package/dist/chunk-BMS5RKQY.js +27 -0
  31. package/dist/{chunk-ZNLWCMVZ.js → chunk-BPKCPIL7.js} +2 -2
  32. package/dist/{chunk-TLQJPP24.js → chunk-BUMFYQFY.js} +1394 -1349
  33. package/dist/{chunk-BNAZZHFG.js → chunk-BYP5D4HI.js} +1 -1
  34. package/dist/chunk-C2LTL2W6.js +2447 -0
  35. package/dist/{chunk-ME6CCNFO.js → chunk-CODPRO7Q.js} +8 -8
  36. package/dist/{chunk-E77JEWSD.js → chunk-CTJ4RNAA.js} +7 -37
  37. package/dist/{chunk-ODFEOB4F.js → chunk-CY6FY24N.js} +26 -8
  38. package/dist/{chunk-7RFXX52T.js → chunk-DQITNCXG.js} +642 -172
  39. package/dist/{chunk-TTHACPOM.js → chunk-DYJP44XW.js} +578 -117
  40. package/dist/{chunk-2HFZQUHL.js → chunk-F4CKPOEQ.js} +18 -8
  41. package/dist/{chunk-DGSYXYMX.js → chunk-FEFIFZTL.js} +3 -3
  42. package/dist/{chunk-GWS3VEIW.js → chunk-FWDFM5ZU.js} +24 -3
  43. package/dist/{chunk-MV3K5QF2.js → chunk-GCSMB2KY.js} +2 -2
  44. package/dist/chunk-GKF55TAZ.js +391 -0
  45. package/dist/{chunk-VWZOAB7K.js → chunk-GR5G2PVF.js} +9 -8
  46. package/dist/{chunk-4DGYLA73.js → chunk-GXNLGKAB.js} +80 -9
  47. package/dist/chunk-HHV2GANA.js +88 -0
  48. package/dist/{chunk-IIZWH4XA.js → chunk-HI63TFOG.js} +5 -4
  49. package/dist/{chunk-WLFILSD5.js → chunk-HJJTYUHX.js} +113 -83
  50. package/dist/{chunk-TT36MB5S.js → chunk-HLW2MRKE.js} +3 -1
  51. package/dist/{chunk-PMDBGQSJ.js → chunk-HWHKMHUA.js} +7 -7
  52. package/dist/chunk-HZHHCK24.js +1631 -0
  53. package/dist/{chunk-WSB3FPX7.js → chunk-I5VEOC6I.js} +39 -143
  54. package/dist/chunk-IBEBSCYA.js +564 -0
  55. package/dist/chunk-IQ7KR472.js +362 -0
  56. package/dist/{chunk-A3WNZD3P.js → chunk-J4W7KFM7.js} +949 -972
  57. package/dist/{chunk-TB5666IT.js → chunk-JDG2WCRO.js} +5 -5
  58. package/dist/{chunk-N22QMJKY.js → chunk-K5C3NCBD.js} +4 -4
  59. package/dist/{chunk-CGKSTWHD.js → chunk-K6BSR66V.js} +2 -1
  60. package/dist/{chunk-5C3AQNDW.js → chunk-KFZI4NIL.js} +216 -38
  61. package/dist/chunk-KMVISBZR.js +132 -0
  62. package/dist/{chunk-WXY7KU3G.js → chunk-LDQ2ZF2M.js} +2 -2
  63. package/dist/{chunk-XN3L4EYL.js → chunk-LQ3DZAMX.js} +3 -3
  64. package/dist/{chunk-U6MBIEMB.js → chunk-LY4S7GJC.js} +173 -144
  65. package/dist/{chunk-4SPRNWDE.js → chunk-MLKNTWH2.js} +19 -19
  66. package/dist/{chunk-MVVUPGPW.js → chunk-MXHC5QYU.js} +6 -6
  67. package/dist/chunk-NEKRRTYW.js +56 -0
  68. package/dist/{chunk-SPULKLCF.js → chunk-NHCZP4K7.js} +3 -3
  69. package/dist/chunk-NHLBIGRH.js +1506 -0
  70. package/dist/chunk-NQQH3YT7.js +302 -0
  71. package/dist/chunk-NYS75XW5.js +15 -0
  72. package/dist/{chunk-GN57SG4G.js → chunk-O4XIVISU.js} +10 -8
  73. package/dist/{chunk-EMYUUSFG.js → chunk-O6TL7WWY.js} +6 -6
  74. package/dist/chunk-OQBA45DZ.js +97 -0
  75. package/dist/{chunk-LU7P4LHA.js → chunk-P3FOHJT4.js} +2 -2
  76. package/dist/chunk-PMZCIOCJ.js +25 -0
  77. package/dist/{chunk-I4HZDVNP.js → chunk-PQEFIJ36.js} +2 -2
  78. package/dist/{chunk-J3YUBZWY.js → chunk-QBJA7R7N.js} +62 -6
  79. package/dist/chunk-QDC3K2U3.js +262 -0
  80. package/dist/{chunk-2HEJ2F35.js → chunk-QLFS5GO2.js} +22 -10
  81. package/dist/{chunk-7RGZWPB6.js → chunk-QLL7ILRG.js} +95 -32
  82. package/dist/{chunk-YS5VLNH5.js → chunk-QREDIESB.js} +6 -6
  83. package/dist/chunk-QSNYB6ZV.js +195 -0
  84. package/dist/{chunk-GOXNB3AO.js → chunk-RAPCMZL4.js} +75 -4
  85. package/dist/chunk-RKKLTLYB.js +45 -0
  86. package/dist/{chunk-P43ETTHK.js → chunk-SJ5ZKQ4S.js} +2 -2
  87. package/dist/{chunk-GPIEI3LY.js → chunk-SP2RXXYO.js} +6 -54
  88. package/dist/chunk-SUCTJL45.js +45 -0
  89. package/dist/{chunk-DYIM5TJT.js → chunk-SUW5DORT.js} +263 -7
  90. package/dist/chunk-T56WDKA5.js +183 -0
  91. package/dist/chunk-TVHHYFHE.js +255 -0
  92. package/dist/{chunk-FJ3H4MN5.js → chunk-TZ3SGWZZ.js} +3 -3
  93. package/dist/{chunk-MXKJU4JB.js → chunk-U77AMWDL.js} +91 -10
  94. package/dist/{chunk-5DHKRSMQ.js → chunk-ULC6OTWO.js} +11 -7
  95. package/dist/{chunk-RWSI4YD7.js → chunk-UM7N4G5A.js} +33 -12
  96. package/dist/{chunk-FCSXB6T2.js → chunk-UOSL25KY.js} +14 -2
  97. package/dist/{chunk-IGWKHNIQ.js → chunk-UXMFQ54G.js} +44 -37
  98. package/dist/{chunk-HFSBBKSQ.js → chunk-V5DHCITQ.js} +171 -3
  99. package/dist/{chunk-5WIGXA4T.js → chunk-VAZSBTKF.js} +111 -4
  100. package/dist/{chunk-VHN4MY6O.js → chunk-VEO4AP2K.js} +2 -2
  101. package/dist/{chunk-IJ7RPIYJ.js → chunk-VFA6GDY5.js} +65 -4
  102. package/dist/{chunk-PT7HYKEM.js → chunk-VO2LKSTM.js} +2 -2
  103. package/dist/chunk-VO67MWHC.js +75 -0
  104. package/dist/{chunk-XK56QHLX.js → chunk-VPKWYKEY.js} +19 -5
  105. package/dist/{chunk-TANS5ZJS.js → chunk-VYMXRQI6.js} +36 -22
  106. package/dist/{chunk-WWCZ5F23.js → chunk-W5VSYASO.js} +77 -16
  107. package/dist/{chunk-WNIJTQQK.js → chunk-WZR7K7ZX.js} +72 -116
  108. package/dist/{chunk-5Q2VVUKB.js → chunk-X3YGUTOB.js} +4 -4
  109. package/dist/chunk-X75E3D2N.js +686 -0
  110. package/dist/{chunk-VAWNZU7Z.js → chunk-YDFRH54B.js} +4 -4
  111. package/dist/chunk-YJX4SHTD.js +40 -0
  112. package/dist/{chunk-ZI647VB5.js → chunk-YPI3QQCF.js} +2 -2
  113. package/dist/chunk-Z2RR6MAK.js +127 -0
  114. package/dist/{chunk-FBVTI2TJ.js → chunk-Z4TXYIEG.js} +12 -131
  115. package/dist/cli/index.js +47 -36
  116. package/dist/{clio-QVTYJ57A.js → clio-2JXHBBY5.js} +7 -7
  117. package/dist/{code-nav-FGGFIE7L.js → code-nav-3YYRMYNF.js} +8 -8
  118. package/dist/{compile-cache-CVJMMODC.js → compile-cache-7FPE6PS3.js} +3 -3
  119. package/dist/{components-ZFA3SAER.js → components-RYZV4JGP.js} +5 -5
  120. package/dist/{config-LW5IJFQN.js → config-QZPCMYSO.js} +99 -63
  121. package/dist/{configure-7XIZCOU4.js → configure-TEGEBYCA.js} +23 -22
  122. package/dist/{context-Y6Y7QPR6.js → context-AV7OEZ4D.js} +12 -12
  123. package/dist/{context-L3WL3X7K.js → context-E6H5RNMC.js} +56 -47
  124. package/dist/{context-N52ZA626.js → context-GSXUE4CT.js} +29 -27
  125. package/dist/{context-clear-MBQRLSDQ.js → context-clear-SHIBYK6T.js} +55 -46
  126. package/dist/{context-index-HVMFQHK3.js → context-index-HNG3MOME.js} +2 -2
  127. package/dist/{context-working-set-GS6DSO7F.js → context-working-set-5ZGKPGZQ.js} +13 -13
  128. package/dist/{dispatch-runner-22ZCNOM3.js → dispatch-runner-EFMJT4LD.js} +93 -64
  129. package/dist/{docs-7LQ23DLM.js → docs-23KQS3XK.js} +5 -5
  130. package/dist/doctor-QOA5FNY5.js +313 -0
  131. package/dist/{eval-BEC2WHDA.js → eval-TFBYQH4H.js} +2032 -156
  132. package/dist/eval-inventory-SXH7PDKX.js +316 -0
  133. package/dist/{evidence-REJUMSKM.js → evidence-ERGESKGN.js} +203 -48
  134. package/dist/{evolve-PY5ZBA5K.js → evolve-VDXTSYCJ.js} +52 -43
  135. package/dist/{extensions-HVKU65YU.js → extensions-7BGBHN57.js} +13 -7
  136. package/dist/{fleet-7WZEWRFA.js → fleet-2RRVDF2V.js} +228 -108
  137. package/dist/{fleet-commands-UVHWM76J.js → fleet-commands-VJ726XIA.js} +11 -11
  138. package/dist/fleet-decisions-EPAPM3XJ.js +157 -0
  139. package/dist/{fleet-graph-6ULH7PES.js → fleet-graph-JF5QOATM.js} +18 -15
  140. package/dist/fleet-inspect-VLY4S7QM.js +442 -0
  141. package/dist/{fleet-preflight-J53T6CCE.js → fleet-preflight-AIZUEJOY.js} +5 -5
  142. package/dist/{fleet-validate-72PC4SLA.js → fleet-validate-AJRPDMDV.js} +22 -19
  143. package/dist/fleet-verify-JFEL2L3H.js +175 -0
  144. package/dist/fleet-view-ZCON35AG.js +102 -0
  145. package/dist/{init-OG3TPGQG.js → init-DN2WWLFE.js} +72 -62
  146. package/dist/install-XGLBQY5E.js +13 -0
  147. package/dist/interop-OZBKXAYL.js +114 -0
  148. package/dist/{library-CNTMPLRF.js → library-YWZG7IMW.js} +21 -18
  149. package/dist/{memory-6IS7F275.js → memory-I4C4HMLW.js} +54 -45
  150. package/dist/{models-ENRJDA5W.js → models-CEYXJBO6.js} +33 -30
  151. package/dist/{monitor-XLDVO7TN.js → monitor-NZ6GCI3P.js} +59 -52
  152. package/dist/{orchestrator-6KSPYRHA.js → orchestrator-GCGQ4N5I.js} +7827 -7328
  153. package/dist/panes-HMABYVO4.js +58 -0
  154. package/dist/panes-KY6W3V2E.js +103 -0
  155. package/dist/{paths-DBXMZMDU.js → paths-II4K7DNR.js} +5 -5
  156. package/dist/{reset-RZ4ER727.js → reset-DQ6FGCSH.js} +13 -11
  157. package/dist/resources-BB3MVJMD.js +111 -0
  158. package/dist/{run-Y2CNK5RU.js → run-H2GQDUER.js} +119 -87
  159. package/dist/{share-A55GYP6Z.js → share-GTJN6A5O.js} +20 -17
  160. package/dist/{skills-ALC5J6AT.js → skills-L55TEW6R.js} +33 -24
  161. package/dist/{skills-eval-JPBEBYQU.js → skills-eval-XVXPH2JI.js} +67 -56
  162. package/dist/skills-inventory-S4MXPJFV.js +126 -0
  163. package/dist/slash-commands-ZSGASKJC.js +77 -0
  164. package/dist/{steer-GGWFUJUD.js → steer-RZGSCY4R.js} +4 -4
  165. package/dist/{support-MIETYA5E.js → support-PKEUNNQL.js} +6 -6
  166. package/dist/{targets-VGNXIR3S.js → targets-NCPZ644J.js} +68 -40
  167. package/dist/{terminal-lease-WOBR64YA.js → terminal-lease-44SV3YCN.js} +6 -4
  168. package/dist/tools-DAF3DI3C.js +27 -0
  169. package/dist/{trace-PNCASAXC.js → trace-FYVW2MQA.js} +207 -10
  170. package/dist/tui-primitives-2AKXQNZK.js +13 -0
  171. package/dist/{uninstall-ZJF5H5ZN.js → uninstall-DW2PNOIC.js} +5 -5
  172. package/dist/{upgrade-FUSUAGHR.js → upgrade-3XPP6OQL.js} +27 -24
  173. package/dist/{usage-N4MKVHKD.js → usage-3NLHGTU2.js} +114 -62
  174. package/dist/{verifiers-YAWOJ3H2.js → verifiers-SSQONKRT.js} +172 -13
  175. package/dist/{verify-LTDHYBGY.js → verify-3U6J7FZI.js} +10 -10
  176. package/dist/{web-fetch-2YHJ3KTG.js → web-fetch-S7RR6GZ7.js} +3 -3
  177. package/dist/{wiki-generate-6M7GHTBJ.js → wiki-generate-CEHYGPGQ.js} +75 -65
  178. package/dist/with-panes-MKB46MPQ.js +782 -0
  179. package/dist/worker/entry.js +106 -75
  180. package/docs/README.md +3 -2
  181. package/docs/acp.md +24 -3
  182. package/docs/alcf-provider.md +1 -1
  183. package/docs/architecture.md +2 -2
  184. package/docs/artifact-versions.md +9 -1
  185. package/docs/built-in-agents.md +1 -1
  186. package/docs/capacity-and-scheduling.md +62 -3
  187. package/docs/commands-and-modes.md +31 -2
  188. package/docs/configuration-and-targets.md +69 -12
  189. package/docs/context-engine.md +63 -4
  190. package/docs/development-pipeline.md +19 -0
  191. package/docs/dispatch-typed-intent.md +385 -0
  192. package/docs/documentation-coverage.md +5 -5
  193. package/docs/documentation-guide.md +1 -1
  194. package/docs/environment-variables.md +3 -0
  195. package/docs/eval-runner.md +262 -11
  196. package/docs/evals-internal.md +72 -2
  197. package/docs/evidence-and-memory.md +12 -11
  198. package/docs/evolution.md +1 -1
  199. package/docs/exit-codes-and-output.md +1 -1
  200. package/docs/extensions-and-sharing.md +27 -1
  201. package/docs/fleet-dispatch.md +25 -4
  202. package/docs/installation-and-lifecycle.md +15 -2
  203. package/docs/middleware-and-components.md +1 -1
  204. package/docs/model-catalog.md +10 -1
  205. package/docs/observability.md +55 -4
  206. package/docs/proactive-memory.md +127 -14
  207. package/docs/prompt-envelope-and-tools.md +19 -1
  208. package/docs/provider-adapter-cookbook.md +1 -1
  209. package/docs/release-cut-checklist.md +19 -3
  210. package/docs/safety-model.md +2 -2
  211. package/docs/scientific-validation.md +3 -3
  212. package/docs/session-lifecycle.md +1 -1
  213. package/docs/skills-marketplace.md +1 -1
  214. package/docs/tool-usage.md +18 -8
  215. package/docs/trace-store.md +1 -1
  216. package/docs/troubleshooting.md +88 -1
  217. package/docs/tui-design.md +1 -1
  218. package/docs/worker-dispatch-mechanics.md +1 -1
  219. package/package.json +5 -2
  220. package/src/cli/acp.ts +6 -2
  221. package/src/cli/agents.ts +1 -1
  222. package/src/cli/argv.ts +25 -0
  223. package/src/cli/config-inspect.ts +33 -6
  224. package/src/cli/config.ts +1 -1
  225. package/src/cli/configure.ts +23 -21
  226. package/src/cli/doctor-panes.ts +124 -0
  227. package/src/cli/doctor-state-size.ts +82 -0
  228. package/src/cli/doctor-toolchain.ts +57 -0
  229. package/src/cli/doctor.ts +22 -1
  230. package/src/cli/eval-inventory.ts +436 -0
  231. package/src/cli/eval.ts +93 -16
  232. package/src/cli/evidence-detail.ts +88 -0
  233. package/src/cli/evidence-inventory.ts +183 -0
  234. package/src/cli/evidence.ts +30 -5
  235. package/src/cli/extensions.ts +5 -1
  236. package/src/cli/fleet-decisions.ts +69 -0
  237. package/src/cli/fleet-inspect.ts +334 -0
  238. package/src/cli/fleet-verify.ts +133 -0
  239. package/src/cli/fleet-view.ts +810 -0
  240. package/src/cli/fleet.ts +179 -39
  241. package/src/cli/index.ts +14 -2
  242. package/src/cli/interop-inspect.ts +128 -0
  243. package/src/cli/interop.ts +34 -0
  244. package/src/cli/panes.ts +35 -0
  245. package/src/cli/reset.ts +5 -2
  246. package/src/cli/run.ts +58 -0
  247. package/src/cli/skills-inventory.ts +185 -0
  248. package/src/cli/skills.ts +16 -13
  249. package/src/cli/targets.ts +44 -13
  250. package/src/cli/tools.ts +321 -0
  251. package/src/cli/trace-inspect.ts +252 -0
  252. package/src/cli/trace.ts +85 -5
  253. package/src/cli/usage.ts +63 -14
  254. package/src/cli/verifiers-inspect.ts +347 -0
  255. package/src/cli/verifiers.ts +9 -0
  256. package/src/core/bus-events.ts +33 -1
  257. package/src/core/cache-telemetry.ts +42 -0
  258. package/src/core/config.ts +67 -0
  259. package/src/core/defaults.ts +124 -8
  260. package/src/core/endpoint-key.ts +27 -0
  261. package/src/core/residency-target-key.ts +25 -0
  262. package/src/core/response-schema.ts +80 -6
  263. package/src/core/theme-token-hex.ts +43 -0
  264. package/src/core/tool-names.ts +2 -1
  265. package/src/core/xdg.ts +1 -1
  266. package/src/domains/agents/fleets/build-review.md +0 -3
  267. package/src/domains/agents/fleets/build-test.md +0 -3
  268. package/src/domains/agents/result-contract-filesystem.ts +32 -0
  269. package/src/domains/agents/result-contract.ts +164 -35
  270. package/src/domains/config/classify.ts +6 -0
  271. package/src/domains/context/codewiki/coordinator.ts +12 -4
  272. package/src/domains/dispatch/admission-error.ts +9 -0
  273. package/src/domains/dispatch/admission.ts +52 -14
  274. package/src/domains/dispatch/capacity-lease.ts +118 -9
  275. package/src/domains/dispatch/contract.ts +11 -0
  276. package/src/domains/dispatch/council-topology.ts +398 -0
  277. package/src/domains/dispatch/execution-plan.ts +44 -4
  278. package/src/domains/dispatch/extension.ts +378 -82
  279. package/src/domains/dispatch/fleet-node-prompt.ts +62 -0
  280. package/src/domains/dispatch/fleet-plan.ts +7 -2
  281. package/src/domains/dispatch/fleet-run.ts +87 -4
  282. package/src/domains/dispatch/gate-decisions.ts +11 -1
  283. package/src/domains/dispatch/gate-role-prompts.ts +9 -0
  284. package/src/domains/dispatch/gate-topology.ts +289 -0
  285. package/src/domains/dispatch/heartbeat.ts +32 -8
  286. package/src/domains/dispatch/index.ts +22 -0
  287. package/src/domains/dispatch/intent-compatibility.ts +330 -0
  288. package/src/domains/dispatch/intent.ts +85 -1
  289. package/src/domains/dispatch/orphan-recovery.ts +5 -0
  290. package/src/domains/dispatch/reservation-store.ts +139 -11
  291. package/src/domains/dispatch/run-event-journal-bridge.ts +149 -0
  292. package/src/domains/dispatch/run-event-journal.ts +598 -0
  293. package/src/domains/dispatch/state.ts +49 -1
  294. package/src/domains/dispatch/types.ts +13 -0
  295. package/src/domains/dispatch/validation.ts +33 -8
  296. package/src/domains/dispatch/worker-spawn.ts +25 -11
  297. package/src/domains/dispatch/write-boundary-enforcer.ts +20 -3
  298. package/src/domains/dispatch/write-boundary.ts +62 -1
  299. package/src/domains/eval/artifacts/store.ts +62 -0
  300. package/src/domains/eval/compare/behavioral.ts +224 -0
  301. package/src/domains/eval/compare/compare.ts +342 -2
  302. package/src/domains/eval/compare/envelope.ts +128 -0
  303. package/src/domains/eval/compare/gates.ts +24 -6
  304. package/src/domains/eval/compare/thresholds.ts +30 -3
  305. package/src/domains/eval/execution-provenance.ts +240 -0
  306. package/src/domains/eval/inventory.ts +113 -0
  307. package/src/domains/eval/metrics/aggregate.ts +136 -0
  308. package/src/domains/eval/metrics/call-ledger-stream.ts +112 -0
  309. package/src/domains/eval/metrics/tracked.ts +413 -0
  310. package/src/domains/eval/provenance.ts +117 -0
  311. package/src/domains/eval/reports/comparison.ts +128 -0
  312. package/src/domains/eval/reports/junit.ts +17 -3
  313. package/src/domains/eval/reports/markdown.ts +3 -3
  314. package/src/domains/eval/reports/text.ts +14 -0
  315. package/src/domains/eval/run-compare.ts +20 -0
  316. package/src/domains/eval/runners/clio-run.ts +127 -0
  317. package/src/domains/eval/runners/external-command.ts +28 -3
  318. package/src/domains/eval/schema/adapter.ts +111 -0
  319. package/src/domains/eval/schema/artifact.ts +20 -0
  320. package/src/domains/eval/schema/behavioral-metrics.ts +204 -0
  321. package/src/domains/eval/schema/behavioral.ts +520 -0
  322. package/src/domains/eval/schema/execution-envelope.ts +194 -0
  323. package/src/domains/eval/schema/serving.ts +105 -0
  324. package/src/domains/eval/schema/suite.ts +38 -8
  325. package/src/domains/eval/schema/validate.ts +58 -3
  326. package/src/domains/eval/schema/verdict.ts +237 -0
  327. package/src/domains/eval/suites/resolve.ts +2 -0
  328. package/src/domains/eval/suites/run.ts +264 -33
  329. package/src/domains/eval/verifiers/command.ts +2 -1
  330. package/src/domains/eval/workspaces/temp-copy.ts +145 -13
  331. package/src/domains/evidence/build.ts +2 -13
  332. package/src/domains/evidence/eval.ts +2 -12
  333. package/src/domains/evidence/findings-markdown.ts +33 -0
  334. package/src/domains/evidence/run-trust.ts +7 -113
  335. package/src/domains/evidence/store.ts +6 -0
  336. package/src/domains/evidence/trust-projection.ts +2 -2
  337. package/src/domains/extensions/compatibility.ts +285 -0
  338. package/src/domains/extensions/discovery.ts +38 -3
  339. package/src/domains/extensions/resources.ts +1 -1
  340. package/src/domains/extensions/state.ts +12 -3
  341. package/src/domains/extensions/types.ts +2 -0
  342. package/src/domains/lifecycle/doctor.ts +69 -1
  343. package/src/domains/memory/index.ts +14 -1
  344. package/src/domains/memory/task-bank-promotion.ts +64 -0
  345. package/src/domains/memory/task-memory-policy.ts +82 -17
  346. package/src/domains/memory/task-memory-spend.ts +131 -0
  347. package/src/domains/memory/task-memory-status.ts +7 -0
  348. package/src/domains/memory/task-memory-telemetry.ts +3 -0
  349. package/src/domains/middleware/index.ts +1 -0
  350. package/src/domains/middleware/memory-intervention.ts +97 -21
  351. package/src/domains/middleware/memory-step-endpoint.ts +71 -0
  352. package/src/domains/mux/contract.ts +434 -0
  353. package/src/domains/mux/detect.ts +158 -0
  354. package/src/domains/mux/extension.ts +47 -0
  355. package/src/domains/mux/index.ts +96 -0
  356. package/src/domains/mux/manifest.ts +6 -0
  357. package/src/domains/mux/operations.ts +164 -0
  358. package/src/domains/mux/pane-registry.ts +90 -0
  359. package/src/domains/mux/protocol.ts +49 -0
  360. package/src/domains/mux/socket-client.ts +816 -0
  361. package/src/domains/mux/types.ts +222 -0
  362. package/src/domains/mux/viewer-command.ts +59 -0
  363. package/src/domains/mux/yazi/assets/init.lua +2 -0
  364. package/src/domains/mux/yazi/assets/plugins/git.yazi/LICENSE +21 -0
  365. package/src/domains/mux/yazi/assets/plugins/git.yazi/README.md +78 -0
  366. package/src/domains/mux/yazi/assets/plugins/git.yazi/main.lua +255 -0
  367. package/src/domains/mux/yazi/assets/plugins/git.yazi/types.lua +12 -0
  368. package/src/domains/mux/yazi/assets/yazi.toml +17 -0
  369. package/src/domains/mux/yazi/event-stream.ts +180 -0
  370. package/src/domains/mux/yazi/profile.ts +299 -0
  371. package/src/domains/mux/yazi/session.ts +228 -0
  372. package/src/domains/mux/yazi/theme.ts +30 -0
  373. package/src/domains/observability/background-memory-usage.ts +140 -0
  374. package/src/domains/observability/cost.ts +22 -1
  375. package/src/domains/observability/index.ts +9 -0
  376. package/src/domains/observability/out-of-turn-usage.ts +51 -2
  377. package/src/domains/observability/trace-store.ts +234 -2
  378. package/src/domains/prompts/compiler.ts +100 -13
  379. package/src/domains/providers/endpoint-capacity.ts +228 -0
  380. package/src/domains/providers/endpoint-slots-store.ts +189 -0
  381. package/src/domains/providers/extension.ts +20 -3
  382. package/src/domains/providers/index.ts +32 -0
  383. package/src/domains/providers/model-runtime-capabilities.ts +32 -0
  384. package/src/domains/providers/models/local-models/clio-local-coding-targets.yaml +243 -1
  385. package/src/domains/providers/runtime-resolution.ts +8 -1
  386. package/src/domains/providers/runtimes/boot-manifest.ts +1 -0
  387. package/src/domains/providers/runtimes/builtins.ts +2 -0
  388. package/src/domains/providers/runtimes/common/probe-helpers.ts +31 -9
  389. package/src/domains/providers/runtimes/local-native/llamacpp-anthropic.ts +1 -1
  390. package/src/domains/providers/runtimes/local-native/llamacpp-completion.ts +1 -1
  391. package/src/domains/providers/runtimes/local-native/llamacpp-embed.ts +1 -1
  392. package/src/domains/providers/runtimes/local-native/llamacpp-rerank.ts +1 -1
  393. package/src/domains/providers/runtimes/local-native/llamacpp.ts +4 -1
  394. package/src/domains/providers/runtimes/local-native/lmstudio.ts +4 -1
  395. package/src/domains/providers/runtimes/local-native/ollama-native.ts +6 -1
  396. package/src/domains/providers/runtimes/protocol/litellm.ts +375 -0
  397. package/src/domains/providers/support.ts +1 -0
  398. package/src/domains/providers/target-model-cache.ts +124 -0
  399. package/src/domains/providers/types/capability-flags.ts +2 -0
  400. package/src/domains/providers/types/target-descriptor.ts +2 -0
  401. package/src/domains/resources/index.ts +3 -0
  402. package/src/domains/resources/prompts/loader.ts +95 -33
  403. package/src/domains/resources/skills/loader.ts +33 -0
  404. package/src/domains/safety/action-classifier.ts +6 -0
  405. package/src/domains/safety/call-target.ts +52 -0
  406. package/src/domains/safety/run-effects.ts +35 -4
  407. package/src/domains/session/context-accounting.ts +52 -1
  408. package/src/domains/session/context-ledger.ts +37 -13
  409. package/src/domains/session/index.ts +6 -0
  410. package/src/domains/session/prompt-cache.ts +140 -0
  411. package/src/domains/session/prompt-manifest.ts +42 -0
  412. package/src/domains/toolchain/archive.ts +175 -0
  413. package/src/domains/toolchain/contract.ts +28 -0
  414. package/src/domains/toolchain/extension.ts +47 -0
  415. package/src/domains/toolchain/index.ts +39 -0
  416. package/src/domains/toolchain/install.ts +327 -0
  417. package/src/domains/toolchain/manifest.ts +8 -0
  418. package/src/domains/toolchain/paths.ts +34 -0
  419. package/src/domains/toolchain/registry.ts +265 -0
  420. package/src/domains/toolchain/remove.ts +218 -0
  421. package/src/domains/toolchain/resolve.ts +182 -0
  422. package/src/domains/toolchain/types.ts +113 -0
  423. package/src/domains/toolchain/version.ts +88 -0
  424. package/src/engine/acp/adapter.ts +18 -3
  425. package/src/engine/acp/server.ts +413 -70
  426. package/src/engine/acp/types.ts +19 -1
  427. package/src/engine/ai.ts +35 -0
  428. package/src/engine/apis/llamacpp-residency.ts +55 -3
  429. package/src/engine/apis/lmstudio.ts +25 -5
  430. package/src/engine/apis/ollama-native.ts +2 -1
  431. package/src/engine/apis/openai-completions.ts +80 -17
  432. package/src/engine/apis/residency-lock.ts +3 -1
  433. package/src/engine/apis/residency.ts +34 -1
  434. package/src/engine/claude/sdk-module.ts +98 -0
  435. package/src/engine/claude/sdk-runtime.ts +19 -11
  436. package/src/engine/provider-payload.ts +29 -1
  437. package/src/engine/tui-primitives.ts +21 -0
  438. package/src/engine/tui.ts +1 -0
  439. package/src/engine/worker-runtime.ts +2 -13
  440. package/src/entry/boot-options.ts +2 -0
  441. package/src/entry/orchestrator.ts +279 -35
  442. package/src/entry/panes-activation.ts +31 -0
  443. package/src/entry/with-panes.ts +20 -0
  444. package/src/interactive/chat-loop-messages.ts +26 -7
  445. package/src/interactive/chat-loop.ts +318 -41
  446. package/src/interactive/chat-panel.ts +62 -8
  447. package/src/interactive/clio-editor.ts +45 -8
  448. package/src/interactive/context-activity.ts +5 -1
  449. package/src/interactive/context-meter.ts +1 -1
  450. package/src/interactive/context-overlay.ts +41 -10
  451. package/src/interactive/cost-overlay.ts +66 -6
  452. package/src/interactive/council-grid.ts +1 -3
  453. package/src/interactive/council.ts +11 -0
  454. package/src/interactive/dispatch-board.ts +102 -20
  455. package/src/interactive/fleet-run-preview.ts +41 -15
  456. package/src/interactive/handoff-round.ts +41 -2
  457. package/src/interactive/interactive-application.ts +177 -7
  458. package/src/interactive/interactive-input-runtime.ts +15 -0
  459. package/src/interactive/interactive-presentation.ts +4 -0
  460. package/src/interactive/interactive-shell.ts +20 -17
  461. package/src/interactive/interactive-slash-runtime.ts +63 -10
  462. package/src/interactive/memory-overlay.ts +9 -0
  463. package/src/interactive/modal-marker.ts +170 -0
  464. package/src/interactive/mutation-preview.ts +295 -0
  465. package/src/interactive/mux-bridge.ts +214 -0
  466. package/src/interactive/overlay-frame.ts +58 -2
  467. package/src/interactive/overlay-general-openers.ts +17 -0
  468. package/src/interactive/overlay-key-routing.ts +52 -3
  469. package/src/interactive/overlay-lifecycle.ts +56 -7
  470. package/src/interactive/overlay-model-selectors.ts +40 -3
  471. package/src/interactive/overlay-permission-lifecycle.ts +112 -24
  472. package/src/interactive/overlay-session-lifecycle.ts +73 -9
  473. package/src/interactive/overlay-transitions.ts +18 -4
  474. package/src/interactive/overlays/agents.ts +1 -0
  475. package/src/interactive/overlays/ask-user.ts +227 -49
  476. package/src/interactive/overlays/auth-dialog.ts +1 -0
  477. package/src/interactive/overlays/context-reset.ts +1 -0
  478. package/src/interactive/overlays/cwd-fallback.ts +1 -0
  479. package/src/interactive/overlays/decisions.ts +11 -11
  480. package/src/interactive/overlays/extensions.ts +1 -0
  481. package/src/interactive/overlays/fleet-run-approval.ts +1 -0
  482. package/src/interactive/overlays/handoff-review.ts +1 -0
  483. package/src/interactive/overlays/help-reference.ts +6 -0
  484. package/src/interactive/overlays/interop.ts +1 -0
  485. package/src/interactive/overlays/library-install-confirm.ts +1 -0
  486. package/src/interactive/overlays/library-tabs.ts +28 -0
  487. package/src/interactive/overlays/list-overlay.ts +10 -1
  488. package/src/interactive/overlays/message-picker.ts +1 -0
  489. package/src/interactive/overlays/model-scope.ts +86 -0
  490. package/src/interactive/overlays/model-selector.ts +1 -0
  491. package/src/interactive/overlays/prompts.ts +12 -1
  492. package/src/interactive/overlays/session-selector.ts +1 -0
  493. package/src/interactive/overlays/settings-sections.ts +30 -0
  494. package/src/interactive/overlays/settings.ts +614 -45
  495. package/src/interactive/overlays/side-question.ts +1 -0
  496. package/src/interactive/overlays/skills-hub.ts +3 -11
  497. package/src/interactive/overlays/tree-selector.ts +1 -0
  498. package/src/interactive/pane-policy.ts +46 -0
  499. package/src/interactive/panes-runtime.ts +292 -0
  500. package/src/interactive/permission-hint.ts +34 -2
  501. package/src/interactive/permission-overlay.ts +159 -9
  502. package/src/interactive/prewarm.ts +197 -0
  503. package/src/interactive/render-trace.ts +162 -15
  504. package/src/interactive/renderers/compaction-summary.ts +29 -0
  505. package/src/interactive/renderers/tool-execution.ts +4 -0
  506. package/src/interactive/renderers/worker-entry.ts +122 -14
  507. package/src/interactive/side-question.ts +58 -1
  508. package/src/interactive/slash-commands.ts +251 -15
  509. package/src/interactive/status/controller.ts +11 -0
  510. package/src/interactive/status/state-machine.ts +54 -2
  511. package/src/interactive/status/types.ts +7 -0
  512. package/src/interactive/tasks-overlay.ts +1 -0
  513. package/src/interactive/terminal-lease.ts +2 -0
  514. package/src/interactive/theme/tokens.ts +3 -14
  515. package/src/interactive/turn-context.ts +346 -33
  516. package/src/interactive/turn-persistence.ts +14 -4
  517. package/src/interactive/turn-prewarm.ts +364 -0
  518. package/src/interactive/turn-queues.ts +7 -4
  519. package/src/interactive/turn-runtime.ts +8 -1
  520. package/src/interactive/turn-state.ts +23 -0
  521. package/src/interactive/view/artifacts.ts +109 -1
  522. package/src/interactive/view/view-overlay.ts +29 -3
  523. package/src/interactive/watch-pane.ts +152 -0
  524. package/src/interactive/worker-progress.ts +7 -1
  525. package/src/interactive/worker-receipts.ts +19 -1
  526. package/src/interactive/worker-stream.ts +5 -0
  527. package/src/interactive/yazi-bridge.ts +444 -0
  528. package/src/tools/ask-user.ts +43 -2
  529. package/src/tools/bootstrap.ts +26 -2
  530. package/src/tools/builtin-tool-catalog.ts +15 -0
  531. package/src/tools/compete-worktrees.ts +83 -2
  532. package/src/tools/core-bootstrap.ts +2 -1
  533. package/src/tools/dispatch-admission.ts +14 -3
  534. package/src/tools/dispatch-arguments.ts +20 -20
  535. package/src/tools/dispatch-plan.ts +17 -9
  536. package/src/tools/dispatch-run-events.ts +134 -19
  537. package/src/tools/dispatch-runner.ts +29 -7
  538. package/src/tools/dispatch-scout.ts +1 -1
  539. package/src/tools/dispatch-types.ts +15 -3
  540. package/src/tools/dispatch.ts +1 -1
  541. package/src/tools/executables.ts +17 -14
  542. package/src/tools/observation.ts +54 -4
  543. package/src/tools/panes-surface.ts +38 -0
  544. package/src/tools/panes.ts +112 -0
  545. package/src/tools/policy.ts +10 -1
  546. package/src/tools/presentation.ts +1 -0
  547. package/src/tools/registry.ts +16 -0
  548. package/dist/chunk-AOCYTWAV.js +0 -449
  549. package/dist/chunk-HLE42MG7.js +0 -37
  550. package/dist/chunk-HWUFFB6L.js +0 -83
  551. package/dist/chunk-JOZYP4GM.js +0 -279
  552. package/dist/doctor-M7YEDGAE.js +0 -91
package/src/cli/fleet.ts CHANGED
@@ -7,6 +7,9 @@
7
7
  * clio-coder fleet commands init draft a repository command registry
8
8
  * clio-coder fleet run <name> --var k=v ... preflight + execute a fleet contract
9
9
  * clio-coder fleet status [--json] runtime snapshot from the durable ledger
10
+ * clio-coder fleet inspect --json bounded recent run and journal projection
11
+ * clio-coder fleet decisions --json bounded sealed review and compete gate verdicts
12
+ * clio-coder fleet view <runId|fleetRootId> one run's transcript, or a root's step index
10
13
  * clio-coder fleet drain|resume [--json] close or reopen durable dispatch admission
11
14
  *
12
15
  * Fleet contracts are repo-owned policy (.clio-coder/fleets/<name>.md). Preflight
@@ -47,27 +50,39 @@ import {
47
50
  type RunToolBudgetEnvelope,
48
51
  } from "../domains/dispatch/budget-envelope.js";
49
52
  import { type CapacityDrain, capacityDrain, setCapacityDraining } from "../domains/dispatch/capacity-lease.js";
50
- import type { DispatchContract } from "../domains/dispatch/contract.js";
51
- import type { ExecutionPlan } from "../domains/dispatch/execution-plan.js";
53
+ import type { DispatchContract, DispatchRequest } from "../domains/dispatch/contract.js";
54
+ import { bindExecutionPlanEndpoints, type ExecutionPlan } from "../domains/dispatch/execution-plan.js";
52
55
  import { agentRoleFactsResolver, requestExecutionRole, withAttemptRole } from "../domains/dispatch/execution-role.js";
53
56
  import { compileFleetExecutionPlan } from "../domains/dispatch/fleet-plan.js";
54
57
  import {
55
- DispatchDomainModule,
58
+ createDispatchDomainModule,
56
59
  type ExecuteFleetRunInput,
57
60
  executeFleetRun,
58
61
  type FleetRunOutcome,
59
62
  planFleetResume,
60
63
  readFleetRun,
61
64
  } from "../domains/dispatch/index.js";
65
+ import { configureRunEventJournal } from "../domains/dispatch/run-event-journal.js";
62
66
  import { openLedger } from "../domains/dispatch/state.js";
63
67
  import type { RunEnvelope, RunReceipt } from "../domains/dispatch/types.js";
64
68
  import { WRITE_BOUNDARY_VIOLATION_REASON } from "../domains/dispatch/write-boundary.js";
65
69
  import { preflightWriteBoundaries } from "../domains/dispatch/write-boundary-enforcer.js";
66
70
  import { ensureClioState, LifecycleDomainModule } from "../domains/lifecycle/index.js";
67
71
  import { MiddlewareDomainModule } from "../domains/middleware/index.js";
68
- import { ObservabilityDomainModule } from "../domains/observability/index.js";
72
+ import {
73
+ aggregateCostAmounts,
74
+ type CostAggregate,
75
+ ObservabilityDomainModule,
76
+ renderCostAggregate,
77
+ renderCostAmount,
78
+ } from "../domains/observability/index.js";
69
79
  import { createPromptsDomainModule } from "../domains/prompts/index.js";
70
- import { ProvidersDomainModule } from "../domains/providers/index.js";
80
+ import {
81
+ type CostProvenance,
82
+ foregroundStreamUsage,
83
+ normalizeCostProvenance,
84
+ ProvidersDomainModule,
85
+ } from "../domains/providers/index.js";
71
86
  import { ResourcesDomainModule } from "../domains/resources/index.js";
72
87
  import type { SafetyContract } from "../domains/safety/contract.js";
73
88
  import { SafetyDomainModule } from "../domains/safety/index.js";
@@ -89,6 +104,10 @@ Subcommands:
89
104
  [--resume <runId>] replay a completed prefix from a prior run of the same plan
90
105
  [--json] emit step receipts as JSON
91
106
  status [--json] show running, retrying, and total dispatch state
107
+ inspect --json emit a bounded recent-run and event-journal projection
108
+ decisions --json emit a bounded window of sealed review and compete gate verdicts
109
+ view <runId> [--follow] read one run's ledger entry, event journal, and receipt
110
+ view <fleetRootId> list a fleet run's steps and the run id to view for each
92
111
  drain [--json] deny new execution starts for up to one hour
93
112
  resume [--json] reopen dispatch admission immediately
94
113
 
@@ -96,6 +115,10 @@ Notes:
96
115
  status reads the durable run ledger. Rows started by another process show
97
116
  heartbeat liveness from the recorded worker pid; per-token live meters are
98
117
  only available inside the process that owns the run.
118
+ view is read-only and shares no memory with the orchestrator, so it follows a
119
+ run from a second terminal or over SSH. Its transcript comes from the run
120
+ event journal, written when panes.journal is on (the default). Handed the
121
+ fleet-<hex> root id that run prints, it lists that run's steps instead.
99
122
  drain preserves running work. Repeat it to renew the one-hour expiry; resume
100
123
  clears it early. The expiry prevents an abandoned drain from wedging Clio.
101
124
  `;
@@ -127,7 +150,9 @@ function parseVars(args: ReadonlyArray<string>): { vars: Record<string, string>;
127
150
  const eq = pair.indexOf("=");
128
151
  const key = pair.slice(0, eq).trim();
129
152
  const value = pair.slice(eq + 1);
130
- if (key.length === 0) return { vars, rest, error: "--var requires a non-empty key" };
153
+ if (key.length === 0) {
154
+ return { vars, rest, error: "--var requires a non-empty key" };
155
+ }
131
156
  vars[key] = value;
132
157
  }
133
158
  return { vars, rest };
@@ -145,7 +170,9 @@ function renderStep(step: FleetContractStep): string {
145
170
  if (step.kind === "code") return `code:${step.command}[${step.scope}]`;
146
171
  if (step.kind === "agent") return `${step.agent}[${step.scope}]`;
147
172
  if (step.kind === "gate") return `gate:${step.path}[${step.run}]`;
148
- if (step.kind === "plan") return `plan:${step.agent}[${step.roster.join(",")}; max ${step.maxTasks}]`;
173
+ if (step.kind === "plan") {
174
+ return `plan:${step.agent}[${step.roster.join(",")}; max ${step.maxTasks}]`;
175
+ }
149
176
  const check =
150
177
  step.check.kind === "code"
151
178
  ? `code:${step.check.command}`
@@ -212,16 +239,28 @@ function contractAgents(
212
239
  ): Array<{ id: string; agent: string; scope: "readonly" | "workspace" }> {
213
240
  const agents: Array<{ id: string; agent: string; scope: "readonly" | "workspace" }> = [];
214
241
  for (const step of contract.steps) {
215
- if (step.kind === "agent") agents.push({ id: step.id, agent: step.agent, scope: step.scope });
216
- else if (step.kind === "gate") agents.push({ id: step.id, agent: step.agent, scope: "workspace" });
217
- else if (step.kind === "plan") {
242
+ if (step.kind === "agent") {
243
+ agents.push({ id: step.id, agent: step.agent, scope: step.scope });
244
+ } else if (step.kind === "gate") {
245
+ agents.push({ id: step.id, agent: step.agent, scope: "workspace" });
246
+ } else if (step.kind === "plan") {
218
247
  agents.push({ id: step.id, agent: step.agent, scope: step.scope });
219
- for (const agent of step.roster) agents.push({ id: `${step.id}.roster`, agent, scope: "readonly" });
248
+ for (const agent of step.roster) {
249
+ agents.push({ id: `${step.id}.roster`, agent, scope: "readonly" });
250
+ }
220
251
  } else if (step.kind === "loop") {
221
252
  if (step.check.kind === "agent") {
222
- agents.push({ id: `${step.id}.check`, agent: step.check.agent, scope: step.check.scope });
253
+ agents.push({
254
+ id: `${step.id}.check`,
255
+ agent: step.check.agent,
256
+ scope: step.check.scope,
257
+ });
223
258
  }
224
- agents.push({ id: `${step.id}.repair`, agent: step.repair.agent, scope: step.repair.scope });
259
+ agents.push({
260
+ id: `${step.id}.repair`,
261
+ agent: step.repair.agent,
262
+ scope: step.repair.scope,
263
+ });
225
264
  }
226
265
  }
227
266
  return agents;
@@ -231,10 +270,12 @@ function preflightFleet(contract: FleetContract, deps: FleetPreflightDeps): stri
231
270
  const targets = new Set(deps.settings.targets.map((target) => target.id));
232
271
  const profiles = new Set(Object.keys(deps.settings.workers?.profiles ?? {}));
233
272
  const checkRoute = (id: string, route: { target?: string; profile?: string }): string | null => {
234
- if (route.target !== undefined && !targets.has(route.target))
273
+ if (route.target !== undefined && !targets.has(route.target)) {
235
274
  return `unknown target '${route.target}' at step '${id}'`;
236
- if (route.profile !== undefined && !profiles.has(route.profile))
275
+ }
276
+ if (route.profile !== undefined && !profiles.has(route.profile)) {
237
277
  return `unknown profile '${route.profile}' at step '${id}'`;
278
+ }
238
279
  return null;
239
280
  };
240
281
  for (const step of contract.steps) {
@@ -280,10 +321,13 @@ async function runFleet(args: ReadonlyArray<string>): Promise<number> {
280
321
  const json = rest.includes("--json");
281
322
  const resumeIndex = rest.indexOf("--resume");
282
323
  const resumeId = resumeIndex === -1 ? undefined : rest[resumeIndex + 1];
283
- if (resumeIndex !== -1 && (resumeId === undefined || resumeId.startsWith("-")))
324
+ if (resumeIndex !== -1 && (resumeId === undefined || resumeId.startsWith("-"))) {
284
325
  return fail("--resume requires a run id");
326
+ }
285
327
  const name = rest.find((arg) => !arg.startsWith("-"));
286
- if (!name) return fail("usage: clio-coder fleet run <name> [--var key=value ...] [--resume <runId>] [--json]");
328
+ if (!name) {
329
+ return fail("usage: clio-coder fleet run <name> [--var key=value ...] [--resume <runId>] [--json]");
330
+ }
287
331
 
288
332
  let contract: FleetContract;
289
333
  let prompt: string;
@@ -312,7 +356,10 @@ async function runFleet(args: ReadonlyArray<string>): Promise<number> {
312
356
  MiddlewareDomainModule,
313
357
  ObservabilityDomainModule,
314
358
  SchedulingDomainModule,
315
- DispatchDomainModule,
359
+ // A fleet step is dispatched by executeFleetRun, which drains the handle
360
+ // itself and never builds a dispatch event registry, so the domain is the
361
+ // only thing that can write each step's durable transcript.
362
+ createDispatchDomainModule({ journalRunEvents: true }),
316
363
  SessionDomainModule,
317
364
  LifecycleDomainModule,
318
365
  ]);
@@ -325,12 +372,17 @@ async function runFleet(args: ReadonlyArray<string>): Promise<number> {
325
372
  await loaded.stop();
326
373
  return fail("required domains unavailable (dispatch/agents/safety)");
327
374
  }
375
+ const fleetSettings = config?.get() ?? readSettings();
376
+ // Install `panes.journal` the same way the interactive composition root
377
+ // does, so a fleet run honours the setting without the journal ever reading
378
+ // settings.yaml from the dispatch event path.
379
+ configureRunEventJournal(fleetSettings.panes.journal);
328
380
  const roleFacts = agentRoleFactsResolver((id) => agents.getSpec(id));
329
381
  const preflightError = preflightFleet(contract, {
330
382
  agents,
331
383
  safety,
332
384
  scheduling,
333
- settings: config?.get() ?? readSettings(),
385
+ settings: fleetSettings,
334
386
  });
335
387
  if (preflightError !== null) {
336
388
  await loaded.stop();
@@ -372,6 +424,35 @@ async function runFleet(args: ReadonlyArray<string>): Promise<number> {
372
424
  await loaded.stop();
373
425
  return fail(err instanceof Error ? err.message : String(err));
374
426
  }
427
+ if (dispatch.preview !== undefined) {
428
+ try {
429
+ const foreground = foregroundStreamUsage();
430
+ const bindings: Record<string, { key: string; limit: number; foregroundHeld?: number } | undefined> = {};
431
+ for (const step of plan.steps) {
432
+ if (step.kind === "code") continue;
433
+ const request: DispatchRequest = {
434
+ agentId: step.agentId,
435
+ executionRole: step.executionRole,
436
+ task: step.task,
437
+ ...(step.scope === "readonly" ? { autonomy: "read-only" as const } : {}),
438
+ ...(step.target !== undefined ? { target: step.target } : {}),
439
+ ...(step.profile !== undefined ? { workerProfile: step.profile } : {}),
440
+ };
441
+ const endpoint = dispatch.preview(request).endpoint;
442
+ if (endpoint === undefined) continue;
443
+ const foregroundHeld = foreground[endpoint.key] ?? 0;
444
+ bindings[step.id] = {
445
+ key: endpoint.key,
446
+ limit: endpoint.limit,
447
+ ...(foregroundHeld > 0 ? { foregroundHeld } : {}),
448
+ };
449
+ }
450
+ plan = bindExecutionPlanEndpoints(plan, bindings);
451
+ } catch (err) {
452
+ await loaded.stop();
453
+ return fail(`route preflight failed: ${err instanceof Error ? err.message : String(err)}`);
454
+ }
455
+ }
375
456
  try {
376
457
  preflightWriteBoundaries(plan, process.cwd());
377
458
  } catch (err) {
@@ -428,30 +509,43 @@ async function runFleet(args: ReadonlyArray<string>): Promise<number> {
428
509
  ...(resume !== undefined ? { resume } : {}),
429
510
  onStepSettled(step) {
430
511
  if (step.replayed === true && step.result !== undefined) {
431
- if (json)
512
+ if (json) {
432
513
  process.stdout.write(
433
- `${JSON.stringify({ stepId: step.stepId, status: "replayed", receipt: { runId: step.result.terminalRunId, digest: step.result.receiptDigest } })}\n`,
514
+ `${JSON.stringify({
515
+ stepId: step.stepId,
516
+ status: "replayed",
517
+ receipt: {
518
+ runId: step.result.terminalRunId,
519
+ digest: step.result.receiptDigest,
520
+ },
521
+ })}\n`,
434
522
  );
435
- else
523
+ } else {
436
524
  process.stdout.write(
437
525
  `step ${step.stepId}: replayed terminal-run=${step.result.terminalRunId} receipt=${step.result.receiptDigest}\n`,
438
526
  );
527
+ }
439
528
  return;
440
529
  }
441
530
  if (step.receipt !== undefined) {
442
531
  if (json) process.stdout.write(`${JSON.stringify(step.receipt)}\n`);
443
- else
532
+ else {
444
533
  process.stdout.write(
445
- `step ${step.stepId} ${step.agentId}: ${step.succeeded ? "succeeded" : "failed"}${step.failureReason !== undefined ? ` reason=${step.failureReason}` : ""} assignment=${step.assignmentId} terminal-run=${step.terminalRunId} cost=$${step.costUsd.toFixed(4)}\n`,
534
+ `step ${step.stepId} ${step.agentId}: ${step.succeeded ? "succeeded" : "failed"}${step.failureReason !== undefined ? ` reason=${step.failureReason}` : ""} assignment=${step.assignmentId} terminal-run=${step.terminalRunId} cost=${renderCostAmount(step.costUsd, step.costProvenance)}\n`,
446
535
  );
536
+ }
447
537
  return;
448
538
  }
449
539
  if (step.codeStep !== undefined) {
450
- if (json) process.stdout.write(`${JSON.stringify({ codeStep: step.codeStep })}\n`);
451
- else
540
+ if (json) {
541
+ process.stdout.write(`${JSON.stringify({ codeStep: step.codeStep })}\n`);
542
+ } else {
452
543
  process.stdout.write(
453
- `step ${step.stepId} code:${step.commandId}: ${step.succeeded ? "passed" : "failed"} exit=${step.codeStep.exitCode} ${step.codeStep.durationMs}ms record=${step.recordPath}\n`,
544
+ `step ${step.stepId} code:${step.commandId}: ${
545
+ step.succeeded ? "passed" : "failed"
546
+ } exit=${step.codeStep.exitCode} ${step.codeStep.durationMs}ms record=${step.recordPath}\n`,
454
547
  );
548
+ }
455
549
  }
456
550
  },
457
551
  onNotice(text, kind) {
@@ -483,21 +577,31 @@ async function runFleet(args: ReadonlyArray<string>): Promise<number> {
483
577
  );
484
578
  } else {
485
579
  process.stdout.write(
486
- `fleet ${contract.name}: ${outcome.succeededStepCount}/${outcome.requiredStepCount} steps succeeded, ${outcome.resolvedLoopCount}/${outcome.result.loops.length} loops resolved, total cost $${outcome.totalCostUsd.toFixed(4)}\n`,
580
+ `fleet ${contract.name}: ${outcome.succeededStepCount}/${outcome.requiredStepCount} steps succeeded, ${outcome.resolvedLoopCount}/${outcome.result.loops.length} loops resolved, total cost ${renderCostAggregate(outcome.totalCost)}\n`,
487
581
  );
488
- for (const loop of outcome.result.loops)
582
+ for (const loop of outcome.result.loops) {
489
583
  process.stdout.write(
490
584
  ` loop ${loop.loopId}: ${loop.reason} after ${loop.attempts} verification(s) and ${loop.repairs} repair(s)\n`,
491
585
  );
492
- if (outcome.result.revalidated.length > 0)
586
+ }
587
+ if (outcome.result.revalidated.length > 0) {
493
588
  process.stdout.write(
494
- ` staleness: re-ran ${outcome.result.revalidated.join(", ")} because a workspace step landed after the last green\n`,
589
+ ` staleness: re-ran ${outcome.result.revalidated.join(
590
+ ", ",
591
+ )} because a workspace step landed after the last green\n`,
495
592
  );
496
- for (const message of outcome.result.needsDecision) process.stdout.write(` needs operator decision: ${message}\n`);
593
+ }
594
+ for (const message of outcome.result.needsDecision) {
595
+ process.stdout.write(` needs operator decision: ${message}\n`);
596
+ }
497
597
  for (const boundary of outcome.result.writeBoundaries) {
498
598
  if (!boundary.violated) continue;
499
599
  process.stdout.write(` write boundary ${boundary.window}: ${boundary.detail ?? WRITE_BOUNDARY_VIOLATION_REASON}\n`);
500
600
  }
601
+ // The root id printed at the top is the only identifier this command
602
+ // advertises, so say what it is good for rather than leaving an operator
603
+ // to guess that the viewer wants a per-step run id.
604
+ process.stdout.write(` clio-coder fleet view ${fleetRootId} step index with each step's run id\n`);
501
605
  }
502
606
  return outcome.cleanRun ? 0 : 1;
503
607
  }
@@ -530,7 +634,10 @@ function receiptTokenSplit(row: RunEnvelope): { input: number; output: number }
530
634
  const path = row.receiptPath ?? join(clioStateDir(), "receipts", `${row.id}.json`);
531
635
  try {
532
636
  const parsed = JSON.parse(readFileSync(path, "utf8")) as Partial<RunReceipt>;
533
- return { input: finiteCount(parsed.inputTokenCount), output: finiteCount(parsed.outputTokenCount) };
637
+ return {
638
+ input: finiteCount(parsed.inputTokenCount),
639
+ output: finiteCount(parsed.outputTokenCount),
640
+ };
534
641
  } catch {
535
642
  return null;
536
643
  }
@@ -543,7 +650,10 @@ function receiptTokenSplit(row: RunEnvelope): { input: number; output: number }
543
650
  */
544
651
  function rowTokenSplit(row: RunEnvelope): { input: number; output: number } {
545
652
  if (row.inputTokenCount !== undefined || row.outputTokenCount !== undefined) {
546
- return { input: finiteCount(row.inputTokenCount), output: finiteCount(row.outputTokenCount) };
653
+ return {
654
+ input: finiteCount(row.inputTokenCount),
655
+ output: finiteCount(row.outputTokenCount),
656
+ };
547
657
  }
548
658
  if (row.endedAt !== null) {
549
659
  return receiptTokenSplit(row) ?? { input: 0, output: 0 };
@@ -553,7 +663,12 @@ function rowTokenSplit(row: RunEnvelope): { input: number; output: number } {
553
663
 
554
664
  export type FleetAdmissionStatus =
555
665
  | { state: "open" }
556
- | { state: "draining"; requestedByPid: number; requestedAt: string; expiresAt: string };
666
+ | {
667
+ state: "draining";
668
+ requestedByPid: number;
669
+ requestedAt: string;
670
+ expiresAt: string;
671
+ };
557
672
 
558
673
  function admissionStatus(drain: CapacityDrain | null): FleetAdmissionStatus {
559
674
  if (drain === null) return { state: "open" };
@@ -565,7 +680,16 @@ export function statusSnapshot(): {
565
680
  admission: FleetAdmissionStatus;
566
681
  running: Array<Record<string, unknown>>;
567
682
  retrying: Array<Record<string, unknown>>;
568
- totals: { inputTokens: number; outputTokens: number; totalTokens: number; costUsd: number; runtimeSeconds: number };
683
+ totals: {
684
+ inputTokens: number;
685
+ outputTokens: number;
686
+ totalTokens: number;
687
+ /** The bare sum, kept for JSON readers that already parse it. Render `cost`. */
688
+ costUsd: number;
689
+ /** Mirrors what `DispatchSnapshot.totals.cost` declares for the in-process surface. */
690
+ cost: CostAggregate;
691
+ runtimeSeconds: number;
692
+ };
569
693
  } {
570
694
  const ledger = openLedger();
571
695
  const nowMs = Date.now();
@@ -586,10 +710,18 @@ export function statusSnapshot(): {
586
710
  elapsedMs: Number.isFinite(startedMs) ? Math.max(0, nowMs - startedMs) : 0,
587
711
  tokens: { input: 0, output: 0, total: row.tokenCount },
588
712
  costUsd: row.costUsd,
713
+ // Absent on pre-provenance ledger rows, which readers must treat as
714
+ // unknown; `renderCostAmount` normalizes it rather than assuming free.
715
+ costProvenance: row.costProvenance,
589
716
  node: row.node?.id ?? "local",
590
717
  };
591
718
  });
592
719
  const totals = { inputTokens: 0, outputTokens: 0, totalTokens: 0, costUsd: 0, runtimeSeconds: 0 };
720
+ // Folded rather than summed: a ledger of runs nobody priced totals to an
721
+ // absent cost claim, not to zero dollars.
722
+ const cost = aggregateCostAmounts(
723
+ rows.map((row) => ({ usd: row.costUsd, provenance: normalizeCostProvenance(row.costProvenance) })),
724
+ );
593
725
  for (const row of rows) {
594
726
  const split = rowTokenSplit(row);
595
727
  totals.inputTokens += split.input;
@@ -609,7 +741,7 @@ export function statusSnapshot(): {
609
741
  admission: admissionStatus(capacityDrain(nowMs)),
610
742
  running,
611
743
  retrying: [],
612
- totals,
744
+ totals: { ...totals, cost },
613
745
  };
614
746
  }
615
747
 
@@ -634,7 +766,7 @@ function runStatus(args: ReadonlyArray<string>): number {
634
766
  for (const row of snapshot.running) {
635
767
  const lineage = row.lineage as { attempt: number; depth: number };
636
768
  process.stdout.write(
637
- ` ${row.runId} ${row.agentId} node=${row.node} ${row.heartbeat} attempt=${lineage.attempt} depth=${lineage.depth} ${Math.round((row.elapsedMs as number) / 1000)}s $${(row.costUsd as number).toFixed(4)}\n`,
769
+ ` ${row.runId} ${row.agentId} node=${row.node} ${row.heartbeat} attempt=${lineage.attempt} depth=${lineage.depth} ${Math.round((row.elapsedMs as number) / 1000)}s ${renderCostAmount(row.costUsd as number, row.costProvenance as CostProvenance | undefined)}\n`,
638
770
  );
639
771
  const budget = row.budget as RunToolBudgetEnvelope | null;
640
772
  if (budget !== null) {
@@ -655,7 +787,7 @@ function runStatus(args: ReadonlyArray<string>): number {
655
787
  }
656
788
  const t = snapshot.totals;
657
789
  process.stdout.write(
658
- `totals: tokens=${t.totalTokens} (in=${t.inputTokens} out=${t.outputTokens}) cost=$${t.costUsd.toFixed(4)} runtime=${Math.round(t.runtimeSeconds)}s\n`,
790
+ `totals: tokens=${t.totalTokens} (in=${t.inputTokens} out=${t.outputTokens}) cost=${renderCostAggregate(t.cost)} runtime=${Math.round(t.runtimeSeconds)}s\n`,
659
791
  );
660
792
  return 0;
661
793
  }
@@ -709,6 +841,14 @@ export async function runFleetCommand(args: ReadonlyArray<string>): Promise<numb
709
841
  return runFleet(args.slice(1));
710
842
  case "status":
711
843
  return runStatus(args.slice(1));
844
+ case "inspect":
845
+ return (await import("./fleet-inspect.js")).runFleetInspect(args.slice(1));
846
+ case "decisions":
847
+ return (await import("./fleet-decisions.js")).runFleetDecisions(args.slice(1));
848
+ case "verify":
849
+ return (await import("./fleet-verify.js")).runFleetVerify(args.slice(1));
850
+ case "view":
851
+ return (await import("./fleet-view.js")).runFleetView(args.slice(1));
712
852
  case "drain":
713
853
  return runAdmissionControl("drain", args.slice(1));
714
854
  case "resume":
package/src/cli/index.ts CHANGED
@@ -30,10 +30,13 @@ science. CLIO stands for Context Layer for Input/Output, named for the Greek mus
30
30
  Usage:
31
31
  clio-coder start interactive repository chat
32
32
  clio-coder acp serve Clio as an ACP v1 agent over stdio
33
+ clio-coder --acp alias for clio-coder acp
33
34
  clio-coder run [flags] <task> run one headless main-agent turn
34
35
  clio-coder --version, -v print the Clio Coder version
35
36
  clio-coder --api-key <key> override the active target API key for this run
36
37
  clio-coder --no-context-files, -nc skip CLIO-CODER.md project-context injection
38
+ clio-coder --with-panes activate the panes extension (terminal panes for workers and tools)
39
+ clio-coder --no-panes keep panes off even when settings turn them on
37
40
  clio-coder configure interactive first-run/configuration wizard
38
41
  clio-coder targets list configured targets, health, auth, and capabilities
39
42
  clio-coder targets add add a target interactively or via flags
@@ -57,7 +60,7 @@ Usage:
57
60
  clio-coder uninstall remove all Clio Coder state; --remove-binary also unlinks the launcher
58
61
  clio-coder upgrade upgrade Clio Coder and run pending migrations
59
62
  clio-coder agents list discovered agent recipes
60
- clio-coder fleet new|validate|graph|commands|run|status|drain|resume fleet authoring, execution, status, and admission control
63
+ clio-coder fleet new|validate|graph|commands|run|status|view|verify|drain|resume fleet authoring, execution, status, verification, and admission control
61
64
  clio-coder evidence build, list, or inspect evidence artifacts
62
65
  clio-coder eval run, report, or compare local eval task files
63
66
  clio-coder memory list, propose, promote, approve, reject, or prune memory
@@ -66,7 +69,10 @@ Usage:
66
69
  clio-coder extensions install, list, enable, disable, or remove extension packages
67
70
  clio-coder skills list, inspect, validate, or install skills
68
71
  clio-coder library list, search, add, or sync agents, prompts, fleets, and skills from catalogs
69
- clio-coder verifiers discover, author, validate, edit, or dry-run project checks
72
+ clio-coder verifiers discover, inspect, author, validate, edit, or dry-run project checks
73
+ clio-coder tools list|status|install|remove <id> pinned external programs Clio can drive
74
+ clio-coder interop inspect --json detected external coding agents and how far each one is wired
75
+ clio-coder panes install install the pane multiplexer (alias for 'tools install herdr')
70
76
  clio-coder docs [topic] serve the HTML docs of a source checkout on 127.0.0.1 (--no-open to skip browser)
71
77
  clio-coder dev <command> harness instruments; run 'clio-coder dev' for the list
72
78
  clio-coder --help, -h this message
@@ -112,6 +118,7 @@ interface CliBootOptions {
112
118
  noContextFiles?: boolean;
113
119
  noSkills?: boolean;
114
120
  skillPaths?: string[];
121
+ panes?: "with" | "without";
115
122
  }
116
123
 
117
124
  type CommandHandler = (subArgs: string[], bootOptions: CliBootOptions) => Promise<number>;
@@ -143,6 +150,7 @@ async function main(argv: string[]): Promise<number> {
143
150
  noContextFiles,
144
151
  noSkills,
145
152
  skillPaths,
153
+ panes,
146
154
  rest,
147
155
  error: globalFlagError,
148
156
  } = extractGlobalFlags(argv, isCommandToken);
@@ -169,6 +177,7 @@ async function main(argv: string[]): Promise<number> {
169
177
  ...(noContextFiles ? { noContextFiles: true } : {}),
170
178
  ...(noSkills ? { noSkills: true } : {}),
171
179
  ...(skillPaths.length > 0 ? { skillPaths } : {}),
180
+ ...(panes === undefined ? {} : { panes }),
172
181
  };
173
182
  if (!subcommand) {
174
183
  await enableBootCompileCache();
@@ -261,6 +270,9 @@ const COMMAND_HANDLERS = new Map<string, CommandHandler>([
261
270
  return (await import("./run.js")).runClioRun(subArgs, bootOptions);
262
271
  },
263
272
  ],
273
+ ["tools", async (subArgs) => (await import("./tools.js")).runToolsCommand(subArgs)],
274
+ ["interop", async (subArgs) => (await import("./interop.js")).runInteropCommand(subArgs)],
275
+ ["panes", async (subArgs) => (await import("./panes.js")).runPanesCommand(subArgs)],
264
276
  ["doctor", async (subArgs) => (await import("./doctor.js")).runDoctorCommand(subArgs)],
265
277
  ["paths", async (subArgs) => (await import("./paths.js")).runPathsCommand(subArgs)],
266
278
  ["reset", async (subArgs) => (await import("./reset.js")).runResetCommand(subArgs)],
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Fixed machine-readable projection of detected external coding agents.
3
+ *
4
+ * `configure --interop` is an interactive review that writes delegation peers
5
+ * into settings, so it is not a transport a GUI host can invoke. This command
6
+ * takes no identifier or flag beyond `--json`, decides nothing, and writes
7
+ * nothing.
8
+ *
9
+ * It also runs no foreign executable. Detection can probe `<bin> --version`,
10
+ * and this read deliberately does not: a GUI refresh must not become "execute
11
+ * every coding agent installed on this machine". The version still crosses,
12
+ * because a non-probing detection keeps the last version the harness observed
13
+ * for the same binary, so what the operator sees is a recorded fact rather than
14
+ * a fresh execution.
15
+ *
16
+ * Resolved binary paths and the agent's home directory are native filesystem
17
+ * facts and stay on the host. Whether a directory exists crosses; where it is
18
+ * does not.
19
+ */
20
+
21
+ import { readSettings } from "../core/config.js";
22
+ import {
23
+ detectInteropAgents,
24
+ INTEROP_AGENT_KINDS,
25
+ type InteropAgentId,
26
+ type InteropPresence,
27
+ interopAgentKind,
28
+ } from "../domains/interop/index.js";
29
+
30
+ export type InteropDecisionState = "accepted" | "declined";
31
+
32
+ export interface InteropInspectAgent {
33
+ readonly id: InteropAgentId;
34
+ readonly label: string;
35
+ readonly presence: InteropPresence;
36
+ /** The last version the harness observed for this binary, never probed here. */
37
+ readonly version: string | null;
38
+ /** Whether the agent owns a directory under the operator's home. The path stays host-side. */
39
+ readonly hasUserDirectory: boolean;
40
+ /** Whether this kind speaks ACP at all. */
41
+ readonly acp: boolean;
42
+ /** Whether the ACP adapter can start without a network install; null for a kind with no recipe. */
43
+ readonly adapter: InteropPresence | null;
44
+ /** Whether a `delegation.agents` entry already names this agent. */
45
+ readonly configured: boolean;
46
+ /** The operator's standing answer, or null when they have not been asked. */
47
+ readonly decision: InteropDecisionState | null;
48
+ readonly decidedAt: string | null;
49
+ /**
50
+ * True when the facts moved since the decision was taken.
51
+ *
52
+ * A standing answer suppresses re-proposal only while the facts it was made
53
+ * against still hold, so this is what says Clio Coder will ask again.
54
+ */
55
+ readonly decisionStale: boolean;
56
+ /** True when Clio Coder would offer to wire this agent on the next review. */
57
+ readonly proposed: boolean;
58
+ /** True when wiring it would fetch the adapter from the network on first use. */
59
+ readonly needsNetworkInstall: boolean;
60
+ }
61
+
62
+ export interface InteropInspectSnapshot {
63
+ readonly version: 1;
64
+ readonly generatedAt: string;
65
+ readonly detectedAt: string;
66
+ /**
67
+ * How many agent kinds the registry knows, so an empty list reads as "none
68
+ * detected" rather than "nothing to detect". Detection drops a kind with no
69
+ * binary, no directory, and no artifacts, so the list is never padded.
70
+ */
71
+ readonly knownKinds: number;
72
+ readonly agents: readonly InteropInspectAgent[];
73
+ }
74
+
75
+ /**
76
+ * Skill and artifact counts are deliberately absent.
77
+ *
78
+ * Detection populates them only from sources the resources and context domains
79
+ * have already loaded, and this command loads neither. Reporting the structural
80
+ * zero that would result would state a fact this read did not establish.
81
+ */
82
+ export async function interopInspectSnapshot(now: () => number = Date.now): Promise<InteropInspectSnapshot> {
83
+ const report = await detectInteropAgents({ cwd: process.cwd(), probeVersion: false });
84
+ const settings = readSettings();
85
+ const configured = new Set(settings.delegation.agents.map((agent) => agent.id));
86
+ const agents: InteropInspectAgent[] = [];
87
+ for (const record of report.agents) {
88
+ const kind = interopAgentKind(record.kind);
89
+ if (kind === undefined) continue;
90
+ const acp = kind.acp !== undefined;
91
+ const decision = record.decision === "accepted" || record.decision === "declined" ? record.decision : null;
92
+ const decisionStale = decision !== null && record.decidedFingerprint !== record.fingerprint;
93
+ const isConfigured = configured.has(kind.id);
94
+ agents.push({
95
+ id: kind.id,
96
+ label: kind.label,
97
+ presence: record.presence,
98
+ version: typeof record.version === "string" && record.version.length > 0 ? record.version : null,
99
+ hasUserDirectory: record.installDir !== undefined,
100
+ acp,
101
+ adapter: acp ? (record.adapter ?? "unknown") : null,
102
+ configured: isConfigured,
103
+ decision,
104
+ decidedAt: decision === null ? null : (record.decidedAt ?? null),
105
+ decisionStale,
106
+ // The same rule `interopProposals` applies, restated over the projected
107
+ // fields so the flag cannot drift from what the review would offer.
108
+ proposed: acp && record.presence === "present" && !isConfigured && (decision === null || decisionStale),
109
+ needsNetworkInstall: acp && record.adapter !== "present",
110
+ });
111
+ }
112
+ return {
113
+ version: 1,
114
+ generatedAt: new Date(now()).toISOString(),
115
+ detectedAt: report.detectedAt,
116
+ knownKinds: INTEROP_AGENT_KINDS.length,
117
+ agents,
118
+ };
119
+ }
120
+
121
+ export async function runInteropInspect(args: ReadonlyArray<string>): Promise<number> {
122
+ if (args.length !== 1 || args[0] !== "--json") {
123
+ process.stderr.write("clio-coder interop inspect: usage: clio-coder interop inspect --json\n");
124
+ return 2;
125
+ }
126
+ process.stdout.write(`${JSON.stringify(await interopInspectSnapshot(), null, 2)}\n`);
127
+ return 0;
128
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * `clio-coder interop`, the read half of external coding agent detection.
3
+ *
4
+ * Reviewing and wiring a detected agent as a delegation peer is an interactive
5
+ * mutation and stays on `configure --interop`. This command family carries the
6
+ * read only, and its one subcommand is the fixed projection a GUI host may run.
7
+ */
8
+
9
+ import { runInteropInspect } from "./interop-inspect.js";
10
+ import { printError } from "./shared.js";
11
+
12
+ const HELP = `clio-coder interop <subcommand>
13
+
14
+ Detected external coding agents and how far each one is wired.
15
+
16
+ Subcommands:
17
+ inspect --json emit the detected agent inventory with no native paths
18
+
19
+ Notes:
20
+ inspect writes nothing and runs no foreign executable. Wiring a detected agent
21
+ as a delegation peer is an explicit review: run \`clio-coder configure --interop\`.
22
+ `;
23
+
24
+ export async function runInteropCommand(args: ReadonlyArray<string>): Promise<number> {
25
+ const sub = args[0];
26
+ if (sub === undefined || sub === "--help" || sub === "-h") {
27
+ process.stdout.write(HELP);
28
+ return sub === undefined ? 2 : 0;
29
+ }
30
+ if (sub === "inspect") return await runInteropInspect(args.slice(1));
31
+ printError(`unknown interop command: ${sub}`);
32
+ process.stdout.write(HELP);
33
+ return 2;
34
+ }