@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.
- package/CHANGELOG.md +102 -0
- package/NOTICE +33 -0
- package/README.md +12 -3
- package/dist/{acp-U67UHUK2.js → acp-G5WJBNCT.js} +13 -12
- package/dist/{agents-YU6SGALZ.js → agents-FMV2Q5G4.js} +41 -36
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-5ZPJOIVG.js → auth-3IDSJEIK.js} +18 -18
- package/dist/{builtins-C6JMZVV6.js → builtins-XCZWXSC7.js} +5 -5
- package/dist/{chunk-IFBNV6H6.js → chunk-2ANTL7MR.js} +3 -3
- package/dist/{chunk-5FR74PWO.js → chunk-2JDWVJND.js} +2 -2
- package/dist/{chunk-XWSF374K.js → chunk-2OQE55CK.js} +3 -3
- package/dist/{chunk-5H3GB5BO.js → chunk-32KWKNSF.js} +8 -384
- package/dist/{chunk-KTYTFRMB.js → chunk-36EJLSQQ.js} +34 -36
- package/dist/{chunk-FHJEP5SW.js → chunk-3BT2XMV4.js} +19 -13
- package/dist/chunk-3DPEIQKN.js +113 -0
- package/dist/{chunk-GU2UIAFZ.js → chunk-3URVFKWK.js} +7 -7
- package/dist/{chunk-WEH5XRJQ.js → chunk-3XML7CDN.js} +3 -3
- package/dist/chunk-42FMPA75.js +101 -0
- package/dist/{chunk-A2NJGIB3.js → chunk-5LXZXPKX.js} +2 -2
- package/dist/{chunk-VCBR6CU7.js → chunk-5PSMVOLM.js} +2 -2
- package/dist/{chunk-NMPKI6XL.js → chunk-6DB53AJS.js} +203 -25
- package/dist/{chunk-3BINW3FP.js → chunk-76ONBSIA.js} +2 -2
- package/dist/{chunk-26LEYJZH.js → chunk-7MCTRUCE.js} +2 -2
- package/dist/{chunk-TYPGUK6W.js → chunk-AB44T6BB.js} +111 -5
- package/dist/{chunk-K4XHGFR5.js → chunk-B7OBL7PK.js} +317 -721
- package/dist/{chunk-B5CSFE7B.js → chunk-BBVJUZHB.js} +2 -2
- package/dist/{chunk-EQ63NRB7.js → chunk-BBVYXMFO.js} +2 -2
- package/dist/{chunk-ZVJ5BLO2.js → chunk-BKFJHQCA.js} +154 -16
- package/dist/chunk-BKFM6EJV.js +462 -0
- package/dist/chunk-BMS5RKQY.js +27 -0
- package/dist/{chunk-ZNLWCMVZ.js → chunk-BPKCPIL7.js} +2 -2
- package/dist/{chunk-TLQJPP24.js → chunk-BUMFYQFY.js} +1394 -1349
- package/dist/{chunk-BNAZZHFG.js → chunk-BYP5D4HI.js} +1 -1
- package/dist/chunk-C2LTL2W6.js +2447 -0
- package/dist/{chunk-ME6CCNFO.js → chunk-CODPRO7Q.js} +8 -8
- package/dist/{chunk-E77JEWSD.js → chunk-CTJ4RNAA.js} +7 -37
- package/dist/{chunk-ODFEOB4F.js → chunk-CY6FY24N.js} +26 -8
- package/dist/{chunk-7RFXX52T.js → chunk-DQITNCXG.js} +642 -172
- package/dist/{chunk-TTHACPOM.js → chunk-DYJP44XW.js} +578 -117
- package/dist/{chunk-2HFZQUHL.js → chunk-F4CKPOEQ.js} +18 -8
- package/dist/{chunk-DGSYXYMX.js → chunk-FEFIFZTL.js} +3 -3
- package/dist/{chunk-GWS3VEIW.js → chunk-FWDFM5ZU.js} +24 -3
- package/dist/{chunk-MV3K5QF2.js → chunk-GCSMB2KY.js} +2 -2
- package/dist/chunk-GKF55TAZ.js +391 -0
- package/dist/{chunk-VWZOAB7K.js → chunk-GR5G2PVF.js} +9 -8
- package/dist/{chunk-4DGYLA73.js → chunk-GXNLGKAB.js} +80 -9
- package/dist/chunk-HHV2GANA.js +88 -0
- package/dist/{chunk-IIZWH4XA.js → chunk-HI63TFOG.js} +5 -4
- package/dist/{chunk-WLFILSD5.js → chunk-HJJTYUHX.js} +113 -83
- package/dist/{chunk-TT36MB5S.js → chunk-HLW2MRKE.js} +3 -1
- package/dist/{chunk-PMDBGQSJ.js → chunk-HWHKMHUA.js} +7 -7
- package/dist/chunk-HZHHCK24.js +1631 -0
- package/dist/{chunk-WSB3FPX7.js → chunk-I5VEOC6I.js} +39 -143
- package/dist/chunk-IBEBSCYA.js +564 -0
- package/dist/chunk-IQ7KR472.js +362 -0
- package/dist/{chunk-A3WNZD3P.js → chunk-J4W7KFM7.js} +949 -972
- package/dist/{chunk-TB5666IT.js → chunk-JDG2WCRO.js} +5 -5
- package/dist/{chunk-N22QMJKY.js → chunk-K5C3NCBD.js} +4 -4
- package/dist/{chunk-CGKSTWHD.js → chunk-K6BSR66V.js} +2 -1
- package/dist/{chunk-5C3AQNDW.js → chunk-KFZI4NIL.js} +216 -38
- package/dist/chunk-KMVISBZR.js +132 -0
- package/dist/{chunk-WXY7KU3G.js → chunk-LDQ2ZF2M.js} +2 -2
- package/dist/{chunk-XN3L4EYL.js → chunk-LQ3DZAMX.js} +3 -3
- package/dist/{chunk-U6MBIEMB.js → chunk-LY4S7GJC.js} +173 -144
- package/dist/{chunk-4SPRNWDE.js → chunk-MLKNTWH2.js} +19 -19
- package/dist/{chunk-MVVUPGPW.js → chunk-MXHC5QYU.js} +6 -6
- package/dist/chunk-NEKRRTYW.js +56 -0
- package/dist/{chunk-SPULKLCF.js → chunk-NHCZP4K7.js} +3 -3
- package/dist/chunk-NHLBIGRH.js +1506 -0
- package/dist/chunk-NQQH3YT7.js +302 -0
- package/dist/chunk-NYS75XW5.js +15 -0
- package/dist/{chunk-GN57SG4G.js → chunk-O4XIVISU.js} +10 -8
- package/dist/{chunk-EMYUUSFG.js → chunk-O6TL7WWY.js} +6 -6
- package/dist/chunk-OQBA45DZ.js +97 -0
- package/dist/{chunk-LU7P4LHA.js → chunk-P3FOHJT4.js} +2 -2
- package/dist/chunk-PMZCIOCJ.js +25 -0
- package/dist/{chunk-I4HZDVNP.js → chunk-PQEFIJ36.js} +2 -2
- package/dist/{chunk-J3YUBZWY.js → chunk-QBJA7R7N.js} +62 -6
- package/dist/chunk-QDC3K2U3.js +262 -0
- package/dist/{chunk-2HEJ2F35.js → chunk-QLFS5GO2.js} +22 -10
- package/dist/{chunk-7RGZWPB6.js → chunk-QLL7ILRG.js} +95 -32
- package/dist/{chunk-YS5VLNH5.js → chunk-QREDIESB.js} +6 -6
- package/dist/chunk-QSNYB6ZV.js +195 -0
- package/dist/{chunk-GOXNB3AO.js → chunk-RAPCMZL4.js} +75 -4
- package/dist/chunk-RKKLTLYB.js +45 -0
- package/dist/{chunk-P43ETTHK.js → chunk-SJ5ZKQ4S.js} +2 -2
- package/dist/{chunk-GPIEI3LY.js → chunk-SP2RXXYO.js} +6 -54
- package/dist/chunk-SUCTJL45.js +45 -0
- package/dist/{chunk-DYIM5TJT.js → chunk-SUW5DORT.js} +263 -7
- package/dist/chunk-T56WDKA5.js +183 -0
- package/dist/chunk-TVHHYFHE.js +255 -0
- package/dist/{chunk-FJ3H4MN5.js → chunk-TZ3SGWZZ.js} +3 -3
- package/dist/{chunk-MXKJU4JB.js → chunk-U77AMWDL.js} +91 -10
- package/dist/{chunk-5DHKRSMQ.js → chunk-ULC6OTWO.js} +11 -7
- package/dist/{chunk-RWSI4YD7.js → chunk-UM7N4G5A.js} +33 -12
- package/dist/{chunk-FCSXB6T2.js → chunk-UOSL25KY.js} +14 -2
- package/dist/{chunk-IGWKHNIQ.js → chunk-UXMFQ54G.js} +44 -37
- package/dist/{chunk-HFSBBKSQ.js → chunk-V5DHCITQ.js} +171 -3
- package/dist/{chunk-5WIGXA4T.js → chunk-VAZSBTKF.js} +111 -4
- package/dist/{chunk-VHN4MY6O.js → chunk-VEO4AP2K.js} +2 -2
- package/dist/{chunk-IJ7RPIYJ.js → chunk-VFA6GDY5.js} +65 -4
- package/dist/{chunk-PT7HYKEM.js → chunk-VO2LKSTM.js} +2 -2
- package/dist/chunk-VO67MWHC.js +75 -0
- package/dist/{chunk-XK56QHLX.js → chunk-VPKWYKEY.js} +19 -5
- package/dist/{chunk-TANS5ZJS.js → chunk-VYMXRQI6.js} +36 -22
- package/dist/{chunk-WWCZ5F23.js → chunk-W5VSYASO.js} +77 -16
- package/dist/{chunk-WNIJTQQK.js → chunk-WZR7K7ZX.js} +72 -116
- package/dist/{chunk-5Q2VVUKB.js → chunk-X3YGUTOB.js} +4 -4
- package/dist/chunk-X75E3D2N.js +686 -0
- package/dist/{chunk-VAWNZU7Z.js → chunk-YDFRH54B.js} +4 -4
- package/dist/chunk-YJX4SHTD.js +40 -0
- package/dist/{chunk-ZI647VB5.js → chunk-YPI3QQCF.js} +2 -2
- package/dist/chunk-Z2RR6MAK.js +127 -0
- package/dist/{chunk-FBVTI2TJ.js → chunk-Z4TXYIEG.js} +12 -131
- package/dist/cli/index.js +47 -36
- package/dist/{clio-QVTYJ57A.js → clio-2JXHBBY5.js} +7 -7
- package/dist/{code-nav-FGGFIE7L.js → code-nav-3YYRMYNF.js} +8 -8
- package/dist/{compile-cache-CVJMMODC.js → compile-cache-7FPE6PS3.js} +3 -3
- package/dist/{components-ZFA3SAER.js → components-RYZV4JGP.js} +5 -5
- package/dist/{config-LW5IJFQN.js → config-QZPCMYSO.js} +99 -63
- package/dist/{configure-7XIZCOU4.js → configure-TEGEBYCA.js} +23 -22
- package/dist/{context-Y6Y7QPR6.js → context-AV7OEZ4D.js} +12 -12
- package/dist/{context-L3WL3X7K.js → context-E6H5RNMC.js} +56 -47
- package/dist/{context-N52ZA626.js → context-GSXUE4CT.js} +29 -27
- package/dist/{context-clear-MBQRLSDQ.js → context-clear-SHIBYK6T.js} +55 -46
- package/dist/{context-index-HVMFQHK3.js → context-index-HNG3MOME.js} +2 -2
- package/dist/{context-working-set-GS6DSO7F.js → context-working-set-5ZGKPGZQ.js} +13 -13
- package/dist/{dispatch-runner-22ZCNOM3.js → dispatch-runner-EFMJT4LD.js} +93 -64
- package/dist/{docs-7LQ23DLM.js → docs-23KQS3XK.js} +5 -5
- package/dist/doctor-QOA5FNY5.js +313 -0
- package/dist/{eval-BEC2WHDA.js → eval-TFBYQH4H.js} +2032 -156
- package/dist/eval-inventory-SXH7PDKX.js +316 -0
- package/dist/{evidence-REJUMSKM.js → evidence-ERGESKGN.js} +203 -48
- package/dist/{evolve-PY5ZBA5K.js → evolve-VDXTSYCJ.js} +52 -43
- package/dist/{extensions-HVKU65YU.js → extensions-7BGBHN57.js} +13 -7
- package/dist/{fleet-7WZEWRFA.js → fleet-2RRVDF2V.js} +228 -108
- package/dist/{fleet-commands-UVHWM76J.js → fleet-commands-VJ726XIA.js} +11 -11
- package/dist/fleet-decisions-EPAPM3XJ.js +157 -0
- package/dist/{fleet-graph-6ULH7PES.js → fleet-graph-JF5QOATM.js} +18 -15
- package/dist/fleet-inspect-VLY4S7QM.js +442 -0
- package/dist/{fleet-preflight-J53T6CCE.js → fleet-preflight-AIZUEJOY.js} +5 -5
- package/dist/{fleet-validate-72PC4SLA.js → fleet-validate-AJRPDMDV.js} +22 -19
- package/dist/fleet-verify-JFEL2L3H.js +175 -0
- package/dist/fleet-view-ZCON35AG.js +102 -0
- package/dist/{init-OG3TPGQG.js → init-DN2WWLFE.js} +72 -62
- package/dist/install-XGLBQY5E.js +13 -0
- package/dist/interop-OZBKXAYL.js +114 -0
- package/dist/{library-CNTMPLRF.js → library-YWZG7IMW.js} +21 -18
- package/dist/{memory-6IS7F275.js → memory-I4C4HMLW.js} +54 -45
- package/dist/{models-ENRJDA5W.js → models-CEYXJBO6.js} +33 -30
- package/dist/{monitor-XLDVO7TN.js → monitor-NZ6GCI3P.js} +59 -52
- package/dist/{orchestrator-6KSPYRHA.js → orchestrator-GCGQ4N5I.js} +7827 -7328
- package/dist/panes-HMABYVO4.js +58 -0
- package/dist/panes-KY6W3V2E.js +103 -0
- package/dist/{paths-DBXMZMDU.js → paths-II4K7DNR.js} +5 -5
- package/dist/{reset-RZ4ER727.js → reset-DQ6FGCSH.js} +13 -11
- package/dist/resources-BB3MVJMD.js +111 -0
- package/dist/{run-Y2CNK5RU.js → run-H2GQDUER.js} +119 -87
- package/dist/{share-A55GYP6Z.js → share-GTJN6A5O.js} +20 -17
- package/dist/{skills-ALC5J6AT.js → skills-L55TEW6R.js} +33 -24
- package/dist/{skills-eval-JPBEBYQU.js → skills-eval-XVXPH2JI.js} +67 -56
- package/dist/skills-inventory-S4MXPJFV.js +126 -0
- package/dist/slash-commands-ZSGASKJC.js +77 -0
- package/dist/{steer-GGWFUJUD.js → steer-RZGSCY4R.js} +4 -4
- package/dist/{support-MIETYA5E.js → support-PKEUNNQL.js} +6 -6
- package/dist/{targets-VGNXIR3S.js → targets-NCPZ644J.js} +68 -40
- package/dist/{terminal-lease-WOBR64YA.js → terminal-lease-44SV3YCN.js} +6 -4
- package/dist/tools-DAF3DI3C.js +27 -0
- package/dist/{trace-PNCASAXC.js → trace-FYVW2MQA.js} +207 -10
- package/dist/tui-primitives-2AKXQNZK.js +13 -0
- package/dist/{uninstall-ZJF5H5ZN.js → uninstall-DW2PNOIC.js} +5 -5
- package/dist/{upgrade-FUSUAGHR.js → upgrade-3XPP6OQL.js} +27 -24
- package/dist/{usage-N4MKVHKD.js → usage-3NLHGTU2.js} +114 -62
- package/dist/{verifiers-YAWOJ3H2.js → verifiers-SSQONKRT.js} +172 -13
- package/dist/{verify-LTDHYBGY.js → verify-3U6J7FZI.js} +10 -10
- package/dist/{web-fetch-2YHJ3KTG.js → web-fetch-S7RR6GZ7.js} +3 -3
- package/dist/{wiki-generate-6M7GHTBJ.js → wiki-generate-CEHYGPGQ.js} +75 -65
- package/dist/with-panes-MKB46MPQ.js +782 -0
- package/dist/worker/entry.js +106 -75
- package/docs/README.md +3 -2
- package/docs/acp.md +24 -3
- package/docs/alcf-provider.md +1 -1
- package/docs/architecture.md +2 -2
- package/docs/artifact-versions.md +9 -1
- package/docs/built-in-agents.md +1 -1
- package/docs/capacity-and-scheduling.md +62 -3
- package/docs/commands-and-modes.md +31 -2
- package/docs/configuration-and-targets.md +69 -12
- package/docs/context-engine.md +63 -4
- package/docs/development-pipeline.md +19 -0
- package/docs/dispatch-typed-intent.md +385 -0
- package/docs/documentation-coverage.md +5 -5
- package/docs/documentation-guide.md +1 -1
- package/docs/environment-variables.md +3 -0
- package/docs/eval-runner.md +262 -11
- package/docs/evals-internal.md +72 -2
- package/docs/evidence-and-memory.md +12 -11
- package/docs/evolution.md +1 -1
- package/docs/exit-codes-and-output.md +1 -1
- package/docs/extensions-and-sharing.md +27 -1
- package/docs/fleet-dispatch.md +25 -4
- package/docs/installation-and-lifecycle.md +15 -2
- package/docs/middleware-and-components.md +1 -1
- package/docs/model-catalog.md +10 -1
- package/docs/observability.md +55 -4
- package/docs/proactive-memory.md +127 -14
- package/docs/prompt-envelope-and-tools.md +19 -1
- package/docs/provider-adapter-cookbook.md +1 -1
- package/docs/release-cut-checklist.md +19 -3
- package/docs/safety-model.md +2 -2
- package/docs/scientific-validation.md +3 -3
- package/docs/session-lifecycle.md +1 -1
- package/docs/skills-marketplace.md +1 -1
- package/docs/tool-usage.md +18 -8
- package/docs/trace-store.md +1 -1
- package/docs/troubleshooting.md +88 -1
- package/docs/tui-design.md +1 -1
- package/docs/worker-dispatch-mechanics.md +1 -1
- package/package.json +5 -2
- package/src/cli/acp.ts +6 -2
- package/src/cli/agents.ts +1 -1
- package/src/cli/argv.ts +25 -0
- package/src/cli/config-inspect.ts +33 -6
- package/src/cli/config.ts +1 -1
- package/src/cli/configure.ts +23 -21
- package/src/cli/doctor-panes.ts +124 -0
- package/src/cli/doctor-state-size.ts +82 -0
- package/src/cli/doctor-toolchain.ts +57 -0
- package/src/cli/doctor.ts +22 -1
- package/src/cli/eval-inventory.ts +436 -0
- package/src/cli/eval.ts +93 -16
- package/src/cli/evidence-detail.ts +88 -0
- package/src/cli/evidence-inventory.ts +183 -0
- package/src/cli/evidence.ts +30 -5
- package/src/cli/extensions.ts +5 -1
- package/src/cli/fleet-decisions.ts +69 -0
- package/src/cli/fleet-inspect.ts +334 -0
- package/src/cli/fleet-verify.ts +133 -0
- package/src/cli/fleet-view.ts +810 -0
- package/src/cli/fleet.ts +179 -39
- package/src/cli/index.ts +14 -2
- package/src/cli/interop-inspect.ts +128 -0
- package/src/cli/interop.ts +34 -0
- package/src/cli/panes.ts +35 -0
- package/src/cli/reset.ts +5 -2
- package/src/cli/run.ts +58 -0
- package/src/cli/skills-inventory.ts +185 -0
- package/src/cli/skills.ts +16 -13
- package/src/cli/targets.ts +44 -13
- package/src/cli/tools.ts +321 -0
- package/src/cli/trace-inspect.ts +252 -0
- package/src/cli/trace.ts +85 -5
- package/src/cli/usage.ts +63 -14
- package/src/cli/verifiers-inspect.ts +347 -0
- package/src/cli/verifiers.ts +9 -0
- package/src/core/bus-events.ts +33 -1
- package/src/core/cache-telemetry.ts +42 -0
- package/src/core/config.ts +67 -0
- package/src/core/defaults.ts +124 -8
- package/src/core/endpoint-key.ts +27 -0
- package/src/core/residency-target-key.ts +25 -0
- package/src/core/response-schema.ts +80 -6
- package/src/core/theme-token-hex.ts +43 -0
- package/src/core/tool-names.ts +2 -1
- package/src/core/xdg.ts +1 -1
- package/src/domains/agents/fleets/build-review.md +0 -3
- package/src/domains/agents/fleets/build-test.md +0 -3
- package/src/domains/agents/result-contract-filesystem.ts +32 -0
- package/src/domains/agents/result-contract.ts +164 -35
- package/src/domains/config/classify.ts +6 -0
- package/src/domains/context/codewiki/coordinator.ts +12 -4
- package/src/domains/dispatch/admission-error.ts +9 -0
- package/src/domains/dispatch/admission.ts +52 -14
- package/src/domains/dispatch/capacity-lease.ts +118 -9
- package/src/domains/dispatch/contract.ts +11 -0
- package/src/domains/dispatch/council-topology.ts +398 -0
- package/src/domains/dispatch/execution-plan.ts +44 -4
- package/src/domains/dispatch/extension.ts +378 -82
- package/src/domains/dispatch/fleet-node-prompt.ts +62 -0
- package/src/domains/dispatch/fleet-plan.ts +7 -2
- package/src/domains/dispatch/fleet-run.ts +87 -4
- package/src/domains/dispatch/gate-decisions.ts +11 -1
- package/src/domains/dispatch/gate-role-prompts.ts +9 -0
- package/src/domains/dispatch/gate-topology.ts +289 -0
- package/src/domains/dispatch/heartbeat.ts +32 -8
- package/src/domains/dispatch/index.ts +22 -0
- package/src/domains/dispatch/intent-compatibility.ts +330 -0
- package/src/domains/dispatch/intent.ts +85 -1
- package/src/domains/dispatch/orphan-recovery.ts +5 -0
- package/src/domains/dispatch/reservation-store.ts +139 -11
- package/src/domains/dispatch/run-event-journal-bridge.ts +149 -0
- package/src/domains/dispatch/run-event-journal.ts +598 -0
- package/src/domains/dispatch/state.ts +49 -1
- package/src/domains/dispatch/types.ts +13 -0
- package/src/domains/dispatch/validation.ts +33 -8
- package/src/domains/dispatch/worker-spawn.ts +25 -11
- package/src/domains/dispatch/write-boundary-enforcer.ts +20 -3
- package/src/domains/dispatch/write-boundary.ts +62 -1
- package/src/domains/eval/artifacts/store.ts +62 -0
- package/src/domains/eval/compare/behavioral.ts +224 -0
- package/src/domains/eval/compare/compare.ts +342 -2
- package/src/domains/eval/compare/envelope.ts +128 -0
- package/src/domains/eval/compare/gates.ts +24 -6
- package/src/domains/eval/compare/thresholds.ts +30 -3
- package/src/domains/eval/execution-provenance.ts +240 -0
- package/src/domains/eval/inventory.ts +113 -0
- package/src/domains/eval/metrics/aggregate.ts +136 -0
- package/src/domains/eval/metrics/call-ledger-stream.ts +112 -0
- package/src/domains/eval/metrics/tracked.ts +413 -0
- package/src/domains/eval/provenance.ts +117 -0
- package/src/domains/eval/reports/comparison.ts +128 -0
- package/src/domains/eval/reports/junit.ts +17 -3
- package/src/domains/eval/reports/markdown.ts +3 -3
- package/src/domains/eval/reports/text.ts +14 -0
- package/src/domains/eval/run-compare.ts +20 -0
- package/src/domains/eval/runners/clio-run.ts +127 -0
- package/src/domains/eval/runners/external-command.ts +28 -3
- package/src/domains/eval/schema/adapter.ts +111 -0
- package/src/domains/eval/schema/artifact.ts +20 -0
- package/src/domains/eval/schema/behavioral-metrics.ts +204 -0
- package/src/domains/eval/schema/behavioral.ts +520 -0
- package/src/domains/eval/schema/execution-envelope.ts +194 -0
- package/src/domains/eval/schema/serving.ts +105 -0
- package/src/domains/eval/schema/suite.ts +38 -8
- package/src/domains/eval/schema/validate.ts +58 -3
- package/src/domains/eval/schema/verdict.ts +237 -0
- package/src/domains/eval/suites/resolve.ts +2 -0
- package/src/domains/eval/suites/run.ts +264 -33
- package/src/domains/eval/verifiers/command.ts +2 -1
- package/src/domains/eval/workspaces/temp-copy.ts +145 -13
- package/src/domains/evidence/build.ts +2 -13
- package/src/domains/evidence/eval.ts +2 -12
- package/src/domains/evidence/findings-markdown.ts +33 -0
- package/src/domains/evidence/run-trust.ts +7 -113
- package/src/domains/evidence/store.ts +6 -0
- package/src/domains/evidence/trust-projection.ts +2 -2
- package/src/domains/extensions/compatibility.ts +285 -0
- package/src/domains/extensions/discovery.ts +38 -3
- package/src/domains/extensions/resources.ts +1 -1
- package/src/domains/extensions/state.ts +12 -3
- package/src/domains/extensions/types.ts +2 -0
- package/src/domains/lifecycle/doctor.ts +69 -1
- package/src/domains/memory/index.ts +14 -1
- package/src/domains/memory/task-bank-promotion.ts +64 -0
- package/src/domains/memory/task-memory-policy.ts +82 -17
- package/src/domains/memory/task-memory-spend.ts +131 -0
- package/src/domains/memory/task-memory-status.ts +7 -0
- package/src/domains/memory/task-memory-telemetry.ts +3 -0
- package/src/domains/middleware/index.ts +1 -0
- package/src/domains/middleware/memory-intervention.ts +97 -21
- package/src/domains/middleware/memory-step-endpoint.ts +71 -0
- package/src/domains/mux/contract.ts +434 -0
- package/src/domains/mux/detect.ts +158 -0
- package/src/domains/mux/extension.ts +47 -0
- package/src/domains/mux/index.ts +96 -0
- package/src/domains/mux/manifest.ts +6 -0
- package/src/domains/mux/operations.ts +164 -0
- package/src/domains/mux/pane-registry.ts +90 -0
- package/src/domains/mux/protocol.ts +49 -0
- package/src/domains/mux/socket-client.ts +816 -0
- package/src/domains/mux/types.ts +222 -0
- package/src/domains/mux/viewer-command.ts +59 -0
- package/src/domains/mux/yazi/assets/init.lua +2 -0
- package/src/domains/mux/yazi/assets/plugins/git.yazi/LICENSE +21 -0
- package/src/domains/mux/yazi/assets/plugins/git.yazi/README.md +78 -0
- package/src/domains/mux/yazi/assets/plugins/git.yazi/main.lua +255 -0
- package/src/domains/mux/yazi/assets/plugins/git.yazi/types.lua +12 -0
- package/src/domains/mux/yazi/assets/yazi.toml +17 -0
- package/src/domains/mux/yazi/event-stream.ts +180 -0
- package/src/domains/mux/yazi/profile.ts +299 -0
- package/src/domains/mux/yazi/session.ts +228 -0
- package/src/domains/mux/yazi/theme.ts +30 -0
- package/src/domains/observability/background-memory-usage.ts +140 -0
- package/src/domains/observability/cost.ts +22 -1
- package/src/domains/observability/index.ts +9 -0
- package/src/domains/observability/out-of-turn-usage.ts +51 -2
- package/src/domains/observability/trace-store.ts +234 -2
- package/src/domains/prompts/compiler.ts +100 -13
- package/src/domains/providers/endpoint-capacity.ts +228 -0
- package/src/domains/providers/endpoint-slots-store.ts +189 -0
- package/src/domains/providers/extension.ts +20 -3
- package/src/domains/providers/index.ts +32 -0
- package/src/domains/providers/model-runtime-capabilities.ts +32 -0
- package/src/domains/providers/models/local-models/clio-local-coding-targets.yaml +243 -1
- package/src/domains/providers/runtime-resolution.ts +8 -1
- package/src/domains/providers/runtimes/boot-manifest.ts +1 -0
- package/src/domains/providers/runtimes/builtins.ts +2 -0
- package/src/domains/providers/runtimes/common/probe-helpers.ts +31 -9
- package/src/domains/providers/runtimes/local-native/llamacpp-anthropic.ts +1 -1
- package/src/domains/providers/runtimes/local-native/llamacpp-completion.ts +1 -1
- package/src/domains/providers/runtimes/local-native/llamacpp-embed.ts +1 -1
- package/src/domains/providers/runtimes/local-native/llamacpp-rerank.ts +1 -1
- package/src/domains/providers/runtimes/local-native/llamacpp.ts +4 -1
- package/src/domains/providers/runtimes/local-native/lmstudio.ts +4 -1
- package/src/domains/providers/runtimes/local-native/ollama-native.ts +6 -1
- package/src/domains/providers/runtimes/protocol/litellm.ts +375 -0
- package/src/domains/providers/support.ts +1 -0
- package/src/domains/providers/target-model-cache.ts +124 -0
- package/src/domains/providers/types/capability-flags.ts +2 -0
- package/src/domains/providers/types/target-descriptor.ts +2 -0
- package/src/domains/resources/index.ts +3 -0
- package/src/domains/resources/prompts/loader.ts +95 -33
- package/src/domains/resources/skills/loader.ts +33 -0
- package/src/domains/safety/action-classifier.ts +6 -0
- package/src/domains/safety/call-target.ts +52 -0
- package/src/domains/safety/run-effects.ts +35 -4
- package/src/domains/session/context-accounting.ts +52 -1
- package/src/domains/session/context-ledger.ts +37 -13
- package/src/domains/session/index.ts +6 -0
- package/src/domains/session/prompt-cache.ts +140 -0
- package/src/domains/session/prompt-manifest.ts +42 -0
- package/src/domains/toolchain/archive.ts +175 -0
- package/src/domains/toolchain/contract.ts +28 -0
- package/src/domains/toolchain/extension.ts +47 -0
- package/src/domains/toolchain/index.ts +39 -0
- package/src/domains/toolchain/install.ts +327 -0
- package/src/domains/toolchain/manifest.ts +8 -0
- package/src/domains/toolchain/paths.ts +34 -0
- package/src/domains/toolchain/registry.ts +265 -0
- package/src/domains/toolchain/remove.ts +218 -0
- package/src/domains/toolchain/resolve.ts +182 -0
- package/src/domains/toolchain/types.ts +113 -0
- package/src/domains/toolchain/version.ts +88 -0
- package/src/engine/acp/adapter.ts +18 -3
- package/src/engine/acp/server.ts +413 -70
- package/src/engine/acp/types.ts +19 -1
- package/src/engine/ai.ts +35 -0
- package/src/engine/apis/llamacpp-residency.ts +55 -3
- package/src/engine/apis/lmstudio.ts +25 -5
- package/src/engine/apis/ollama-native.ts +2 -1
- package/src/engine/apis/openai-completions.ts +80 -17
- package/src/engine/apis/residency-lock.ts +3 -1
- package/src/engine/apis/residency.ts +34 -1
- package/src/engine/claude/sdk-module.ts +98 -0
- package/src/engine/claude/sdk-runtime.ts +19 -11
- package/src/engine/provider-payload.ts +29 -1
- package/src/engine/tui-primitives.ts +21 -0
- package/src/engine/tui.ts +1 -0
- package/src/engine/worker-runtime.ts +2 -13
- package/src/entry/boot-options.ts +2 -0
- package/src/entry/orchestrator.ts +279 -35
- package/src/entry/panes-activation.ts +31 -0
- package/src/entry/with-panes.ts +20 -0
- package/src/interactive/chat-loop-messages.ts +26 -7
- package/src/interactive/chat-loop.ts +318 -41
- package/src/interactive/chat-panel.ts +62 -8
- package/src/interactive/clio-editor.ts +45 -8
- package/src/interactive/context-activity.ts +5 -1
- package/src/interactive/context-meter.ts +1 -1
- package/src/interactive/context-overlay.ts +41 -10
- package/src/interactive/cost-overlay.ts +66 -6
- package/src/interactive/council-grid.ts +1 -3
- package/src/interactive/council.ts +11 -0
- package/src/interactive/dispatch-board.ts +102 -20
- package/src/interactive/fleet-run-preview.ts +41 -15
- package/src/interactive/handoff-round.ts +41 -2
- package/src/interactive/interactive-application.ts +177 -7
- package/src/interactive/interactive-input-runtime.ts +15 -0
- package/src/interactive/interactive-presentation.ts +4 -0
- package/src/interactive/interactive-shell.ts +20 -17
- package/src/interactive/interactive-slash-runtime.ts +63 -10
- package/src/interactive/memory-overlay.ts +9 -0
- package/src/interactive/modal-marker.ts +170 -0
- package/src/interactive/mutation-preview.ts +295 -0
- package/src/interactive/mux-bridge.ts +214 -0
- package/src/interactive/overlay-frame.ts +58 -2
- package/src/interactive/overlay-general-openers.ts +17 -0
- package/src/interactive/overlay-key-routing.ts +52 -3
- package/src/interactive/overlay-lifecycle.ts +56 -7
- package/src/interactive/overlay-model-selectors.ts +40 -3
- package/src/interactive/overlay-permission-lifecycle.ts +112 -24
- package/src/interactive/overlay-session-lifecycle.ts +73 -9
- package/src/interactive/overlay-transitions.ts +18 -4
- package/src/interactive/overlays/agents.ts +1 -0
- package/src/interactive/overlays/ask-user.ts +227 -49
- package/src/interactive/overlays/auth-dialog.ts +1 -0
- package/src/interactive/overlays/context-reset.ts +1 -0
- package/src/interactive/overlays/cwd-fallback.ts +1 -0
- package/src/interactive/overlays/decisions.ts +11 -11
- package/src/interactive/overlays/extensions.ts +1 -0
- package/src/interactive/overlays/fleet-run-approval.ts +1 -0
- package/src/interactive/overlays/handoff-review.ts +1 -0
- package/src/interactive/overlays/help-reference.ts +6 -0
- package/src/interactive/overlays/interop.ts +1 -0
- package/src/interactive/overlays/library-install-confirm.ts +1 -0
- package/src/interactive/overlays/library-tabs.ts +28 -0
- package/src/interactive/overlays/list-overlay.ts +10 -1
- package/src/interactive/overlays/message-picker.ts +1 -0
- package/src/interactive/overlays/model-scope.ts +86 -0
- package/src/interactive/overlays/model-selector.ts +1 -0
- package/src/interactive/overlays/prompts.ts +12 -1
- package/src/interactive/overlays/session-selector.ts +1 -0
- package/src/interactive/overlays/settings-sections.ts +30 -0
- package/src/interactive/overlays/settings.ts +614 -45
- package/src/interactive/overlays/side-question.ts +1 -0
- package/src/interactive/overlays/skills-hub.ts +3 -11
- package/src/interactive/overlays/tree-selector.ts +1 -0
- package/src/interactive/pane-policy.ts +46 -0
- package/src/interactive/panes-runtime.ts +292 -0
- package/src/interactive/permission-hint.ts +34 -2
- package/src/interactive/permission-overlay.ts +159 -9
- package/src/interactive/prewarm.ts +197 -0
- package/src/interactive/render-trace.ts +162 -15
- package/src/interactive/renderers/compaction-summary.ts +29 -0
- package/src/interactive/renderers/tool-execution.ts +4 -0
- package/src/interactive/renderers/worker-entry.ts +122 -14
- package/src/interactive/side-question.ts +58 -1
- package/src/interactive/slash-commands.ts +251 -15
- package/src/interactive/status/controller.ts +11 -0
- package/src/interactive/status/state-machine.ts +54 -2
- package/src/interactive/status/types.ts +7 -0
- package/src/interactive/tasks-overlay.ts +1 -0
- package/src/interactive/terminal-lease.ts +2 -0
- package/src/interactive/theme/tokens.ts +3 -14
- package/src/interactive/turn-context.ts +346 -33
- package/src/interactive/turn-persistence.ts +14 -4
- package/src/interactive/turn-prewarm.ts +364 -0
- package/src/interactive/turn-queues.ts +7 -4
- package/src/interactive/turn-runtime.ts +8 -1
- package/src/interactive/turn-state.ts +23 -0
- package/src/interactive/view/artifacts.ts +109 -1
- package/src/interactive/view/view-overlay.ts +29 -3
- package/src/interactive/watch-pane.ts +152 -0
- package/src/interactive/worker-progress.ts +7 -1
- package/src/interactive/worker-receipts.ts +19 -1
- package/src/interactive/worker-stream.ts +5 -0
- package/src/interactive/yazi-bridge.ts +444 -0
- package/src/tools/ask-user.ts +43 -2
- package/src/tools/bootstrap.ts +26 -2
- package/src/tools/builtin-tool-catalog.ts +15 -0
- package/src/tools/compete-worktrees.ts +83 -2
- package/src/tools/core-bootstrap.ts +2 -1
- package/src/tools/dispatch-admission.ts +14 -3
- package/src/tools/dispatch-arguments.ts +20 -20
- package/src/tools/dispatch-plan.ts +17 -9
- package/src/tools/dispatch-run-events.ts +134 -19
- package/src/tools/dispatch-runner.ts +29 -7
- package/src/tools/dispatch-scout.ts +1 -1
- package/src/tools/dispatch-types.ts +15 -3
- package/src/tools/dispatch.ts +1 -1
- package/src/tools/executables.ts +17 -14
- package/src/tools/observation.ts +54 -4
- package/src/tools/panes-surface.ts +38 -0
- package/src/tools/panes.ts +112 -0
- package/src/tools/policy.ts +10 -1
- package/src/tools/presentation.ts +1 -0
- package/src/tools/registry.ts +16 -0
- package/dist/chunk-AOCYTWAV.js +0 -449
- package/dist/chunk-HLE42MG7.js +0 -37
- package/dist/chunk-HWUFFB6L.js +0 -83
- package/dist/chunk-JOZYP4GM.js +0 -279
- package/dist/doctor-M7YEDGAE.js +0 -91
package/src/cli/eval.ts
CHANGED
|
@@ -2,10 +2,10 @@ import { resolve } from "node:path";
|
|
|
2
2
|
import { InvalidIdError } from "../core/safe-id.js";
|
|
3
3
|
import { clioDataDir } from "../core/xdg.js";
|
|
4
4
|
import { loadEvalArtifactV4, writeEvalArtifactV4 } from "../domains/eval/artifacts/store.js";
|
|
5
|
-
import { compareEvalArtifactsV4
|
|
6
|
-
import { evaluateGate, renderGateFailure } from "../domains/eval/compare/gates.js";
|
|
5
|
+
import { compareEvalArtifactsV4 } from "../domains/eval/compare/compare.js";
|
|
6
|
+
import { evaluateGate, renderGateFailure, renderInformationalBudget } from "../domains/eval/compare/gates.js";
|
|
7
7
|
import { loadThresholds } from "../domains/eval/compare/thresholds.js";
|
|
8
|
-
|
|
8
|
+
import { type EvalComparisonReportFormat, renderEvalComparisonReportV1 } from "../domains/eval/reports/comparison.js";
|
|
9
9
|
import { renderEvalJsonReportV4 } from "../domains/eval/reports/json.js";
|
|
10
10
|
import { renderEvalJunitReportV4 } from "../domains/eval/reports/junit.js";
|
|
11
11
|
import { renderEvalMarkdownReportV4 } from "../domains/eval/reports/markdown.js";
|
|
@@ -22,11 +22,18 @@ const HELP = `clio-coder eval <command>
|
|
|
22
22
|
|
|
23
23
|
Commands:
|
|
24
24
|
clio-coder eval validate --suite <suite.yaml>
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
clio-coder eval run --suite <suite.yaml> [--trials <n>] [--target <id>] [--model <id>] [--out <path>] [--clio-coder-entry <path>]
|
|
26
|
+
clio-coder eval run --task-file <tasks.yaml> [--repeat <n>] [--out <path>] [--clio-coder-entry <path>]
|
|
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";
|
|
@@ -37,6 +44,7 @@ interface ParsedEvalArgs {
|
|
|
37
44
|
suite?: string;
|
|
38
45
|
taskFile?: string;
|
|
39
46
|
repeat: number;
|
|
47
|
+
trials?: number;
|
|
40
48
|
target?: string;
|
|
41
49
|
model?: string;
|
|
42
50
|
out?: string;
|
|
@@ -44,13 +52,21 @@ interface ParsedEvalArgs {
|
|
|
44
52
|
evalId?: string;
|
|
45
53
|
format: EvalReportFormat;
|
|
46
54
|
compareIds: string[];
|
|
55
|
+
metric?: string;
|
|
56
|
+
allowConfigDrift: boolean;
|
|
47
57
|
baseline?: string;
|
|
48
58
|
thresholds?: string;
|
|
49
59
|
help: boolean;
|
|
50
60
|
}
|
|
51
61
|
|
|
52
62
|
function parseEvalArgs(args: ReadonlyArray<string>): ParsedEvalArgs {
|
|
53
|
-
const parsed: ParsedEvalArgs = {
|
|
63
|
+
const parsed: ParsedEvalArgs = {
|
|
64
|
+
repeat: 1,
|
|
65
|
+
compareIds: [],
|
|
66
|
+
format: "text",
|
|
67
|
+
allowConfigDrift: false,
|
|
68
|
+
help: false,
|
|
69
|
+
};
|
|
54
70
|
for (let index = 0; index < args.length; index += 1) {
|
|
55
71
|
const arg = args[index];
|
|
56
72
|
if (arg === undefined) continue;
|
|
@@ -110,6 +126,11 @@ function parseEvalArgs(args: ReadonlyArray<string>): ParsedEvalArgs {
|
|
|
110
126
|
index += 1;
|
|
111
127
|
continue;
|
|
112
128
|
}
|
|
129
|
+
if (arg === "--trials") {
|
|
130
|
+
parsed.trials = positiveInteger(requiredValue(args, index, "--trials"), "--trials");
|
|
131
|
+
index += 1;
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
113
134
|
throw new Error(`unknown eval run argument: ${arg}`);
|
|
114
135
|
}
|
|
115
136
|
if (parsed.command === "report") {
|
|
@@ -125,6 +146,20 @@ function parseEvalArgs(args: ReadonlyArray<string>): ParsedEvalArgs {
|
|
|
125
146
|
throw new Error(`unexpected eval report argument: ${arg}`);
|
|
126
147
|
}
|
|
127
148
|
if (parsed.command === "compare") {
|
|
149
|
+
if (arg === "--format") {
|
|
150
|
+
parsed.format = comparisonFormat(requiredValue(args, index, "--format"));
|
|
151
|
+
index += 1;
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
if (arg === "--metric") {
|
|
155
|
+
parsed.metric = requiredValue(args, index, "--metric");
|
|
156
|
+
index += 1;
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
if (arg === "--allow-config-drift") {
|
|
160
|
+
parsed.allowConfigDrift = true;
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
128
163
|
if (!arg.startsWith("-")) {
|
|
129
164
|
parsed.compareIds.push(arg);
|
|
130
165
|
continue;
|
|
@@ -166,6 +201,12 @@ function parseEvalArgs(args: ReadonlyArray<string>): ParsedEvalArgs {
|
|
|
166
201
|
}
|
|
167
202
|
|
|
168
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
|
+
}
|
|
169
210
|
let parsed: ParsedEvalArgs;
|
|
170
211
|
try {
|
|
171
212
|
parsed = parseEvalArgs(args);
|
|
@@ -202,15 +243,21 @@ async function runEvalRun(parsed: ParsedEvalArgs): Promise<number> {
|
|
|
202
243
|
const loaded =
|
|
203
244
|
parsed.suite !== undefined
|
|
204
245
|
? await loadEvalSuiteFile(parsed.suite)
|
|
205
|
-
: await loadV1TaskFileAsSuite(parsed.taskFile ?? "", parsed.repeat);
|
|
246
|
+
: await loadV1TaskFileAsSuite(parsed.taskFile ?? "", parsed.trials ?? parsed.repeat);
|
|
206
247
|
const resolveOptions: { target?: string; model?: string } = {};
|
|
207
248
|
if (parsed.target !== undefined) resolveOptions.target = parsed.target;
|
|
208
249
|
if (parsed.model !== undefined) resolveOptions.model = parsed.model;
|
|
209
|
-
const suite = resolveSuiteForRun(loaded.suite,
|
|
250
|
+
const suite = resolveSuiteForRun(loaded.suite, {
|
|
251
|
+
...resolveOptions,
|
|
252
|
+
...(parsed.trials ? { trials: parsed.trials } : {}),
|
|
253
|
+
});
|
|
210
254
|
// Runner commands execute with cwd inside prepared eval workspaces, so a
|
|
211
255
|
// relative --clio-coder-entry must be pinned to the invoking directory here.
|
|
212
256
|
const clioEntry = resolve(parsed.clioEntry ?? process.argv[1] ?? "dist/cli/index.js");
|
|
213
|
-
const artifact = await runEvalSuiteV2(
|
|
257
|
+
const artifact = await runEvalSuiteV2(
|
|
258
|
+
{ ...loaded, suite },
|
|
259
|
+
{ clioEntry, freshWorkspaces: parsed.trials !== undefined },
|
|
260
|
+
);
|
|
214
261
|
const artifactPath = await writeEvalArtifactV4(clioDataDir(), artifact, parsed.out);
|
|
215
262
|
process.stdout.write(`${renderEvalTextReportV4(artifact)}artifact: ${artifactPath}\n`);
|
|
216
263
|
// A suite that declares thresholds is gated by them here, on the artifact
|
|
@@ -221,6 +268,10 @@ async function runEvalRun(parsed: ParsedEvalArgs): Promise<number> {
|
|
|
221
268
|
process.stdout.write(`gate: fail (${gate.failures.length} threshold failure)\n`);
|
|
222
269
|
for (const failure of gate.failures) process.stdout.write(renderGateFailure(failure));
|
|
223
270
|
}
|
|
271
|
+
if (gate !== null && gate.informational.length > 0) {
|
|
272
|
+
process.stdout.write(`informational budgets: ${gate.informational.length} notice\n`);
|
|
273
|
+
for (const finding of gate.informational) process.stdout.write(renderInformationalBudget(finding));
|
|
274
|
+
}
|
|
224
275
|
return artifact.summary.failed === 0 && (gate === null || gate.pass) ? 0 : 1;
|
|
225
276
|
} catch (error) {
|
|
226
277
|
return handleEvalLoadError(error, 1);
|
|
@@ -246,8 +297,12 @@ async function runEvalCompareCommand(parsed: ParsedEvalArgs): Promise<number> {
|
|
|
246
297
|
const dataDir = clioDataDir();
|
|
247
298
|
const baseline = await loadEvalArtifactV4(dataDir, baselineEvalId);
|
|
248
299
|
const candidate = await loadEvalArtifactV4(dataDir, candidateEvalId);
|
|
249
|
-
|
|
250
|
-
|
|
300
|
+
const summary = compareEvalArtifactsV4(baseline, candidate, {
|
|
301
|
+
allowConfigDrift: parsed.allowConfigDrift,
|
|
302
|
+
...(parsed.metric === undefined ? {} : { metric: parsed.metric }),
|
|
303
|
+
});
|
|
304
|
+
process.stdout.write(renderEvalComparisonReportV1(summary, parsed.format as EvalComparisonReportFormat));
|
|
305
|
+
return summary.hardGate.pass ? 0 : 1;
|
|
251
306
|
} catch (error) {
|
|
252
307
|
printError(error instanceof Error ? error.message : String(error));
|
|
253
308
|
return error instanceof InvalidIdError ? 2 : 1;
|
|
@@ -258,18 +313,35 @@ async function runEvalGateCommand(parsed: ParsedEvalArgs): Promise<number> {
|
|
|
258
313
|
try {
|
|
259
314
|
const dataDir = clioDataDir();
|
|
260
315
|
const candidate = await loadEvalArtifactV4(dataDir, parsed.evalId ?? "");
|
|
261
|
-
await loadEvalArtifactV4(dataDir, parsed.baseline ?? "");
|
|
316
|
+
const baseline = await loadEvalArtifactV4(dataDir, parsed.baseline ?? "");
|
|
262
317
|
const thresholds =
|
|
263
318
|
parsed.thresholds === undefined
|
|
264
|
-
? { fail: [{ metric: "result.pass", op: "eq" as const, value: false }] }
|
|
319
|
+
? { fail: [{ metric: "result.pass", op: "eq" as const, value: false }], informational: [] }
|
|
265
320
|
: loadThresholds(parsed.thresholds);
|
|
266
321
|
const gate = evaluateGate(candidate, thresholds);
|
|
267
|
-
|
|
322
|
+
const comparison = compareEvalArtifactsV4(baseline, candidate);
|
|
323
|
+
if (gate.informational.length > 0) {
|
|
324
|
+
process.stdout.write(`informational budgets: ${gate.informational.length} notice\n`);
|
|
325
|
+
for (const finding of gate.informational) process.stdout.write(renderInformationalBudget(finding));
|
|
326
|
+
}
|
|
327
|
+
if (gate.pass && comparison.hardGate.pass) {
|
|
268
328
|
process.stdout.write("gate: pass\n");
|
|
269
329
|
return 0;
|
|
270
330
|
}
|
|
271
|
-
|
|
331
|
+
const failureCount =
|
|
332
|
+
gate.failures.length + comparison.hardGate.failures.length + comparison.hardGate.envelopeFailures.length;
|
|
333
|
+
process.stdout.write(`gate: fail (${failureCount} hard failure)\n`);
|
|
272
334
|
for (const failure of gate.failures) process.stdout.write(renderGateFailure(failure));
|
|
335
|
+
for (const failure of comparison.hardGate.failures) {
|
|
336
|
+
process.stdout.write(
|
|
337
|
+
` ${failure.metric} [${failure.scenarioId}:${failure.role}:${failure.target.id}/${failure.target.model ?? "none"}]: ${failure.change} (hard behavioral gate)\n`,
|
|
338
|
+
);
|
|
339
|
+
}
|
|
340
|
+
for (const failure of comparison.hardGate.envelopeFailures) {
|
|
341
|
+
process.stdout.write(
|
|
342
|
+
` execution envelope [${failure.scenarioId}:${failure.role}:${failure.target.id}/${failure.target.model ?? "none"}]: incomparable fields ${failure.fields.join(", ")}\n`,
|
|
343
|
+
);
|
|
344
|
+
}
|
|
273
345
|
return 1;
|
|
274
346
|
} catch (error) {
|
|
275
347
|
printError(error instanceof Error ? error.message : String(error));
|
|
@@ -313,3 +385,8 @@ function reportFormat(value: string): EvalReportFormat {
|
|
|
313
385
|
if (value === "text" || value === "json" || value === "md" || value === "swe-jsonl" || value === "junit") return value;
|
|
314
386
|
throw new Error("--format must be text, json, md, swe-jsonl, or junit");
|
|
315
387
|
}
|
|
388
|
+
|
|
389
|
+
function comparisonFormat(value: string): EvalComparisonReportFormat {
|
|
390
|
+
if (value === "text" || value === "json" || value === "md" || value === "junit") return value;
|
|
391
|
+
throw new Error("eval compare --format must be text, json, md, or junit");
|
|
392
|
+
}
|
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fixed machine-readable projection of recent evidence artifacts.
|
|
3
|
+
*
|
|
4
|
+
* `evidence list` is an operator table and `evidence inspect <id>` needs an id,
|
|
5
|
+
* so neither is a transport a GUI host can invoke blind. This command accepts
|
|
6
|
+
* no identifier, path, or limit, selects a bounded newest-first window itself,
|
|
7
|
+
* and emits provenance, tags, totals, and a trust verdict.
|
|
8
|
+
*
|
|
9
|
+
* An overview carries the working directories the runs executed in, the task
|
|
10
|
+
* text the operator typed, and the file names inside the bundle. None of that
|
|
11
|
+
* appears here. What does is the shape of the artifact and how far it can be
|
|
12
|
+
* trusted, which is what an operator picks a bundle by.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { clioDataDir } from "../core/xdg.js";
|
|
16
|
+
import {
|
|
17
|
+
EVIDENCE_TAGS,
|
|
18
|
+
type EvidenceOverview,
|
|
19
|
+
type EvidenceTag,
|
|
20
|
+
listEvidenceOverviews,
|
|
21
|
+
loadEvidenceTrustStatus,
|
|
22
|
+
type TrustVerdict,
|
|
23
|
+
trustVerdict,
|
|
24
|
+
} from "../domains/evidence/index.js";
|
|
25
|
+
import { sanitizeCallTargetText } from "../domains/safety/call-target.js";
|
|
26
|
+
import { truncateToWidth } from "../engine/tui-primitives.js";
|
|
27
|
+
|
|
28
|
+
export const EVIDENCE_INVENTORY_MAX_ARTIFACTS = 12;
|
|
29
|
+
export const EVIDENCE_INVENTORY_MAX_IDS = 8;
|
|
30
|
+
|
|
31
|
+
const IDENTITY_WIDTH = 128;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Worst verdict first.
|
|
35
|
+
*
|
|
36
|
+
* An artifact covering several runs is only as trustworthy as its weakest run,
|
|
37
|
+
* so the fold takes the worst rather than the newest or the most common. A
|
|
38
|
+
* `compromised` run inside an otherwise clean bundle is the fact the operator
|
|
39
|
+
* needs, and averaging it away would be the one summary worth not printing.
|
|
40
|
+
*/
|
|
41
|
+
const VERDICT_SEVERITY: ReadonlyArray<TrustVerdict> = ["compromised", "unverified", "unknown", "grounded", "reviewed"];
|
|
42
|
+
|
|
43
|
+
export interface EvidenceInventoryArtifact {
|
|
44
|
+
readonly evidenceId: string;
|
|
45
|
+
readonly sourceKind: "run" | "session" | "eval";
|
|
46
|
+
readonly generatedAt: string;
|
|
47
|
+
readonly startedAt: string | null;
|
|
48
|
+
readonly endedAt: string | null;
|
|
49
|
+
readonly runIds: readonly string[];
|
|
50
|
+
readonly runIdsTruncated: boolean;
|
|
51
|
+
readonly agentIds: readonly string[];
|
|
52
|
+
readonly statuses: readonly string[];
|
|
53
|
+
readonly tags: readonly EvidenceTag[];
|
|
54
|
+
readonly totals: Readonly<{
|
|
55
|
+
runs: number;
|
|
56
|
+
receipts: number;
|
|
57
|
+
toolCalls: number;
|
|
58
|
+
toolErrors: number;
|
|
59
|
+
blockedToolCalls: number;
|
|
60
|
+
protectedArtifacts: number;
|
|
61
|
+
tokens: number;
|
|
62
|
+
costUsd: number;
|
|
63
|
+
wallTimeMs: number;
|
|
64
|
+
}>;
|
|
65
|
+
/** Secret-shaped values the builder replaced across the bundle's exports. */
|
|
66
|
+
readonly redactionCount: number;
|
|
67
|
+
readonly trust: Readonly<{
|
|
68
|
+
verdict: TrustVerdict;
|
|
69
|
+
/** Runs whose canonical trust status the bundle actually recorded. */
|
|
70
|
+
runsCovered: number;
|
|
71
|
+
/** True when the bundle predates the canonical trust projection. */
|
|
72
|
+
historical: boolean;
|
|
73
|
+
}>;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface EvidenceInventorySnapshot {
|
|
77
|
+
readonly version: 1;
|
|
78
|
+
readonly generatedAt: string;
|
|
79
|
+
readonly artifacts: readonly EvidenceInventoryArtifact[];
|
|
80
|
+
readonly truncated: boolean;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function bounded(value: string, width: number): string {
|
|
84
|
+
const sanitized = sanitizeCallTargetText(value);
|
|
85
|
+
if (sanitized.length === 0) return "unavailable";
|
|
86
|
+
return sanitizeCallTargetText(truncateToWidth(sanitized, width, "…", false));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** Distinct, sanitized, bounded, in first-seen order. */
|
|
90
|
+
function identities(values: ReadonlyArray<string>): string[] {
|
|
91
|
+
const seen: string[] = [];
|
|
92
|
+
for (const value of values) {
|
|
93
|
+
const text = bounded(value, IDENTITY_WIDTH);
|
|
94
|
+
if (!seen.includes(text)) seen.push(text);
|
|
95
|
+
if (seen.length >= EVIDENCE_INVENTORY_MAX_IDS) break;
|
|
96
|
+
}
|
|
97
|
+
return seen;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function tally(value: number | undefined): number {
|
|
101
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? Math.trunc(value) : 0;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function amount(value: number | undefined): number {
|
|
105
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : 0;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** Newest generation first. An unparseable stamp sorts oldest rather than throwing. */
|
|
109
|
+
function byNewest(a: EvidenceOverview, b: EvidenceOverview): number {
|
|
110
|
+
return (Date.parse(b.generatedAt) || 0) - (Date.parse(a.generatedAt) || 0);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export async function evidenceInventorySnapshot(
|
|
114
|
+
now: () => number = Date.now,
|
|
115
|
+
dataDir: string = clioDataDir(),
|
|
116
|
+
): Promise<EvidenceInventorySnapshot> {
|
|
117
|
+
const all = (await listEvidenceOverviews(dataDir)).sort(byNewest);
|
|
118
|
+
const window = all.slice(0, EVIDENCE_INVENTORY_MAX_ARTIFACTS);
|
|
119
|
+
const artifacts: EvidenceInventoryArtifact[] = [];
|
|
120
|
+
for (const overview of window) {
|
|
121
|
+
// One unreadable trust file costs that artifact its verdict, never the
|
|
122
|
+
// whole inventory: the bundle itself is still the thing being listed.
|
|
123
|
+
let verdict: TrustVerdict = "unknown";
|
|
124
|
+
let runsCovered = 0;
|
|
125
|
+
let historical = true;
|
|
126
|
+
try {
|
|
127
|
+
const status = await loadEvidenceTrustStatus(dataDir, overview.evidenceId);
|
|
128
|
+
historical = status.projection !== "canonical";
|
|
129
|
+
runsCovered = status.runs.length;
|
|
130
|
+
const verdicts = status.runs.map((run) => trustVerdict(run.status));
|
|
131
|
+
verdict = VERDICT_SEVERITY.find((candidate) => verdicts.includes(candidate)) ?? "unknown";
|
|
132
|
+
} catch {
|
|
133
|
+
verdict = "unknown";
|
|
134
|
+
}
|
|
135
|
+
artifacts.push({
|
|
136
|
+
evidenceId: bounded(overview.evidenceId, IDENTITY_WIDTH),
|
|
137
|
+
sourceKind: overview.source.kind,
|
|
138
|
+
generatedAt: overview.generatedAt,
|
|
139
|
+
startedAt: overview.startedAt,
|
|
140
|
+
endedAt: overview.endedAt,
|
|
141
|
+
runIds: identities(overview.runIds),
|
|
142
|
+
runIdsTruncated: overview.runIds.length > EVIDENCE_INVENTORY_MAX_IDS,
|
|
143
|
+
agentIds: identities(overview.agentIds),
|
|
144
|
+
statuses: identities(overview.statuses),
|
|
145
|
+
tags: overview.tags.filter((tag) => EVIDENCE_TAGS.includes(tag)),
|
|
146
|
+
totals: {
|
|
147
|
+
runs: tally(overview.totals.runs),
|
|
148
|
+
receipts: tally(overview.totals.receipts),
|
|
149
|
+
toolCalls: tally(overview.totals.toolCalls),
|
|
150
|
+
toolErrors: tally(overview.totals.toolErrors),
|
|
151
|
+
blockedToolCalls: tally(overview.totals.blockedToolCalls),
|
|
152
|
+
protectedArtifacts: tally(overview.totals.protectedArtifacts),
|
|
153
|
+
tokens: tally(overview.totals.tokens),
|
|
154
|
+
costUsd: amount(overview.totals.costUsd),
|
|
155
|
+
wallTimeMs: tally(overview.totals.wallTimeMs),
|
|
156
|
+
},
|
|
157
|
+
redactionCount: tally(overview.redactionCount),
|
|
158
|
+
trust: { verdict, runsCovered, historical },
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
return {
|
|
162
|
+
version: 1,
|
|
163
|
+
generatedAt: new Date(now()).toISOString(),
|
|
164
|
+
artifacts,
|
|
165
|
+
truncated: all.length > window.length,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* `clio-coder evidence inventory --json`, and nothing else.
|
|
171
|
+
*
|
|
172
|
+
* `fixed` is false as soon as the caller supplied an id or any other argument.
|
|
173
|
+
* A GUI host invokes this knowing the process it started cannot be steered into
|
|
174
|
+
* reading a different bundle or a wider window.
|
|
175
|
+
*/
|
|
176
|
+
export async function runEvidenceInventory(fixed: boolean): Promise<number> {
|
|
177
|
+
if (!fixed) {
|
|
178
|
+
process.stderr.write("clio-coder evidence inventory: usage: clio-coder evidence inventory --json\n");
|
|
179
|
+
return 2;
|
|
180
|
+
}
|
|
181
|
+
process.stdout.write(`${JSON.stringify(await evidenceInventorySnapshot(), null, 2)}\n`);
|
|
182
|
+
return 0;
|
|
183
|
+
}
|
package/src/cli/evidence.ts
CHANGED
|
@@ -12,21 +12,25 @@ import {
|
|
|
12
12
|
loadEvidenceRunProvenance,
|
|
13
13
|
provenanceTranscriptLines,
|
|
14
14
|
} from "../domains/evidence/index.js";
|
|
15
|
+
import { runEvidenceDetail } from "./evidence-detail.js";
|
|
16
|
+
import { runEvidenceInventory } from "./evidence-inventory.js";
|
|
15
17
|
import { printError, printNote, printOk } from "./shared.js";
|
|
16
18
|
|
|
17
19
|
const HELP = `clio-coder evidence build --run <runId>
|
|
18
20
|
clio-coder evidence build --session <sessionId>
|
|
19
21
|
clio-coder evidence build --eval <evalId>
|
|
20
|
-
clio-coder evidence inspect <evidenceId>
|
|
22
|
+
clio-coder evidence inspect <evidenceId> [--json]
|
|
21
23
|
clio-coder evidence list
|
|
24
|
+
clio-coder evidence inventory --json
|
|
22
25
|
|
|
23
26
|
Build or inspect deterministic Clio evidence artifacts.
|
|
24
27
|
`;
|
|
25
28
|
|
|
26
|
-
type EvidenceCommand = "build" | "inspect" | "list";
|
|
29
|
+
type EvidenceCommand = "build" | "inspect" | "list" | "inventory";
|
|
27
30
|
|
|
28
31
|
interface ParsedEvidenceArgs {
|
|
29
32
|
command?: EvidenceCommand;
|
|
33
|
+
json: boolean;
|
|
30
34
|
runId?: string;
|
|
31
35
|
sessionId?: string;
|
|
32
36
|
evalId?: string;
|
|
@@ -35,7 +39,7 @@ interface ParsedEvidenceArgs {
|
|
|
35
39
|
}
|
|
36
40
|
|
|
37
41
|
function parseEvidenceArgs(args: ReadonlyArray<string>): ParsedEvidenceArgs {
|
|
38
|
-
const parsed: ParsedEvidenceArgs = { help: false };
|
|
42
|
+
const parsed: ParsedEvidenceArgs = { help: false, json: false };
|
|
39
43
|
for (let index = 0; index < args.length; index += 1) {
|
|
40
44
|
const arg = args[index];
|
|
41
45
|
if (arg === undefined) continue;
|
|
@@ -44,12 +48,22 @@ function parseEvidenceArgs(args: ReadonlyArray<string>): ParsedEvidenceArgs {
|
|
|
44
48
|
continue;
|
|
45
49
|
}
|
|
46
50
|
if (parsed.command === undefined) {
|
|
47
|
-
if (arg === "build" || arg === "inspect" || arg === "list") {
|
|
51
|
+
if (arg === "build" || arg === "inspect" || arg === "list" || arg === "inventory") {
|
|
48
52
|
parsed.command = arg;
|
|
49
53
|
continue;
|
|
50
54
|
}
|
|
51
55
|
throw new Error(`unknown evidence command: ${arg}`);
|
|
52
56
|
}
|
|
57
|
+
// `inventory` is the fixed read a GUI host may invoke. Its argv is not a
|
|
58
|
+
// surface, so anything past the one required flag is a usage error rather
|
|
59
|
+
// than something to ignore.
|
|
60
|
+
if (parsed.command === "inventory") {
|
|
61
|
+
if (arg === "--json" && !parsed.json) {
|
|
62
|
+
parsed.json = true;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
throw new Error("inventory accepts only --json");
|
|
66
|
+
}
|
|
53
67
|
if (parsed.command === "build") {
|
|
54
68
|
if (arg === "--run") {
|
|
55
69
|
const value = args[index + 1];
|
|
@@ -74,6 +88,10 @@ function parseEvidenceArgs(args: ReadonlyArray<string>): ParsedEvidenceArgs {
|
|
|
74
88
|
}
|
|
75
89
|
throw new Error(`unknown evidence build argument: ${arg}`);
|
|
76
90
|
}
|
|
91
|
+
if (parsed.command === "inspect" && arg === "--json" && !parsed.json) {
|
|
92
|
+
parsed.json = true;
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
77
95
|
if (parsed.command === "inspect" && parsed.evidenceId === undefined) {
|
|
78
96
|
if (arg.startsWith("-")) throw new Error("inspect requires an evidence id");
|
|
79
97
|
parsed.evidenceId = arg;
|
|
@@ -103,6 +121,11 @@ function parseEvidenceArgs(args: ReadonlyArray<string>): ParsedEvidenceArgs {
|
|
|
103
121
|
) {
|
|
104
122
|
throw new Error("list does not accept extra arguments");
|
|
105
123
|
}
|
|
124
|
+
// The GUI read is only fixed if `--json` is required rather than defaulted:
|
|
125
|
+
// a bare `evidence inventory` must not quietly print something else.
|
|
126
|
+
if (parsed.command === "inventory" && !parsed.json) {
|
|
127
|
+
throw new Error("inventory requires --json");
|
|
128
|
+
}
|
|
106
129
|
return parsed;
|
|
107
130
|
}
|
|
108
131
|
|
|
@@ -159,6 +182,7 @@ export async function runEvidenceCommand(args: ReadonlyArray<string>): Promise<n
|
|
|
159
182
|
printError("inspect requires an evidence id");
|
|
160
183
|
return 2;
|
|
161
184
|
}
|
|
185
|
+
if (parsed.json) return runEvidenceDetail(evidenceId);
|
|
162
186
|
const inspected = await inspectEvidence(dataDir, evidenceId);
|
|
163
187
|
const provenance = await loadEvidenceRunProvenance(dataDir, evidenceId);
|
|
164
188
|
renderEvidence(inspected, provenance);
|
|
@@ -168,7 +192,8 @@ export async function runEvidenceCommand(args: ReadonlyArray<string>): Promise<n
|
|
|
168
192
|
renderEvidenceList(await listEvidenceOverviews(dataDir));
|
|
169
193
|
return 0;
|
|
170
194
|
}
|
|
171
|
-
|
|
195
|
+
if (parsed.command === "inventory") return runEvidenceInventory(parsed.json);
|
|
196
|
+
printError("evidence requires build, inspect, list, or inventory");
|
|
172
197
|
return 2;
|
|
173
198
|
} catch (error) {
|
|
174
199
|
printError(error instanceof Error ? error.message : String(error));
|
package/src/cli/extensions.ts
CHANGED
|
@@ -91,6 +91,7 @@ function resourceSummary(extension: InstalledExtension): string {
|
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
function stateLabel(extension: InstalledExtension): string {
|
|
94
|
+
if (!extension.compatible) return "incompatible";
|
|
94
95
|
if (!extension.enabled) return "disabled";
|
|
95
96
|
if (!extension.effective) return `shadowed:${extension.overriddenBy ?? "higher"}`;
|
|
96
97
|
return "active";
|
|
@@ -143,7 +144,10 @@ export function runExtensionsCommand(argv: ReadonlyArray<string>): number {
|
|
|
143
144
|
case "list": {
|
|
144
145
|
const items = listInstalledExtensions(process.cwd(), { ...scopeOptions, all: parsed.all });
|
|
145
146
|
if (parsed.json) process.stdout.write(`${JSON.stringify({ extensions: items }, null, 2)}\n`);
|
|
146
|
-
else
|
|
147
|
+
else {
|
|
148
|
+
printList(items);
|
|
149
|
+
for (const item of items) printDiagnostics(item.diagnostics);
|
|
150
|
+
}
|
|
147
151
|
return 0;
|
|
148
152
|
}
|
|
149
153
|
case "discover": {
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fixed machine-readable projection of durable coordinator gate decisions.
|
|
3
|
+
*
|
|
4
|
+
* A review or compete gate seals an integrity-covered artifact linking the
|
|
5
|
+
* decider receipt to every subject receipt, and nothing in the operator surface
|
|
6
|
+
* reads them: `fleet view` shows a run, not the verdict a gate reached about
|
|
7
|
+
* it. This command accepts no identifier, group, or limit, selects a bounded
|
|
8
|
+
* newest-first window itself, and emits the shape of each decision.
|
|
9
|
+
*
|
|
10
|
+
* It is a separate command from `fleet inspect --json` rather than another
|
|
11
|
+
* field on it, on the same reasoning the trace read used. The decisions live in
|
|
12
|
+
* their own directory with their own failure mode, and an installation that has
|
|
13
|
+
* never run a gate has no directory at all, so folding the read in would turn a
|
|
14
|
+
* missing directory into a failure of the run journal.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import {
|
|
18
|
+
GATE_TOPOLOGY_MAX_DECISIONS,
|
|
19
|
+
GATE_TOPOLOGY_MAX_SUBJECTS,
|
|
20
|
+
type GateDecisionReason,
|
|
21
|
+
type GateTopologyDecision,
|
|
22
|
+
gateTopology,
|
|
23
|
+
} from "../domains/dispatch/gate-topology.js";
|
|
24
|
+
|
|
25
|
+
export {
|
|
26
|
+
GATE_TOPOLOGY_MAX_DECISIONS as FLEET_DECISIONS_MAX,
|
|
27
|
+
GATE_TOPOLOGY_MAX_SUBJECTS as FLEET_DECISIONS_MAX_SUBJECTS,
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export interface FleetDecisionsSnapshot {
|
|
31
|
+
readonly version: 1;
|
|
32
|
+
readonly generatedAt: string;
|
|
33
|
+
readonly available: boolean;
|
|
34
|
+
readonly decisions: readonly GateTopologyDecision[];
|
|
35
|
+
readonly truncated: boolean;
|
|
36
|
+
readonly unverifiable: number;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export type { GateDecisionReason, GateTopologyDecision };
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Pure command payload builder, exported so the fixed CLI contract is testable
|
|
43
|
+
* without subprocess output capture.
|
|
44
|
+
*
|
|
45
|
+
* `available` separates an installation that has never run a gate from one
|
|
46
|
+
* whose gates all aged out of the scan. Both report no decisions and they are
|
|
47
|
+
* different operator states, so the flag is reported rather than inferred from
|
|
48
|
+
* an empty list.
|
|
49
|
+
*/
|
|
50
|
+
export function fleetDecisionsSnapshot(now: () => number = Date.now): FleetDecisionsSnapshot {
|
|
51
|
+
const topology = gateTopology();
|
|
52
|
+
return {
|
|
53
|
+
version: 1,
|
|
54
|
+
generatedAt: new Date(now()).toISOString(),
|
|
55
|
+
available: topology.present,
|
|
56
|
+
decisions: topology.decisions,
|
|
57
|
+
truncated: topology.truncated,
|
|
58
|
+
unverifiable: topology.unverifiable,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function runFleetDecisions(args: ReadonlyArray<string>): number {
|
|
63
|
+
if (args.length !== 1 || args[0] !== "--json") {
|
|
64
|
+
process.stderr.write("clio-coder fleet decisions: usage: clio-coder fleet decisions --json\n");
|
|
65
|
+
return 2;
|
|
66
|
+
}
|
|
67
|
+
process.stdout.write(`${JSON.stringify(fleetDecisionsSnapshot(), null, 2)}\n`);
|
|
68
|
+
return 0;
|
|
69
|
+
}
|