@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
@@ -0,0 +1,436 @@
1
+ /**
2
+ * Fixed machine-readable projection of the eval reports this installation stored.
3
+ *
4
+ * Neither existing read works as a transport. `eval report <evalId>` and
5
+ * `eval compare <a> <b>` both require the operator to already name the reports
6
+ * they want, and nothing enumerated the store, so a GUI host had nowhere to
7
+ * start. This command accepts no identifier, no path, and no limit; it selects
8
+ * a bounded newest-first window itself and emits each report's identity,
9
+ * provenance, serving facts, accounting, and per-scenario outcome counts.
10
+ *
11
+ * An eval artifact is the largest single host-only payload in this harness, and
12
+ * the reason is worth stating rather than discovering. `results[].artifacts`
13
+ * holds whatever the runner attached, which for the `clio-run` runner is the
14
+ * entire session transcript: the operator's task text, every tool argument and
15
+ * result, the model's replies, provider endpoint URLs, error prose, and the
16
+ * prepared workspace path. There is no width at which a projection of that is
17
+ * safe, so it does not cross at any width and its per-report count crosses
18
+ * instead. That is the same class as a trace event's payload and a process
19
+ * command line, and it is why this read is a summary rather than a viewer.
20
+ *
21
+ * Held back for the same reason or the next one down: the eval entry path, the
22
+ * per-result metric map (open-keyed, and its string values include content
23
+ * hashes and a workspace's own structural digest), the compiled prompt hash,
24
+ * the suite hash, the terminal receipt digests, and the behavioral judge's
25
+ * facts and excerpts. What crosses instead is how many of each there are, and
26
+ * the closed vocabularies the harness mints itself.
27
+ */
28
+
29
+ import { clioDataDir } from "../core/xdg.js";
30
+ import { listEvalReports } from "../domains/eval/inventory.js";
31
+ import type { EvalArtifactResultV4, EvalArtifactV4 } from "../domains/eval/schema/artifact.js";
32
+ import { EVAL_EXECUTION_MATRIX_DIMENSIONS_V1 } from "../domains/eval/schema/execution-envelope.js";
33
+ import { evalServingConfigurationOf, sameEvalServingConfiguration } from "../domains/eval/schema/serving.js";
34
+ import { CANONICAL_METRIC_PREFIXES, CANONICAL_METRICS } from "../domains/eval/schema/suite.js";
35
+
36
+ /** Wire bound on the report window. */
37
+ export const EVAL_INVENTORY_MAX_REPORTS = 8;
38
+ /** Wire bound on each report's per-scenario roll-up. */
39
+ export const EVAL_INVENTORY_MAX_SCENARIOS = 16;
40
+
41
+ /**
42
+ * Every failure class the suite runner mints, and nothing else.
43
+ *
44
+ * The legacy v1 runner also has `timeout` and `cwd_missing`, and they are
45
+ * deliberately absent: routing accepts artifact v4 only, so this read can never
46
+ * emit them and carrying them would state a distinction it never establishes.
47
+ */
48
+ const FAILURE_CLASSES = [
49
+ "budget_exhausted",
50
+ "runner_failed",
51
+ "grader_failed",
52
+ "verifier_failed",
53
+ "forbidden_path",
54
+ "assertion_unresolved",
55
+ "assertion_failed",
56
+ "setup_failed",
57
+ "command_error",
58
+ ] as const;
59
+
60
+ /** A class outside the set is a real answer: the result still failed, and the operator still learns that. */
61
+ type EvalInventoryFailureClass = (typeof FAILURE_CLASSES)[number] | "other";
62
+
63
+ const REPORTED_FAILURE_CLASSES: readonly EvalInventoryFailureClass[] = [...FAILURE_CLASSES, "other"];
64
+
65
+ const BEHAVIOR_OUTCOMES = ["pass", "behavioral_failure", "unknown", "unmeasured", "infrastructure_failure"] as const;
66
+ type EvalInventoryBehaviorOutcome = (typeof BEHAVIOR_OUTCOMES)[number];
67
+
68
+ const IDENTIFIER_PATTERN = /^[A-Za-z0-9._-]{1,128}$/u;
69
+ const VERSION_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._+-]{0,63}$/u;
70
+ const COMMIT_PATTERN = /^[0-9a-f]{7,64}$/u;
71
+
72
+ export interface EvalInventoryTokens {
73
+ /** False when no run reported provider usage. The counts are then absent rather than zero. */
74
+ readonly measured: boolean;
75
+ readonly runs: number;
76
+ readonly measuredRuns: number;
77
+ readonly input: number | null;
78
+ readonly output: number | null;
79
+ readonly total: number | null;
80
+ readonly cacheRead: number | null;
81
+ readonly cacheWrite: number | null;
82
+ }
83
+
84
+ export interface EvalInventoryScenario {
85
+ readonly scenarioId: string;
86
+ readonly trials: number;
87
+ readonly passed: number;
88
+ readonly failed: number;
89
+ readonly unmeasured: number;
90
+ readonly machineryFailures: number;
91
+ readonly passAtK: number;
92
+ readonly passPowK: number;
93
+ }
94
+
95
+ export interface EvalInventoryReport {
96
+ readonly evalId: string;
97
+ readonly startedAt: string | null;
98
+ readonly suiteId: string;
99
+ /**
100
+ * A 1-based ordinal over `sameEvalServingConfiguration`, the rule `eval
101
+ * compare` itself uses to decide two runs are comparable.
102
+ *
103
+ * The fields that rule compares include the compiled prompt hash, which is a
104
+ * fingerprint and does not cross. The relation it establishes does: two
105
+ * reports sharing an ordinal are two `eval compare` will accept without
106
+ * `--allow-config-drift`, which is the fact an operator picking a baseline
107
+ * needs, and the ordinal reveals nothing about the values behind it.
108
+ */
109
+ readonly servingGroup: number;
110
+ readonly clioVersion: string | null;
111
+ readonly clioCommit: string | null;
112
+ readonly platform: string | null;
113
+ readonly node: string | null;
114
+ readonly matrix: {
115
+ readonly target: string | null;
116
+ readonly model: string | null;
117
+ readonly thinking: string | null;
118
+ readonly dimensions: readonly string[];
119
+ };
120
+ readonly serving: {
121
+ /** False when the artifact recorded none and the matrix it declared is standing in. */
122
+ readonly observed: boolean;
123
+ readonly targetId: string | null;
124
+ readonly runtimeId: string | null;
125
+ readonly modelId: string | null;
126
+ readonly serverBuild: string | null;
127
+ readonly thinkingLevel: string | null;
128
+ readonly totalSlots: number | null;
129
+ /** Whether a compiled prompt hash was recorded. The hash itself stays on the host. */
130
+ readonly compiledPromptPinned: boolean;
131
+ };
132
+ readonly summary: {
133
+ readonly runs: number;
134
+ readonly passed: number;
135
+ readonly failed: number;
136
+ readonly passRate: number;
137
+ readonly wallTimeMs: number;
138
+ readonly tokens: EvalInventoryTokens;
139
+ };
140
+ readonly results: {
141
+ readonly total: number;
142
+ readonly withAssignment: number;
143
+ readonly withTerminalReceipt: number;
144
+ readonly withVerdict: number;
145
+ readonly withBehavioral: number;
146
+ readonly withExecutionEnvelope: number;
147
+ readonly machineryFailures: number;
148
+ /** Runner attachments across the report. Their contents are host-only at any width. */
149
+ readonly attachments: number;
150
+ /** Metric readings whose name the suite schema declares, and readings whose name it does not. */
151
+ readonly canonicalMetrics: number;
152
+ readonly otherMetrics: number;
153
+ };
154
+ readonly failureClasses: readonly { readonly failureClass: EvalInventoryFailureClass; readonly count: number }[];
155
+ readonly behaviorOutcomes: readonly {
156
+ readonly outcome: EvalInventoryBehaviorOutcome;
157
+ readonly count: number;
158
+ }[];
159
+ /** Null when the artifact carried no scenario reductions at all, which is not the same as carrying none. */
160
+ readonly scenarios: readonly EvalInventoryScenario[] | null;
161
+ readonly scenariosTruncated: boolean;
162
+ /** Reductions refused because their own counts did not add up, counted rather than hidden. */
163
+ readonly scenariosDropped: number;
164
+ }
165
+
166
+ export interface EvalInventorySnapshot {
167
+ readonly version: 1;
168
+ readonly generatedAt: string;
169
+ readonly available: boolean;
170
+ readonly stored: number;
171
+ readonly unreadable: number;
172
+ readonly reports: readonly EvalInventoryReport[];
173
+ readonly truncated: boolean;
174
+ }
175
+
176
+ const CANONICAL_METRIC_NAMES: ReadonlySet<string> = new Set(CANONICAL_METRICS);
177
+
178
+ function isCanonicalMetric(name: string): boolean {
179
+ return CANONICAL_METRIC_NAMES.has(name) || CANONICAL_METRIC_PREFIXES.some((prefix) => name.startsWith(prefix));
180
+ }
181
+
182
+ function identifier(value: string | null): string | null {
183
+ return value !== null && IDENTIFIER_PATTERN.test(value) ? value : null;
184
+ }
185
+
186
+ function tally(value: unknown): number {
187
+ return typeof value === "number" && Number.isFinite(value) && value >= 0 ? Math.trunc(value) : 0;
188
+ }
189
+
190
+ function isRecord(value: unknown): value is Record<string, unknown> {
191
+ return typeof value === "object" && value !== null && !Array.isArray(value);
192
+ }
193
+
194
+ /**
195
+ * `parseEvalArtifactV4` casts the aggregates array through without checking its
196
+ * entries, so this is the first thing that looks at them. A scenario whose id
197
+ * or counts are not what the reducer produces is dropped rather than repaired:
198
+ * a scenario roll-up is a derived number, and a wrong one is worse than a
199
+ * missing one.
200
+ */
201
+ function projectScenarios(artifact: EvalArtifactV4): {
202
+ scenarios: EvalInventoryScenario[] | null;
203
+ truncated: boolean;
204
+ dropped: number;
205
+ } {
206
+ if (artifact.aggregates === undefined) return { scenarios: null, truncated: false, dropped: 0 };
207
+ const projected: EvalInventoryScenario[] = [];
208
+ let dropped = 0;
209
+ for (const entry of artifact.aggregates) {
210
+ if (!isRecord(entry)) {
211
+ dropped += 1;
212
+ continue;
213
+ }
214
+ const scenarioId = identifier(typeof entry.scenarioId === "string" ? entry.scenarioId : null);
215
+ if (scenarioId === null) {
216
+ dropped += 1;
217
+ continue;
218
+ }
219
+ const trials = tally(entry.trials);
220
+ const passed = tally(entry.passed);
221
+ const failed = tally(entry.failed);
222
+ const unmeasured = tally(entry.unmeasured);
223
+ const machineryFailures = tally(entry.machineryFailures);
224
+ // The reducer partitions one scenario's trials into exactly three outcomes
225
+ // and counts machinery failures inside them, so anything else did not come
226
+ // out of `aggregateEvalVerdicts`. It is counted rather than hidden, because
227
+ // a scenario list that looks whole while a reduction was refused would let
228
+ // the wire cross-check read as satisfied.
229
+ if (passed + failed + unmeasured !== trials || machineryFailures > failed) {
230
+ dropped += 1;
231
+ continue;
232
+ }
233
+ projected.push({
234
+ scenarioId,
235
+ trials,
236
+ passed,
237
+ failed,
238
+ unmeasured,
239
+ machineryFailures,
240
+ // Re-derived rather than read, because both are pure functions of the
241
+ // counts beside them and a stored disagreement is not a second opinion.
242
+ passAtK: trials > 0 && passed > 0 ? 1 : 0,
243
+ passPowK: trials > 0 && passed === trials ? 1 : 0,
244
+ });
245
+ }
246
+ const scenarios = projected.slice(0, EVAL_INVENTORY_MAX_SCENARIOS);
247
+ return { scenarios, truncated: scenarios.length < projected.length, dropped };
248
+ }
249
+
250
+ function projectTokens(artifact: EvalArtifactV4): EvalInventoryTokens {
251
+ const tokens = artifact.summary.tokens;
252
+ if (!tokens.measured) {
253
+ return {
254
+ measured: false,
255
+ runs: tally(tokens.runs),
256
+ measuredRuns: 0,
257
+ input: null,
258
+ output: null,
259
+ total: null,
260
+ cacheRead: null,
261
+ cacheWrite: null,
262
+ };
263
+ }
264
+ return {
265
+ measured: true,
266
+ runs: tally(tokens.runs),
267
+ measuredRuns: tally(tokens.measuredRuns),
268
+ input: tally(tokens.input),
269
+ output: tally(tokens.output),
270
+ total: tally(tokens.total),
271
+ cacheRead: tally(tokens.cacheRead),
272
+ cacheWrite: tally(tokens.cacheWrite),
273
+ };
274
+ }
275
+
276
+ function classifyFailure(failureClass: string | null): EvalInventoryFailureClass | null {
277
+ if (failureClass === null) return null;
278
+ return (FAILURE_CLASSES as readonly string[]).includes(failureClass)
279
+ ? (failureClass as EvalInventoryFailureClass)
280
+ : "other";
281
+ }
282
+
283
+ function countResults(results: readonly EvalArtifactResultV4[]): {
284
+ counts: EvalInventoryReport["results"];
285
+ failureClasses: EvalInventoryReport["failureClasses"];
286
+ behaviorOutcomes: EvalInventoryReport["behaviorOutcomes"];
287
+ } {
288
+ let withAssignment = 0;
289
+ let withTerminalReceipt = 0;
290
+ let withVerdict = 0;
291
+ let withBehavioral = 0;
292
+ let withExecutionEnvelope = 0;
293
+ let machineryFailures = 0;
294
+ let attachments = 0;
295
+ let canonicalMetrics = 0;
296
+ let otherMetrics = 0;
297
+ const failures = new Map<EvalInventoryFailureClass, number>();
298
+ const outcomes = new Map<EvalInventoryBehaviorOutcome, number>();
299
+ for (const result of results) {
300
+ if (result.assignmentId !== null) withAssignment += 1;
301
+ if (result.terminalReceiptDigest !== null) withTerminalReceipt += 1;
302
+ if (result.verdict !== undefined) withVerdict += 1;
303
+ if (result.verdict?.machinery === "infrastructure_failure") machineryFailures += 1;
304
+ if (result.behavioral !== undefined) withBehavioral += 1;
305
+ if (result.executionEnvelope !== undefined) withExecutionEnvelope += 1;
306
+ attachments += Object.keys(result.artifacts).length;
307
+ for (const name of Object.keys(result.metrics)) {
308
+ if (isCanonicalMetric(name)) canonicalMetrics += 1;
309
+ else otherMetrics += 1;
310
+ }
311
+ const failureClass = classifyFailure(result.failureClass);
312
+ if (failureClass !== null) failures.set(failureClass, (failures.get(failureClass) ?? 0) + 1);
313
+ const outcome = result.behavioral?.outcome;
314
+ if (outcome !== undefined && (BEHAVIOR_OUTCOMES as readonly string[]).includes(outcome)) {
315
+ outcomes.set(outcome, (outcomes.get(outcome) ?? 0) + 1);
316
+ }
317
+ }
318
+ return {
319
+ counts: {
320
+ total: results.length,
321
+ withAssignment,
322
+ withTerminalReceipt,
323
+ withVerdict,
324
+ withBehavioral,
325
+ withExecutionEnvelope,
326
+ machineryFailures,
327
+ attachments,
328
+ canonicalMetrics,
329
+ otherMetrics,
330
+ },
331
+ failureClasses: REPORTED_FAILURE_CLASSES.flatMap((failureClass) => {
332
+ const count = failures.get(failureClass) ?? 0;
333
+ return count === 0 ? [] : [{ failureClass, count }];
334
+ }),
335
+ behaviorOutcomes: BEHAVIOR_OUTCOMES.flatMap((outcome) => {
336
+ const count = outcomes.get(outcome) ?? 0;
337
+ return count === 0 ? [] : [{ outcome, count }];
338
+ }),
339
+ };
340
+ }
341
+
342
+ function projectReport(
343
+ evalId: string,
344
+ startedAt: string | null,
345
+ artifact: EvalArtifactV4,
346
+ servingGroup: number,
347
+ ): EvalInventoryReport {
348
+ const serving = evalServingConfigurationOf(artifact);
349
+ const { counts, failureClasses, behaviorOutcomes } = countResults(artifact.results);
350
+ const { scenarios, truncated, dropped } = projectScenarios(artifact);
351
+ const version = artifact.clio.version;
352
+ const commit = artifact.clio.commit;
353
+ return {
354
+ evalId,
355
+ startedAt,
356
+ suiteId: identifier(artifact.suite.id) ?? "unavailable",
357
+ servingGroup,
358
+ clioVersion: VERSION_PATTERN.test(version) ? version : null,
359
+ clioCommit: commit !== null && COMMIT_PATTERN.test(commit) ? commit : null,
360
+ platform: identifier(artifact.environment.platform),
361
+ node: identifier(artifact.environment.node),
362
+ matrix: {
363
+ target: identifier(artifact.matrix.target),
364
+ model: identifier(artifact.matrix.model),
365
+ thinking: identifier(artifact.matrix.thinking),
366
+ dimensions: (artifact.matrix.dimensions ?? []).filter((dimension) =>
367
+ (EVAL_EXECUTION_MATRIX_DIMENSIONS_V1 as readonly string[]).includes(dimension),
368
+ ),
369
+ },
370
+ serving: {
371
+ observed: artifact.servingConfiguration !== undefined,
372
+ targetId: identifier(serving.targetId),
373
+ runtimeId: identifier(serving.runtimeId),
374
+ modelId: identifier(serving.modelId),
375
+ serverBuild: identifier(serving.serverBuild),
376
+ thinkingLevel: identifier(serving.thinkingLevel),
377
+ totalSlots: serving.total_slots === null ? null : tally(serving.total_slots),
378
+ compiledPromptPinned: serving.compiledPromptHash !== null,
379
+ },
380
+ summary: {
381
+ runs: tally(artifact.summary.runs),
382
+ passed: tally(artifact.summary.passed),
383
+ failed: tally(artifact.summary.failed),
384
+ passRate: Number.isFinite(artifact.summary.passRate) ? Math.min(1, Math.max(0, artifact.summary.passRate)) : 0,
385
+ wallTimeMs: tally(artifact.summary.wallTimeMs),
386
+ tokens: projectTokens(artifact),
387
+ },
388
+ results: counts,
389
+ failureClasses,
390
+ behaviorOutcomes,
391
+ scenarios,
392
+ scenariosTruncated: truncated,
393
+ scenariosDropped: dropped,
394
+ };
395
+ }
396
+
397
+ export async function evalInventorySnapshot(
398
+ now: () => number = Date.now,
399
+ dataDir: string = clioDataDir(),
400
+ ): Promise<EvalInventorySnapshot> {
401
+ const listing = await listEvalReports(dataDir, EVAL_INVENTORY_MAX_REPORTS);
402
+ // One group per distinct serving configuration, numbered in the order the
403
+ // window meets them, so the newest report is always in group 1.
404
+ const groups: ReturnType<typeof evalServingConfigurationOf>[] = [];
405
+ const reports = listing.reports.map((stored) => {
406
+ const serving = evalServingConfigurationOf(stored.artifact);
407
+ let index = groups.findIndex((candidate) => sameEvalServingConfiguration(candidate, serving));
408
+ if (index === -1) index = groups.push(serving) - 1;
409
+ return projectReport(stored.evalId, stored.startedAt, stored.artifact, index + 1);
410
+ });
411
+ return {
412
+ version: 1,
413
+ generatedAt: new Date(now()).toISOString(),
414
+ available: listing.available,
415
+ stored: listing.stored,
416
+ unreadable: listing.unreadable,
417
+ reports,
418
+ truncated: listing.stored > listing.reports.length + listing.unreadable,
419
+ };
420
+ }
421
+
422
+ /**
423
+ * `clio-coder eval inventory --json`, and nothing else.
424
+ *
425
+ * Anything but the exact argv is a usage error, so a GUI host starts this
426
+ * process knowing it cannot be steered into reading a different store, a wider
427
+ * window, or one named report.
428
+ */
429
+ export async function runEvalInventory(args: ReadonlyArray<string>): Promise<number> {
430
+ if (args.length !== 1 || args[0] !== "--json") {
431
+ process.stderr.write("clio-coder eval inventory: usage: clio-coder eval inventory --json\n");
432
+ return 2;
433
+ }
434
+ process.stdout.write(`${JSON.stringify(await evalInventorySnapshot(), null, 2)}\n`);
435
+ return 0;
436
+ }
package/src/cli/eval.ts CHANGED
@@ -27,6 +27,13 @@ Commands:
27
27
  clio-coder eval report <evalId> --format text|json|md|swe-jsonl|junit
28
28
  clio-coder eval compare <baselineEvalId> <candidateEvalId> [--metric <name>] [--format text|json|md|junit] [--allow-config-drift]
29
29
  clio-coder eval gate <candidateEvalId> --baseline <baselineEvalId> [--thresholds <file>]
30
+ clio-coder eval inventory --json
31
+
32
+ inventory is the fixed machine-readable read a GUI host may run. Unlike report
33
+ and compare it names no eval id, so the process it starts cannot be steered to a
34
+ different report or a wider window. It carries each stored report's identity,
35
+ provenance, serving facts, accounting, and per-scenario outcomes, and none of
36
+ the runner attachments a report holds.
30
37
  `;
31
38
 
32
39
  type EvalCommand = "validate" | "run" | "report" | "compare" | "gate";
@@ -194,6 +201,12 @@ function parseEvalArgs(args: ReadonlyArray<string>): ParsedEvalArgs {
194
201
  }
195
202
 
196
203
  export async function runEvalCommand(args: ReadonlyArray<string>): Promise<number> {
204
+ // Routed before the shared parser so the fixed read stays exactly fixed: no
205
+ // eval flag can reach it, and no flag it does not name can be spent on it.
206
+ if (args[0] === "inventory") {
207
+ const { runEvalInventory } = await import("./eval-inventory.js");
208
+ return runEvalInventory(args.slice(1));
209
+ }
197
210
  let parsed: ParsedEvalArgs;
198
211
  try {
199
212
  parsed = parseEvalArgs(args);
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Fixed machine-readable projection of one evidence bundle's trust record.
3
+ *
4
+ * `evidence inspect <id>` prints an operator record that quotes the task text,
5
+ * the bundle's file list, and per-finding prose. This is the same bundle read
6
+ * down to the one thing a GUI can carry safely and usefully: which runs the
7
+ * bundle covers, what verdict each run earned, and which axis produced it.
8
+ *
9
+ * Every value here comes from a closed vocabulary. The axis names, the axis
10
+ * states, and the verdicts are all enumerations the harness owns, so there is
11
+ * no free-form text on this surface at all, which is what lets it answer the
12
+ * question the inventory raises without reopening the boundary the inventory
13
+ * closed.
14
+ *
15
+ * Unlike the other fixed reads this one takes an identifier, because an
16
+ * operator names the bundle. The GUI host may only pass back an id it served
17
+ * inside its current bounded window; see `apps/workbench/artifact-allowlist.ts`.
18
+ */
19
+
20
+ import { clioDataDir } from "../core/xdg.js";
21
+ import {
22
+ inspectEvidence,
23
+ TRUST_STATUS_AXES,
24
+ type TrustStatusAxis,
25
+ type TrustVerdict,
26
+ trustVerdict,
27
+ } from "../domains/evidence/index.js";
28
+
29
+ export const EVIDENCE_DETAIL_MAX_RUNS = 16;
30
+
31
+ export interface EvidenceDetailRun {
32
+ readonly runId: string;
33
+ readonly verdict: TrustVerdict;
34
+ /** Every axis, always all six, so an absent axis is stated rather than missing. */
35
+ readonly axes: Readonly<Record<TrustStatusAxis, string>>;
36
+ }
37
+
38
+ export interface EvidenceDetailSnapshot {
39
+ readonly version: 1;
40
+ readonly generatedAt: string;
41
+ readonly evidenceId: string;
42
+ readonly sourceKind: "run" | "session" | "eval";
43
+ /** False when the bundle predates the canonical trust projection. */
44
+ readonly canonical: boolean;
45
+ readonly runs: readonly EvidenceDetailRun[];
46
+ readonly runsTruncated: boolean;
47
+ }
48
+
49
+ export async function evidenceDetailSnapshot(
50
+ evidenceId: string,
51
+ now: () => number = Date.now,
52
+ dataDir: string = clioDataDir(),
53
+ ): Promise<EvidenceDetailSnapshot> {
54
+ const inspected = await inspectEvidence(dataDir, evidenceId);
55
+ const all = inspected.trustStatus.runs;
56
+ const window = all.slice(0, EVIDENCE_DETAIL_MAX_RUNS);
57
+ return {
58
+ version: 1,
59
+ generatedAt: new Date(now()).toISOString(),
60
+ evidenceId: inspected.overview.evidenceId,
61
+ sourceKind: inspected.overview.source.kind,
62
+ canonical: inspected.trustStatus.projection === "canonical",
63
+ runs: window.map(
64
+ (run): EvidenceDetailRun => ({
65
+ runId: run.runId,
66
+ verdict: trustVerdict(run.status),
67
+ axes: Object.fromEntries(TRUST_STATUS_AXES.map((axis) => [axis, run.status[axis].state])) as Record<
68
+ TrustStatusAxis,
69
+ string
70
+ >,
71
+ }),
72
+ ),
73
+ runsTruncated: all.length > window.length,
74
+ };
75
+ }
76
+
77
+ /**
78
+ * `clio-coder evidence inspect <id> --json`.
79
+ *
80
+ * The id is the only argument, and the caller supplies it. A GUI host is bound
81
+ * by its own allowlist rather than by this command, because an operator typing
82
+ * an id at a terminal is naming something on their own machine, which is a
83
+ * different act from a browser frame naming it.
84
+ */
85
+ export async function runEvidenceDetail(evidenceId: string): Promise<number> {
86
+ process.stdout.write(`${JSON.stringify(await evidenceDetailSnapshot(evidenceId), null, 2)}\n`);
87
+ return 0;
88
+ }