@iowarp/clio-coder 0.3.1 → 0.3.3
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 +233 -373
- package/CONTRIBUTING.md +23 -23
- package/README.md +284 -613
- package/dist/{acp-FPR54DGL.js → acp-P2AQILE2.js} +43 -53
- package/dist/{agents-OGPIHPJH.js → agents-72W3BI7I.js} +43 -26
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-IC3K6NIZ.js → auth-5TWEIYDN.js} +20 -12
- package/dist/chunk-2DJ2KNFG.js +2095 -0
- package/dist/{chunk-IS3ONKU3.js → chunk-2IR2NMPA.js} +6 -4
- package/dist/chunk-2SFS6XQE.js +122 -0
- package/dist/{chunk-PV4JUBVJ.js → chunk-2TLUCQVG.js} +40 -21
- package/dist/chunk-2VTFPG5O.js +48 -0
- package/dist/chunk-4BJ5BYCE.js +61 -0
- package/dist/{chunk-474KN5II.js → chunk-4BPJXDWC.js} +111 -181
- package/dist/chunk-4VP4KH3K.js +962 -0
- package/dist/chunk-4XUGQOHA.js +797 -0
- package/dist/chunk-4ZG3XFUR.js +77 -0
- package/dist/chunk-5B2AEOW5.js +5407 -0
- package/dist/{chunk-K2ITRMHZ.js → chunk-5TSRNF4G.js} +6 -138
- package/dist/{chunk-4QKXUHSR.js → chunk-5UFT4SUX.js} +70 -20
- package/dist/{chunk-OLBBMFRD.js → chunk-5UUP6MWO.js} +24 -62
- package/dist/chunk-65DEGPJ6.js +52 -0
- package/dist/chunk-6EJMN2Y3.js +17 -0
- package/dist/chunk-6N5PTWMY.js +136 -0
- package/dist/chunk-6SGHMWE3.js +277 -0
- package/dist/chunk-6XLNIQDB.js +27 -0
- package/dist/chunk-7CR24IG7.js +242 -0
- package/dist/chunk-7MNJORFF.js +22 -0
- package/dist/{chunk-KY56HMHH.js → chunk-A3CYT5EX.js} +125 -31
- package/dist/chunk-AGYYIBLL.js +1069 -0
- package/dist/{chunk-GB6QRBXN.js → chunk-APJ265NV.js} +54 -1187
- package/dist/{chunk-673JJUWJ.js → chunk-BMEMKKIT.js} +2 -2
- package/dist/chunk-CBCAPZAA.js +229 -0
- package/dist/chunk-CMZWFGD2.js +352 -0
- package/dist/chunk-COU2UHX6.js +400 -0
- package/dist/chunk-DSELYM6W.js +1077 -0
- package/dist/chunk-DUYJ5IO6.js +644 -0
- package/dist/chunk-ECH6PKUQ.js +39 -0
- package/dist/chunk-ED4KHGC3.js +143 -0
- package/dist/chunk-EKMEHE4H.js +340 -0
- package/dist/chunk-FCSXB6T2.js +338 -0
- package/dist/chunk-FJ3H4MN5.js +48 -0
- package/dist/{chunk-RPTR2H26.js → chunk-FNTMWMX5.js} +21 -15
- package/dist/chunk-FQ4SKYE4.js +29 -0
- package/dist/chunk-G4BMMOKF.js +182 -0
- package/dist/{chunk-ZPY3JZ5E.js → chunk-GGXXDWE4.js} +183 -1233
- package/dist/chunk-HC4CLZ2Y.js +68 -0
- package/dist/{chunk-LU4TK2PR.js → chunk-HFSBBKSQ.js} +5 -56
- package/dist/{chunk-PIUMUEMV.js → chunk-HKIYEGME.js} +10 -6
- package/dist/chunk-I4HZDVNP.js +73 -0
- package/dist/chunk-IKCO5N3L.js +162 -0
- package/dist/chunk-IR4CFBFN.js +56 -0
- package/dist/{chunk-R5KLMSBV.js → chunk-J5Q24KAG.js} +2 -2
- package/dist/chunk-J7CWMCQD.js +255 -0
- package/dist/{chunk-K5XEMXTI.js → chunk-JVCV3ICN.js} +1 -1
- package/dist/chunk-KZWTDYJF.js +217 -0
- package/dist/chunk-LBMZMYH2.js +285 -0
- package/dist/{chunk-G34LV2PF.js → chunk-LM5TQCJZ.js} +84 -170
- package/dist/chunk-LW6DSM3M.js +5135 -0
- package/dist/chunk-LWLEKMDQ.js +3482 -0
- package/dist/{chunk-H6F6BYOH.js → chunk-LZSJBIVT.js} +7003 -7434
- package/dist/{chunk-HQQID6OA.js → chunk-M6SHUN7Q.js} +5 -5
- package/dist/{chunk-FST4FYJB.js → chunk-MFFY33HR.js} +99 -140
- package/dist/{chunk-BSU2YIWB.js → chunk-MVVUPGPW.js} +131 -136
- package/dist/chunk-OAO4GE4M.js +619 -0
- package/dist/{chunk-Q3RUPKEJ.js → chunk-OC7FIQPC.js} +58 -189
- package/dist/chunk-OKGUZO2U.js +34 -0
- package/dist/{chunk-GAEBEQVI.js → chunk-OOJYHWRB.js} +32 -346
- package/dist/{chunk-Q5WJOSJ7.js → chunk-OQ33BKR3.js} +2 -1
- package/dist/chunk-OQE5J4C6.js +73 -0
- package/dist/{chunk-KKNLWXI6.js → chunk-ORBHGJC5.js} +8 -8
- package/dist/{chunk-MAR7Y6HW.js → chunk-PAJK6MAQ.js} +23 -16
- package/dist/{chunk-M5T5VO65.js → chunk-PIWWS5BL.js} +837 -635
- package/dist/chunk-POHLU5DW.js +1186 -0
- package/dist/chunk-QKMUKYO7.js +4961 -0
- package/dist/chunk-SRDMMSEP.js +16405 -0
- package/dist/chunk-SST6Z5JA.js +80 -0
- package/dist/chunk-STBPMHSX.js +2456 -0
- package/dist/chunk-T6YILFSB.js +80 -0
- package/dist/chunk-TZK7PACC.js +174 -0
- package/dist/chunk-TZTZS7QK.js +227 -0
- package/dist/{chunk-ASND7OZK.js → chunk-UFIIWP2H.js} +13 -13
- package/dist/chunk-UOV2BYIW.js +107 -0
- package/dist/{chunk-PFEFKVGL.js → chunk-V6RTAOC2.js} +13 -11
- package/dist/chunk-VAKQQHWR.js +434 -0
- package/dist/chunk-VG7TBQIY.js +128 -0
- package/dist/chunk-VJWL6YS5.js +244 -0
- package/dist/{chunk-EYOKLTMF.js → chunk-VPAYEGVX.js} +17 -3
- package/dist/chunk-WEH5XRJQ.js +32 -0
- package/dist/chunk-X4RCMKVQ.js +641 -0
- package/dist/{chunk-TEKV33Q5.js → chunk-X6IAEBZR.js} +65 -33
- package/dist/chunk-XBXAASKX.js +18 -0
- package/dist/chunk-XN3L4EYL.js +46 -0
- package/dist/{chunk-RDLVBZEO.js → chunk-YCWGATWI.js} +6 -4
- package/dist/chunk-YHZX5GEU.js +193 -0
- package/dist/chunk-YXLYO42X.js +91 -0
- package/dist/{chunk-NMOX6HFD.js → chunk-ZDOOVTXZ.js} +29 -77
- package/dist/chunk-ZI647VB5.js +37 -0
- package/dist/{chunk-C4PTHK7P.js → chunk-ZWLZP4ZT.js} +5 -5
- package/dist/chunk-ZWMF7253.js +1882 -0
- package/dist/cli/index.js +62 -54
- package/dist/clio-JOU4FXVA.js +25 -0
- package/dist/code-nav-7AX6FYE6.js +600 -0
- package/dist/codewiki/build-worker.js +66 -0
- package/dist/compile-cache-CVJMMODC.js +18 -0
- package/dist/{components-DMAOEKFB.js → components-KELWS457.js} +11 -6
- package/dist/{config-IRUQ7SE4.js → config-XCDVKR23.js} +92 -55
- package/dist/configure-4GAP54ZW.js +42 -0
- package/dist/{context-5RADCKTR.js → context-4UOGGLQ5.js} +71 -35
- package/dist/context-5VKGUVJJ.js +866 -0
- package/dist/{context-3KWFLHJG.js → context-77FM5DV5.js} +15 -13
- package/dist/{context-clear-7TSNPAAI.js → context-clear-XXJRLCJJ.js} +54 -28
- package/dist/{context-index-W4RLWOQH.js → context-index-BZ4UYMTC.js} +30 -24
- package/dist/dispatch-runner-QPRDDBDX.js +1997 -0
- package/dist/{docs-5AWSPS37.js → docs-2C2LTVT2.js} +23 -10
- package/dist/{doctor-UC5NAJYQ.js → doctor-HR46URBJ.js} +27 -17
- package/dist/{eval-U6TJHRLX.js → eval-XSSNATB4.js} +29 -16
- package/dist/{evidence-YEGUW4L3.js → evidence-6HG2PY2B.js} +46 -26
- package/dist/{evolve-TXARCTPG.js → evolve-K7YU3NCY.js} +45 -25
- package/dist/{extensions-OZFJ3A3G.js → extensions-QVDOHDGJ.js} +16 -7
- package/dist/{fleet-6G3DHNYE.js → fleet-VY3HHKN6.js} +163 -54
- package/dist/{fleet-preflight-DSNT37JK.js → fleet-preflight-DDN536IT.js} +7 -4
- package/dist/{init-KZ5QTF6M.js → init-JYGXI3FK.js} +69 -32
- package/dist/{memory-73ESV5YC.js → memory-WFZMGYHX.js} +48 -27
- package/dist/{models-A4PVNWJK.js → models-I5QWSEOM.js} +39 -25
- package/dist/monitor-GE4ID3IA.js +661 -0
- package/dist/{chunk-FCIH3BIZ.js → orchestrator-EM5MC3HM.js} +15979 -12407
- package/dist/{paths-C4H6IV77.js → paths-UXLN5YYZ.js} +10 -5
- package/dist/{preload-6WVMHX3A.js → preload-P6DGH2PZ.js} +2 -2
- package/dist/{reset-BGW6OGMV.js → reset-L2FQEE3E.js} +16 -10
- package/dist/{run-YTPEYQOH.js → run-ZU3QMZPZ.js} +101 -61
- package/dist/{share-YIFFV4NQ.js → share-S5BZQC5I.js} +15 -8
- package/dist/{skills-2V6RA3OQ.js → skills-X5VXCRNQ.js} +34 -14
- package/dist/{skills-eval-S2TVJO4F.js → skills-eval-WKIHWTHR.js} +70 -34
- package/dist/steer-GGWFUJUD.js +77 -0
- package/dist/{targets-TYXLPB23.js → targets-SNCPI2NR.js} +43 -27
- package/dist/terminal-lease-BNAHVHBS.js +395 -0
- package/dist/{trace-GGOJ6Q6Z.js → trace-PNCASAXC.js} +41 -16
- package/dist/{chunk-N6F52NLF.js → tree-sitter-HGKH6LG4.js} +28 -2306
- package/dist/{uninstall-LLLT4F4W.js → uninstall-FZCQCDKC.js} +10 -5
- package/dist/{upgrade-33G2LMM5.js → upgrade-JQHHPQ4K.js} +45 -25
- package/dist/{usage-ZAFSXKKG.js → usage-OR4O5SMZ.js} +62 -31
- package/dist/verify-375KUB3Y.js +716 -0
- package/dist/web-fetch-2YHJ3KTG.js +638 -0
- package/dist/{wiki-generate-NUQCVOQ3.js → wiki-generate-UEXP2ARI.js} +74 -34
- package/dist/worker/entry.js +221 -36
- package/dist/workspace-G4ZWUIPR.js +22 -0
- package/docs/README.md +22 -17
- package/docs/acp.md +168 -16
- package/docs/alcf-provider.md +1 -1
- package/docs/architecture.md +136 -7
- package/docs/artifact-versions.md +1 -1
- package/docs/built-in-agents.md +1 -1
- package/docs/capacity-and-scheduling.md +1 -1
- package/docs/commands-and-modes.md +114 -71
- package/docs/config-knobs-audit.md +1 -3
- package/docs/configuration-and-targets.md +174 -46
- package/docs/context-engine.md +29 -6
- package/docs/development-pipeline.md +26 -1
- package/docs/dispatch-architecture-rationale.md +1 -1
- package/docs/documentation-coverage.md +2 -2
- package/docs/documentation-guide.md +1 -1
- package/docs/environment-variables.md +13 -5
- package/docs/eval-runner.md +1 -1
- package/docs/evals-internal.md +1 -1
- package/docs/evidence-and-memory.md +6 -2
- package/docs/evolution.md +2 -2
- package/docs/exit-codes-and-output.md +15 -9
- package/docs/extensions-and-sharing.md +9 -9
- package/docs/fleet-dispatch.md +7 -5
- package/docs/git-commit-provenance.md +120 -0
- package/docs/glossary.md +1 -1
- package/docs/installation-and-lifecycle.md +34 -27
- package/docs/middleware-and-components.md +1 -1
- package/docs/model-catalog.md +45 -14
- package/docs/observability.md +8 -5
- package/docs/performance-methodology.md +491 -0
- package/docs/pi-boundary.md +72 -0
- package/docs/proactive-memory.md +3 -3
- package/docs/prompt-envelope-and-tools.md +24 -3
- package/docs/provider-adapter-cookbook.md +57 -4
- package/docs/release-cut-checklist.md +129 -115
- package/docs/safety-model.md +9 -5
- package/docs/scientific-validation.md +3 -3
- package/docs/session-lifecycle.md +55 -12
- package/docs/skills-marketplace.md +12 -8
- package/docs/time-conventions.md +1 -1
- package/docs/tool-usage.md +3 -3
- package/docs/trace-store.md +1 -1
- package/docs/troubleshooting.md +10 -7
- package/docs/tui-design.md +47 -10
- package/docs/worker-dispatch-mechanics.md +1 -1
- package/package.json +19 -22
- package/skills/coding/ast-grep/SKILL.md +136 -0
- package/skills/coding/ast-grep/evals.md +56 -0
- package/skills/coding/ast-grep/references/rule_reference.md +297 -0
- package/skills/coding/coding-standards/SKILL.md +113 -0
- package/skills/coding/coding-standards/evals.md +34 -0
- package/skills/coding/prototype/SKILL.md +86 -0
- package/skills/coding/prototype/evals.md +42 -0
- package/skills/coding/prototype/references/LOGIC.md +67 -0
- package/skills/coding/prototype/references/UI.md +112 -0
- package/skills/coding/tdd/SKILL.md +101 -0
- package/skills/coding/tdd/evals.md +41 -0
- package/skills/coding/tdd/references/mocking.md +59 -0
- package/skills/coding/tdd/references/tests.md +77 -0
- package/skills/context/context-handoff/SKILL.md +126 -0
- package/skills/context/context-handoff/evals.md +57 -0
- package/skills/context/context-handoff/scripts/new-handoff.sh +26 -0
- package/skills/context/context-prime/SKILL.md +95 -0
- package/skills/context/context-prime/evals.md +54 -0
- package/skills/meta/clio-dev/SKILL.md +91 -0
- package/skills/meta/clio-dev/evals.md +45 -0
- package/skills/meta/clio-test/SKILL.md +130 -0
- package/skills/meta/clio-test/evals.md +43 -0
- package/skills/meta/clio-test/references/harness.md +97 -0
- package/skills/meta/clio-test/references/test-map.md +59 -0
- package/skills/meta/credentials/SKILL.md +125 -0
- package/skills/meta/credentials/evals.md +104 -0
- package/skills/meta/find-skills/SKILL.md +72 -0
- package/skills/meta/find-skills/evals.md +47 -0
- package/skills/meta/herdr/SKILL.md +127 -0
- package/skills/meta/herdr/evals.md +38 -0
- package/skills/meta/skill-craft/SKILL.md +102 -0
- package/skills/meta/skill-craft/evals.md +41 -0
- package/skills/planning/architecture/SKILL.md +129 -0
- package/skills/planning/architecture/evals.md +36 -0
- package/skills/planning/backlog/SKILL.md +90 -0
- package/skills/planning/backlog/evals.md +43 -0
- package/skills/planning/prd/SKILL.md +82 -0
- package/skills/planning/prd/evals.md +49 -0
- package/skills/planning/product-intent/SKILL.md +112 -0
- package/skills/planning/product-intent/evals.md +36 -0
- package/skills/planning/tech-spec/SKILL.md +115 -0
- package/skills/planning/tech-spec/evals.md +47 -0
- package/skills/registry.yaml +136 -0
- package/skills/research/arxiv-literature/SKILL.md +104 -0
- package/skills/research/arxiv-literature/evals.md +58 -0
- package/skills/research/experiment-protocol/SKILL.md +122 -0
- package/skills/research/experiment-protocol/evals.md +91 -0
- package/skills/research/scientific-debugging/SKILL.md +119 -0
- package/skills/research/scientific-debugging/evals.md +138 -0
- package/skills/research/scientific-modernization/SKILL.md +138 -0
- package/skills/research/scientific-modernization/evals.md +84 -0
- package/skills/workflow/design-council/SKILL.md +139 -0
- package/skills/workflow/design-council/evals.md +97 -0
- package/skills/workflow/grill-me/SKILL.md +186 -0
- package/skills/workflow/grill-me/evals.md +78 -0
- package/skills/workflow/workflow-distiller/SKILL.md +136 -0
- package/skills/workflow/workflow-distiller/evals.md +107 -0
- package/src/cli/acp.ts +31 -4
- package/src/cli/clio.ts +68 -6
- package/src/cli/config-inspect.ts +28 -22
- package/src/cli/configure.ts +47 -9
- package/src/cli/context-clear.ts +2 -2
- package/src/cli/context-index.ts +21 -23
- package/src/cli/context.ts +13 -8
- package/src/cli/default-target.ts +9 -17
- package/src/cli/docs.ts +11 -5
- package/src/cli/evidence.ts +4 -1
- package/src/cli/extensions.ts +10 -1
- package/src/cli/fleet.ts +47 -6
- package/src/cli/index.ts +55 -26
- package/src/cli/memory.ts +3 -1
- package/src/cli/models.ts +1 -1
- package/src/cli/modes/json-stream.ts +37 -1
- package/src/cli/modes/print.ts +24 -9
- package/src/cli/run.ts +2 -2
- package/src/cli/skills-eval.ts +23 -8
- package/src/cli/skills.ts +19 -4
- package/src/cli/targets.ts +4 -0
- package/src/cli/text-layout.ts +15 -5
- package/src/cli/trace.ts +62 -14
- package/src/cli/upgrade.ts +18 -2
- package/src/cli/usage.ts +10 -3
- package/src/cli/wiki-generate.ts +2 -1
- package/src/core/agent-environment.ts +7 -0
- package/src/core/bash-exec.ts +72 -1
- package/src/core/boot-trace.ts +9 -4
- package/src/core/bus-events.ts +20 -4
- package/src/core/commit-attribution.ts +157 -0
- package/src/core/compile-cache.ts +159 -0
- package/src/core/config.ts +131 -2
- package/src/core/defaults.ts +39 -5
- package/src/core/domain-loader.ts +12 -5
- package/src/core/git-commit-attribution.ts +387 -0
- package/src/core/incomplete-installation.ts +45 -0
- package/src/core/response-schema.ts +1 -1
- package/src/core/safe-exec.ts +13 -1
- package/src/core/settings-layers.ts +155 -21
- package/src/core/skill-activation.ts +1 -1
- package/src/core/startup-timer.ts +3 -3
- package/src/core/state-file-lock.ts +13 -1
- package/src/core/termination.ts +78 -5
- package/src/domains/config/classify.ts +15 -3
- package/src/domains/config/extension.ts +19 -13
- package/src/domains/config/index.ts +10 -0
- package/src/domains/config/keybindings.ts +45 -9
- package/src/domains/context/bootstrap-prompt.ts +1 -1
- package/src/domains/context/bootstrap.ts +111 -18
- package/src/domains/context/clear.ts +16 -11
- package/src/domains/context/clio-md.ts +111 -9
- package/src/domains/context/codewiki/artifact.ts +400 -0
- package/src/domains/context/codewiki/build-worker-protocol.ts +24 -0
- package/src/domains/context/codewiki/build-worker.ts +54 -0
- package/src/domains/context/codewiki/coordinator.ts +182 -0
- package/src/domains/context/codewiki/indexer.ts +59 -144
- package/src/domains/context/codewiki/paths.ts +67 -0
- package/src/domains/context/codewiki/schema.ts +80 -0
- package/src/domains/context/codewiki/tree-sitter.ts +1 -1
- package/src/domains/context/contract.ts +11 -5
- package/src/domains/context/extension.ts +94 -143
- package/src/domains/context/fingerprint.ts +3 -1
- package/src/domains/context/index.ts +12 -22
- package/src/domains/context/project-metadata.ts +19 -0
- package/src/domains/context/prompt-context.ts +9 -10
- package/src/domains/context/refresh.ts +29 -21
- package/src/domains/context/runtime.ts +17 -0
- package/src/domains/context/wiki/generate.ts +39 -34
- package/src/domains/context/wiki/plan.ts +1 -1
- package/src/domains/context/wiki/prompts.ts +21 -8
- package/src/domains/dispatch/code-step.ts +20 -1
- package/src/domains/dispatch/extension.ts +158 -21
- package/src/domains/dispatch/failure-classification.ts +6 -0
- package/src/domains/dispatch/fleet-commit-attribution.ts +56 -0
- package/src/domains/dispatch/orphan-recovery.ts +50 -8
- package/src/domains/dispatch/receipt-integrity.ts +5 -0
- package/src/domains/dispatch/state.ts +31 -6
- package/src/domains/dispatch/transport.ts +2 -1
- package/src/domains/dispatch/types.ts +14 -0
- package/src/domains/dispatch/worker-spawn.ts +21 -2
- package/src/domains/eval/metrics/context.ts +1 -1
- package/src/domains/eval/types.ts +0 -1
- package/src/domains/evidence/build.ts +41 -1
- package/src/domains/lifecycle/migrations/2026-08-18-lmstudio-runtime-id.ts +52 -0
- package/src/domains/lifecycle/migrations/index.ts +24 -4
- package/src/domains/middleware/hooks-io.ts +12 -0
- package/src/domains/middleware/skills-reminder.ts +30 -15
- package/src/domains/prompts/compiler.ts +142 -84
- package/src/domains/prompts/contract.ts +18 -2
- package/src/domains/prompts/extension.ts +39 -7
- package/src/domains/prompts/fragment-loader.ts +0 -1
- package/src/domains/prompts/fragments/identity/clio.md +2 -4
- package/src/domains/prompts/fragments/identity/docs-routing.md +10 -0
- package/src/domains/prompts/fragments/identity/self-awareness.md +1 -45
- package/src/domains/prompts/fragments/operating/contract.md +4 -50
- package/src/domains/prompts/fragments/operating/delegation.md +42 -0
- package/src/domains/prompts/fragments/operating/skills.md +26 -0
- package/src/domains/prompts/fragments/operating/worker.md +16 -0
- package/src/domains/prompts/fragments/safety/auto-edit.md +5 -5
- package/src/domains/prompts/fragments/safety/full-auto.md +3 -3
- package/src/domains/prompts/fragments/safety/read-only.md +4 -4
- package/src/domains/prompts/fragments/safety/suggest.md +2 -2
- package/src/domains/prompts/fragments/wiki/page.md +10 -0
- package/src/domains/prompts/fragments/wiki/plan.md +10 -0
- package/src/domains/prompts/preload.ts +3 -3
- package/src/domains/providers/auth/api-key.ts +1 -1
- package/src/domains/providers/auth/backend-file.ts +20 -10
- package/src/domains/providers/auth/backend-memory.ts +59 -4
- package/src/domains/providers/auth/boot-status.ts +65 -0
- package/src/domains/providers/auth/oauth.ts +2 -1
- package/src/domains/providers/auth/storage.ts +97 -38
- package/src/domains/providers/capabilities.ts +12 -4
- package/src/domains/providers/contract.ts +15 -4
- package/src/domains/providers/extension.ts +18 -6
- package/src/domains/providers/model-runtime-capabilities.ts +15 -4
- package/src/domains/providers/models/local-models/clio-local-coding-targets.yaml +118 -35
- package/src/domains/providers/plugins.ts +5 -3
- package/src/domains/providers/probe/fingerprint.ts +25 -5
- package/src/domains/providers/registry.ts +31 -10
- package/src/domains/providers/runtimes/boot-manifest.ts +55 -0
- package/src/domains/providers/runtimes/builtins.ts +2 -2
- package/src/domains/providers/runtimes/common/lmstudio-http.ts +423 -0
- package/src/domains/providers/runtimes/common/local-synth.ts +6 -7
- package/src/domains/providers/runtimes/local-native/lmstudio.ts +241 -0
- package/src/domains/providers/support.ts +6 -3
- package/src/domains/providers/types/local-model-quirks.ts +7 -9
- package/src/domains/providers/types/runtime-descriptor.ts +12 -1
- package/src/domains/providers/types/target-descriptor.ts +22 -0
- package/src/domains/resources/contract.ts +0 -1
- package/src/domains/resources/extension.ts +1 -3
- package/src/domains/resources/loader.ts +3 -4
- package/src/domains/resources/prompts/loader.ts +16 -2
- package/src/domains/resources/prompts/substitute.ts +1 -65
- package/src/domains/resources/skills/content-hash.ts +2 -0
- package/src/domains/resources/skills/install.ts +17 -0
- package/src/domains/resources/skills/loader.ts +17 -10
- package/src/domains/resources/skills/marketplace.ts +55 -9
- package/src/domains/safety/action-classifier.ts +4 -2
- package/src/domains/safety/audit.ts +8 -2
- package/src/domains/safety/extension.ts +1 -1
- package/src/domains/session/compaction/branch-summary.ts +3 -2
- package/src/domains/session/compaction/cut-point.ts +2 -1
- package/src/domains/session/compaction/tokens.ts +2 -1
- package/src/domains/session/context-ledger.ts +14 -0
- package/src/domains/session/contract.ts +15 -0
- package/src/domains/session/decision-board.ts +190 -0
- package/src/domains/session/entries.ts +66 -3
- package/src/domains/session/extension.ts +93 -12
- package/src/domains/session/retry.ts +10 -18
- package/src/domains/session/session-artifacts.ts +107 -0
- package/src/domains/session/task-board.ts +207 -13
- package/src/domains/session/tree/active-path.ts +44 -5
- package/src/domains/session/tree/fork.ts +26 -27
- package/src/domains/session/tree/preview.ts +2 -2
- package/src/domains/session/workspace/git-probe.ts +17 -11
- package/src/domains/user-tasks/store.ts +297 -0
- package/src/engine/acp/errors.ts +96 -0
- package/src/engine/acp/server.ts +1728 -146
- package/src/engine/acp/transport.ts +135 -14
- package/src/engine/acp/types.ts +26 -0
- package/src/engine/agent.ts +3 -3
- package/src/engine/ai.ts +32 -27
- package/src/engine/alcf-oauth.ts +26 -19
- package/src/engine/api-registry.ts +223 -0
- package/src/engine/apis/index.ts +3 -7
- package/src/engine/apis/llamacpp-residency.ts +49 -9
- package/src/engine/apis/lmstudio-residency.ts +5 -21
- package/src/engine/apis/lmstudio.ts +243 -0
- package/src/engine/apis/ollama-native.ts +24 -3
- package/src/engine/apis/openai-completions.ts +170 -91
- package/src/engine/apis/residency.ts +139 -3
- package/src/engine/apis/types.ts +16 -0
- package/src/engine/env-api-keys.ts +98 -0
- package/src/engine/gemma-channel-filter.ts +223 -0
- package/src/engine/instrumented-tui.ts +192 -0
- package/src/engine/messages.ts +14 -0
- package/src/engine/models.ts +42 -0
- package/src/engine/oauth.ts +16 -12
- package/src/engine/prompt-templates.ts +1 -0
- package/src/engine/provider-payload.ts +16 -59
- package/src/engine/strip-tokenizer-sentinels.ts +1 -1
- package/src/engine/truncate.ts +9 -0
- package/src/engine/tui.ts +17 -9
- package/src/engine/types.ts +3 -6
- package/src/engine/worker-runtime-capabilities.ts +5 -0
- package/src/engine/worker-runtime.ts +1 -1
- package/src/engine/worker-tools.ts +9 -4
- package/src/entry/boot-options.ts +50 -0
- package/src/entry/orchestrator.ts +288 -150
- package/src/interactive/application-controller.ts +89 -2
- package/src/interactive/chat-loop.ts +266 -41
- package/src/interactive/chat-panel.ts +715 -278
- package/src/interactive/chat-renderer.ts +306 -85
- package/src/interactive/clio-editor.ts +3 -8
- package/src/interactive/command-fallbacks.ts +2 -2
- package/src/interactive/context-overlay.ts +27 -1
- package/src/interactive/editor-submit.ts +253 -24
- package/src/interactive/export-html/ansi-to-html.ts +161 -0
- package/src/interactive/export-html/index.ts +51 -0
- package/src/interactive/export-html/template.ts +45 -0
- package/src/interactive/export-html/tool-renderer.ts +54 -0
- package/src/interactive/footer/dashboard.ts +4 -0
- package/src/interactive/footer/notifications.ts +1 -1
- package/src/interactive/footer/widgets.ts +42 -22
- package/src/interactive/footer-panel.ts +8 -3
- package/src/interactive/format-time.ts +14 -2
- package/src/interactive/interactive-application.ts +203 -17
- package/src/interactive/interactive-event-projection.ts +18 -1
- package/src/interactive/interactive-input-runtime.ts +50 -4
- package/src/interactive/interactive-presentation.ts +151 -19
- package/src/interactive/interactive-shell.ts +268 -14
- package/src/interactive/interactive-slash-runtime.ts +184 -117
- package/src/interactive/interactive-tickers.ts +38 -7
- package/src/interactive/keybinding-manager.ts +1 -1
- package/src/interactive/layout.ts +40 -3
- package/src/interactive/overlay-frame.ts +1 -1
- package/src/interactive/overlay-general-openers.ts +58 -1
- package/src/interactive/overlay-key-routing.ts +3 -0
- package/src/interactive/overlay-lifecycle.ts +13 -0
- package/src/interactive/overlay-permission-lifecycle.ts +2 -1
- package/src/interactive/overlay-session-lifecycle.ts +69 -12
- package/src/interactive/overlays/ask-user.ts +146 -24
- package/src/interactive/overlays/decisions.ts +300 -0
- package/src/interactive/overlays/help-reference.ts +15 -10
- package/src/interactive/overlays/model-selector.ts +34 -16
- package/src/interactive/overlays/session-selector.ts +18 -0
- package/src/interactive/overlays/settings.ts +105 -17
- package/src/interactive/overlays/skills-hub.ts +4 -4
- package/src/interactive/overlays/tree-selector.ts +41 -6
- package/src/interactive/render-trace.ts +499 -90
- package/src/interactive/renderers/compaction-summary.ts +2 -2
- package/src/interactive/renderers/diff.ts +115 -104
- package/src/interactive/renderers/mermaid.ts +53 -0
- package/src/interactive/renderers/tool-execution.ts +516 -168
- package/src/interactive/renderers/worker-entry.ts +20 -4
- package/src/interactive/session-switch-settlement.ts +10 -0
- package/src/interactive/slash-autocomplete.ts +6 -114
- package/src/interactive/slash-commands.ts +135 -47
- package/src/interactive/slash-spec.ts +9 -38
- package/src/interactive/status/controller.ts +5 -1
- package/src/interactive/status/index.ts +12 -1
- package/src/interactive/status/reasoning.ts +87 -0
- package/src/interactive/status/summary.ts +13 -2
- package/src/interactive/stdout-backpressure.ts +99 -0
- package/src/interactive/stream-pacer.ts +530 -0
- package/src/interactive/stream-pacing-policy.ts +66 -0
- package/src/interactive/tasks-overlay.ts +368 -14
- package/src/interactive/terminal-lease.ts +485 -0
- package/src/interactive/theme/tokens.ts +1 -1
- package/src/interactive/transcript-detail.ts +120 -0
- package/src/interactive/turn-context.ts +4 -3
- package/src/interactive/turn-persistence.ts +30 -13
- package/src/interactive/turn-queues.ts +12 -0
- package/src/interactive/turn-recovery.ts +25 -8
- package/src/interactive/turn-runtime.ts +79 -12
- package/src/interactive/turn-state.ts +10 -0
- package/src/interactive/view/artifacts.ts +114 -4
- package/src/interactive/view/view-overlay.ts +3 -0
- package/src/interactive/welcome-dashboard.ts +17 -16
- package/src/interactive/worker-receipts.ts +52 -3
- package/src/interactive/worker-stream.ts +5 -1
- package/src/tools/agent-tools.ts +23 -3
- package/src/tools/artifact.ts +2 -2
- package/src/tools/ask-user.ts +23 -13
- package/src/tools/bash.ts +30 -2
- package/src/tools/bootstrap.ts +34 -431
- package/src/tools/builtin-tool-catalog.ts +271 -0
- package/src/tools/codewiki/code-nav-surface.ts +29 -0
- package/src/tools/codewiki/code-nav.ts +8 -22
- package/src/tools/codewiki/shared.ts +41 -38
- package/src/tools/context/docs-engine.ts +14 -3
- package/src/tools/context/index.ts +107 -28
- package/src/tools/context/surface.ts +19 -0
- package/src/tools/core-bootstrap.ts +168 -0
- package/src/tools/credential-present.ts +5 -5
- package/src/tools/dispatch-admission.ts +533 -0
- package/src/tools/dispatch-background.ts +54 -0
- package/src/tools/dispatch-event-text.ts +6 -0
- package/src/tools/dispatch-plan.ts +9 -4
- package/src/tools/dispatch-run-events.ts +238 -0
- package/src/tools/dispatch-runner.ts +2370 -0
- package/src/tools/dispatch-scout-admission.ts +295 -0
- package/src/tools/dispatch-types.ts +77 -0
- package/src/tools/dispatch.ts +67 -3161
- package/src/tools/find.ts +4 -2
- package/src/tools/grep.ts +2 -2
- package/src/tools/lazy-tool.ts +60 -0
- package/src/tools/ledger.ts +3 -3
- package/src/tools/monitor-surface.ts +36 -0
- package/src/tools/monitor.ts +2 -32
- package/src/tools/observers.ts +2 -2
- package/src/tools/presentation.ts +107 -0
- package/src/tools/registry.ts +45 -27
- package/src/tools/safe-exec.ts +2 -2
- package/src/tools/steer-surface.ts +17 -0
- package/src/tools/steer.ts +2 -13
- package/src/tools/tasks.ts +108 -11
- package/src/tools/truncate.ts +25 -184
- package/src/tools/verify/frontend.ts +3 -1
- package/src/tools/verify/index.ts +3 -38
- package/src/tools/verify/surface.ts +46 -0
- package/src/tools/web-fetch-surface.ts +23 -0
- package/src/tools/web-fetch.ts +2 -20
- package/src/tools/write.ts +7 -2
- package/src/worker/entry.ts +39 -2
- package/src/worker/spec-contract.ts +26 -5
- package/dist/chunk-7SS2CTV2.js +0 -61361
- package/dist/chunk-DKGKUHFA.js +0 -924
- package/dist/chunk-GEP36Y4X.js +0 -12796
- package/dist/chunk-XYWBQRDM.js +0 -137
- package/dist/clio-BZVGEUFJ.js +0 -58
- package/dist/configure-S7S6F6CL.js +0 -32
- package/docs/html/agents_blueprint.html +0 -936
- package/docs/html/alcf_blueprint.html +0 -324
- package/docs/html/architecture_blueprint.html +0 -850
- package/docs/html/commands_blueprint.html +0 -939
- package/docs/html/config_knobs_audit_blueprint.html +0 -178
- package/docs/html/configuration_blueprint.html +0 -1080
- package/docs/html/context_blueprint.html +0 -603
- package/docs/html/documentation_blueprint.html +0 -832
- package/docs/html/environment_blueprint.html +0 -404
- package/docs/html/eval_blueprint.html +0 -743
- package/docs/html/evals_internal_blueprint.html +0 -190
- package/docs/html/evolution_blueprint.html +0 -674
- package/docs/html/extensions_blueprint.html +0 -2065
- package/docs/html/fleet_dispatch_blueprint.html +0 -286
- package/docs/html/index.html +0 -919
- package/docs/html/lifecycle_blueprint.html +0 -723
- package/docs/html/memory_blueprint.html +0 -699
- package/docs/html/middleware_blueprint.html +0 -664
- package/docs/html/models_blueprint.html +0 -2366
- package/docs/html/observability_blueprint.html +0 -683
- package/docs/html/provider_adapter_blueprint.html +0 -245
- package/docs/html/safety_blueprint.html +0 -1386
- package/docs/html/shared.css +0 -571
- package/docs/html/shared.js +0 -143
- package/docs/html/skills_blueprint.html +0 -671
- package/docs/html/soak_blueprint.html +0 -182
- package/docs/html/tool_usage_blueprint.html +0 -350
- package/docs/html/tools_blueprint.html +0 -2249
- package/docs/html/trace_blueprint.html +0 -235
- package/docs/html/tui_design_blueprint.html +0 -374
- package/docs/html/validation_blueprint.html +0 -961
- package/docs/html/worker_dispatch_blueprint.html +0 -231
- package/src/core/release.ts +0 -2
- package/src/domains/providers/runtimes/common/lmstudio-logger.ts +0 -32
- package/src/domains/providers/runtimes/local-native/lmstudio-native.ts +0 -491
- package/src/engine/apis/lmstudio-native.ts +0 -1438
- package/src/engine/apis/thinking-replay.ts +0 -11
- package/src/tools/string-enum.ts +0 -15
package/src/cli/index.ts
CHANGED
|
@@ -5,14 +5,21 @@
|
|
|
5
5
|
// a crashed boot are both legible to `ps`, `pgrep -f`, and htop.
|
|
6
6
|
process.title = "clio-coder";
|
|
7
7
|
|
|
8
|
+
import { AI_AGENT_NAME } from "../core/agent-environment.js";
|
|
9
|
+
|
|
10
|
+
// Pi and other agent-aware developer tools use this generic marker to
|
|
11
|
+
// attribute subprocess activity without knowing Clio-specific variables.
|
|
12
|
+
// Set it unconditionally so every child inherits the actual spawning agent.
|
|
13
|
+
process.env.AI_AGENT = AI_AGENT_NAME;
|
|
14
|
+
|
|
8
15
|
// Only argument parsing and boot tracing load statically. Every subcommand is
|
|
9
16
|
// imported dynamically through the command registry (see `dispatch`), so a bare `clio`
|
|
10
17
|
// (interactive) or `clio-coder --version` pays for its own module graph and nothing
|
|
11
18
|
// else — this is the highest-value cut of the cold module-load tax. Code
|
|
12
19
|
// splitting (tsup.config.ts) keeps each command's transitive heavy externals in
|
|
13
20
|
// its own chunk.
|
|
14
|
-
import { fileURLToPath } from "node:url";
|
|
15
21
|
import { traceBoot } from "../core/boot-trace.js";
|
|
22
|
+
import { incompleteInstallationAdvice } from "../core/incomplete-installation.js";
|
|
16
23
|
import { extractGlobalFlags, parseFlags, printError } from "./argv.js";
|
|
17
24
|
|
|
18
25
|
const HELP = `Clio Coder command line
|
|
@@ -56,7 +63,7 @@ Usage:
|
|
|
56
63
|
clio-coder trace query or view the durable dispatch trace mirror
|
|
57
64
|
clio-coder extensions install, list, enable, disable, or remove extension packages
|
|
58
65
|
clio-coder skills list, inspect, validate, or install skills
|
|
59
|
-
clio-coder docs [topic] serve
|
|
66
|
+
clio-coder docs [topic] serve the HTML docs of a source checkout on 127.0.0.1 (--no-open to skip browser)
|
|
60
67
|
clio-coder dev <command> harness instruments; run 'clio-coder dev' for the list
|
|
61
68
|
clio-coder --help, -h this message
|
|
62
69
|
clio-coder --help --all this message plus every command under 'clio-coder dev'
|
|
@@ -160,6 +167,7 @@ async function main(argv: string[]): Promise<number> {
|
|
|
160
167
|
...(skillPaths.length > 0 ? { skillPaths } : {}),
|
|
161
168
|
};
|
|
162
169
|
if (!subcommand) {
|
|
170
|
+
await enableBootCompileCache();
|
|
163
171
|
const { runClioCommand } = await import("./clio.js");
|
|
164
172
|
return runClioCommand(bootOptions);
|
|
165
173
|
}
|
|
@@ -167,6 +175,21 @@ async function main(argv: string[]): Promise<number> {
|
|
|
167
175
|
return dispatch(subcommand, subArgs, bootOptions);
|
|
168
176
|
}
|
|
169
177
|
|
|
178
|
+
/**
|
|
179
|
+
* Cache the boot-path module graphs' bytecode. Only the three long-lived
|
|
180
|
+
* entrypoints that already write state enable it (interactive, `run`, `acp`);
|
|
181
|
+
* read-only and dry-run commands such as `paths` and bare `doctor` document
|
|
182
|
+
* that they create nothing, and enabling the cache creates its directory, so
|
|
183
|
+
* a dispatch-wide enable would break that promise on every initialized home.
|
|
184
|
+
* A help invocation of a boot command is itself zero-side-effect, so the
|
|
185
|
+
* guard runs before enablement, not after the module's own help check.
|
|
186
|
+
*/
|
|
187
|
+
async function enableBootCompileCache(subArgs: ReadonlyArray<string> = []): Promise<void> {
|
|
188
|
+
if (subArgs.includes("--help") || subArgs.includes("-h")) return;
|
|
189
|
+
const { enableClioCompileCache } = await import("../core/compile-cache.js");
|
|
190
|
+
enableClioCompileCache();
|
|
191
|
+
}
|
|
192
|
+
|
|
170
193
|
/**
|
|
171
194
|
* The dispatcher is also the command-recognition source used by top-level
|
|
172
195
|
* value flags. Every dynamic import stays a literal so tsup can split command
|
|
@@ -177,7 +200,13 @@ const extensionsCommand: CommandHandler = async (subArgs) =>
|
|
|
177
200
|
(await import("./extensions.js")).runExtensionsCommand(subArgs);
|
|
178
201
|
|
|
179
202
|
const COMMAND_HANDLERS = new Map<string, CommandHandler>([
|
|
180
|
-
[
|
|
203
|
+
[
|
|
204
|
+
"acp",
|
|
205
|
+
async (subArgs, bootOptions) => {
|
|
206
|
+
await enableBootCompileCache(subArgs);
|
|
207
|
+
return (await import("./acp.js")).runAcpCommand(subArgs, bootOptions);
|
|
208
|
+
},
|
|
209
|
+
],
|
|
181
210
|
["auth", async (subArgs) => (await import("./auth.js")).runAuthCommand(subArgs)],
|
|
182
211
|
["config", async (subArgs) => (await import("./config.js")).runConfigCommand(subArgs)],
|
|
183
212
|
["configure", async (subArgs) => (await import("./configure.js")).runConfigureCommand(subArgs)],
|
|
@@ -219,7 +248,13 @@ const COMMAND_HANDLERS = new Map<string, CommandHandler>([
|
|
|
219
248
|
["export", async (subArgs) => (await import("./share.js")).runExportCommand(subArgs)],
|
|
220
249
|
["import", async (subArgs) => (await import("./share.js")).runImportCommand(subArgs)],
|
|
221
250
|
["context", async (subArgs) => (await import("./context.js")).runContextCommand(subArgs)],
|
|
222
|
-
[
|
|
251
|
+
[
|
|
252
|
+
"run",
|
|
253
|
+
async (subArgs, bootOptions) => {
|
|
254
|
+
await enableBootCompileCache(subArgs);
|
|
255
|
+
return (await import("./run.js")).runClioRun(subArgs, bootOptions);
|
|
256
|
+
},
|
|
257
|
+
],
|
|
223
258
|
["doctor", async (subArgs) => (await import("./doctor.js")).runDoctorCommand(subArgs)],
|
|
224
259
|
["paths", async (subArgs) => (await import("./paths.js")).runPathsCommand(subArgs)],
|
|
225
260
|
["reset", async (subArgs) => (await import("./reset.js")).runResetCommand(subArgs)],
|
|
@@ -232,6 +267,16 @@ const COMMAND_HANDLERS = new Map<string, CommandHandler>([
|
|
|
232
267
|
// Internal: the native worker stream server (WorkerSpec on stdin,
|
|
233
268
|
// NDJSON on stdout). The entry module runs main() on import and owns
|
|
234
269
|
// process exit; this settles only on a pre-run import failure.
|
|
270
|
+
// This is how SSH placement launches a worker on the remote install,
|
|
271
|
+
// where no local spawn boundary injected NODE_COMPILE_CACHE, so the
|
|
272
|
+
// worker graph enables the remote cache itself before it loads. The
|
|
273
|
+
// enable is in-process only: no environment variable is set, so the
|
|
274
|
+
// worker's own children inherit nothing. Nothing on this path
|
|
275
|
+
// injected the provenance pair either, so any marker present is
|
|
276
|
+
// foreign; strip it (and only it) so the entry's consume can never
|
|
277
|
+
// match and delete an operator's own NODE_COMPILE_CACHE.
|
|
278
|
+
Reflect.deleteProperty(process.env, "CLIO_CODER_INJECTED_COMPILE_CACHE");
|
|
279
|
+
await enableBootCompileCache();
|
|
235
280
|
await import("../worker/entry.js");
|
|
236
281
|
return 0;
|
|
237
282
|
},
|
|
@@ -257,27 +302,6 @@ function isCommandToken(token: string): boolean {
|
|
|
257
302
|
* this repository can act on. The filter on our own output directory keeps a
|
|
258
303
|
* module error raised by a user's extension or hook reporting itself normally.
|
|
259
304
|
*/
|
|
260
|
-
function incompleteInstallationAdvice(err: unknown): string | null {
|
|
261
|
-
if ((err as NodeJS.ErrnoException | undefined)?.code !== "ERR_MODULE_NOT_FOUND") return null;
|
|
262
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
263
|
-
let outputDir: string;
|
|
264
|
-
try {
|
|
265
|
-
outputDir = fileURLToPath(new URL("../", import.meta.url));
|
|
266
|
-
} catch {
|
|
267
|
-
return null;
|
|
268
|
-
}
|
|
269
|
-
if (!message.includes(outputDir)) return null;
|
|
270
|
-
return [
|
|
271
|
-
`${message}`,
|
|
272
|
-
"",
|
|
273
|
-
"This Clio Coder installation is incomplete: the command's own module is missing from",
|
|
274
|
-
`${outputDir}`,
|
|
275
|
-
"Reinstall to restore it, using the line that matches how you installed:",
|
|
276
|
-
" npm install -g @iowarp/clio-coder # npm install",
|
|
277
|
-
" npm run install:local # source checkout",
|
|
278
|
-
].join("\n");
|
|
279
|
-
}
|
|
280
|
-
|
|
281
305
|
/**
|
|
282
306
|
* Route a subcommand to its registered handler, importing only that command's
|
|
283
307
|
* module. Unknown names fail before loading any command graph.
|
|
@@ -295,7 +319,12 @@ async function dispatch(subcommand: string, subArgs: string[], bootOptions: CliB
|
|
|
295
319
|
}
|
|
296
320
|
}
|
|
297
321
|
printError(`unknown subcommand: ${subcommand}`);
|
|
298
|
-
|
|
322
|
+
// The usage that explains a rejection belongs with the rejection on stderr.
|
|
323
|
+
// Writing it to stdout meant a mistyped command still produced a full page on
|
|
324
|
+
// the stream the caller was capturing for output, next to an error on the one
|
|
325
|
+
// it was probably not reading. `clio-coder --help` is the request for this
|
|
326
|
+
// text, and it still answers on stdout with exit 0.
|
|
327
|
+
process.stderr.write(helpText(false));
|
|
299
328
|
return 2;
|
|
300
329
|
}
|
|
301
330
|
|
package/src/cli/memory.ts
CHANGED
|
@@ -92,7 +92,9 @@ export async function runMemoryCommand(args: ReadonlyArray<string>): Promise<num
|
|
|
92
92
|
parsed = parseMemoryArgs(args);
|
|
93
93
|
} catch (error) {
|
|
94
94
|
printError(error instanceof Error ? error.message : String(error));
|
|
95
|
-
|
|
95
|
+
// Usage that accompanies an error goes to stderr with it; see the same
|
|
96
|
+
// note in evidence.ts.
|
|
97
|
+
process.stderr.write(HELP);
|
|
96
98
|
return 2;
|
|
97
99
|
}
|
|
98
100
|
if (parsed.help) {
|
package/src/cli/models.ts
CHANGED
|
@@ -117,7 +117,7 @@ export async function runModelsCommand(args: ReadonlyArray<string>): Promise<num
|
|
|
117
117
|
return 0;
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
function collectRows(entries: ReadonlyArray<TargetStatus>, providers: ProvidersContract): ModelRow[] {
|
|
120
|
+
export function collectRows(entries: ReadonlyArray<TargetStatus>, providers: ProvidersContract): ModelRow[] {
|
|
121
121
|
const rows: ModelRow[] = [];
|
|
122
122
|
for (const status of entries) {
|
|
123
123
|
const runtimeId = status.runtime?.id ?? status.target.runtime;
|
|
@@ -14,6 +14,13 @@
|
|
|
14
14
|
* the `message_end` that follows.
|
|
15
15
|
* - `text_delta` / `thinking_delta` carry the increment, not the growing
|
|
16
16
|
* partial text.
|
|
17
|
+
* - `message_end` keeps the message's accounting (role, model, usage, stop
|
|
18
|
+
* reason, tool calls) and replaces the assistant `text` and `thinking`
|
|
19
|
+
* blocks the deltas already carried with a marker naming their length.
|
|
20
|
+
* Without this the stream carried every assistant token twice: measured on
|
|
21
|
+
* one run, 41,094 bytes of deltas alongside 24,600 bytes of `message_end`
|
|
22
|
+
* re-stating the same thinking and text. `user` and `toolResult` messages
|
|
23
|
+
* pass through whole, because nothing else on the stream carries them.
|
|
17
24
|
* - `agent_end` carries its segment's usage and message count, not a second
|
|
18
25
|
* copy of every message already streamed.
|
|
19
26
|
* - `turn_end` keeps its assistant message (stop reason and usage live
|
|
@@ -34,13 +41,42 @@ export function projectHeadlessJsonEvent(event: ChatLoopEvent): unknown | null {
|
|
|
34
41
|
if (event.type === "thinking_delta") {
|
|
35
42
|
return { type: event.type, contentIndex: event.contentIndex, delta: event.delta };
|
|
36
43
|
}
|
|
44
|
+
if (event.type === "message_end") {
|
|
45
|
+
return { ...event, message: withoutStreamedContent(event.message) };
|
|
46
|
+
}
|
|
37
47
|
if (event.type === "agent_end") return segmentSummary(event.type, event.messages);
|
|
38
48
|
if (event.type === "turn_end") {
|
|
39
|
-
return { type: event.type, message: event.message };
|
|
49
|
+
return { type: event.type, message: withoutStreamedContent(event.message) };
|
|
40
50
|
}
|
|
41
51
|
return event;
|
|
42
52
|
}
|
|
43
53
|
|
|
54
|
+
/**
|
|
55
|
+
* Replace the content blocks a reader has already received as deltas.
|
|
56
|
+
*
|
|
57
|
+
* Only an assistant message streams: its `text` and `thinking` blocks arrive
|
|
58
|
+
* incrementally as `text_delta` and `thinking_delta` keyed by the same
|
|
59
|
+
* `contentIndex` this array is indexed by, so a reader reassembles them itself.
|
|
60
|
+
* `toolCall` blocks never stream and are kept whole. A `user` or `toolResult`
|
|
61
|
+
* message is returned untouched, because no delta ever carried it.
|
|
62
|
+
*/
|
|
63
|
+
function withoutStreamedContent<T>(message: T): T {
|
|
64
|
+
if (!isRecord(message) || message.role !== "assistant" || !Array.isArray(message.content)) return message;
|
|
65
|
+
const content = message.content.map((block: unknown) => {
|
|
66
|
+
if (!isRecord(block)) return block;
|
|
67
|
+
if (block.type === "text" && typeof block.text === "string") {
|
|
68
|
+
const { text: _text, ...rest } = block;
|
|
69
|
+
return { ...rest, streamed: true, textLength: block.text.length };
|
|
70
|
+
}
|
|
71
|
+
if (block.type === "thinking" && typeof block.thinking === "string") {
|
|
72
|
+
const { thinking: _thinking, ...rest } = block;
|
|
73
|
+
return { ...rest, streamed: true, thinkingLength: block.thinking.length };
|
|
74
|
+
}
|
|
75
|
+
return block;
|
|
76
|
+
});
|
|
77
|
+
return { ...message, content } as T;
|
|
78
|
+
}
|
|
79
|
+
|
|
44
80
|
/**
|
|
45
81
|
* Projection for the dispatch `--json` stream, whose events come off a worker
|
|
46
82
|
* rather than out of the chat loop.
|
package/src/cli/modes/print.ts
CHANGED
|
@@ -211,14 +211,29 @@ function countToolStats(stats: Map<string, ToolCallStat>): number {
|
|
|
211
211
|
return count;
|
|
212
212
|
}
|
|
213
213
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
"
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
214
|
+
function prefixHeadlessFailure(chat: ChatLoop, message: string): string {
|
|
215
|
+
const snapshot = chat.lastRunSnapshot?.();
|
|
216
|
+
if (!snapshot) return message;
|
|
217
|
+
const url = snapshot.targetUrl ?? "endpoint unavailable";
|
|
218
|
+
return `target '${snapshot.targetId}' (${snapshot.runtimeId} ${url}): ${message}`;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* The events `--json-events terminal` lets through, alongside the `turn_start`
|
|
223
|
+
* and `turn_end` frames this mode synthesizes itself.
|
|
224
|
+
*
|
|
225
|
+
* The mode's contract is the run receipt and nothing else. It used to admit
|
|
226
|
+
* `message_end`, which is the largest event on the stream and carries the
|
|
227
|
+
* injected system reminders, the operator's prompt, and every thinking block:
|
|
228
|
+
* "Say OK." produced 39.8 KB. `agent_start` and the two `tool_execution_*`
|
|
229
|
+
* events are per-step progress, which is what `--json-events full` is for.
|
|
230
|
+
*
|
|
231
|
+
* `turn_end` is deliberately absent even though the mode emits one. The
|
|
232
|
+
* synthesized frame carries `startedAt`, `endedAt`, and `exitCode`; the streamed
|
|
233
|
+
* event of the same name carries the turn's assistant message instead. Letting
|
|
234
|
+
* both through would put two different shapes behind one `type` on one stream.
|
|
235
|
+
*/
|
|
236
|
+
const TERMINAL_JSON_EVENT_TYPES = new Set(["agent_end", "notice"]);
|
|
222
237
|
|
|
223
238
|
function isMainAgentRunKind(value: string): value is RunKind {
|
|
224
239
|
return value === "http" || value === "sdk" || value === "subprocess";
|
|
@@ -542,7 +557,7 @@ export async function runHeadlessMainAgent(chat: ChatLoop, options: HeadlessMain
|
|
|
542
557
|
stderrMessage = result.abortReason;
|
|
543
558
|
} else if (result.error) {
|
|
544
559
|
terminal = { exitCode: 1, outcome: "failed", status: "failed", failureMessage: result.error };
|
|
545
|
-
stderrMessage = result.error;
|
|
560
|
+
stderrMessage = prefixHeadlessFailure(chat, result.error);
|
|
546
561
|
} else if (result.text.length === 0 && !result.sawTerminatingToolResult) {
|
|
547
562
|
const failureMessage =
|
|
548
563
|
result.lastNotice !== null
|
package/src/cli/run.ts
CHANGED
|
@@ -7,7 +7,7 @@ import type { AgentsContract } from "../domains/agents/contract.js";
|
|
|
7
7
|
import { AgentsDomainModule } from "../domains/agents/index.js";
|
|
8
8
|
import type { ConfigContract } from "../domains/config/contract.js";
|
|
9
9
|
import { ConfigDomainModule } from "../domains/config/index.js";
|
|
10
|
-
import { createContextDomainModule } from "../domains/context/
|
|
10
|
+
import { createContextDomainModule } from "../domains/context/runtime.js";
|
|
11
11
|
import type { DispatchContract, DispatchRequest } from "../domains/dispatch/contract.js";
|
|
12
12
|
import { agentRoleFactsResolver, requestExecutionRole } from "../domains/dispatch/execution-role.js";
|
|
13
13
|
import { createDispatchDomainModule } from "../domains/dispatch/index.js";
|
|
@@ -28,7 +28,7 @@ import { SafetyDomainModule } from "../domains/safety/index.js";
|
|
|
28
28
|
import { SchedulingDomainModule } from "../domains/scheduling/index.js";
|
|
29
29
|
import { SessionDomainModule } from "../domains/session/index.js";
|
|
30
30
|
import type { ImageContent } from "../engine/types.js";
|
|
31
|
-
import { assistantTextFromEvent } from "../tools/dispatch.js";
|
|
31
|
+
import { assistantTextFromEvent } from "../tools/dispatch-event-text.js";
|
|
32
32
|
import { isToolProfileName } from "../tools/profiles.js";
|
|
33
33
|
import { parseRunCliArgs, type RunCliArgs } from "./args.js";
|
|
34
34
|
import { runClioCommand } from "./clio.js";
|
package/src/cli/skills-eval.ts
CHANGED
|
@@ -33,7 +33,7 @@ import { formatColumns, printError } from "./shared.js";
|
|
|
33
33
|
* `evals.md` with RED-GREEN scenarios; this lane executes them instead of
|
|
34
34
|
* trusting the prose: per scenario one baseline headless run (no skills), one
|
|
35
35
|
* treatment run (the skill loaded via the explicit --skill path and invoked
|
|
36
|
-
* with /skill
|
|
36
|
+
* with /skill <name>), then one judge run that scores each Expected bullet
|
|
37
37
|
* pass/fail from the two transcripts.
|
|
38
38
|
*
|
|
39
39
|
* Deltas from the task-file eval harness, recorded rather than papered over:
|
|
@@ -302,10 +302,12 @@ function describeArmPolicyOutcome(allowNetwork: boolean): string {
|
|
|
302
302
|
type EvalArm = "baseline" | "treatment" | "judge";
|
|
303
303
|
|
|
304
304
|
/**
|
|
305
|
-
* The argv for one arm's child `clio-coder run`. Every arm streams
|
|
306
|
-
*
|
|
307
|
-
*
|
|
308
|
-
*
|
|
305
|
+
* The argv for one arm's child `clio-coder run`. Every arm streams the full JSON
|
|
306
|
+
* event sequence because the evaluator scores assistant messages and tool
|
|
307
|
+
* evidence, while terminal mode is intentionally receipt-only. A turn that ends
|
|
308
|
+
* on a terminating tool carries its content in the full event stream rather
|
|
309
|
+
* than text mode. Discovery stays off so only the treatment arm's explicit
|
|
310
|
+
* skill loads.
|
|
309
311
|
*
|
|
310
312
|
* @internal Exported for contract tests.
|
|
311
313
|
*/
|
|
@@ -314,7 +316,7 @@ export function armRunArgs(
|
|
|
314
316
|
prompt: string,
|
|
315
317
|
options: { target?: string | undefined; skillBaseDir?: string | undefined } = {},
|
|
316
318
|
): string[] {
|
|
317
|
-
const args = ["run", "--json", "--json-events", "
|
|
319
|
+
const args = ["run", "--json", "--json-events", "full", "--no-skills"];
|
|
318
320
|
if (arm !== "judge") args.push("--autonomy", ARM_AUTONOMY);
|
|
319
321
|
if (options.skillBaseDir !== undefined) args.push("--skill", options.skillBaseDir);
|
|
320
322
|
if (options.target !== undefined) args.push("--target", options.target);
|
|
@@ -465,7 +467,7 @@ async function runScenario(
|
|
|
465
467
|
childEnv,
|
|
466
468
|
);
|
|
467
469
|
const treatment = await captureHeadlessRun(
|
|
468
|
-
armRunArgs("treatment", `/skill
|
|
470
|
+
armRunArgs("treatment", `/skill ${skillName} ${scenario.setup}`, { target, skillBaseDir }),
|
|
469
471
|
runWorkspaces.treatment,
|
|
470
472
|
timeoutMs,
|
|
471
473
|
childEnv,
|
|
@@ -817,6 +819,7 @@ export function parseRunStdout(stdout: string): { sessionId: string | null; tran
|
|
|
817
819
|
const lines: string[] = [];
|
|
818
820
|
let finalText = "";
|
|
819
821
|
let sawJson = false;
|
|
822
|
+
const streamedText = new Map<number, string>();
|
|
820
823
|
// Tool calls whose result is the skill's own SKILL.md. Correlated by
|
|
821
824
|
// toolCallId, which both the start and end events carry.
|
|
822
825
|
const skillBodyCallIds = new Set<string>();
|
|
@@ -834,6 +837,11 @@ export function parseRunStdout(stdout: string): { sessionId: string | null; tran
|
|
|
834
837
|
sessionId = event.id;
|
|
835
838
|
continue;
|
|
836
839
|
}
|
|
840
|
+
if (event.type === "text_delta" && typeof event.delta === "string") {
|
|
841
|
+
const contentIndex = typeof event.contentIndex === "number" ? event.contentIndex : 0;
|
|
842
|
+
streamedText.set(contentIndex, `${streamedText.get(contentIndex) ?? ""}${event.delta}`);
|
|
843
|
+
continue;
|
|
844
|
+
}
|
|
837
845
|
if (event.type === "tool_execution_start") {
|
|
838
846
|
const tool = readString(event.toolName) ?? readString(event.tool) ?? "tool";
|
|
839
847
|
const args = event.args ?? event.arguments ?? event.input;
|
|
@@ -865,13 +873,20 @@ export function parseRunStdout(stdout: string): { sessionId: string | null; tran
|
|
|
865
873
|
}
|
|
866
874
|
if (event.type === "message_end" && isRecord(event.message) && event.message.role === "assistant") {
|
|
867
875
|
const content = Array.isArray(event.message.content) ? event.message.content : [];
|
|
868
|
-
const
|
|
876
|
+
const completedText = content
|
|
869
877
|
.filter((item): item is { type: "text"; text: string } => {
|
|
870
878
|
return isRecord(item) && item.type === "text" && typeof item.text === "string";
|
|
871
879
|
})
|
|
872
880
|
.map((item) => item.text)
|
|
873
881
|
.join("")
|
|
874
882
|
.trim();
|
|
883
|
+
const streamed = [...streamedText.entries()]
|
|
884
|
+
.sort(([left], [right]) => left - right)
|
|
885
|
+
.map(([, text]) => text)
|
|
886
|
+
.join("")
|
|
887
|
+
.trim();
|
|
888
|
+
streamedText.clear();
|
|
889
|
+
const text = completedText.length > 0 ? completedText : streamed;
|
|
875
890
|
if (text.length > 0) {
|
|
876
891
|
lines.push(`ASSISTANT: ${text}`);
|
|
877
892
|
finalText = text;
|
package/src/cli/skills.ts
CHANGED
|
@@ -27,8 +27,10 @@ Commands:
|
|
|
27
27
|
clio-coder skills sync [--force]
|
|
28
28
|
clio-coder skills eval <name|path> [--scenario <id>] [--target <id>] [--workspace <path>] [--timeout <seconds>] [--trust-fixtures] [--allow-network] [--json]
|
|
29
29
|
|
|
30
|
-
search covers installed skills plus the local marketplace
|
|
31
|
-
catalog,
|
|
30
|
+
search covers installed skills plus the local marketplace: CLIO_CODER_SKILL_CATALOG_DIR,
|
|
31
|
+
a repo skills/ catalog, or the catalog and skill-marketplace.json index the
|
|
32
|
+
installed clio-coder package carries. Installing from the shipped catalog copies
|
|
33
|
+
local files and needs no network.
|
|
32
34
|
|
|
33
35
|
install resolves a bare name through that marketplace; a path or GitHub URL
|
|
34
36
|
installs directly, and an existing local path always wins over a same-named
|
|
@@ -198,6 +200,9 @@ function skillRows(skills: ReadonlyArray<Skill>): string[][] {
|
|
|
198
200
|
skill.trusted ? "trusted" : "untrusted",
|
|
199
201
|
skill.disableModelInvocation ? "manual" : "model",
|
|
200
202
|
skill.hash.slice(0, 12),
|
|
203
|
+
// Blank for the ordinary operator-installed case; a worker install is
|
|
204
|
+
// the anomaly worth a column, so it is the only value that ever prints.
|
|
205
|
+
skill.provenance?.installedBy ?? "",
|
|
201
206
|
skill.description,
|
|
202
207
|
]);
|
|
203
208
|
}
|
|
@@ -208,7 +213,7 @@ function printList(skills: ReadonlyArray<Skill>): void {
|
|
|
208
213
|
return;
|
|
209
214
|
}
|
|
210
215
|
process.stdout.write(
|
|
211
|
-
formatColumns([["name", "scope", "source", "trust", "invoke", "hash", "description"], ...skillRows(skills)]),
|
|
216
|
+
formatColumns([["name", "scope", "source", "trust", "invoke", "hash", "by", "description"], ...skillRows(skills)]),
|
|
212
217
|
);
|
|
213
218
|
}
|
|
214
219
|
|
|
@@ -222,6 +227,9 @@ function printInspect(skill: Skill): void {
|
|
|
222
227
|
process.stdout.write(`trusted: ${skill.trusted}\n`);
|
|
223
228
|
process.stdout.write(`disableModelInvocation: ${skill.disableModelInvocation}\n`);
|
|
224
229
|
process.stdout.write(`hash: ${skill.hash}\n`);
|
|
230
|
+
if (skill.provenance?.installedBy) {
|
|
231
|
+
process.stdout.write(`installed-by: ${skill.provenance.installedBy}\n`);
|
|
232
|
+
}
|
|
225
233
|
if (skill.diagnostics.length > 0) {
|
|
226
234
|
process.stdout.write("diagnostics:\n");
|
|
227
235
|
for (const diag of skill.diagnostics) process.stdout.write(` ${diag.type}: ${diag.message}\n`);
|
|
@@ -249,10 +257,17 @@ export async function runSkillsCommand(argv: ReadonlyArray<string>): Promise<num
|
|
|
249
257
|
process.stderr.write(HELP);
|
|
250
258
|
return 2;
|
|
251
259
|
}
|
|
252
|
-
if (parsed.help
|
|
260
|
+
if (parsed.help) {
|
|
253
261
|
process.stdout.write(HELP);
|
|
254
262
|
return 0;
|
|
255
263
|
}
|
|
264
|
+
// A bare `clio-coder skills` is a missing required argument, which the
|
|
265
|
+
// exit-code contract puts at 2 with the usage on stderr. See the same note in
|
|
266
|
+
// extensions.ts.
|
|
267
|
+
if (!parsed.command) {
|
|
268
|
+
process.stderr.write(HELP);
|
|
269
|
+
return 2;
|
|
270
|
+
}
|
|
256
271
|
switch (parsed.command) {
|
|
257
272
|
case "list": {
|
|
258
273
|
const list = loadSkills({ cwd: process.cwd() });
|
package/src/cli/targets.ts
CHANGED
|
@@ -1101,6 +1101,7 @@ interface SerializedStatus {
|
|
|
1101
1101
|
probeCapabilities?: TargetStatus["probeCapabilities"];
|
|
1102
1102
|
probeModelId?: TargetStatus["probeModelId"];
|
|
1103
1103
|
probeNotes?: TargetStatus["probeNotes"];
|
|
1104
|
+
probeSurfaces?: TargetStatus["probeSurfaces"];
|
|
1104
1105
|
discoveredModels: TargetStatus["discoveredModels"];
|
|
1105
1106
|
discoveredModelsSource?: TargetStatus["discoveredModelsSource"];
|
|
1106
1107
|
discoveredModelStates?: TargetStatus["discoveredModelStates"];
|
|
@@ -1146,5 +1147,8 @@ function serializeStatus(
|
|
|
1146
1147
|
if (status.probeNotes !== undefined) {
|
|
1147
1148
|
out.probeNotes = status.probeNotes;
|
|
1148
1149
|
}
|
|
1150
|
+
if (status.probeSurfaces !== undefined) {
|
|
1151
|
+
out.probeSurfaces = status.probeSurfaces;
|
|
1152
|
+
}
|
|
1149
1153
|
return out;
|
|
1150
1154
|
}
|
package/src/cli/text-layout.ts
CHANGED
|
@@ -14,12 +14,22 @@
|
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
/** Columns to lay out for, with a floor that keeps arithmetic non-negative. */
|
|
17
|
-
export function terminalColumns(
|
|
17
|
+
export function terminalColumns(
|
|
18
|
+
stream: { columns?: number | undefined } = process.stdout,
|
|
19
|
+
env: { COLUMNS?: string | undefined } = process.env,
|
|
20
|
+
): number {
|
|
18
21
|
const columns = stream.columns;
|
|
19
|
-
|
|
20
|
-
// width the
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
if (typeof columns === "number" && Number.isFinite(columns)) return Math.max(20, Math.floor(columns));
|
|
23
|
+
// A pipe reports no width, and the fallback used to end there: `clio-coder
|
|
24
|
+
// targets | less` was pinned to 80 with no way to widen it, which cut the
|
|
25
|
+
// port off every url and ellipsized the model column, the two the table
|
|
26
|
+
// exists to tell apart. $COLUMNS is what a shell exports for exactly this,
|
|
27
|
+
// so an operator or a CI job can say how wide the capture is.
|
|
28
|
+
const declared = Number(env.COLUMNS);
|
|
29
|
+
if (Number.isFinite(declared) && declared > 0) return Math.max(20, Math.floor(declared));
|
|
30
|
+
// 80 is the conventional answer and is also the width the fixed-width rows
|
|
31
|
+
// were implicitly written for.
|
|
32
|
+
return 80;
|
|
23
33
|
}
|
|
24
34
|
|
|
25
35
|
/** Shorten to `width`, marking the cut so a truncated value never reads as complete. */
|
package/src/cli/trace.ts
CHANGED
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
} from "../domains/observability/trace-store.js";
|
|
15
15
|
|
|
16
16
|
const HELP = `Usage:
|
|
17
|
-
clio-coder trace runs [--db PATH] [--limit N]
|
|
17
|
+
clio-coder trace runs [--db PATH] [--limit N] [--json]
|
|
18
18
|
clio-coder trace phases <runId> [--db PATH]
|
|
19
19
|
clio-coder trace tail <runId> [--follow] [--db PATH]
|
|
20
20
|
clio-coder trace procs <runId> [--db PATH]
|
|
@@ -33,6 +33,7 @@ interface ParsedTraceArgs {
|
|
|
33
33
|
follow: boolean;
|
|
34
34
|
limit: number;
|
|
35
35
|
port: number;
|
|
36
|
+
json: boolean;
|
|
36
37
|
}
|
|
37
38
|
|
|
38
39
|
function parseTraceArgs(args: string[]): ParsedTraceArgs {
|
|
@@ -42,9 +43,11 @@ function parseTraceArgs(args: string[]): ParsedTraceArgs {
|
|
|
42
43
|
let follow = false;
|
|
43
44
|
let limit = 50;
|
|
44
45
|
let port = 0;
|
|
46
|
+
let json = false;
|
|
45
47
|
for (let index = 0; index < args.length; index += 1) {
|
|
46
48
|
const arg = args[index];
|
|
47
49
|
if (arg === "--follow") follow = true;
|
|
50
|
+
else if (arg === "--json") json = true;
|
|
48
51
|
else if (arg === "--db" || arg === "--limit" || arg === "--port") {
|
|
49
52
|
const value = args[index + 1];
|
|
50
53
|
if (value === undefined) throw new Error(`${arg} requires a value`);
|
|
@@ -62,7 +65,33 @@ function parseTraceArgs(args: string[]): ParsedTraceArgs {
|
|
|
62
65
|
else if (arg?.startsWith("-")) throw new Error(`unknown trace flag: ${arg}`);
|
|
63
66
|
else if (arg !== undefined) positional.push(arg);
|
|
64
67
|
}
|
|
65
|
-
return { positional, db, dbExplicit, follow, limit, port };
|
|
68
|
+
return { positional, db, dbExplicit, follow, limit, port, json };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** Every subcommand `trace` answers to. Anything else is a usage error. */
|
|
72
|
+
const TRACE_COMMANDS = new Set(["runs", "phases", "tail", "procs", "sql", "ui"]);
|
|
73
|
+
|
|
74
|
+
/** The subcommands whose first positional is a run id. */
|
|
75
|
+
const TRACE_COMMANDS_NEEDING_RUN_ID = new Set(["phases", "tail", "procs"]);
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Reject a malformed invocation before the database is consulted.
|
|
79
|
+
*
|
|
80
|
+
* The no-database path below is a courtesy that exits 0, because a state tree
|
|
81
|
+
* nothing has written to is the empty state rather than a failure. Running it
|
|
82
|
+
* ahead of this check meant that on a fresh install every typed subcommand
|
|
83
|
+
* succeeded: `trace bogus`, `trace phases` with no run id, and `trace sql` with
|
|
84
|
+
* no query all exited 0 with the same "no trace database yet" line, so a CI step
|
|
85
|
+
* gated on one of them went on to the next line. The same invocations against a
|
|
86
|
+
* home that had a database exited 2, which is the documented behavior.
|
|
87
|
+
*/
|
|
88
|
+
function invocationError(command: string, runId: string | undefined): number | null {
|
|
89
|
+
if (!TRACE_COMMANDS.has(command)) {
|
|
90
|
+
process.stderr.write(`unknown trace command: ${command}\n${HELP}`);
|
|
91
|
+
return 2;
|
|
92
|
+
}
|
|
93
|
+
if (TRACE_COMMANDS_NEEDING_RUN_ID.has(command) && !runId) return missingRunId(command);
|
|
94
|
+
return null;
|
|
66
95
|
}
|
|
67
96
|
|
|
68
97
|
export async function runTraceCommand(args: string[]): Promise<number> {
|
|
@@ -86,6 +115,14 @@ export async function runTraceCommand(args: string[]): Promise<number> {
|
|
|
86
115
|
process.stdout.write(HELP);
|
|
87
116
|
return command === "help" ? 0 : 2;
|
|
88
117
|
}
|
|
118
|
+
const sqlQuery = parsed.positional.slice(1).join(" ");
|
|
119
|
+
const usageError = invocationError(command, runId);
|
|
120
|
+
if (usageError !== null) return usageError;
|
|
121
|
+
if (command === "sql" && !sqlQuery) {
|
|
122
|
+
process.stderr.write("trace sql requires a SELECT query\n");
|
|
123
|
+
return 2;
|
|
124
|
+
}
|
|
125
|
+
|
|
89
126
|
if (command === "ui") return runTraceUi(parsed.db, parsed.port);
|
|
90
127
|
|
|
91
128
|
// A database that was never written is the empty state, not a failure. Handing
|
|
@@ -104,29 +141,40 @@ export async function runTraceCommand(args: string[]): Promise<number> {
|
|
|
104
141
|
return 1;
|
|
105
142
|
}
|
|
106
143
|
try {
|
|
144
|
+
// Every case below is reachable only after `invocationError` accepted the
|
|
145
|
+
// command and its required positional, so the run id is present wherever
|
|
146
|
+
// this reads one.
|
|
107
147
|
switch (command) {
|
|
108
|
-
case "runs":
|
|
109
|
-
|
|
148
|
+
case "runs": {
|
|
149
|
+
const rows = reader.runs(parsed.limit);
|
|
150
|
+
if (parsed.json) process.stdout.write(`${JSON.stringify(rows, jsonBigInt, 2)}\n`);
|
|
151
|
+
else printRuns(rows);
|
|
110
152
|
return 0;
|
|
153
|
+
}
|
|
111
154
|
case "phases":
|
|
112
|
-
|
|
113
|
-
printPhases(reader.phases(runId));
|
|
155
|
+
printPhases(reader.phases(runId ?? ""));
|
|
114
156
|
return 0;
|
|
115
157
|
case "tail":
|
|
116
|
-
|
|
117
|
-
await tail(reader, runId, parsed.follow);
|
|
158
|
+
await tail(reader, runId ?? "", parsed.follow);
|
|
118
159
|
return 0;
|
|
119
160
|
case "procs":
|
|
120
|
-
|
|
121
|
-
printProcesses(reader.processes(runId));
|
|
161
|
+
printProcesses(reader.processes(runId ?? ""));
|
|
122
162
|
return 0;
|
|
123
163
|
case "sql": {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
164
|
+
// The database opened cleanly above, so anything the store objects to
|
|
165
|
+
// here is the query the operator typed: a mutating statement, more
|
|
166
|
+
// than one statement, or SQL that will not parse. All three are usage
|
|
167
|
+
// errors. Refusing `DELETE FROM runs` with exit 1 said "the command
|
|
168
|
+
// failed" when the truth is "that is not a query this accepts", and
|
|
169
|
+
// the exit-code contract puts a mutation keyword at 2.
|
|
170
|
+
let rows: unknown;
|
|
171
|
+
try {
|
|
172
|
+
rows = reader.select(sqlQuery);
|
|
173
|
+
} catch (error) {
|
|
174
|
+
process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
|
|
127
175
|
return 2;
|
|
128
176
|
}
|
|
129
|
-
process.stdout.write(`${JSON.stringify(
|
|
177
|
+
process.stdout.write(`${JSON.stringify(rows, jsonBigInt, 2)}\n`);
|
|
130
178
|
return 0;
|
|
131
179
|
}
|
|
132
180
|
default:
|
package/src/cli/upgrade.ts
CHANGED
|
@@ -172,9 +172,12 @@ export async function runUpgradeCommand(argv: ReadonlyArray<string>): Promise<nu
|
|
|
172
172
|
// After `npm install -g` the two differ until the refresh below, and that
|
|
173
173
|
// difference is the upgrade this command reports.
|
|
174
174
|
const recorded = readStateInfo()?.version ?? null;
|
|
175
|
+
// Both the dry run and the real run print this, so it stays in the mood the
|
|
176
|
+
// call site sets with "would refresh" or "refreshed". The null branch used to
|
|
177
|
+
// bake in "would write it", which a real upgrade printed after writing it.
|
|
175
178
|
const describeRefresh = (): string =>
|
|
176
179
|
recorded === null
|
|
177
|
-
? "state metadata (none recorded
|
|
180
|
+
? "state metadata (none recorded)"
|
|
178
181
|
: recorded === before
|
|
179
182
|
? `state metadata (already ${before})`
|
|
180
183
|
: `state metadata ${recorded} -> ${before}`;
|
|
@@ -233,7 +236,20 @@ export async function runUpgradeCommand(argv: ReadonlyArray<string>): Promise<nu
|
|
|
233
236
|
printError("lifecycle domain unavailable");
|
|
234
237
|
return 1;
|
|
235
238
|
}
|
|
236
|
-
|
|
239
|
+
let result: Awaited<ReturnType<LifecycleContract["runMigrations"]>>;
|
|
240
|
+
try {
|
|
241
|
+
result = await lifecycle.runMigrations(stateDir);
|
|
242
|
+
} catch (err) {
|
|
243
|
+
// A migration reports why it could not run, but on its own that reads
|
|
244
|
+
// as the whole upgrade being impossible. It is not: the rest of the
|
|
245
|
+
// upgrade is independent of it, and naming the flag that runs the rest
|
|
246
|
+
// is the difference between a stuck operator and a moved one.
|
|
247
|
+
printError(
|
|
248
|
+
`migration failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
249
|
+
"the rest of the upgrade does not depend on it; run `clio-coder upgrade --skip-migrations` to continue, then fix the cause and re-run `clio-coder upgrade`.",
|
|
250
|
+
);
|
|
251
|
+
return 1;
|
|
252
|
+
}
|
|
237
253
|
appliedIds = [...result.applied];
|
|
238
254
|
appliedCount = appliedIds.length;
|
|
239
255
|
if (appliedCount === 0) {
|