@iowarp/clio-coder 0.3.7 → 0.3.9
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 +80 -0
- package/README.md +13 -4
- package/dist/{acp-SK4MD6MM.js → acp-7LOELQFP.js} +13 -13
- package/dist/{agents-2FN2K6ME.js → agents-FIBG2SHA.js} +41 -37
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-QIYZWM5I.js → auth-OI4LIH2I.js} +31 -24
- package/dist/builtins-AD25UL3C.js +17 -0
- package/dist/{chunk-5FR74PWO.js → chunk-2JDWVJND.js} +2 -2
- package/dist/chunk-3DPEIQKN.js +113 -0
- package/dist/{chunk-EOOQZZDE.js → chunk-3DUR4WUA.js} +19 -19
- package/dist/{chunk-WHJYKASB.js → chunk-3MRC2YSQ.js} +2 -2
- package/dist/{chunk-EBEFWSGL.js → chunk-3UUY7R3Z.js} +14 -10
- package/dist/{chunk-LADCF22A.js → chunk-3V5AYSEQ.js} +113 -54
- package/dist/{chunk-BMWK7ZIZ.js → chunk-465CC7FK.js} +16 -13
- package/dist/{chunk-5WIGXA4T.js → chunk-47CMYGET.js} +111 -4
- package/dist/{chunk-CEYBNUGC.js → chunk-4H6ULJ3H.js} +378 -36
- package/dist/{chunk-YTYFXUI3.js → chunk-4LJX2PUC.js} +9 -9
- package/dist/{chunk-DOOEX22V.js → chunk-56KB5IJP.js} +5 -5
- package/dist/{chunk-SPULKLCF.js → chunk-5DQRIYDZ.js} +2 -2
- package/dist/{chunk-TSHXZTOQ.js → chunk-5HFBWUMU.js} +23 -11
- package/dist/{chunk-5UJ6ECTS.js → chunk-5PVQ4SRS.js} +80 -8
- package/dist/{chunk-ZWLZP4ZT.js → chunk-5QKCQQ3E.js} +359 -17
- package/dist/{chunk-6M7VS3J3.js → chunk-5T7RBWN2.js} +111 -5
- package/dist/chunk-774ILSRL.js +172 -0
- package/dist/chunk-7C6RYZGQ.js +391 -0
- package/dist/{chunk-GH5622CP.js → chunk-A2NJGIB3.js} +2 -2
- package/dist/{chunk-C4JBQ5SR.js → chunk-AD7Y7STJ.js} +6 -6
- package/dist/{chunk-GEYXPTRF.js → chunk-AEYBF3TB.js} +33 -12
- package/dist/{chunk-2SFS6XQE.js → chunk-AMKHQW3C.js} +3 -2
- package/dist/{chunk-D4MDIG46.js → chunk-B5CSFE7B.js} +7 -7
- package/dist/{chunk-MXI6J5JF.js → chunk-B5XRQOLB.js} +10 -10
- package/dist/{chunk-X2KV5FXT.js → chunk-BVDVID7E.js} +2 -2
- package/dist/{chunk-JNXPYBB4.js → chunk-CA42X6KT.js} +3 -3
- package/dist/{chunk-VREKEFLL.js → chunk-D73KXYPF.js} +3 -3
- package/dist/{chunk-JTSEDYVQ.js → chunk-DG4M6ZUE.js} +7 -7
- package/dist/{chunk-DQA7QLMD.js → chunk-EBOC7MT3.js} +10 -25
- package/dist/{chunk-KZ2H5X4G.js → chunk-ECUO3KDP.js} +129 -14
- package/dist/{chunk-JRIO5UD2.js → chunk-EQ63NRB7.js} +5 -5
- package/dist/{chunk-YD734TPH.js → chunk-FALJGAWU.js} +2 -2
- package/dist/{chunk-GWS3VEIW.js → chunk-FWDFM5ZU.js} +24 -3
- package/dist/{chunk-XEGB6BCN.js → chunk-GAYUJ7LE.js} +68 -14
- package/dist/{chunk-UND3GU2L.js → chunk-H7IXIC72.js} +2 -2
- package/dist/{chunk-IR4CFBFN.js → chunk-HAY4ZE2P.js} +12 -12
- package/dist/{chunk-UVDSQ6LW.js → chunk-HCBCAYZU.js} +74 -147
- package/dist/{chunk-4DWFMQDR.js → chunk-HJB5IUKP.js} +89 -145
- package/dist/{chunk-M4AKACEO.js → chunk-HKO36JWF.js} +33 -5
- package/dist/{chunk-KCMKRQX4.js → chunk-HPCTNZM2.js} +45 -82
- package/dist/{chunk-465YSENW.js → chunk-IFBNV6H6.js} +3 -3
- package/dist/{chunk-FJ3H4MN5.js → chunk-IHKBWSXF.js} +2 -2
- package/dist/chunk-JEQQR47K.js +3025 -0
- package/dist/{chunk-FO5ZOVUY.js → chunk-KV2AOLDF.js} +27 -7
- package/dist/chunk-LU7P4LHA.js +33 -0
- package/dist/{chunk-6TUKSZVF.js → chunk-LXPJXFM5.js} +11 -11
- package/dist/{chunk-VQNODYQ4.js → chunk-MIX5N5AC.js} +488 -3668
- package/dist/chunk-MLOK6ZOS.js +2888 -0
- package/dist/{chunk-ZZMN5OM4.js → chunk-MV2VUEJC.js} +2 -2
- package/dist/{chunk-MVVUPGPW.js → chunk-MXHC5QYU.js} +6 -6
- package/dist/{chunk-OBMAI2DP.js → chunk-N3PBVRTZ.js} +12 -388
- package/dist/{chunk-WJHBC77E.js → chunk-N5XKWMDW.js} +17 -7
- package/dist/{chunk-5C3AQNDW.js → chunk-NNNWO6F2.js} +124 -36
- package/dist/{chunk-UFQ3F4FW.js → chunk-NQ6UCCOD.js} +4 -4
- package/dist/chunk-NUGM5KR6.js +165 -0
- package/dist/{chunk-DMD2AGVS.js → chunk-NZU6YDNV.js} +20 -18
- package/dist/{chunk-WHGPSPT5.js → chunk-O6I4CIEU.js} +151 -13
- package/dist/{chunk-XN3L4EYL.js → chunk-OEDBCISO.js} +2 -2
- package/dist/{chunk-PD3MESLB.js → chunk-P3JGPQFL.js} +4 -4
- package/dist/{chunk-UHXRNZ2J.js → chunk-PNY46YEY.js} +23 -6
- package/dist/{chunk-THKY7CD7.js → chunk-PZ4I4JE2.js} +134 -29
- package/dist/{chunk-SROCI7ZU.js → chunk-QQ7EKM72.js} +5 -5
- package/dist/{chunk-QCTRSGHQ.js → chunk-R7LNVMCS.js} +91 -53
- package/dist/{chunk-GOXNB3AO.js → chunk-RAPCMZL4.js} +75 -4
- package/dist/chunk-RKKLTLYB.js +45 -0
- package/dist/{chunk-OB5HIGJY.js → chunk-RKRLDWD3.js} +4 -1
- package/dist/{chunk-DJNLUABN.js → chunk-S4COXYBG.js} +588 -32
- package/dist/{chunk-3HAPLH5M.js → chunk-T3Z6VAAF.js} +172 -11
- package/dist/{chunk-FOT2FX5J.js → chunk-TD7UE2L5.js} +12 -10
- package/dist/{chunk-UUANF5CR.js → chunk-TEO2TLVN.js} +856 -967
- package/dist/{chunk-FCSXB6T2.js → chunk-UOSL25KY.js} +14 -2
- package/dist/{chunk-EELBMBT6.js → chunk-VKBMFOYV.js} +74 -15
- package/dist/chunk-VO2LKSTM.js +165 -0
- package/dist/{chunk-5C77SEEY.js → chunk-VPTUJU4P.js} +3 -3
- package/dist/{chunk-WEH5XRJQ.js → chunk-WIE7ZOSW.js} +2 -2
- package/dist/{chunk-J7PIKKWC.js → chunk-WXCJ7VME.js} +8 -8
- package/dist/{chunk-4DGYLA73.js → chunk-XDOQXGFO.js} +22 -7
- package/dist/{chunk-PPAMZ32Z.js → chunk-XK56QHLX.js} +6 -1
- package/dist/{chunk-AB4XIIVB.js → chunk-YKOFT37S.js} +6 -6
- package/dist/chunk-YSEHGPCT.js +127 -0
- package/dist/{chunk-HFSBBKSQ.js → chunk-YW7UVM5V.js} +138 -3
- package/dist/cli/index.js +32 -32
- package/dist/{clio-WBVQEBKO.js → clio-LT5V7SSZ.js} +9 -9
- package/dist/{code-nav-FGGFIE7L.js → code-nav-LMW275PA.js} +5 -5
- package/dist/codewiki/build-worker.js +4 -4
- package/dist/{components-F7OEATSO.js → components-ZFA3SAER.js} +8 -8
- package/dist/{config-TRBL3RCF.js → config-RXS5T3JT.js} +98 -65
- package/dist/{configure-OLCVPHNM.js → configure-2WYWSCSD.js} +26 -22
- package/dist/{context-MJIJ6GOX.js → context-I3BTOTCS.js} +12 -12
- package/dist/{context-XEWE3MOJ.js → context-MVOORGMF.js} +54 -47
- package/dist/{context-WFPKQSM6.js → context-PALKKQYL.js} +28 -28
- package/dist/{context-clear-KNOS2JPB.js → context-clear-N2WOYZ2K.js} +53 -46
- package/dist/{context-index-SSR5ECNE.js → context-index-HNG3MOME.js} +6 -6
- package/dist/{context-working-set-EUXAZI6N.js → context-working-set-MIEVECVZ.js} +17 -18
- package/dist/{dispatch-runner-B7MTOVKL.js → dispatch-runner-VVA4SRRH.js} +90 -61
- package/dist/{docs-FLJTIDSE.js → docs-7LQ23DLM.js} +8 -8
- package/dist/doctor-TWBWFK5V.js +165 -0
- package/dist/eval-IJ5VEZDJ.js +4483 -0
- package/dist/{evidence-JZNBUOQZ.js → evidence-L5APPXNV.js} +68 -61
- package/dist/{evolve-FJVC4KKI.js → evolve-RGNKFJ52.js} +47 -40
- package/dist/{extensions-IQL36S7K.js → extensions-7WYWUX5A.js} +13 -7
- package/dist/{fleet-BDKYJFCP.js → fleet-6CNVBZZP.js} +113 -76
- package/dist/{fleet-commands-ZFIWZSB3.js → fleet-commands-L2SXSYEI.js} +10 -10
- package/dist/{fleet-graph-Y6HPXIVF.js → fleet-graph-2J3OOIPO.js} +17 -15
- package/dist/{fleet-preflight-BHSNPBMH.js → fleet-preflight-CZRJ4JP5.js} +5 -6
- package/dist/{fleet-validate-BIYREGIK.js → fleet-validate-C5RI6DP7.js} +20 -19
- package/dist/{init-LQUB5COQ.js → init-VBN2ACVA.js} +70 -63
- package/dist/{library-NJAHIGG4.js → library-JHGUMLY2.js} +22 -20
- package/dist/{memory-OG6HOYKM.js → memory-K4OQIYWG.js} +49 -42
- package/dist/{models-5ZG5XY7J.js → models-2NCZUWDD.js} +35 -29
- package/dist/{monitor-TJ7AMTGB.js → monitor-MMVTJABD.js} +64 -45
- package/dist/{orchestrator-WZYB54DM.js → orchestrator-ZKBPCHW6.js} +1971 -520
- package/dist/{paths-XUC7GS6E.js → paths-DBXMZMDU.js} +5 -5
- package/dist/registry-LG64LTF4.js +11 -0
- package/dist/{reset-PXQT45IY.js → reset-DD5JGOY3.js} +11 -11
- package/dist/{run-FQ74YF62.js → run-QEGNX7FL.js} +89 -83
- package/dist/{share-FW7SVCL3.js → share-JKD3BQMW.js} +20 -18
- package/dist/{skills-7E7IRB3R.js → skills-LMQIKDOZ.js} +23 -21
- package/dist/{skills-eval-LI75W6OK.js → skills-eval-I7X2774U.js} +59 -52
- package/dist/{steer-GGWFUJUD.js → steer-CF5TDANS.js} +3 -3
- package/dist/support-I7LOJLIF.js +38 -0
- package/dist/{targets-4CIFKCTW.js → targets-RUSR6B5Z.js} +77 -42
- package/dist/{terminal-lease-WUZY7ZV5.js → terminal-lease-QYVORFR4.js} +6 -4
- package/dist/{trace-PNCASAXC.js → trace-ODOQIVIW.js} +61 -6
- package/dist/{uninstall-7FV7IP4E.js → uninstall-ZJF5H5ZN.js} +8 -8
- package/dist/{upgrade-K2HVIVMQ.js → upgrade-XANW3FXB.js} +29 -26
- package/dist/{usage-GTZELZQX.js → usage-4H7ZRXQT.js} +110 -61
- package/dist/{verifiers-RLAHT27O.js → verifiers-UZXNBZEB.js} +13 -13
- package/dist/{verify-BX3BRKH5.js → verify-BVKWTNDL.js} +9 -9
- package/dist/{wiki-generate-ASIFASCN.js → wiki-generate-MY7WV2QI.js} +76 -69
- package/dist/worker/entry.js +69 -66
- package/docs/alcf-provider.md +1 -1
- package/docs/architecture.md +1 -1
- package/docs/artifact-versions.md +11 -5
- package/docs/built-in-agents.md +1 -1
- package/docs/capacity-and-scheduling.md +23 -2
- package/docs/commands-and-modes.md +2 -2
- package/docs/configuration-and-targets.md +37 -5
- package/docs/context-engine.md +63 -4
- package/docs/documentation-coverage.md +3 -3
- package/docs/documentation-guide.md +1 -1
- package/docs/environment-variables.md +2 -0
- package/docs/eval-runner.md +262 -11
- package/docs/evals-internal.md +72 -2
- package/docs/evidence-and-memory.md +77 -12
- package/docs/evolution.md +1 -1
- package/docs/extensions-and-sharing.md +3 -1
- package/docs/fleet-dispatch.md +34 -9
- package/docs/glossary.md +21 -1
- package/docs/installation-and-lifecycle.md +1 -1
- package/docs/middleware-and-components.md +1 -1
- package/docs/model-catalog.md +1 -1
- package/docs/observability.md +54 -3
- package/docs/proactive-memory.md +127 -14
- package/docs/prompt-envelope-and-tools.md +22 -2
- package/docs/provider-adapter-cookbook.md +1 -1
- package/docs/release-cut-checklist.md +60 -41
- package/docs/safety-model.md +1 -1
- package/docs/scientific-validation.md +1 -1
- package/docs/skills-marketplace.md +1 -1
- package/docs/tool-usage.md +1 -1
- package/docs/trace-store.md +1 -1
- package/docs/troubleshooting.md +87 -0
- package/docs/tui-design.md +1 -1
- package/docs/worker-dispatch-mechanics.md +1 -1
- package/package.json +2 -2
- package/src/cli/agents.ts +1 -1
- package/src/cli/argv.ts +5 -0
- package/src/cli/config-inspect.ts +33 -6
- package/src/cli/config.ts +1 -1
- package/src/cli/configure.ts +107 -23
- package/src/cli/doctor-state-size.ts +82 -0
- package/src/cli/doctor.ts +7 -1
- package/src/cli/eval.ts +80 -16
- package/src/cli/evidence.ts +30 -25
- package/src/cli/extensions.ts +5 -1
- package/src/cli/fleet-preflight.ts +2 -12
- package/src/cli/fleet.ts +32 -3
- package/src/cli/shared.ts +1 -0
- package/src/cli/targets.ts +45 -11
- package/src/cli/trace.ts +63 -4
- package/src/cli/usage.ts +63 -14
- package/src/cli/validate-model.ts +60 -5
- package/src/core/bus-events.ts +54 -1
- package/src/core/cache-telemetry.ts +42 -0
- package/src/core/commit-attribution.ts +4 -4
- package/src/core/config.ts +18 -0
- package/src/core/defaults.ts +36 -6
- package/src/core/endpoint-key.ts +27 -0
- package/src/core/path-boundary.ts +100 -0
- package/src/core/residency-target-key.ts +25 -0
- package/src/core/response-schema.ts +36 -2
- package/src/domains/agents/extension.ts +2 -11
- package/src/domains/agents/fleet-contract.ts +30 -12
- package/src/domains/agents/recipe.ts +7 -1
- package/src/domains/agents/registry.ts +73 -5
- package/src/domains/agents/result-contract.ts +128 -17
- package/src/domains/agents/write-boundary.ts +15 -50
- package/src/domains/config/classify.ts +3 -0
- package/src/domains/context/codewiki/coordinator.ts +12 -4
- package/src/domains/context/project-rules.ts +51 -1
- package/src/domains/dispatch/admission.ts +40 -3
- package/src/domains/dispatch/assignment-reconcile.ts +22 -5
- package/src/domains/dispatch/assignment-store.ts +151 -14
- package/src/domains/dispatch/capacity-lease.ts +98 -9
- package/src/domains/dispatch/contract.ts +26 -1
- package/src/domains/dispatch/delegation-plan.ts +2 -5
- package/src/domains/dispatch/execution-plan.ts +44 -4
- package/src/domains/dispatch/execution-role.ts +9 -1
- package/src/domains/dispatch/extension.ts +309 -96
- package/src/domains/dispatch/fleet-run.ts +78 -4
- package/src/domains/dispatch/gate-role-prompts.ts +38 -0
- package/src/domains/dispatch/heartbeat.ts +32 -8
- package/src/domains/dispatch/index.ts +6 -1
- package/src/domains/dispatch/intent-requirements.ts +40 -0
- package/src/domains/dispatch/intent.ts +84 -8
- package/src/domains/dispatch/orphan-recovery.ts +5 -0
- package/src/domains/dispatch/path-scope.ts +370 -0
- package/src/domains/dispatch/receipt-integrity.ts +2 -1
- package/src/domains/dispatch/reservation-store.ts +116 -8
- package/src/domains/dispatch/state.ts +4 -0
- package/src/domains/dispatch/types.ts +14 -7
- package/src/domains/dispatch/validation.ts +6 -3
- package/src/domains/dispatch/worker-spawn.ts +25 -11
- package/src/domains/dispatch/write-boundary-enforcer.ts +62 -0
- package/src/domains/dispatch/write-boundary.ts +262 -22
- 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 +355 -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/metrics/aggregate.ts +136 -0
- package/src/domains/eval/metrics/call-ledger-stream.ts +112 -0
- package/src/domains/eval/metrics/evidence.ts +79 -2
- 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 +139 -2
- 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 +74 -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 +68 -21
- package/src/domains/evidence/eval.ts +2 -12
- package/src/domains/evidence/findings-markdown.ts +33 -0
- package/src/domains/evidence/index.ts +21 -0
- package/src/domains/evidence/provenance.ts +46 -11
- package/src/domains/evidence/run-trust.ts +7 -113
- package/src/domains/evidence/trust-projection.ts +274 -0
- package/src/domains/evidence/trust-status.ts +145 -17
- package/src/domains/evidence/types.ts +4 -0
- package/src/domains/extensions/compatibility.ts +285 -0
- package/src/domains/extensions/discovery.ts +126 -4
- package/src/domains/extensions/resources.ts +21 -9
- package/src/domains/extensions/state.ts +18 -5
- package/src/domains/extensions/types.ts +6 -1
- package/src/domains/lifecycle/doctor.ts +209 -2
- package/src/domains/memory/index.ts +14 -0
- package/src/domains/memory/task-bank-promotion.ts +64 -0
- package/src/domains/memory/task-memory-policy.ts +77 -8
- 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 +2 -0
- package/src/domains/middleware/index.ts +1 -0
- package/src/domains/middleware/memory-intervention.ts +69 -5
- package/src/domains/middleware/memory-step-endpoint.ts +71 -0
- package/src/domains/observability/background-memory-usage.ts +140 -0
- package/src/domains/observability/cost.ts +1 -1
- package/src/domains/observability/index.ts +7 -0
- package/src/domains/observability/out-of-turn-usage.ts +51 -2
- package/src/domains/observability/trace-store.ts +192 -2
- package/src/domains/prompts/compiler.ts +100 -13
- package/src/domains/prompts/contract.ts +3 -5
- package/src/domains/providers/endpoint-capacity.ts +96 -0
- package/src/domains/providers/extension.ts +30 -2
- package/src/domains/providers/index.ts +10 -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/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/types/capability-flags.ts +2 -0
- package/src/domains/providers/types/target-descriptor.ts +2 -0
- package/src/domains/resources/common-loader.ts +3 -0
- package/src/domains/resources/prompts/loader.ts +184 -17
- package/src/domains/safety/call-target.ts +52 -0
- package/src/domains/safety/policy-engine.ts +5 -5
- package/src/domains/safety/run-effects.ts +96 -2
- package/src/domains/safety/scope.ts +7 -12
- 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/engine/acp/adapter.ts +18 -3
- package/src/engine/acp/server.ts +4 -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/prompt-templates.ts +18 -1
- package/src/engine/provider-payload.ts +29 -1
- package/src/engine/worker-runtime.ts +6 -3
- package/src/entry/orchestrator.ts +176 -30
- 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 +40 -10
- package/src/interactive/cost-overlay.ts +64 -6
- package/src/interactive/dispatch-board.ts +127 -5
- package/src/interactive/fleet-run-preview.ts +41 -15
- package/src/interactive/handoff-round.ts +41 -2
- package/src/interactive/interactive-application.ts +24 -1
- package/src/interactive/interactive-event-projection.ts +14 -0
- package/src/interactive/interactive-input-runtime.ts +8 -0
- package/src/interactive/interactive-presentation.ts +4 -0
- package/src/interactive/interactive-shell.ts +20 -17
- package/src/interactive/interactive-slash-runtime.ts +27 -4
- package/src/interactive/memory-overlay.ts +8 -0
- package/src/interactive/mutation-preview.ts +295 -0
- package/src/interactive/overlay-general-openers.ts +16 -0
- package/src/interactive/overlay-key-routing.ts +38 -0
- package/src/interactive/overlay-lifecycle.ts +38 -5
- package/src/interactive/overlay-permission-lifecycle.ts +22 -2
- package/src/interactive/overlay-session-lifecycle.ts +73 -9
- package/src/interactive/overlays/ask-user.ts +91 -19
- package/src/interactive/overlays/help-reference.ts +4 -0
- package/src/interactive/overlays/prompts.ts +11 -1
- package/src/interactive/overlays/settings.ts +176 -48
- 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/tool-execution.ts +4 -0
- package/src/interactive/side-question.ts +58 -1
- package/src/interactive/slash-commands.ts +7 -2
- 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/terminal-lease.ts +2 -0
- package/src/interactive/turn-context.ts +299 -31
- 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 +42 -9
- package/src/interactive/view/view-overlay.ts +43 -6
- package/src/interactive/worker-receipts.ts +14 -2
- package/src/interactive/worker-stream.ts +8 -0
- package/src/tools/ask-user.ts +43 -2
- package/src/tools/dispatch-admission.ts +12 -13
- package/src/tools/dispatch-arguments.ts +27 -0
- package/src/tools/dispatch-plan.ts +46 -9
- package/src/tools/dispatch-runner.ts +48 -13
- package/src/tools/dispatch-scout.ts +1 -1
- package/src/tools/monitor.ts +13 -0
- package/src/tools/registry.ts +16 -0
- package/src/tools/worker-evidence.ts +19 -13
- package/src/worker/spec-contract.ts +2 -1
- package/dist/chunk-AOCYTWAV.js +0 -449
- package/dist/chunk-HWUFFB6L.js +0 -83
- package/dist/chunk-R346GLFC.js +0 -31
- package/dist/chunk-ZGH7FGS5.js +0 -1079
- package/dist/doctor-RN4YKO2X.js +0 -87
- package/dist/eval-RUBJVSNQ.js +0 -2557
package/src/cli/evidence.ts
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import { InvalidIdError } from "../core/safe-id.js";
|
|
2
2
|
import { clioDataDir, clioStateDir } from "../core/xdg.js";
|
|
3
|
-
import type {
|
|
3
|
+
import type { EvidenceOverview, EvidenceRunProvenance } from "../domains/evidence/index.js";
|
|
4
4
|
import {
|
|
5
5
|
buildEvalEvidence,
|
|
6
6
|
buildEvidence,
|
|
7
7
|
EvidenceNotFoundError,
|
|
8
|
+
formatTrustAxes,
|
|
9
|
+
formatTrustSummary,
|
|
8
10
|
inspectEvidence,
|
|
9
11
|
listEvidenceOverviews,
|
|
10
12
|
loadEvidenceRunProvenance,
|
|
11
13
|
provenanceTranscriptLines,
|
|
12
14
|
} from "../domains/evidence/index.js";
|
|
13
|
-
import { printError, printOk } from "./shared.js";
|
|
15
|
+
import { printError, printNote, printOk } from "./shared.js";
|
|
14
16
|
|
|
15
17
|
const HELP = `clio-coder evidence build --run <runId>
|
|
16
18
|
clio-coder evidence build --session <sessionId>
|
|
@@ -137,15 +139,19 @@ export async function runEvidenceCommand(args: ReadonlyArray<string>): Promise<n
|
|
|
137
139
|
// but the verdict line and exit code must not say ok over a receipt
|
|
138
140
|
// that failed integrity verification.
|
|
139
141
|
const integrityFailures = result.findings.filter((entry) => entry.tag === "receipt-integrity");
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
142
|
+
// A retired seal is the expected state of every run that predates an
|
|
143
|
+
// integrity bump: the receipt is set aside unread, as a missing one
|
|
144
|
+
// is, so it is a note beside the verdict and leaves the exit code alone.
|
|
145
|
+
const retiredSeals = result.findings.filter((entry) => entry.tag === "receipt-retired");
|
|
146
|
+
if (integrityFailures.length > 0) process.stdout.write(`wrote ${result.evidenceId} ${result.directory}\n`);
|
|
147
|
+
else printOk(`wrote ${result.evidenceId} ${result.directory}`);
|
|
148
|
+
for (const entry of retiredSeals) {
|
|
149
|
+
printNote(`${entry.runId !== null ? `run ${entry.runId}: ` : ""}${entry.message}`);
|
|
146
150
|
}
|
|
147
|
-
|
|
148
|
-
|
|
151
|
+
for (const failure of integrityFailures) {
|
|
152
|
+
printError(`${failure.runId !== null ? `run ${failure.runId}: ` : ""}${failure.message}`);
|
|
153
|
+
}
|
|
154
|
+
return integrityFailures.length > 0 ? 1 : 0;
|
|
149
155
|
}
|
|
150
156
|
if (parsed.command === "inspect") {
|
|
151
157
|
const evidenceId = parsed.evidenceId;
|
|
@@ -191,30 +197,29 @@ function renderEvidence(
|
|
|
191
197
|
if (trustStatus.projection === "historical_format") {
|
|
192
198
|
process.stdout.write("trust status: unavailable (historical bundle without canonical projection)\n");
|
|
193
199
|
} else {
|
|
200
|
+
// The compact projection answers the trust questions; the canonical axis
|
|
201
|
+
// line beneath it is the drill-down, in the same form the dispatch tool
|
|
202
|
+
// and monitor print.
|
|
194
203
|
for (const run of trustStatus.runs) {
|
|
195
|
-
process.stdout.write(`trust ${run.runId}: ${
|
|
204
|
+
process.stdout.write(`trust ${run.runId}: ${formatTrustSummary(run.status)}\n`);
|
|
205
|
+
process.stdout.write(` ${formatTrustAxes(run.status)}\n`);
|
|
196
206
|
}
|
|
197
207
|
}
|
|
198
|
-
// Provenance is
|
|
199
|
-
//
|
|
208
|
+
// Provenance is the detail behind the projection, never a second reading
|
|
209
|
+
// of it: each run's block is gated on that run's canonical status, so a
|
|
210
|
+
// receipt the projection withheld (a broken or retired seal) prints no
|
|
211
|
+
// autonomy value here, and a run whose block would be empty prints no
|
|
212
|
+
// header. A historical bundle has no projection and admits no axis detail.
|
|
213
|
+
const statusByRun = new Map(trustStatus.runs.map((entry) => [entry.runId, entry.status]));
|
|
200
214
|
for (const { runId, view } of provenance) {
|
|
215
|
+
const lines = provenanceTranscriptLines(view, statusByRun.get(runId));
|
|
216
|
+
if (lines.length === 0) continue;
|
|
201
217
|
process.stdout.write(`provenance ${runId}:\n`);
|
|
202
|
-
for (const line of
|
|
218
|
+
for (const line of lines) process.stdout.write(` ${line}\n`);
|
|
203
219
|
}
|
|
204
220
|
process.stdout.write(`files: ${formatList(overview.files)}\n`);
|
|
205
221
|
}
|
|
206
222
|
|
|
207
|
-
function formatTrustStatus(status: CanonicalTrustStatus): string {
|
|
208
|
-
return [
|
|
209
|
-
`artifactIntegrity=${status.artifactIntegrity.state}`,
|
|
210
|
-
`validationGrounding=${status.validationGrounding.state}`,
|
|
211
|
-
`independentReview=${status.independentReview.state}`,
|
|
212
|
-
`contextProvenance=${status.contextProvenance.state}`,
|
|
213
|
-
`autonomyEnforcement=${status.autonomyEnforcement.state}`,
|
|
214
|
-
`completionEvidence=${status.completionEvidence.state}`,
|
|
215
|
-
].join(" ");
|
|
216
|
-
}
|
|
217
|
-
|
|
218
223
|
function renderEvidenceList(overviews: ReadonlyArray<EvidenceOverview>): void {
|
|
219
224
|
process.stdout.write(`${overviews.length} evidence artifacts\n`);
|
|
220
225
|
if (overviews.length === 0) return;
|
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": {
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import { join } from "node:path";
|
|
2
1
|
import { readSettings } from "../core/config.js";
|
|
3
|
-
import { resolvePackageRoot } from "../core/package-root.js";
|
|
4
|
-
import { clioConfigDir } from "../core/xdg.js";
|
|
5
2
|
import {
|
|
6
3
|
type FleetCommandRegistry,
|
|
7
4
|
type FleetContract,
|
|
@@ -9,7 +6,7 @@ import {
|
|
|
9
6
|
loadFleetContract,
|
|
10
7
|
renderFleetPrompt,
|
|
11
8
|
} from "../domains/agents/index.js";
|
|
12
|
-
import {
|
|
9
|
+
import { discoverAgentRecipes } from "../domains/agents/registry.js";
|
|
13
10
|
import { type AgentSpec, normalizeAgentSpec } from "../domains/agents/spec.js";
|
|
14
11
|
import type { ExecutionPlan } from "../domains/dispatch/execution-plan.js";
|
|
15
12
|
import { requestExecutionRole, withAttemptRole } from "../domains/dispatch/execution-role.js";
|
|
@@ -23,14 +20,7 @@ export interface FleetPreflightResult {
|
|
|
23
20
|
}
|
|
24
21
|
|
|
25
22
|
function discoverSpecs(cwd: string): AgentSpec[] {
|
|
26
|
-
|
|
27
|
-
const builtin = loadRecipesFromDir(
|
|
28
|
-
{ dir: join(resolvePackageRoot(), "src", "domains", "agents", "builtins"), source: "builtin" },
|
|
29
|
-
diagnostics,
|
|
30
|
-
);
|
|
31
|
-
const user = loadRecipesFromDir({ dir: join(clioConfigDir(), "agents"), source: "user" }, diagnostics);
|
|
32
|
-
const project = loadRecipesFromDir({ dir: join(cwd, ".clio-coder", "agents"), source: "project" }, diagnostics);
|
|
33
|
-
return mergeRecipes(builtin, user, project).map(normalizeAgentSpec);
|
|
23
|
+
return discoverAgentRecipes(cwd).map(normalizeAgentSpec);
|
|
34
24
|
}
|
|
35
25
|
|
|
36
26
|
export function inspectFleet(name: string, vars?: Readonly<Record<string, string>>): FleetPreflightResult {
|
package/src/cli/fleet.ts
CHANGED
|
@@ -47,8 +47,8 @@ import {
|
|
|
47
47
|
type RunToolBudgetEnvelope,
|
|
48
48
|
} from "../domains/dispatch/budget-envelope.js";
|
|
49
49
|
import { type CapacityDrain, capacityDrain, setCapacityDraining } from "../domains/dispatch/capacity-lease.js";
|
|
50
|
-
import type { DispatchContract } from "../domains/dispatch/contract.js";
|
|
51
|
-
import type
|
|
50
|
+
import type { DispatchContract, DispatchRequest } from "../domains/dispatch/contract.js";
|
|
51
|
+
import { bindExecutionPlanEndpoints, type ExecutionPlan } from "../domains/dispatch/execution-plan.js";
|
|
52
52
|
import { agentRoleFactsResolver, requestExecutionRole, withAttemptRole } from "../domains/dispatch/execution-role.js";
|
|
53
53
|
import { compileFleetExecutionPlan } from "../domains/dispatch/fleet-plan.js";
|
|
54
54
|
import {
|
|
@@ -67,7 +67,7 @@ import { ensureClioState, LifecycleDomainModule } from "../domains/lifecycle/ind
|
|
|
67
67
|
import { MiddlewareDomainModule } from "../domains/middleware/index.js";
|
|
68
68
|
import { ObservabilityDomainModule } from "../domains/observability/index.js";
|
|
69
69
|
import { createPromptsDomainModule } from "../domains/prompts/index.js";
|
|
70
|
-
import { ProvidersDomainModule } from "../domains/providers/index.js";
|
|
70
|
+
import { foregroundStreamUsage, ProvidersDomainModule } from "../domains/providers/index.js";
|
|
71
71
|
import { ResourcesDomainModule } from "../domains/resources/index.js";
|
|
72
72
|
import type { SafetyContract } from "../domains/safety/contract.js";
|
|
73
73
|
import { SafetyDomainModule } from "../domains/safety/index.js";
|
|
@@ -372,6 +372,35 @@ async function runFleet(args: ReadonlyArray<string>): Promise<number> {
|
|
|
372
372
|
await loaded.stop();
|
|
373
373
|
return fail(err instanceof Error ? err.message : String(err));
|
|
374
374
|
}
|
|
375
|
+
if (dispatch.preview !== undefined) {
|
|
376
|
+
try {
|
|
377
|
+
const foreground = foregroundStreamUsage();
|
|
378
|
+
const bindings: Record<string, { key: string; limit: number; foregroundHeld?: number } | undefined> = {};
|
|
379
|
+
for (const step of plan.steps) {
|
|
380
|
+
if (step.kind === "code") continue;
|
|
381
|
+
const request: DispatchRequest = {
|
|
382
|
+
agentId: step.agentId,
|
|
383
|
+
executionRole: step.executionRole,
|
|
384
|
+
task: step.task,
|
|
385
|
+
...(step.scope === "readonly" ? { autonomy: "read-only" as const } : {}),
|
|
386
|
+
...(step.target !== undefined ? { target: step.target } : {}),
|
|
387
|
+
...(step.profile !== undefined ? { workerProfile: step.profile } : {}),
|
|
388
|
+
};
|
|
389
|
+
const endpoint = dispatch.preview(request).endpoint;
|
|
390
|
+
if (endpoint === undefined) continue;
|
|
391
|
+
const foregroundHeld = foreground[endpoint.key] ?? 0;
|
|
392
|
+
bindings[step.id] = {
|
|
393
|
+
key: endpoint.key,
|
|
394
|
+
limit: endpoint.limit,
|
|
395
|
+
...(foregroundHeld > 0 ? { foregroundHeld } : {}),
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
plan = bindExecutionPlanEndpoints(plan, bindings);
|
|
399
|
+
} catch (err) {
|
|
400
|
+
await loaded.stop();
|
|
401
|
+
return fail(`route preflight failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
375
404
|
try {
|
|
376
405
|
preflightWriteBoundaries(plan, process.cwd());
|
|
377
406
|
} catch (err) {
|
package/src/cli/shared.ts
CHANGED
package/src/cli/targets.ts
CHANGED
|
@@ -14,6 +14,7 @@ import { ConfigDomainModule } from "../domains/config/index.js";
|
|
|
14
14
|
import { ensureClioState } from "../domains/lifecycle/index.js";
|
|
15
15
|
import type { ProvidersContract, TargetStatus } from "../domains/providers/contract.js";
|
|
16
16
|
import {
|
|
17
|
+
endpointCapacityForStatus,
|
|
17
18
|
isDispatchEligibleRuntime,
|
|
18
19
|
isOrchestratorEligibleRuntime,
|
|
19
20
|
ProvidersDomainModule,
|
|
@@ -24,7 +25,7 @@ import type { CapabilityFlags } from "../domains/providers/types/capability-flag
|
|
|
24
25
|
import type { RuntimeTier } from "../domains/providers/types/runtime-descriptor.js";
|
|
25
26
|
import { runConfigureCommand, runTargetRemove, runTargetRename } from "./configure.js";
|
|
26
27
|
import { printError, printOk } from "./shared.js";
|
|
27
|
-
import { column, terminalColumns, truncate } from "./text-layout.js";
|
|
28
|
+
import { column, terminalColumns, truncate, wrapPlain } from "./text-layout.js";
|
|
28
29
|
|
|
29
30
|
const HEADER: ReadonlyArray<string> = ["id", "tier", "runtime", "auth", "url", "model", "health", "caps", "notes"];
|
|
30
31
|
type ProviderOutputTier = RuntimeTier | "unknown";
|
|
@@ -805,9 +806,11 @@ export interface TargetTableRow {
|
|
|
805
806
|
health: string;
|
|
806
807
|
caps: string;
|
|
807
808
|
notes: string;
|
|
809
|
+
/** Full degraded-health reason, kept separately so a narrow table can repeat it below the row. */
|
|
810
|
+
diagnostic?: string;
|
|
808
811
|
}
|
|
809
812
|
|
|
810
|
-
type TargetTableColumn = keyof TargetTableRow
|
|
813
|
+
type TargetTableColumn = Exclude<keyof TargetTableRow, "diagnostic">;
|
|
811
814
|
type TargetTableWidths = Record<TargetTableColumn, number>;
|
|
812
815
|
|
|
813
816
|
const TABLE_COLUMNS: ReadonlyArray<TargetTableColumn> = [
|
|
@@ -918,20 +921,35 @@ export function formatTargetTable(
|
|
|
918
921
|
rows: ReadonlyArray<TargetTableRow>,
|
|
919
922
|
width: number,
|
|
920
923
|
paintHealth: (cell: string, row: TargetTableRow) => string = (cell) => cell,
|
|
921
|
-
): { header: string; rows: ReadonlyArray<string
|
|
924
|
+
): { header: string; rows: ReadonlyArray<string>; details: ReadonlyArray<ReadonlyArray<string>> } {
|
|
922
925
|
const widths = tableWidths(rows, width);
|
|
923
926
|
const line = (cells: ReadonlyArray<string>): string => cells.join(" ".repeat(TABLE_GAP)).trimEnd();
|
|
927
|
+
const formatted = rows.map((row) => {
|
|
928
|
+
const cells = TABLE_COLUMNS.map((key) => column(row[key], widths[key]));
|
|
929
|
+
const plain = line(cells);
|
|
930
|
+
const rendered =
|
|
931
|
+
plain.length > width
|
|
932
|
+
? truncate(plain, width)
|
|
933
|
+
: line(cells.map((cell, index) => (TABLE_COLUMNS[index] === "health" ? paintHealth(cell, row) : cell)));
|
|
934
|
+
const diagnosticFits = !row.diagnostic || (plain.length <= width && widths.notes >= row.diagnostic.length);
|
|
935
|
+
const details = diagnosticFits ? [] : targetDiagnosticDetails(row.diagnostic ?? "", width);
|
|
936
|
+
return { rendered, details };
|
|
937
|
+
});
|
|
924
938
|
return {
|
|
925
939
|
header: truncate(line(TABLE_COLUMNS.map((key, index) => column(HEADER[index] ?? key, widths[key]))), width),
|
|
926
|
-
rows:
|
|
927
|
-
|
|
928
|
-
const plain = line(cells);
|
|
929
|
-
if (plain.length > width) return truncate(plain, width);
|
|
930
|
-
return line(cells.map((cell, index) => (TABLE_COLUMNS[index] === "health" ? paintHealth(cell, row) : cell)));
|
|
931
|
-
}),
|
|
940
|
+
rows: formatted.map(({ rendered }) => rendered),
|
|
941
|
+
details: formatted.map(({ details }) => details),
|
|
932
942
|
};
|
|
933
943
|
}
|
|
934
944
|
|
|
945
|
+
/** Indented diagnostic text that retains every word when the table row cannot. */
|
|
946
|
+
function targetDiagnosticDetails(diagnostic: string, width: number): string[] {
|
|
947
|
+
const indent = 2;
|
|
948
|
+
return wrapPlain(`reason: ${diagnostic}`, Math.max(8, width - indent), indent).map((line, index) =>
|
|
949
|
+
index === 0 ? `${" ".repeat(indent)}${line}` : line,
|
|
950
|
+
);
|
|
951
|
+
}
|
|
952
|
+
|
|
935
953
|
function renderTable(providers: ProvidersContract, entries: ReadonlyArray<TargetStatus>): void {
|
|
936
954
|
const sorted = [...entries].sort(compareStatusByTier);
|
|
937
955
|
const table = formatTargetTable(
|
|
@@ -950,10 +968,12 @@ function renderTable(providers: ProvidersContract, entries: ReadonlyArray<Target
|
|
|
950
968
|
process.stdout.write(`${chalk.bold(table.header)}\n`);
|
|
951
969
|
}
|
|
952
970
|
process.stdout.write(`${table.rows[index] ?? ""}\n`);
|
|
971
|
+
for (const detail of table.details[index] ?? []) process.stdout.write(`${detail}\n`);
|
|
953
972
|
}
|
|
954
973
|
}
|
|
955
974
|
|
|
956
|
-
function targetTableRow(providers: ProvidersContract, status: TargetStatus): TargetTableRow {
|
|
975
|
+
export function targetTableRow(providers: ProvidersContract, status: TargetStatus): TargetTableRow {
|
|
976
|
+
const diagnostic = degradedHealthDiagnostic(status);
|
|
957
977
|
return {
|
|
958
978
|
id: status.target.id,
|
|
959
979
|
tier: statusTier(status),
|
|
@@ -964,6 +984,7 @@ function targetTableRow(providers: ProvidersContract, status: TargetStatus): Tar
|
|
|
964
984
|
health: status.health.status,
|
|
965
985
|
caps: capabilityBadges(status.capabilities),
|
|
966
986
|
notes: formatNotes(status),
|
|
987
|
+
...(diagnostic ? { diagnostic } : {}),
|
|
967
988
|
};
|
|
968
989
|
}
|
|
969
990
|
|
|
@@ -1044,8 +1065,14 @@ export function formatContextWindow(
|
|
|
1044
1065
|
: `ctx ${window}`;
|
|
1045
1066
|
}
|
|
1046
1067
|
|
|
1047
|
-
function formatNotes(status: TargetStatus): string {
|
|
1068
|
+
export function formatNotes(status: TargetStatus): string {
|
|
1048
1069
|
const parts: string[] = [];
|
|
1070
|
+
const diagnostic = degradedHealthDiagnostic(status);
|
|
1071
|
+
// The health diagnosis leads because gateway, context, and residency facts
|
|
1072
|
+
// are supplementary once the target says it cannot serve its default model.
|
|
1073
|
+
if (diagnostic) parts.push(diagnostic);
|
|
1074
|
+
const endpoint = endpointCapacityForStatus(status);
|
|
1075
|
+
if (endpoint) parts.push(`slots ${endpoint.limit}`);
|
|
1049
1076
|
if (status.target.gateway) parts.push("gateway");
|
|
1050
1077
|
if (status.runtime?.auth === "oauth") parts.push("oauth");
|
|
1051
1078
|
if (status.runtime?.auth === "claude-cli") parts.push("claude-cli");
|
|
@@ -1057,6 +1084,10 @@ function formatNotes(status: TargetStatus): string {
|
|
|
1057
1084
|
return parts.join(" ");
|
|
1058
1085
|
}
|
|
1059
1086
|
|
|
1087
|
+
function degradedHealthDiagnostic(status: TargetStatus): string | null {
|
|
1088
|
+
return status.health.status === "degraded" && status.health.lastError ? status.health.lastError : null;
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1060
1091
|
function statusTier(status: TargetStatus): ProviderOutputTier {
|
|
1061
1092
|
return status.runtime?.tier ?? "unknown";
|
|
1062
1093
|
}
|
|
@@ -1117,6 +1148,7 @@ interface SerializedStatus {
|
|
|
1117
1148
|
tier: ProviderOutputTier;
|
|
1118
1149
|
detectedReasoning: boolean | null;
|
|
1119
1150
|
reasoningCandidateModelId: string | null;
|
|
1151
|
+
endpointCapacity?: ReturnType<typeof endpointCapacityForStatus>;
|
|
1120
1152
|
}
|
|
1121
1153
|
|
|
1122
1154
|
function serializeStatus(
|
|
@@ -1138,6 +1170,8 @@ function serializeStatus(
|
|
|
1138
1170
|
detectedReasoning: extras.detectedReasoning,
|
|
1139
1171
|
reasoningCandidateModelId: extras.candidateModelId,
|
|
1140
1172
|
};
|
|
1173
|
+
const endpointCapacity = endpointCapacityForStatus(status);
|
|
1174
|
+
if (endpointCapacity !== null) out.endpointCapacity = endpointCapacity;
|
|
1141
1175
|
if (status.contextWindowProvenance !== undefined) {
|
|
1142
1176
|
out.contextWindowProvenance = status.contextWindowProvenance;
|
|
1143
1177
|
}
|
package/src/cli/trace.ts
CHANGED
|
@@ -4,12 +4,15 @@ import { resolve } from "node:path";
|
|
|
4
4
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
5
5
|
import { clioStatePath } from "../core/xdg.js";
|
|
6
6
|
import {
|
|
7
|
+
DEFAULT_TRACE_RETENTION_POLICY,
|
|
8
|
+
resolveTraceRetentionPolicy,
|
|
7
9
|
TRACE_EVENT_POLL_LIMIT,
|
|
8
10
|
type TraceEventRow,
|
|
9
11
|
type TracePhaseRow,
|
|
10
12
|
type TraceProcessRow,
|
|
11
13
|
TraceReader,
|
|
12
14
|
type TraceRunRow,
|
|
15
|
+
TraceStore,
|
|
13
16
|
traceDatabasePath,
|
|
14
17
|
} from "../domains/observability/trace-store.js";
|
|
15
18
|
|
|
@@ -18,11 +21,15 @@ const HELP = `Usage:
|
|
|
18
21
|
clio-coder trace phases <runId> [--db PATH]
|
|
19
22
|
clio-coder trace tail <runId> [--follow] [--db PATH]
|
|
20
23
|
clio-coder trace procs <runId> [--db PATH]
|
|
24
|
+
clio-coder trace prune [--max-age-days N] [--max-bytes N] [--db PATH] [--json]
|
|
21
25
|
clio-coder trace sql <SELECT query> [--db PATH]
|
|
22
26
|
clio-coder trace ui [--db PATH] [--port N] source checkout only
|
|
23
27
|
|
|
24
28
|
The viewer ships with the repository, not the npm package, so from an installed
|
|
25
29
|
Clio the subcommands above are the way in. They read the same database.
|
|
30
|
+
Pruning keeps ${DEFAULT_TRACE_RETENTION_POLICY.maxAgeDays} days and at most ${DEFAULT_TRACE_RETENTION_POLICY.maxBytes} bytes by default. Set
|
|
31
|
+
CLIO_CODER_TRACE_RETENTION_DAYS or CLIO_CODER_TRACE_MAX_BYTES to change the automatic
|
|
32
|
+
policy; prune flags override those values for one command.
|
|
26
33
|
`;
|
|
27
34
|
|
|
28
35
|
interface ParsedTraceArgs {
|
|
@@ -34,6 +41,8 @@ interface ParsedTraceArgs {
|
|
|
34
41
|
limit: number;
|
|
35
42
|
port: number;
|
|
36
43
|
json: boolean;
|
|
44
|
+
maxAgeDays: number | undefined;
|
|
45
|
+
maxBytes: number | undefined;
|
|
37
46
|
}
|
|
38
47
|
|
|
39
48
|
function parseTraceArgs(args: string[]): ParsedTraceArgs {
|
|
@@ -44,11 +53,19 @@ function parseTraceArgs(args: string[]): ParsedTraceArgs {
|
|
|
44
53
|
let limit = 50;
|
|
45
54
|
let port = 0;
|
|
46
55
|
let json = false;
|
|
56
|
+
let maxAgeDays: number | undefined;
|
|
57
|
+
let maxBytes: number | undefined;
|
|
47
58
|
for (let index = 0; index < args.length; index += 1) {
|
|
48
59
|
const arg = args[index];
|
|
49
60
|
if (arg === "--follow") follow = true;
|
|
50
61
|
else if (arg === "--json") json = true;
|
|
51
|
-
else if (
|
|
62
|
+
else if (
|
|
63
|
+
arg === "--db" ||
|
|
64
|
+
arg === "--limit" ||
|
|
65
|
+
arg === "--port" ||
|
|
66
|
+
arg === "--max-age-days" ||
|
|
67
|
+
arg === "--max-bytes"
|
|
68
|
+
) {
|
|
52
69
|
const value = args[index + 1];
|
|
53
70
|
if (value === undefined) throw new Error(`${arg} requires a value`);
|
|
54
71
|
index += 1;
|
|
@@ -56,20 +73,25 @@ function parseTraceArgs(args: string[]): ParsedTraceArgs {
|
|
|
56
73
|
db = resolve(value);
|
|
57
74
|
dbExplicit = true;
|
|
58
75
|
} else if (arg === "--limit") limit = parseInteger(value, "--limit", 1, 500);
|
|
59
|
-
else port = parseInteger(value, "--port", 0, 65_535);
|
|
76
|
+
else if (arg === "--port") port = parseInteger(value, "--port", 0, 65_535);
|
|
77
|
+
else if (arg === "--max-age-days") maxAgeDays = parseInteger(value, arg, 1, 36_500);
|
|
78
|
+
else maxBytes = parseInteger(value, arg, 1024 * 1024, Number.MAX_SAFE_INTEGER);
|
|
60
79
|
} else if (arg?.startsWith("--db=")) {
|
|
61
80
|
db = resolve(arg.slice(5));
|
|
62
81
|
dbExplicit = true;
|
|
63
82
|
} else if (arg?.startsWith("--limit=")) limit = parseInteger(arg.slice(8), "--limit", 1, 500);
|
|
64
83
|
else if (arg?.startsWith("--port=")) port = parseInteger(arg.slice(7), "--port", 0, 65_535);
|
|
84
|
+
else if (arg?.startsWith("--max-age-days=")) maxAgeDays = parseInteger(arg.slice(15), "--max-age-days", 1, 36_500);
|
|
85
|
+
else if (arg?.startsWith("--max-bytes="))
|
|
86
|
+
maxBytes = parseInteger(arg.slice(12), "--max-bytes", 1024 * 1024, Number.MAX_SAFE_INTEGER);
|
|
65
87
|
else if (arg?.startsWith("-")) throw new Error(`unknown trace flag: ${arg}`);
|
|
66
88
|
else if (arg !== undefined) positional.push(arg);
|
|
67
89
|
}
|
|
68
|
-
return { positional, db, dbExplicit, follow, limit, port, json };
|
|
90
|
+
return { positional, db, dbExplicit, follow, limit, port, json, maxAgeDays, maxBytes };
|
|
69
91
|
}
|
|
70
92
|
|
|
71
93
|
/** Every subcommand `trace` answers to. Anything else is a usage error. */
|
|
72
|
-
const TRACE_COMMANDS = new Set(["runs", "phases", "tail", "procs", "sql", "ui"]);
|
|
94
|
+
const TRACE_COMMANDS = new Set(["runs", "phases", "tail", "procs", "prune", "sql", "ui"]);
|
|
73
95
|
|
|
74
96
|
/** The subcommands whose first positional is a run id. */
|
|
75
97
|
const TRACE_COMMANDS_NEEDING_RUN_ID = new Set(["phases", "tail", "procs"]);
|
|
@@ -132,6 +154,7 @@ export async function runTraceCommand(args: string[]): Promise<number> {
|
|
|
132
154
|
// the operator typed is a different claim, so a --db that is not there stays
|
|
133
155
|
// an error and says which path it means.
|
|
134
156
|
if (!existsSync(parsed.db)) return missingDatabase(parsed);
|
|
157
|
+
if (command === "prune") return runTracePrune(parsed);
|
|
135
158
|
|
|
136
159
|
let reader: TraceReader;
|
|
137
160
|
try {
|
|
@@ -189,6 +212,42 @@ export async function runTraceCommand(args: string[]): Promise<number> {
|
|
|
189
212
|
}
|
|
190
213
|
}
|
|
191
214
|
|
|
215
|
+
function runTracePrune(parsed: ParsedTraceArgs): number {
|
|
216
|
+
let policy: ReturnType<typeof resolveTraceRetentionPolicy>;
|
|
217
|
+
try {
|
|
218
|
+
policy = resolveTraceRetentionPolicy({
|
|
219
|
+
...(parsed.maxAgeDays === undefined ? {} : { maxAgeDays: parsed.maxAgeDays }),
|
|
220
|
+
...(parsed.maxBytes === undefined ? {} : { maxBytes: parsed.maxBytes }),
|
|
221
|
+
});
|
|
222
|
+
} catch (error) {
|
|
223
|
+
process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
|
|
224
|
+
return 1;
|
|
225
|
+
}
|
|
226
|
+
let store: TraceStore;
|
|
227
|
+
try {
|
|
228
|
+
store = new TraceStore(parsed.db, { retention: policy });
|
|
229
|
+
} catch (error) {
|
|
230
|
+
process.stderr.write(`trace database: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
231
|
+
return 1;
|
|
232
|
+
}
|
|
233
|
+
try {
|
|
234
|
+
const result = store.prune(policy);
|
|
235
|
+
if (parsed.json) {
|
|
236
|
+
process.stdout.write(`${JSON.stringify({ policy, ...result }, null, 2)}\n`);
|
|
237
|
+
} else {
|
|
238
|
+
process.stdout.write(
|
|
239
|
+
`trace prune: removed ${result.runsRemoved.toLocaleString("en-US")} runs and ${result.rowsRemoved.toLocaleString("en-US")} rows; reclaimed ${result.bytesRemoved.toLocaleString("en-US")} bytes; VACUUM ${result.vacuumed ? "ran" : "not needed"}; protected ${result.protectedRuns.toLocaleString("en-US")} live runs\n`,
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
return 0;
|
|
243
|
+
} catch (error) {
|
|
244
|
+
process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
|
|
245
|
+
return 1;
|
|
246
|
+
} finally {
|
|
247
|
+
store.close();
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
192
251
|
async function tail(reader: TraceReader, runId: string, follow: boolean): Promise<void> {
|
|
193
252
|
let cursor = 0;
|
|
194
253
|
let idleTerminalPolls = 0;
|
package/src/cli/usage.ts
CHANGED
|
@@ -12,9 +12,12 @@ import { readEvidenceIndex } from "../domains/observability/evidence-index.js";
|
|
|
12
12
|
import { type OutOfTurnUsageRow, readOutOfTurnUsageRows } from "../domains/observability/out-of-turn-usage.js";
|
|
13
13
|
import { loadSkills } from "../domains/resources/index.js";
|
|
14
14
|
import {
|
|
15
|
+
foldPromptCacheTelemetry,
|
|
16
|
+
hasPromptCacheTelemetry,
|
|
15
17
|
type LedgerUsageCall,
|
|
16
18
|
ledgerUsageCalls,
|
|
17
19
|
listSessionLedgerRefs,
|
|
20
|
+
type PromptCacheTelemetry,
|
|
18
21
|
parseSessionEntries,
|
|
19
22
|
readAuditRows,
|
|
20
23
|
} from "../domains/session/index.js";
|
|
@@ -69,6 +72,8 @@ interface SessionUsage {
|
|
|
69
72
|
entriesInWindow: number;
|
|
70
73
|
/** Completed API calls this session recorded in the window, one per call. */
|
|
71
74
|
usageCalls: LedgerUsageCall[];
|
|
75
|
+
/** Backend prompt-cache facts persisted on assistant calls in the window. */
|
|
76
|
+
promptCache: PromptCacheTelemetry;
|
|
72
77
|
}
|
|
73
78
|
|
|
74
79
|
/** Per-call usage folded over one grouping (a model, or the whole window). */
|
|
@@ -102,32 +107,37 @@ function addResponseModelIdObservation(counts: ResponseModelIdObservationCounts,
|
|
|
102
107
|
|
|
103
108
|
/**
|
|
104
109
|
* How the folded calls split between the session's own turns and the rounds
|
|
105
|
-
* that were billed beside it. A `/btw` side question
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
110
|
+
* that were billed beside it. A `/btw` side question, a `/handoff` round, a
|
|
111
|
+
* session pre-warm, and a proactive-memory step are real spend and belong in
|
|
112
|
+
* the token and cost totals, but none of them is a turn: they never entered
|
|
113
|
+
* the session. `turns` therefore subtracts them from the folded row count,
|
|
114
|
+
* which is exactly what the `/cost` overlay does.
|
|
109
115
|
*/
|
|
110
116
|
interface CallOrigins {
|
|
111
117
|
rows: number;
|
|
112
118
|
sideQuestions: number;
|
|
113
119
|
handoffs: number;
|
|
120
|
+
prewarms: number;
|
|
121
|
+
backgroundMemory: number;
|
|
114
122
|
}
|
|
115
123
|
|
|
116
124
|
function emptyCallOrigins(): CallOrigins {
|
|
117
|
-
return { rows: 0, sideQuestions: 0, handoffs: 0 };
|
|
125
|
+
return { rows: 0, sideQuestions: 0, handoffs: 0, prewarms: 0, backgroundMemory: 0 };
|
|
118
126
|
}
|
|
119
127
|
|
|
120
128
|
function turnsOf(origins: CallOrigins): number {
|
|
121
|
-
return origins.rows - origins.sideQuestions - origins.handoffs;
|
|
129
|
+
return origins.rows - origins.sideQuestions - origins.handoffs - origins.prewarms - origins.backgroundMemory;
|
|
122
130
|
}
|
|
123
131
|
|
|
124
132
|
function hasLabelledCall(origins: CallOrigins): boolean {
|
|
125
|
-
return origins.sideQuestions > 0 || origins.handoffs > 0;
|
|
133
|
+
return origins.sideQuestions > 0 || origins.handoffs > 0 || origins.prewarms > 0 || origins.backgroundMemory > 0;
|
|
126
134
|
}
|
|
127
135
|
|
|
128
136
|
function addOutOfTurnRow(origins: CallOrigins, row: OutOfTurnUsageRow): void {
|
|
129
137
|
origins.rows += 1;
|
|
130
138
|
if (row.label === "side-question") origins.sideQuestions += 1;
|
|
139
|
+
else if (row.label === "prewarm") origins.prewarms += 1;
|
|
140
|
+
else if (row.label === "background-memory") origins.backgroundMemory += 1;
|
|
131
141
|
else origins.handoffs += 1;
|
|
132
142
|
}
|
|
133
143
|
|
|
@@ -435,6 +445,9 @@ export async function runUsageCommand(argv: ReadonlyArray<string>): Promise<numb
|
|
|
435
445
|
const usageRows = [...usageByModel.values()].sort(
|
|
436
446
|
(a, b) => b.totals.totalTokens - a.totals.totalTokens || a.providerId.localeCompare(b.providerId),
|
|
437
447
|
);
|
|
448
|
+
const cacheSessions = sessions
|
|
449
|
+
.filter((session) => hasPromptCacheTelemetry(session.promptCache))
|
|
450
|
+
.sort((a, b) => a.sessionId.localeCompare(b.sessionId));
|
|
438
451
|
|
|
439
452
|
const approvedMemory = memoryRecords.filter((record) => record.approved && record.rejectedAt === undefined);
|
|
440
453
|
const pendingMemory = memoryRecords.filter((record) => !record.approved && record.rejectedAt === undefined);
|
|
@@ -515,8 +528,8 @@ export async function runUsageCommand(argv: ReadonlyArray<string>): Promise<numb
|
|
|
515
528
|
emit({ kind: "fact", fact: "audit-tool-calls", value: auditToolCalls.length, blocked: auditBlocked.length });
|
|
516
529
|
if (usageMeasurable) {
|
|
517
530
|
// The origin split is emitted only when something out of turn was
|
|
518
|
-
// recorded, so a report over an archive with no `/btw
|
|
519
|
-
// round in it stays byte-identical to what it printed before.
|
|
531
|
+
// recorded, so a report over an archive with no `/btw`, `/handoff`, or
|
|
532
|
+
// pre-warm round in it stays byte-identical to what it printed before.
|
|
520
533
|
emit({
|
|
521
534
|
kind: "fact",
|
|
522
535
|
fact: "tokens",
|
|
@@ -526,6 +539,8 @@ export async function runUsageCommand(argv: ReadonlyArray<string>): Promise<numb
|
|
|
526
539
|
turns: turnsOf(callOrigins),
|
|
527
540
|
sideQuestions: callOrigins.sideQuestions,
|
|
528
541
|
handoffs: callOrigins.handoffs,
|
|
542
|
+
prewarms: callOrigins.prewarms,
|
|
543
|
+
backgroundMemorySteps: callOrigins.backgroundMemory,
|
|
529
544
|
}
|
|
530
545
|
: {}),
|
|
531
546
|
});
|
|
@@ -540,6 +555,15 @@ export async function runUsageCommand(argv: ReadonlyArray<string>): Promise<numb
|
|
|
540
555
|
...row.totals,
|
|
541
556
|
});
|
|
542
557
|
}
|
|
558
|
+
for (const session of cacheSessions) {
|
|
559
|
+
emit({
|
|
560
|
+
kind: "fact",
|
|
561
|
+
fact: "session-cache",
|
|
562
|
+
sessionId: session.sessionId,
|
|
563
|
+
uncachedPrefillTokens: session.promptCache.uncachedPrefillTokens,
|
|
564
|
+
verdictCounts: session.promptCache.verdictCounts,
|
|
565
|
+
});
|
|
566
|
+
}
|
|
543
567
|
}
|
|
544
568
|
for (const [tool, totals] of topTools) emit({ kind: "fact", fact: "top-tool", tool, ...totals });
|
|
545
569
|
for (const [shape, count] of topShapes) {
|
|
@@ -600,6 +624,10 @@ export async function runUsageCommand(argv: ReadonlyArray<string>): Promise<numb
|
|
|
600
624
|
out(` turns in window: ${turnsOf(callOrigins)}`);
|
|
601
625
|
if (callOrigins.sideQuestions > 0) out(` side questions in window: ${callOrigins.sideQuestions}`);
|
|
602
626
|
if (callOrigins.handoffs > 0) out(` handoffs in window: ${callOrigins.handoffs}`);
|
|
627
|
+
if (callOrigins.prewarms > 0) out(` pre-warms in window: ${callOrigins.prewarms}`);
|
|
628
|
+
if (callOrigins.backgroundMemory > 0) {
|
|
629
|
+
out(` background memory steps in window: ${callOrigins.backgroundMemory}`);
|
|
630
|
+
}
|
|
603
631
|
}
|
|
604
632
|
out(` provider-reported cost in window: $${usageTotals.costUsd.toFixed(4)}`);
|
|
605
633
|
}
|
|
@@ -639,6 +667,27 @@ export async function runUsageCommand(argv: ReadonlyArray<string>): Promise<numb
|
|
|
639
667
|
),
|
|
640
668
|
);
|
|
641
669
|
}
|
|
670
|
+
if (cacheSessions.length > 0) {
|
|
671
|
+
out("");
|
|
672
|
+
out(" prompt cache by session (from backend timings and persisted verdicts)");
|
|
673
|
+
process.stdout.write(
|
|
674
|
+
indent(
|
|
675
|
+
formatColumns([
|
|
676
|
+
["session", "uncached prefill", "hot/partial/cold/small"],
|
|
677
|
+
...cacheSessions.map((session) => [
|
|
678
|
+
session.sessionId,
|
|
679
|
+
session.promptCache.uncachedPrefillTokens === null ? "n/a" : String(session.promptCache.uncachedPrefillTokens),
|
|
680
|
+
[
|
|
681
|
+
session.promptCache.verdictCounts.hot,
|
|
682
|
+
session.promptCache.verdictCounts.partial,
|
|
683
|
+
session.promptCache.verdictCounts.cold,
|
|
684
|
+
session.promptCache.verdictCounts.small,
|
|
685
|
+
].join("/"),
|
|
686
|
+
]),
|
|
687
|
+
]),
|
|
688
|
+
),
|
|
689
|
+
);
|
|
690
|
+
}
|
|
642
691
|
if (topTools.length > 0) {
|
|
643
692
|
out("");
|
|
644
693
|
out(" top tools (from receipt toolStats)");
|
|
@@ -865,6 +914,9 @@ async function readSessions(
|
|
|
865
914
|
}
|
|
866
915
|
const parsedEntries = parseSessionEntries(raw, ref.path);
|
|
867
916
|
diagnostics.malformedSessionLines += parsedEntries.errors.length;
|
|
917
|
+
const accountingEntries = parsedEntries.entries.filter(
|
|
918
|
+
(entry) => entry.kind === "modelChange" || inWindow(entry.timestamp, windowStart, windowEnd),
|
|
919
|
+
);
|
|
868
920
|
const usage: SessionUsage = {
|
|
869
921
|
sessionId: ref.sessionId,
|
|
870
922
|
cwdHash: ref.cwdHash,
|
|
@@ -874,11 +926,8 @@ async function readSessions(
|
|
|
874
926
|
// modelChange rows are kept regardless of the window: they carry no
|
|
875
927
|
// usage of their own, and dropping the ones that predate the window
|
|
876
928
|
// would attribute in-window calls to the wrong target.
|
|
877
|
-
usageCalls: ledgerUsageCalls(
|
|
878
|
-
|
|
879
|
-
(entry) => entry.kind === "modelChange" || inWindow(entry.timestamp, windowStart, windowEnd),
|
|
880
|
-
),
|
|
881
|
-
),
|
|
929
|
+
usageCalls: ledgerUsageCalls(accountingEntries),
|
|
930
|
+
promptCache: foldPromptCacheTelemetry(accountingEntries),
|
|
882
931
|
};
|
|
883
932
|
for (const entry of parsedEntries.entries) {
|
|
884
933
|
if (!inWindow(entry.timestamp, windowStart, windowEnd)) continue;
|