@iowarp/clio-coder 0.3.0 → 0.3.2
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 +123 -2
- package/CONTRIBUTING.md +23 -23
- package/README.md +295 -627
- package/dist/acp-BIYHVZIM.js +128 -0
- package/dist/{agents-Q4MYPMUW.js → agents-YT6SSRIT.js} +52 -27
- package/dist/assets/codewiki.json +1 -0
- package/dist/assets/grammars/notices/@vscode__tree-sitter-wasm/LICENSE +21 -0
- package/dist/assets/grammars/notices/@vscode__tree-sitter-wasm/cgmanifest.json +16 -0
- package/dist/assets/grammars/notices/tree-sitter-wasms/LICENSE +24 -0
- package/dist/assets/grammars/tree-sitter-c-sharp.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-c.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-cpp.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-go.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-java.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-javascript.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-python.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-ruby.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-rust.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-tsx.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-typescript.wasm +0 -0
- package/dist/assets/grammars/tree-sitter.wasm +0 -0
- package/dist/{auth-O6HYIJ6J.js → auth-5TWEIYDN.js} +30 -15
- package/dist/chunk-2EHAIA3X.js +481 -0
- package/dist/{chunk-ME6DNWIU.js → chunk-2IR2NMPA.js} +12 -4
- package/dist/chunk-2SFS6XQE.js +122 -0
- package/dist/{chunk-KKKPTZLM.js → chunk-2STGEDFV.js} +8 -1
- package/dist/chunk-2VTFPG5O.js +48 -0
- package/dist/chunk-3I7MS7N2.js +40 -0
- package/dist/chunk-3R73A4XB.js +69 -0
- package/dist/{chunk-JPOWPFCU.js → chunk-3ZXDFGR5.js} +52 -23
- package/dist/chunk-4BJ5BYCE.js +61 -0
- package/dist/{chunk-26BZQOAD.js → chunk-4BPJXDWC.js} +161 -260
- package/dist/chunk-4KLWL3UC.js +18 -0
- package/dist/{chunk-5LDRNKX2.js → chunk-4VP4KH3K.js} +161 -262
- package/dist/chunk-4ZG3XFUR.js +77 -0
- package/dist/chunk-5B2AEOW5.js +5407 -0
- package/dist/chunk-5TSRNF4G.js +510 -0
- package/dist/{chunk-WD6AJM35.js → chunk-5UUP6MWO.js} +48 -69
- package/dist/{chunk-X3BR7HWV.js → chunk-5WIGXA4T.js} +7 -1
- package/dist/chunk-65DEGPJ6.js +52 -0
- package/dist/chunk-6EJMN2Y3.js +17 -0
- package/dist/chunk-6EJV5X2W.js +16405 -0
- package/dist/chunk-6N5PTWMY.js +136 -0
- package/dist/chunk-6XLNIQDB.js +27 -0
- package/dist/{chunk-XNISANGE.js → chunk-77VKQEHF.js} +171 -74
- package/dist/chunk-7CR24IG7.js +242 -0
- package/dist/{chunk-UWIJNAOB.js → chunk-7EYHLWU7.js} +907 -638
- package/dist/chunk-7MNJORFF.js +22 -0
- package/dist/{chunk-JWHCJDCI.js → chunk-A3CYT5EX.js} +257 -79
- package/dist/chunk-AGYYIBLL.js +1069 -0
- package/dist/chunk-AO4RKG4M.js +277 -0
- package/dist/chunk-APJ265NV.js +7410 -0
- package/dist/chunk-ARBGF5F7.js +174 -0
- package/dist/{chunk-TFSSEXL6.js → chunk-BMEMKKIT.js} +14 -4
- package/dist/{chunk-X3NE4WVW.js → chunk-BNAZZHFG.js} +7 -1
- package/dist/chunk-CBCAPZAA.js +229 -0
- package/dist/{chunk-QV47YRF4.js → chunk-CGKSTWHD.js} +7 -1
- package/dist/chunk-CMZWFGD2.js +352 -0
- package/dist/chunk-ECH6PKUQ.js +39 -0
- package/dist/{chunk-67MTHP2E.js → chunk-ED4KHGC3.js} +13 -5
- package/dist/chunk-EKMEHE4H.js +340 -0
- package/dist/{chunk-O4EJEDHO.js → chunk-EPVUXGXG.js} +50 -35
- package/dist/chunk-FCSXB6T2.js +338 -0
- package/dist/chunk-FJ3H4MN5.js +48 -0
- package/dist/chunk-FQ4SKYE4.js +29 -0
- package/dist/chunk-G2DE3C7R.js +644 -0
- package/dist/chunk-G4BMMOKF.js +182 -0
- package/dist/{chunk-7BHLZB3A.js → chunk-GGXXDWE4.js} +190 -1218
- package/dist/chunk-HC4CLZ2Y.js +68 -0
- package/dist/{chunk-E3NYWENM.js → chunk-HFSBBKSQ.js} +55 -61
- package/dist/chunk-HKIYEGME.js +30 -0
- package/dist/chunk-I4HZDVNP.js +73 -0
- package/dist/chunk-IGLFWIYI.js +161 -0
- package/dist/chunk-IHXBNWMM.js +137 -0
- package/dist/chunk-IKCO5N3L.js +162 -0
- package/dist/chunk-IR4CFBFN.js +56 -0
- package/dist/{chunk-DXQNI4PC.js → chunk-IWHMRKLL.js} +8 -1
- package/dist/{chunk-VOO7NYPP.js → chunk-J5HN4RYU.js} +27 -9
- package/dist/{chunk-4UQA7NCT.js → chunk-J5Q24KAG.js} +7 -2
- package/dist/{chunk-KBR4MZZR.js → chunk-JVCV3ICN.js} +7 -1
- package/dist/chunk-KJ5LWLOE.js +1077 -0
- package/dist/chunk-LBMZMYH2.js +285 -0
- package/dist/{chunk-3DANZDGR.js → chunk-LBNRH5WM.js} +100 -161
- package/dist/{chunk-TKHQ4DGZ.js → chunk-LZSJBIVT.js} +7358 -7414
- package/dist/{chunk-UGYAX5YI.js → chunk-M6SHUN7Q.js} +13 -8
- package/dist/chunk-MAW544W2.js +1882 -0
- package/dist/chunk-MBS4V7ZP.js +217 -0
- package/dist/{chunk-2J63S4SF.js → chunk-MFFY33HR.js} +167 -140
- package/dist/chunk-MNA4JGU4.js +255 -0
- package/dist/chunk-MQSRRFWA.js +3428 -0
- package/dist/{chunk-RQDWMVRB.js → chunk-MVVUPGPW.js} +138 -137
- package/dist/chunk-OAO4GE4M.js +619 -0
- package/dist/chunk-OHHN2SO4.js +5135 -0
- package/dist/chunk-OKGUZO2U.js +34 -0
- package/dist/{chunk-BBUH4VAA.js → chunk-OOJYHWRB.js} +60 -361
- package/dist/{chunk-D5YD55AR.js → chunk-OQ33BKR3.js} +12 -1
- package/dist/chunk-OQE5J4C6.js +73 -0
- package/dist/{chunk-AMFR5YA3.js → chunk-ORBHGJC5.js} +26 -12
- package/dist/chunk-POHLU5DW.js +1186 -0
- package/dist/chunk-QKMUKYO7.js +4961 -0
- package/dist/{chunk-7RBKDI66.js → chunk-QTYWRVRA.js} +104 -12
- package/dist/{chunk-5N2FG33Q.js → chunk-R346GLFC.js} +7 -1
- package/dist/chunk-SRF2PJNW.js +184 -0
- package/dist/chunk-SST6Z5JA.js +80 -0
- package/dist/{chunk-XV4ZJ6ZM.js → chunk-STBPMHSX.js} +473 -1194
- package/dist/{chunk-HBU5MTAM.js → chunk-SVNXH4L2.js} +7 -1
- package/dist/chunk-T6YILFSB.js +80 -0
- package/dist/chunk-TXOTCRLG.js +15 -0
- package/dist/chunk-TZTZS7QK.js +227 -0
- package/dist/chunk-UOV2BYIW.js +107 -0
- package/dist/{chunk-527KG6XR.js → chunk-V4RXGQ5Q.js} +72 -185
- package/dist/chunk-VAKQQHWR.js +434 -0
- package/dist/chunk-VG7TBQIY.js +128 -0
- package/dist/chunk-VJWL6YS5.js +244 -0
- package/dist/chunk-WEH5XRJQ.js +32 -0
- package/dist/{chunk-VPAWTYLY.js → chunk-WEPFGWHJ.js} +7 -1
- package/dist/chunk-WMSVI4G2.js +2095 -0
- package/dist/chunk-WVO7V2QY.js +797 -0
- package/dist/chunk-X4RCMKVQ.js +641 -0
- package/dist/chunk-X75S7HFS.js +374 -0
- package/dist/chunk-XN3L4EYL.js +46 -0
- package/dist/{chunk-HMYNFFY4.js → chunk-XPLRXC72.js} +7 -2
- package/dist/{chunk-PIDUD6M2.js → chunk-YCWGATWI.js} +12 -5
- package/dist/chunk-YHZX5GEU.js +193 -0
- package/dist/chunk-YXLYO42X.js +91 -0
- package/dist/{chunk-UHTSULZS.js → chunk-ZDOOVTXZ.js} +38 -73
- package/dist/chunk-ZI647VB5.js +37 -0
- package/dist/{chunk-CLJ5HLUD.js → chunk-ZWLZP4ZT.js} +25 -6
- package/dist/cli/index.js +70 -56
- package/dist/clio-4LY5K2AC.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-JVHMUBEB.js → components-KELWS457.js} +31 -9
- package/dist/{config-ZFCDBMDC.js → config-GTLUW2PR.js} +104 -56
- package/dist/configure-R6A64DHX.js +42 -0
- package/dist/context-5VKGUVJJ.js +866 -0
- package/dist/{context-CDXTP2MP.js → context-JFZEJ7W5.js} +21 -13
- package/dist/{context-E3KIFVXI.js → context-RW5HC47S.js} +77 -36
- package/dist/{context-clear-3F4PLXOS.js → context-clear-6ZHBAZZT.js} +64 -30
- package/dist/{context-index-Q7YSYTR3.js → context-index-BZ4UYMTC.js} +36 -24
- package/dist/dispatch-runner-VKBRCWQC.js +1997 -0
- package/dist/{docs-YIETIWZI.js → docs-2C2LTVT2.js} +32 -13
- package/dist/doctor-KI767GSN.js +87 -0
- package/dist/{eval-B3KZZESM.js → eval-XSSNATB4.js} +93 -27
- package/dist/{evidence-V67CHM35.js → evidence-UA6AWDQQ.js} +55 -27
- package/dist/{evolve-YDZSUQYA.js → evolve-QNTFGV6Z.js} +59 -26
- package/dist/{extensions-SRG7XCAH.js → extensions-QVDOHDGJ.js} +23 -8
- package/dist/{fleet-CA2CRTVG.js → fleet-Q7UOMUSG.js} +173 -56
- package/dist/fleet-preflight-DDN536IT.js +26 -0
- package/dist/{init-2OZDJE2D.js → init-WBB65ZHQ.js} +79 -34
- package/dist/{memory-3PIQQAKX.js → memory-MD3O64RI.js} +57 -28
- package/dist/{models-DY35XI7Y.js → models-BZU34YWD.js} +49 -24
- package/dist/monitor-MEQA5C3I.js +661 -0
- package/dist/{chunk-PS4PFJQP.js → orchestrator-CGFKEP27.js} +22837 -18564
- package/dist/{paths-5OMXW7Z4.js → paths-UXLN5YYZ.js} +17 -6
- package/dist/preload-P6DGH2PZ.js +13 -0
- package/dist/{reset-PIFYNOS3.js → reset-L2FQEE3E.js} +25 -13
- package/dist/{run-3VSPP24F.js → run-IV4Q6RLN.js} +115 -63
- package/dist/{share-D36RQCXM.js → share-S5BZQC5I.js} +23 -10
- package/dist/{skills-F2MRLELY.js → skills-LQEKRDTN.js} +42 -15
- package/dist/{skills-eval-E2ZTW4PL.js → skills-eval-3DC4HEWS.js} +90 -45
- package/dist/steer-GGWFUJUD.js +77 -0
- package/dist/{targets-DZMEZAH4.js → targets-C4SSGQOB.js} +78 -60
- package/dist/terminal-lease-IT5JW2NR.js +395 -0
- package/dist/{trace-7NYCUI2J.js → trace-PNCASAXC.js} +48 -17
- package/dist/tree-sitter-HGKH6LG4.js +4673 -0
- package/dist/{uninstall-AD3JWHBB.js → uninstall-FZCQCDKC.js} +19 -8
- package/dist/{upgrade-WYYBKGDY.js → upgrade-7TT7SQ3G.js} +66 -24
- package/dist/{usage-ULIDAGFF.js → usage-GV4PKT3M.js} +71 -32
- package/dist/verify-G6V4D2G7.js +716 -0
- package/dist/version-KGEG7EPO.js +21 -0
- package/dist/web-fetch-2YHJ3KTG.js +638 -0
- package/dist/{wiki-generate-PKFIX6OB.js → wiki-generate-DQF6Z66B.js} +98 -48
- package/dist/worker/entry.js +297 -54
- package/dist/workspace-G4ZWUIPR.js +22 -0
- package/docs/README.md +29 -21
- package/docs/acp.md +191 -16
- package/docs/alcf-provider.md +1 -1
- package/docs/architecture.md +157 -7
- package/docs/artifact-placement.md +101 -0
- package/docs/artifact-versions.md +1 -1
- package/docs/built-in-agents.md +4 -2
- package/docs/capacity-and-scheduling.md +1 -1
- package/docs/commands-and-modes.md +224 -97
- package/docs/config-knobs-audit.md +1 -3
- package/docs/configuration-and-targets.md +236 -38
- package/docs/context-engine.md +34 -7
- package/docs/development-pipeline.md +102 -0
- package/docs/dispatch-architecture-rationale.md +1 -1
- package/docs/documentation-coverage.md +4 -4
- package/docs/documentation-guide.md +3 -3
- package/docs/environment-variables.md +15 -6
- package/docs/eval-runner.md +3 -3
- package/docs/evals-internal.md +2 -2
- package/docs/evidence-and-memory.md +10 -2
- package/docs/evolution.md +2 -2
- package/docs/exit-codes-and-output.md +15 -9
- package/docs/extensions-and-sharing.md +25 -18
- package/docs/fleet-demo-runbook.md +22 -23
- package/docs/fleet-dispatch.md +117 -16
- package/docs/git-commit-provenance.md +120 -0
- package/docs/glossary.md +107 -15
- package/docs/installation-and-lifecycle.md +75 -17
- package/docs/middleware-and-components.md +1 -1
- package/docs/model-catalog.md +46 -15
- 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 +14 -14
- package/docs/prompt-envelope-and-tools.md +25 -4
- package/docs/provider-adapter-cookbook.md +57 -4
- package/docs/release-cut-checklist.md +129 -111
- package/docs/safety-model.md +28 -8
- 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 +101 -0
- package/docs/tool-usage.md +6 -5
- package/docs/trace-store.md +1 -1
- package/docs/troubleshooting.md +10 -7
- package/docs/tui-design.md +121 -28
- package/docs/worker-dispatch-mechanics.md +3 -3
- package/package.json +33 -36
- package/skills/README.md +5 -6
- 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/git/file-ticket/SKILL.md +107 -0
- package/skills/git/file-ticket/evals.md +54 -0
- package/skills/git/fix-issue/SKILL.md +106 -0
- package/skills/git/fix-issue/evals.md +71 -0
- package/skills/git/ship/SKILL.md +92 -0
- package/skills/git/ship/evals.md +72 -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/skill-marketplace.json +12 -20
- 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 +115 -0
- package/src/cli/agents.ts +60 -0
- package/src/cli/args.ts +280 -0
- package/src/cli/argv.ts +170 -0
- package/src/cli/ask.ts +34 -0
- package/src/cli/auth.ts +468 -0
- package/src/cli/bootstrap-generate.ts +498 -0
- package/src/cli/clio.ts +96 -0
- package/src/cli/components.ts +195 -0
- package/src/cli/config-inspect.ts +336 -0
- package/src/cli/config.ts +72 -0
- package/src/cli/configure-interop.ts +67 -0
- package/src/cli/configure-layout.ts +172 -0
- package/src/cli/configure.ts +1525 -0
- package/src/cli/context-clear.ts +76 -0
- package/src/cli/context-index.ts +100 -0
- package/src/cli/context.ts +321 -0
- package/src/cli/default-target.ts +55 -0
- package/src/cli/docs.ts +346 -0
- package/src/cli/doctor.ts +54 -0
- package/src/cli/eval.ts +315 -0
- package/src/cli/evidence.ts +225 -0
- package/src/cli/evolve.ts +219 -0
- package/src/cli/extensions.ts +214 -0
- package/src/cli/fleet.ts +868 -0
- package/src/cli/index.ts +338 -0
- package/src/cli/init.ts +219 -0
- package/src/cli/initial-message.ts +47 -0
- package/src/cli/internal-dispatch.ts +55 -0
- package/src/cli/memory.ts +182 -0
- package/src/cli/models.ts +257 -0
- package/src/cli/modes/json-stream.ts +121 -0
- package/src/cli/modes/jsonl.ts +9 -0
- package/src/cli/modes/print.ts +604 -0
- package/src/cli/oauth-manual-input.ts +72 -0
- package/src/cli/oauth-select.ts +36 -0
- package/src/cli/output-guard.ts +48 -0
- package/src/cli/paths.ts +44 -0
- package/src/cli/provider-target.ts +113 -0
- package/src/cli/removal.ts +72 -0
- package/src/cli/reset.ts +253 -0
- package/src/cli/run.ts +497 -0
- package/src/cli/share.ts +243 -0
- package/src/cli/shared.ts +60 -0
- package/src/cli/skills-eval.ts +1240 -0
- package/src/cli/skills.ts +485 -0
- package/src/cli/steer-channel.ts +86 -0
- package/src/cli/targets.ts +1154 -0
- package/src/cli/text-layout.ts +112 -0
- package/src/cli/trace.ts +322 -0
- package/src/cli/uninstall.ts +405 -0
- package/src/cli/upgrade.ts +286 -0
- package/src/cli/usage.ts +876 -0
- package/src/cli/validate-model.ts +28 -0
- package/src/cli/version.ts +7 -0
- package/src/cli/wiki-generate.ts +510 -0
- package/src/core/agent-environment.ts +7 -0
- package/src/core/artifact-paths.ts +43 -0
- package/src/core/bash-exec.ts +313 -0
- package/src/core/boot-trace.ts +42 -0
- package/src/core/bus-events.ts +744 -0
- package/src/core/bus-trace.ts +53 -0
- package/src/core/c-header-language.ts +265 -0
- package/src/core/clio-repo.ts +78 -0
- package/src/core/commit-attribution.ts +157 -0
- package/src/core/compile-cache.ts +159 -0
- package/src/core/config.ts +1722 -0
- package/src/core/context-floor.ts +33 -0
- package/src/core/defaults.ts +659 -0
- package/src/core/domain-loader.ts +177 -0
- package/src/core/event-bus.ts +94 -0
- package/src/core/file-references.ts +282 -0
- package/src/core/git-commit-attribution.ts +362 -0
- package/src/core/guardrails.ts +185 -0
- package/src/core/headless-permission.ts +21 -0
- package/src/core/incomplete-installation.ts +45 -0
- package/src/core/init.ts +223 -0
- package/src/core/json-payload.ts +58 -0
- package/src/core/package-root.ts +54 -0
- package/src/core/path-canonical.ts +37 -0
- package/src/core/process-identity.ts +41 -0
- package/src/core/recent-models.ts +91 -0
- package/src/core/residency-protection.ts +56 -0
- package/src/core/resolve-config-value.ts +88 -0
- package/src/core/response-schema.ts +279 -0
- package/src/core/run-overrides.ts +77 -0
- package/src/core/safe-exec.ts +205 -0
- package/src/core/safe-id.ts +37 -0
- package/src/core/safe-resource-write.ts +162 -0
- package/src/core/session-routing.ts +339 -0
- package/src/core/settings-layers.ts +354 -0
- package/src/core/shared-bus.ts +8 -0
- package/src/core/shell-quote.ts +26 -0
- package/src/core/skill-activation.ts +190 -0
- package/src/core/startup-timer.ts +37 -0
- package/src/core/state-file-lock.ts +219 -0
- package/src/core/termination.ts +275 -0
- package/src/core/timers.ts +38 -0
- package/src/core/tool-names.ts +65 -0
- package/src/core/verification-scripts.ts +13 -0
- package/src/core/workspace-files.ts +492 -0
- package/src/core/xdg.ts +177 -0
- package/src/domains/agents/builtins/architect.md +4 -4
- package/src/domains/agents/builtins/coder.md +3 -2
- package/src/domains/agents/builtins/debugger.md +1 -1
- package/src/domains/agents/builtins/documenter.md +1 -1
- package/src/domains/agents/builtins/git-master.md +3 -3
- package/src/domains/agents/builtins/provenance.md +1 -1
- package/src/domains/agents/builtins/researcher.md +1 -1
- package/src/domains/agents/builtins/scout.md +1 -1
- package/src/domains/agents/builtins/tester.md +1 -1
- package/src/domains/agents/builtins/verifier.md +1 -1
- package/src/domains/agents/builtins/wiki-writer.md +1 -1
- package/src/domains/agents/catalog.ts +172 -0
- package/src/domains/agents/contract.ts +16 -0
- package/src/domains/agents/extension.ts +110 -0
- package/src/domains/agents/fleet-commands.ts +154 -0
- package/src/domains/agents/fleet-contract.ts +797 -0
- package/src/domains/agents/frontmatter.ts +40 -0
- package/src/domains/agents/index.ts +102 -0
- package/src/domains/agents/manifest.ts +6 -0
- package/src/domains/agents/recipe-schema.ts +202 -0
- package/src/domains/agents/recipe.ts +125 -0
- package/src/domains/agents/registry.ts +111 -0
- package/src/domains/agents/result-contract.ts +1265 -0
- package/src/domains/agents/spec.ts +371 -0
- package/src/domains/agents/write-boundary.ts +109 -0
- package/src/domains/components/diff.ts +99 -0
- package/src/domains/components/hash.ts +21 -0
- package/src/domains/components/index.ts +3 -0
- package/src/domains/components/scan.ts +304 -0
- package/src/domains/components/snapshot.ts +108 -0
- package/src/domains/components/types.ts +82 -0
- package/src/domains/config/agent-namespace.ts +13 -0
- package/src/domains/config/classify.ts +106 -0
- package/src/domains/config/contract.ts +22 -0
- package/src/domains/config/extension.ts +142 -0
- package/src/domains/config/index.ts +23 -0
- package/src/domains/config/keybindings.ts +200 -0
- package/src/domains/config/manifest.ts +6 -0
- package/src/domains/config/watcher.ts +41 -0
- package/src/domains/context/adoption.ts +880 -0
- package/src/domains/context/bootstrap-prompt.ts +273 -0
- package/src/domains/context/bootstrap.ts +1502 -0
- package/src/domains/context/clear.ts +91 -0
- package/src/domains/context/clio-md.ts +429 -0
- 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/cmake.ts +356 -0
- package/src/domains/context/codewiki/cooperative.ts +46 -0
- package/src/domains/context/codewiki/coordinator.ts +182 -0
- package/src/domains/context/codewiki/digest.ts +135 -0
- package/src/domains/context/codewiki/grammar-assets.ts +33 -0
- package/src/domains/context/codewiki/indexer.ts +1529 -0
- 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 +771 -0
- package/src/domains/context/contract.ts +68 -0
- package/src/domains/context/excluded-dirs.ts +1 -0
- package/src/domains/context/extension.ts +358 -0
- package/src/domains/context/fingerprint.ts +198 -0
- package/src/domains/context/index.ts +154 -0
- package/src/domains/context/init-options.ts +69 -0
- package/src/domains/context/manifest.ts +6 -0
- package/src/domains/context/operator-profile.ts +157 -0
- package/src/domains/context/project-metadata.ts +529 -0
- package/src/domains/context/project-rules.ts +227 -0
- package/src/domains/context/prompt-context.ts +61 -0
- package/src/domains/context/refresh.ts +178 -0
- package/src/domains/context/runtime.ts +17 -0
- package/src/domains/context/sibling-files.ts +10 -0
- package/src/domains/context/state.ts +237 -0
- package/src/domains/context/wiki/assemble.ts +303 -0
- package/src/domains/context/wiki/frontmatter.ts +210 -0
- package/src/domains/context/wiki/generate.ts +595 -0
- package/src/domains/context/wiki/layout.ts +111 -0
- package/src/domains/context/wiki/meta.ts +221 -0
- package/src/domains/context/wiki/plan-store.ts +217 -0
- package/src/domains/context/wiki/plan.ts +250 -0
- package/src/domains/context/wiki/prompts.ts +283 -0
- package/src/domains/context/wiki/staleness.ts +198 -0
- package/src/domains/dispatch/active-route-planner.ts +168 -0
- package/src/domains/dispatch/admission-queue.ts +150 -0
- package/src/domains/dispatch/admission.ts +334 -0
- package/src/domains/dispatch/agent-candidates.ts +307 -0
- package/src/domains/dispatch/agent-ledger-hub.ts +71 -0
- package/src/domains/dispatch/agent-ledger-store.ts +257 -0
- package/src/domains/dispatch/agent-ledger.ts +212 -0
- package/src/domains/dispatch/agent-plan-adapter.ts +85 -0
- package/src/domains/dispatch/assignment-events.ts +132 -0
- package/src/domains/dispatch/assignment-reconcile.ts +76 -0
- package/src/domains/dispatch/assignment-store.ts +162 -0
- package/src/domains/dispatch/assignment.ts +278 -0
- package/src/domains/dispatch/backoff.ts +59 -0
- package/src/domains/dispatch/batch-store.ts +134 -0
- package/src/domains/dispatch/batch-tracker.ts +66 -0
- package/src/domains/dispatch/capability-match.ts +155 -0
- package/src/domains/dispatch/capacity-lease.ts +413 -0
- package/src/domains/dispatch/code-step-store.ts +52 -0
- package/src/domains/dispatch/code-step.ts +387 -0
- package/src/domains/dispatch/contract.ts +278 -0
- package/src/domains/dispatch/dedup.ts +133 -0
- package/src/domains/dispatch/event-pump.ts +251 -0
- package/src/domains/dispatch/execution-handoff.ts +29 -0
- package/src/domains/dispatch/execution-plan.ts +328 -0
- package/src/domains/dispatch/execution-role.ts +277 -0
- package/src/domains/dispatch/execution-scheduler.ts +583 -0
- package/src/domains/dispatch/extension.ts +6006 -0
- package/src/domains/dispatch/failure-classification.ts +147 -0
- package/src/domains/dispatch/fleet-commit-attribution.ts +56 -0
- package/src/domains/dispatch/fleet-plan.ts +225 -0
- package/src/domains/dispatch/fleet-preflight.ts +394 -0
- package/src/domains/dispatch/gate-decisions.ts +1040 -0
- package/src/domains/dispatch/gate-role-prompts.ts +58 -0
- package/src/domains/dispatch/heartbeat.ts +27 -0
- package/src/domains/dispatch/index.ts +137 -0
- package/src/domains/dispatch/joint-route-adapter.ts +114 -0
- package/src/domains/dispatch/joint-route-resolver.ts +283 -0
- package/src/domains/dispatch/manifest.ts +6 -0
- package/src/domains/dispatch/orphan-recovery.ts +266 -0
- package/src/domains/dispatch/outcome.ts +109 -0
- package/src/domains/dispatch/phase-timing.ts +47 -0
- package/src/domains/dispatch/placement.ts +202 -0
- package/src/domains/dispatch/receipt-findings.ts +255 -0
- package/src/domains/dispatch/receipt-integrity.ts +383 -0
- package/src/domains/dispatch/recovery-candidates.ts +74 -0
- package/src/domains/dispatch/reproducibility.ts +48 -0
- package/src/domains/dispatch/reservation-store.ts +501 -0
- package/src/domains/dispatch/route-approval.ts +177 -0
- package/src/domains/dispatch/route-candidates.ts +57 -0
- package/src/domains/dispatch/route-decision.ts +1079 -0
- package/src/domains/dispatch/route-facts.ts +187 -0
- package/src/domains/dispatch/route-history.ts +238 -0
- package/src/domains/dispatch/route-observer.ts +488 -0
- package/src/domains/dispatch/route-policy.ts +327 -0
- package/src/domains/dispatch/route-quality.ts +256 -0
- package/src/domains/dispatch/route-readiness.ts +120 -0
- package/src/domains/dispatch/routing-intent.ts +287 -0
- package/src/domains/dispatch/run-identity.ts +56 -0
- package/src/domains/dispatch/scout-transition.ts +130 -0
- package/src/domains/dispatch/state.ts +302 -0
- package/src/domains/dispatch/tool-stats.ts +132 -0
- package/src/domains/dispatch/transport.ts +210 -0
- package/src/domains/dispatch/types.ts +799 -0
- package/src/domains/dispatch/validation-grounding.ts +154 -0
- package/src/domains/dispatch/validation.ts +721 -0
- package/src/domains/dispatch/worker-protocol.ts +275 -0
- package/src/domains/dispatch/worker-spawn.ts +585 -0
- package/src/domains/dispatch/write-boundary-enforcer.ts +97 -0
- package/src/domains/dispatch/write-boundary.ts +426 -0
- package/src/domains/eval/artifacts/redact.ts +42 -0
- package/src/domains/eval/artifacts/store.ts +173 -0
- package/src/domains/eval/compare/compare.ts +33 -0
- package/src/domains/eval/compare/gates.ts +66 -0
- package/src/domains/eval/compare/thresholds.ts +92 -0
- package/src/domains/eval/harness-metrics.ts +62 -0
- package/src/domains/eval/index.ts +66 -0
- package/src/domains/eval/metrics/chaos-stream.ts +93 -0
- package/src/domains/eval/metrics/context.ts +34 -0
- package/src/domains/eval/metrics/coverage.ts +21 -0
- package/src/domains/eval/metrics/evidence.ts +182 -0
- package/src/domains/eval/metrics/fleet-loop-stream.ts +196 -0
- package/src/domains/eval/metrics/invariants.ts +736 -0
- package/src/domains/eval/metrics/latency.ts +4 -0
- package/src/domains/eval/metrics/token-stream.ts +139 -0
- package/src/domains/eval/metrics/tokens.ts +51 -0
- package/src/domains/eval/metrics/tool-calls.ts +7 -0
- package/src/domains/eval/proactive-memory.ts +279 -0
- package/src/domains/eval/provenance.ts +35 -0
- package/src/domains/eval/report.ts +234 -0
- package/src/domains/eval/reports/json.ts +5 -0
- package/src/domains/eval/reports/junit.ts +23 -0
- package/src/domains/eval/reports/markdown.ts +20 -0
- package/src/domains/eval/reports/swe-jsonl.ts +16 -0
- package/src/domains/eval/reports/text.ts +25 -0
- package/src/domains/eval/run-compare.ts +274 -0
- package/src/domains/eval/runner.ts +244 -0
- package/src/domains/eval/runners/clio-run.ts +148 -0
- package/src/domains/eval/runners/context-index.ts +56 -0
- package/src/domains/eval/runners/context-init.ts +203 -0
- package/src/domains/eval/runners/external-command.ts +350 -0
- package/src/domains/eval/runtime-paths.ts +171 -0
- package/src/domains/eval/schema/artifact.ts +75 -0
- package/src/domains/eval/schema/suite.ts +235 -0
- package/src/domains/eval/schema/validate.ts +339 -0
- package/src/domains/eval/store.ts +392 -0
- package/src/domains/eval/suites/load.ts +74 -0
- package/src/domains/eval/suites/matrix.ts +19 -0
- package/src/domains/eval/suites/resolve.ts +44 -0
- package/src/domains/eval/suites/run.ts +325 -0
- package/src/domains/eval/task-file.ts +186 -0
- package/src/domains/eval/types.ts +140 -0
- package/src/domains/eval/verifiers/command.ts +27 -0
- package/src/domains/eval/verifiers/file-exists.ts +6 -0
- package/src/domains/eval/verifiers/patch.ts +22 -0
- package/src/domains/eval/workspaces/git.ts +41 -0
- package/src/domains/eval/workspaces/local.ts +17 -0
- package/src/domains/eval/workspaces/temp-copy.ts +29 -0
- package/src/domains/evidence/build.ts +1754 -0
- package/src/domains/evidence/eval.ts +605 -0
- package/src/domains/evidence/failure-attribution.ts +54 -0
- package/src/domains/evidence/finish-contract-map.ts +42 -0
- package/src/domains/evidence/index.ts +55 -0
- package/src/domains/evidence/provenance.ts +200 -0
- package/src/domains/evidence/redact.ts +81 -0
- package/src/domains/evidence/store.ts +291 -0
- package/src/domains/evidence/types.ts +325 -0
- package/src/domains/evolution/SELF_EDIT_GATE.md +91 -0
- package/src/domains/evolution/index.ts +26 -0
- package/src/domains/evolution/manifest.ts +154 -0
- package/src/domains/evolution/validate.ts +304 -0
- package/src/domains/extensions/contract.ts +22 -0
- package/src/domains/extensions/discovery.ts +193 -0
- package/src/domains/extensions/extension.ts +46 -0
- package/src/domains/extensions/index.ts +34 -0
- package/src/domains/extensions/manager.ts +30 -0
- package/src/domains/extensions/manifest.ts +6 -0
- package/src/domains/extensions/resources.ts +38 -0
- package/src/domains/extensions/state.ts +224 -0
- package/src/domains/extensions/types.ts +83 -0
- package/src/domains/interop/consent.ts +185 -0
- package/src/domains/interop/contract.ts +29 -0
- package/src/domains/interop/detect.ts +173 -0
- package/src/domains/interop/extension.ts +59 -0
- package/src/domains/interop/index.ts +34 -0
- package/src/domains/interop/manifest.ts +6 -0
- package/src/domains/interop/registry.ts +139 -0
- package/src/domains/interop/state.ts +92 -0
- package/src/domains/interop/types.ts +109 -0
- package/src/domains/lifecycle/contract.ts +11 -0
- package/src/domains/lifecycle/doctor.ts +536 -0
- package/src/domains/lifecycle/extension.ts +23 -0
- package/src/domains/lifecycle/index.ts +21 -0
- package/src/domains/lifecycle/install-method.ts +51 -0
- package/src/domains/lifecycle/manifest.ts +6 -0
- package/src/domains/lifecycle/migrations/2026-08-18-lmstudio-runtime-id.ts +52 -0
- package/src/domains/lifecycle/migrations/index.ts +114 -0
- package/src/domains/lifecycle/state.ts +93 -0
- package/src/domains/lifecycle/upgrade-notice.ts +35 -0
- package/src/domains/lifecycle/version.ts +35 -0
- package/src/domains/memory/index.ts +128 -0
- package/src/domains/memory/operations.ts +143 -0
- package/src/domains/memory/prompt-section.ts +86 -0
- package/src/domains/memory/proposal.ts +180 -0
- package/src/domains/memory/store.ts +163 -0
- package/src/domains/memory/task-bank.ts +229 -0
- package/src/domains/memory/task-memory-handoff.ts +222 -0
- package/src/domains/memory/task-memory-policy.ts +602 -0
- package/src/domains/memory/task-memory-status.ts +58 -0
- package/src/domains/memory/task-memory-telemetry.ts +346 -0
- package/src/domains/memory/task-memory-trace.ts +89 -0
- package/src/domains/memory/types.ts +74 -0
- package/src/domains/memory/validate.ts +297 -0
- package/src/domains/middleware/budget.ts +216 -0
- package/src/domains/middleware/contract.ts +35 -0
- package/src/domains/middleware/dispatch-nudge.ts +469 -0
- package/src/domains/middleware/extension.ts +129 -0
- package/src/domains/middleware/hook-receipts.ts +70 -0
- package/src/domains/middleware/hooks-io.ts +186 -0
- package/src/domains/middleware/hooks.ts +432 -0
- package/src/domains/middleware/index.ts +154 -0
- package/src/domains/middleware/manifest.ts +6 -0
- package/src/domains/middleware/memory-intervention.ts +701 -0
- package/src/domains/middleware/rules.ts +42 -0
- package/src/domains/middleware/runtime.ts +333 -0
- package/src/domains/middleware/skills-reminder.ts +202 -0
- package/src/domains/middleware/snapshot.ts +71 -0
- package/src/domains/middleware/stalled-turn.ts +71 -0
- package/src/domains/middleware/task-board-reminder.ts +87 -0
- package/src/domains/middleware/task-nudge.ts +77 -0
- package/src/domains/middleware/tool-choice-control.ts +42 -0
- package/src/domains/middleware/types.ts +131 -0
- package/src/domains/middleware/validate.ts +329 -0
- package/src/domains/observability/accountability.ts +67 -0
- package/src/domains/observability/contract.ts +168 -0
- package/src/domains/observability/cost.ts +206 -0
- package/src/domains/observability/evidence-index.ts +123 -0
- package/src/domains/observability/extension.ts +281 -0
- package/src/domains/observability/index.ts +78 -0
- package/src/domains/observability/manifest.ts +10 -0
- package/src/domains/observability/metrics.ts +37 -0
- package/src/domains/observability/projection.ts +477 -0
- package/src/domains/observability/telemetry.ts +89 -0
- package/src/domains/observability/trace-store.ts +1454 -0
- package/src/domains/prompts/compiler.ts +614 -0
- package/src/domains/prompts/contract.ts +46 -0
- package/src/domains/prompts/extension.ts +336 -0
- package/src/domains/prompts/fragment-loader.ts +138 -0
- package/src/domains/prompts/fragments/identity/clio.md +5 -6
- package/src/domains/prompts/fragments/identity/docs-routing.md +10 -0
- package/src/domains/prompts/fragments/identity/self-awareness.md +19 -0
- package/src/domains/prompts/fragments/operating/contract.md +4 -41
- 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/hash.ts +73 -0
- package/src/domains/prompts/index.ts +32 -0
- package/src/domains/prompts/manifest.ts +8 -0
- package/src/domains/prompts/memory-intervention.ts +57 -0
- package/src/domains/prompts/preload.ts +82 -0
- package/src/domains/providers/auth/api-key.ts +47 -0
- package/src/domains/providers/auth/backend-file.ts +79 -0
- package/src/domains/providers/auth/backend-memory.ts +72 -0
- package/src/domains/providers/auth/boot-status.ts +65 -0
- package/src/domains/providers/auth/index.ts +37 -0
- package/src/domains/providers/auth/oauth.ts +37 -0
- package/src/domains/providers/auth/storage.ts +726 -0
- package/src/domains/providers/capabilities.ts +58 -0
- package/src/domains/providers/catalog.ts +162 -0
- package/src/domains/providers/contract.ts +162 -0
- package/src/domains/providers/credentials.ts +20 -0
- package/src/domains/providers/eligibility.ts +24 -0
- package/src/domains/providers/errors.ts +64 -0
- package/src/domains/providers/extension.ts +548 -0
- package/src/domains/providers/index.ts +142 -0
- package/src/domains/providers/knowledge-base-path.ts +102 -0
- package/src/domains/providers/manifest.ts +6 -0
- package/src/domains/providers/model-capabilities.ts +136 -0
- package/src/domains/providers/model-discovery.ts +144 -0
- package/src/domains/providers/model-family.ts +32 -0
- package/src/domains/providers/model-runtime-capabilities.ts +723 -0
- package/src/domains/providers/models/local-models/clio-local-coding-targets.yaml +120 -37
- package/src/domains/providers/plugins.ts +61 -0
- package/src/domains/providers/probe/fingerprint.ts +64 -0
- package/src/domains/providers/probe/http.ts +114 -0
- package/src/domains/providers/probe/reasoning.ts +111 -0
- package/src/domains/providers/registry.ts +187 -0
- package/src/domains/providers/resolver.ts +156 -0
- package/src/domains/providers/runtime-resolution.ts +720 -0
- package/src/domains/providers/runtimes/antigravity/antigravity-code.ts +90 -0
- package/src/domains/providers/runtimes/boot-manifest.ts +55 -0
- package/src/domains/providers/runtimes/builtins.ts +78 -0
- package/src/domains/providers/runtimes/claude/claude-code.ts +38 -0
- package/src/domains/providers/runtimes/claude/claude-sdk.ts +38 -0
- package/src/domains/providers/runtimes/claude/common.ts +55 -0
- package/src/domains/providers/runtimes/cloud/alcf.ts +171 -0
- package/src/domains/providers/runtimes/cloud/anthropic-max.ts +71 -0
- package/src/domains/providers/runtimes/cloud/anthropic.ts +43 -0
- package/src/domains/providers/runtimes/cloud/bedrock.ts +35 -0
- package/src/domains/providers/runtimes/cloud/deepseek.ts +50 -0
- package/src/domains/providers/runtimes/cloud/google.ts +41 -0
- package/src/domains/providers/runtimes/cloud/groq.ts +46 -0
- package/src/domains/providers/runtimes/cloud/mistral.ts +46 -0
- package/src/domains/providers/runtimes/cloud/openai-codex.ts +49 -0
- package/src/domains/providers/runtimes/cloud/openai.ts +46 -0
- package/src/domains/providers/runtimes/cloud/openrouter.ts +111 -0
- package/src/domains/providers/runtimes/common/lmstudio-http.ts +423 -0
- package/src/domains/providers/runtimes/common/local-synth.ts +164 -0
- package/src/domains/providers/runtimes/common/probe-helpers.ts +474 -0
- package/src/domains/providers/runtimes/local-native/lemonade-anthropic.ts +27 -0
- package/src/domains/providers/runtimes/local-native/lemonade-openai.ts +26 -0
- package/src/domains/providers/runtimes/local-native/llamacpp-anthropic.ts +88 -0
- package/src/domains/providers/runtimes/local-native/llamacpp-completion.ts +207 -0
- package/src/domains/providers/runtimes/local-native/llamacpp-embed.ts +180 -0
- package/src/domains/providers/runtimes/local-native/llamacpp-rerank.ts +126 -0
- package/src/domains/providers/runtimes/local-native/llamacpp.ts +98 -0
- package/src/domains/providers/runtimes/local-native/lmstudio.ts +241 -0
- package/src/domains/providers/runtimes/local-native/ollama-native.ts +117 -0
- package/src/domains/providers/runtimes/local-native/sglang.ts +26 -0
- package/src/domains/providers/runtimes/local-native/vllm.ts +27 -0
- package/src/domains/providers/runtimes/protocol/anthropic-compat.ts +104 -0
- package/src/domains/providers/runtimes/protocol/anthropic-messages.ts +28 -0
- package/src/domains/providers/runtimes/protocol/bedrock.ts +26 -0
- package/src/domains/providers/runtimes/protocol/google.ts +27 -0
- package/src/domains/providers/runtimes/protocol/openai-compat.ts +145 -0
- package/src/domains/providers/support.ts +241 -0
- package/src/domains/providers/thinking-control-policy.ts +85 -0
- package/src/domains/providers/types/capability-flags.ts +114 -0
- package/src/domains/providers/types/cost-provenance.ts +7 -0
- package/src/domains/providers/types/inference.ts +41 -0
- package/src/domains/providers/types/knowledge-base.ts +156 -0
- package/src/domains/providers/types/local-model-quirks.ts +216 -0
- package/src/domains/providers/types/runtime-descriptor.ts +181 -0
- package/src/domains/providers/types/target-descriptor.ts +60 -0
- package/src/domains/resources/collision.ts +92 -0
- package/src/domains/resources/common-loader.ts +140 -0
- package/src/domains/resources/contract.ts +24 -0
- package/src/domains/resources/extension.ts +59 -0
- package/src/domains/resources/index.ts +74 -0
- package/src/domains/resources/loader.ts +85 -0
- package/src/domains/resources/manifest.ts +6 -0
- package/src/domains/resources/prompts/loader.ts +246 -0
- package/src/domains/resources/prompts/substitute.ts +1 -0
- package/src/domains/resources/skills/content-hash.ts +107 -0
- package/src/domains/resources/skills/evals.ts +175 -0
- package/src/domains/resources/skills/install.ts +427 -0
- package/src/domains/resources/skills/loader.ts +985 -0
- package/src/domains/resources/skills/marketplace.ts +301 -0
- package/src/domains/resources/skills/provenance-pin.ts +115 -0
- package/src/domains/safety/action-classifier.ts +270 -0
- package/src/domains/safety/approval-axis.ts +23 -0
- package/src/domains/safety/audit.ts +493 -0
- package/src/domains/safety/autonomy.ts +174 -0
- package/src/domains/safety/call-target.ts +59 -0
- package/src/domains/safety/contract.ts +65 -0
- package/src/domains/safety/damage-control.ts +44 -0
- package/src/domains/safety/default-path-policy.ts +117 -0
- package/src/domains/safety/extension.ts +383 -0
- package/src/domains/safety/finish-contract-registration.ts +128 -0
- package/src/domains/safety/finish-contract.ts +554 -0
- package/src/domains/safety/index.ts +44 -0
- package/src/domains/safety/loop-detector.ts +143 -0
- package/src/domains/safety/manifest.ts +6 -0
- package/src/domains/safety/path-policy.ts +164 -0
- package/src/domains/safety/policy-engine.ts +994 -0
- package/src/domains/safety/project-policy.ts +391 -0
- package/src/domains/safety/protected-artifacts-registration.ts +189 -0
- package/src/domains/safety/protected-artifacts.ts +993 -0
- package/src/domains/safety/rejection-feedback.ts +102 -0
- package/src/domains/safety/rigor.ts +72 -0
- package/src/domains/safety/rule-compiler.ts +48 -0
- package/src/domains/safety/rule-pack-loader.ts +92 -0
- package/src/domains/safety/run-effects.ts +197 -0
- package/src/domains/safety/scope.ts +61 -0
- package/src/domains/scheduling/budget.ts +35 -0
- package/src/domains/scheduling/cluster.ts +175 -0
- package/src/domains/scheduling/contract.ts +30 -0
- package/src/domains/scheduling/extension.ts +91 -0
- package/src/domains/scheduling/index.ts +12 -0
- package/src/domains/scheduling/manifest.ts +6 -0
- package/src/domains/session/archive-readers.ts +208 -0
- package/src/domains/session/checkpoint.ts +38 -0
- package/src/domains/session/compaction/auto.ts +89 -0
- package/src/domains/session/compaction/branch-summary.ts +187 -0
- package/src/domains/session/compaction/compact.ts +493 -0
- package/src/domains/session/compaction/cut-point.ts +172 -0
- package/src/domains/session/compaction/defaults.ts +34 -0
- package/src/domains/session/compaction/mask-observations.ts +265 -0
- package/src/domains/session/compaction/session-entries.ts +18 -0
- package/src/domains/session/compaction/tokens.ts +148 -0
- package/src/domains/session/context-accounting.ts +583 -0
- package/src/domains/session/context-ledger.ts +362 -0
- package/src/domains/session/contract.ts +159 -0
- package/src/domains/session/cwd-fallback.ts +65 -0
- package/src/domains/session/decision-board.ts +190 -0
- package/src/domains/session/entries.ts +572 -0
- package/src/domains/session/extension.ts +403 -0
- package/src/domains/session/history.ts +172 -0
- package/src/domains/session/index.ts +84 -0
- package/src/domains/session/manager.ts +128 -0
- package/src/domains/session/manifest.ts +6 -0
- package/src/domains/session/migrations/index.ts +27 -0
- package/src/domains/session/prompt-manifest.ts +173 -0
- package/src/domains/session/protected-artifact-journal.ts +241 -0
- package/src/domains/session/protected-artifacts.ts +90 -0
- package/src/domains/session/retry.ts +230 -0
- package/src/domains/session/session-artifacts.ts +107 -0
- package/src/domains/session/task-board.ts +569 -0
- package/src/domains/session/tree/active-path.ts +137 -0
- package/src/domains/session/tree/fork.ts +159 -0
- package/src/domains/session/tree/manager.ts +128 -0
- package/src/domains/session/tree/navigator.ts +177 -0
- package/src/domains/session/tree/preview.ts +259 -0
- package/src/domains/session/usage.ts +148 -0
- package/src/domains/session/workspace/git-probe.ts +167 -0
- package/src/domains/session/workspace/index.ts +4 -0
- package/src/domains/session/workspace/project-type.ts +217 -0
- package/src/domains/session/workspace/snapshot.ts +74 -0
- package/src/domains/share/archive.ts +684 -0
- package/src/domains/share/contract.ts +9 -0
- package/src/domains/share/extension.ts +26 -0
- package/src/domains/share/index.ts +28 -0
- package/src/domains/share/manifest.ts +6 -0
- package/src/domains/user-tasks/store.ts +297 -0
- package/src/engine/acp/adapter.ts +397 -0
- package/src/engine/acp/errors.ts +128 -0
- package/src/engine/acp/event-mapper.ts +154 -0
- package/src/engine/acp/server.ts +2238 -0
- package/src/engine/acp/tool-mediator.ts +686 -0
- package/src/engine/acp/transport.ts +775 -0
- package/src/engine/acp/types.ts +196 -0
- package/src/engine/agent.ts +29 -0
- package/src/engine/ai.ts +207 -0
- package/src/engine/alcf-oauth.ts +205 -0
- package/src/engine/antigravity/subprocess-runtime.ts +205 -0
- package/src/engine/api-registry.ts +223 -0
- package/src/engine/apis/degraded-inference.ts +95 -0
- package/src/engine/apis/index.ts +16 -0
- package/src/engine/apis/llamacpp-residency.ts +292 -0
- package/src/engine/apis/lmstudio-residency.ts +76 -0
- package/src/engine/apis/lmstudio.ts +243 -0
- package/src/engine/apis/ollama-native.ts +528 -0
- package/src/engine/apis/openai-completions.ts +795 -0
- package/src/engine/apis/output-budget.ts +99 -0
- package/src/engine/apis/residency-lock.ts +29 -0
- package/src/engine/apis/residency.ts +776 -0
- package/src/engine/apis/resident-models.ts +42 -0
- package/src/engine/apis/sampling-overrides.ts +38 -0
- package/src/engine/apis/types.ts +16 -0
- package/src/engine/claude/sdk-runtime.ts +685 -0
- package/src/engine/claude/session-id.ts +5 -0
- package/src/engine/claude/subprocess-runtime.ts +316 -0
- package/src/engine/claude/tool-safety.ts +400 -0
- package/src/engine/env-api-keys.ts +98 -0
- package/src/engine/external-subprocess.ts +23 -0
- package/src/engine/gemma-channel-filter.ts +223 -0
- package/src/engine/harmony-response.ts +165 -0
- package/src/engine/instrumented-tui.ts +192 -0
- package/src/engine/loop-guard.ts +1127 -0
- package/src/engine/messages.ts +14 -0
- package/src/engine/models.ts +42 -0
- package/src/engine/oauth.ts +196 -0
- package/src/engine/pi-mono-names.ts +13 -0
- package/src/engine/prompt-templates.ts +1 -0
- package/src/engine/provider-payload.ts +272 -0
- package/src/engine/select-list.ts +53 -0
- package/src/engine/session.ts +834 -0
- package/src/engine/strip-tokenizer-sentinels.ts +125 -0
- package/src/engine/truncate.ts +9 -0
- package/src/engine/tui.ts +111 -0
- package/src/engine/types.ts +63 -0
- package/src/engine/worker-events.ts +100 -0
- package/src/engine/worker-runtime-capabilities.ts +5 -0
- package/src/engine/worker-runtime.ts +1022 -0
- package/src/engine/worker-tools.ts +208 -0
- package/src/entry/boot-options.ts +50 -0
- package/src/entry/orchestrator.ts +2011 -0
- package/src/interactive/application-controller.ts +433 -0
- package/src/interactive/bus-notices.ts +265 -0
- package/src/interactive/chat-loop-messages.ts +626 -0
- package/src/interactive/chat-loop-policy.ts +18 -0
- package/src/interactive/chat-loop.ts +1090 -0
- package/src/interactive/chat-panel.ts +1820 -0
- package/src/interactive/chat-renderer.ts +1228 -0
- package/src/interactive/clio-editor.ts +161 -0
- package/src/interactive/command-fallbacks.ts +23 -0
- package/src/interactive/command-output.ts +85 -0
- package/src/interactive/context-activity.ts +203 -0
- package/src/interactive/context-meter.ts +223 -0
- package/src/interactive/context-overlay.ts +246 -0
- package/src/interactive/cost-overlay.ts +279 -0
- package/src/interactive/dispatch-board.ts +1319 -0
- package/src/interactive/dispatch-steering.ts +86 -0
- package/src/interactive/editor-bash.ts +46 -0
- package/src/interactive/editor-steer.ts +51 -0
- package/src/interactive/editor-submit.ts +507 -0
- 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/external-editor.ts +67 -0
- package/src/interactive/follow-up-queue-panel.ts +75 -0
- package/src/interactive/footer/dashboard.ts +538 -0
- package/src/interactive/footer/notifications.ts +275 -0
- package/src/interactive/footer/widgets.ts +1264 -0
- package/src/interactive/footer-panel.ts +187 -0
- package/src/interactive/format-time.ts +97 -0
- package/src/interactive/index.ts +11 -0
- package/src/interactive/interactive-application.ts +939 -0
- package/src/interactive/interactive-event-projection.ts +385 -0
- package/src/interactive/interactive-input-runtime.ts +307 -0
- package/src/interactive/interactive-presentation.ts +584 -0
- package/src/interactive/interactive-shell.ts +388 -0
- package/src/interactive/interactive-slash-runtime.ts +554 -0
- package/src/interactive/interactive-subscriptions.ts +111 -0
- package/src/interactive/interactive-tickers.ts +183 -0
- package/src/interactive/keybinding-manager.ts +496 -0
- package/src/interactive/layout.ts +57 -0
- package/src/interactive/leader-key.ts +143 -0
- package/src/interactive/loop-guard-interrupt.ts +101 -0
- package/src/interactive/memory-overlay.ts +280 -0
- package/src/interactive/overlay-ask-user-lifecycle.ts +110 -0
- package/src/interactive/overlay-auth-lifecycle.ts +308 -0
- package/src/interactive/overlay-frame.ts +502 -0
- package/src/interactive/overlay-general-openers.ts +274 -0
- package/src/interactive/overlay-key-routing.ts +216 -0
- package/src/interactive/overlay-lifecycle.ts +426 -0
- package/src/interactive/overlay-model-selectors.ts +127 -0
- package/src/interactive/overlay-permission-lifecycle.ts +345 -0
- package/src/interactive/overlay-resource-openers.ts +112 -0
- package/src/interactive/overlay-session-lifecycle.ts +327 -0
- package/src/interactive/overlay-transitions.ts +57 -0
- package/src/interactive/overlays/agents.ts +69 -0
- package/src/interactive/overlays/ask-user.ts +921 -0
- package/src/interactive/overlays/auth-dialog.ts +221 -0
- package/src/interactive/overlays/context-reset.ts +108 -0
- package/src/interactive/overlays/cwd-fallback.ts +141 -0
- package/src/interactive/overlays/decisions.ts +300 -0
- package/src/interactive/overlays/extensions.ts +54 -0
- package/src/interactive/overlays/help-reference.ts +145 -0
- package/src/interactive/overlays/interop.ts +139 -0
- package/src/interactive/overlays/keybinding-detail.ts +90 -0
- package/src/interactive/overlays/list-overlay.ts +606 -0
- package/src/interactive/overlays/message-picker.ts +155 -0
- package/src/interactive/overlays/model-selector.ts +1109 -0
- package/src/interactive/overlays/prompts.ts +72 -0
- package/src/interactive/overlays/session-selector-search.ts +31 -0
- package/src/interactive/overlays/session-selector.ts +284 -0
- package/src/interactive/overlays/settings.ts +3451 -0
- package/src/interactive/overlays/skills-hub.ts +237 -0
- package/src/interactive/overlays/tree-selector.ts +422 -0
- package/src/interactive/permission-overlay.ts +170 -0
- package/src/interactive/render-trace.ts +534 -0
- package/src/interactive/renderers/branch-summary.ts +86 -0
- package/src/interactive/renderers/code-ink.ts +420 -0
- package/src/interactive/renderers/compaction-summary.ts +112 -0
- package/src/interactive/renderers/diff.ts +137 -0
- package/src/interactive/renderers/mermaid.ts +53 -0
- package/src/interactive/renderers/notice.ts +28 -0
- package/src/interactive/renderers/retry-status.ts +31 -0
- package/src/interactive/renderers/structured.ts +89 -0
- package/src/interactive/renderers/tool-execution.ts +1357 -0
- package/src/interactive/renderers/worker-entry.ts +280 -0
- package/src/interactive/session-last-turn.ts +186 -0
- package/src/interactive/session-switch-settlement.ts +10 -0
- package/src/interactive/session-transcript.ts +105 -0
- package/src/interactive/session-usage-reseed.ts +74 -0
- package/src/interactive/slash-autocomplete.ts +256 -0
- package/src/interactive/slash-commands.ts +1407 -0
- package/src/interactive/slash-spec.ts +424 -0
- package/src/interactive/status/controller.ts +260 -0
- package/src/interactive/status/index.ts +23 -0
- package/src/interactive/status/state-machine.ts +530 -0
- package/src/interactive/status/summary.ts +170 -0
- package/src/interactive/status/types.ts +121 -0
- package/src/interactive/status/verbs.ts +163 -0
- package/src/interactive/status/watchdog.ts +24 -0
- 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 +540 -0
- package/src/interactive/terminal-lease.ts +485 -0
- package/src/interactive/theme/components.ts +55 -0
- package/src/interactive/theme/glyphs.ts +70 -0
- package/src/interactive/theme/index.ts +15 -0
- package/src/interactive/theme/labels.ts +88 -0
- package/src/interactive/theme/rules.ts +138 -0
- package/src/interactive/theme/segments.ts +88 -0
- package/src/interactive/theme/tokens.ts +121 -0
- package/src/interactive/thinking-level-policy.ts +6 -0
- package/src/interactive/tool-prose-loop.ts +122 -0
- package/src/interactive/tool-prose-registration.ts +48 -0
- package/src/interactive/turn-context.ts +855 -0
- package/src/interactive/turn-middleware.ts +283 -0
- package/src/interactive/turn-persistence.ts +458 -0
- package/src/interactive/turn-queues.ts +181 -0
- package/src/interactive/turn-recovery.ts +323 -0
- package/src/interactive/turn-runtime.ts +869 -0
- package/src/interactive/turn-state.ts +133 -0
- package/src/interactive/view/artifacts.ts +1452 -0
- package/src/interactive/view/view-overlay.ts +735 -0
- package/src/interactive/welcome-dashboard.ts +537 -0
- package/src/interactive/worker-receipts.ts +143 -0
- package/src/interactive/worker-replay.ts +111 -0
- package/src/interactive/worker-share.ts +100 -0
- package/src/interactive/worker-stream.ts +446 -0
- package/src/interactive/workspace-facts.ts +141 -0
- package/src/tools/agent-tools.ts +402 -0
- package/src/tools/artifact.ts +103 -0
- package/src/tools/ask-user.ts +666 -0
- package/src/tools/bash.ts +204 -0
- package/src/tools/bootstrap.ts +77 -0
- package/src/tools/builtin-tool-catalog.ts +265 -0
- package/src/tools/codewiki/code-nav-surface.ts +29 -0
- package/src/tools/codewiki/code-nav.ts +549 -0
- package/src/tools/codewiki/shared.ts +118 -0
- package/src/tools/compete-worktrees.ts +898 -0
- package/src/tools/context/docs-engine.ts +630 -0
- package/src/tools/context/index.ts +514 -0
- package/src/tools/context/surface.ts +19 -0
- package/src/tools/core-bootstrap.ts +168 -0
- package/src/tools/credential-present.ts +151 -0
- package/src/tools/dispatch-admission.ts +533 -0
- package/src/tools/dispatch-arguments.ts +228 -0
- package/src/tools/dispatch-background.ts +54 -0
- package/src/tools/dispatch-event-text.ts +6 -0
- package/src/tools/dispatch-plan.ts +746 -0
- 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-scout.ts +461 -0
- package/src/tools/dispatch-types.ts +77 -0
- package/src/tools/dispatch.ts +244 -0
- package/src/tools/edit-diff.ts +534 -0
- package/src/tools/edit.ts +128 -0
- package/src/tools/executables.ts +22 -0
- package/src/tools/file-mutation-queue.ts +35 -0
- package/src/tools/find.ts +294 -0
- package/src/tools/grep.ts +495 -0
- package/src/tools/ignore-policy.ts +169 -0
- package/src/tools/lazy-tool.ts +60 -0
- package/src/tools/ledger.ts +206 -0
- package/src/tools/ls.ts +110 -0
- package/src/tools/monitor-surface.ts +36 -0
- package/src/tools/monitor.ts +767 -0
- package/src/tools/network-policy.ts +29 -0
- package/src/tools/observation.ts +421 -0
- package/src/tools/observers.ts +99 -0
- package/src/tools/path-utils.ts +79 -0
- package/src/tools/policy.ts +154 -0
- package/src/tools/profiles.ts +108 -0
- package/src/tools/read.ts +173 -0
- package/src/tools/registry.ts +1169 -0
- package/src/tools/result-shaping.ts +204 -0
- package/src/tools/safe-exec.ts +128 -0
- package/src/tools/spawn-hygiene.ts +182 -0
- package/src/tools/steer-surface.ts +17 -0
- package/src/tools/steer.ts +77 -0
- package/src/tools/tasks.ts +265 -0
- package/src/tools/truncate-utf8.ts +17 -0
- package/src/tools/truncate.ts +43 -0
- package/src/tools/verify/frontend.ts +687 -0
- package/src/tools/verify/index.ts +31 -0
- package/src/tools/verify/scripts.ts +108 -0
- package/src/tools/verify/surface.ts +46 -0
- package/src/tools/web-fetch-surface.ts +23 -0
- package/src/tools/web-fetch.ts +759 -0
- package/src/tools/worker-evidence.ts +215 -0
- package/src/tools/write.ts +57 -0
- package/src/utils/exif-orientation.ts +192 -0
- package/src/utils/git.ts +24 -0
- package/src/utils/image-resize.ts +148 -0
- package/src/utils/photon.ts +103 -0
- package/src/worker/control-lane.ts +22 -0
- package/src/worker/entry.ts +294 -0
- package/src/worker/event-projection.ts +56 -0
- package/src/worker/heartbeat.ts +24 -0
- package/src/worker/ledger-mirror.ts +95 -0
- package/src/worker/ndjson.ts +40 -0
- package/src/worker/protocol.ts +529 -0
- package/src/worker/resource-facts.ts +79 -0
- package/src/worker/runtime-registry.ts +12 -0
- package/src/worker/spec-contract.ts +675 -0
- package/src/worker/stdin-demux.ts +316 -0
- package/dist/acp-UMLFVA3F.js +0 -92
- package/dist/chunk-262G75JS.js +0 -35
- package/dist/chunk-6CWDTGUC.js +0 -20
- package/dist/chunk-BYEU76JP.js +0 -899
- package/dist/chunk-GNGDQYDU.js +0 -34688
- package/dist/chunk-GOTUR54M.js +0 -9
- package/dist/chunk-NI4DEJMC.js +0 -88
- package/dist/chunk-TPOCL34A.js +0 -2876
- package/dist/chunk-UU3R62TT.js +0 -128
- package/dist/clio-KIQ5SNDS.js +0 -53
- package/dist/configure-G4E3A2PG.js +0 -27
- package/dist/doctor-M5HJJZOL.js +0 -61
- package/dist/domains/agents/builtins/architect.md +0 -33
- package/dist/domains/agents/builtins/coder.md +0 -31
- package/dist/domains/agents/builtins/context-bootstrap.md +0 -38
- package/dist/domains/agents/builtins/debugger.md +0 -30
- package/dist/domains/agents/builtins/documenter.md +0 -31
- package/dist/domains/agents/builtins/git-master.md +0 -30
- package/dist/domains/agents/builtins/provenance.md +0 -30
- package/dist/domains/agents/builtins/researcher.md +0 -71
- package/dist/domains/agents/builtins/scout.md +0 -42
- package/dist/domains/agents/builtins/tester.md +0 -31
- package/dist/domains/agents/builtins/verifier.md +0 -30
- package/dist/domains/agents/builtins/wiki-writer.md +0 -41
- package/dist/fleet-preflight-CLIAX7YR.js +0 -21
- package/dist/preload-KZVHET2B.js +0 -11
- package/dist/version-ROZ6CZKH.js +0 -16
- 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 -794
- 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 -314
- package/docs/html/validation_blueprint.html +0 -961
- package/docs/html/worker_dispatch_blueprint.html +0 -231
- package/skills/git/commit-crafting/SKILL.md +0 -79
- package/skills/git/commit-crafting/evals.md +0 -92
- package/skills/git/create-pr/SKILL.md +0 -116
- package/skills/git/create-pr/evals.md +0 -114
- package/skills/git/investigate-issue/SKILL.md +0 -139
- package/skills/git/investigate-issue/evals.md +0 -94
- package/skills/git/review-changes/SKILL.md +0 -103
- package/skills/git/review-changes/evals.md +0 -85
|
@@ -0,0 +1,993 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { artifactDefaultPath } from "../../core/artifact-paths.js";
|
|
3
|
+
import { canonicalizeExistingPath } from "../../core/path-canonical.js";
|
|
4
|
+
import { ToolNames } from "../../core/tool-names.js";
|
|
5
|
+
import { isVerificationScriptName } from "../../core/verification-scripts.js";
|
|
6
|
+
|
|
7
|
+
export type ProtectedArtifactSource = "validation" | "middleware" | "user" | "session";
|
|
8
|
+
|
|
9
|
+
export interface ProtectedArtifact {
|
|
10
|
+
path: string;
|
|
11
|
+
protectedAt: string;
|
|
12
|
+
reason: string;
|
|
13
|
+
validationCommand?: string;
|
|
14
|
+
validationExitCode?: number;
|
|
15
|
+
source: ProtectedArtifactSource;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface ProtectedArtifactState {
|
|
19
|
+
artifacts: ProtectedArtifact[];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export type DestructiveCommandOperation =
|
|
23
|
+
| "rm"
|
|
24
|
+
| "mv"
|
|
25
|
+
| "truncate"
|
|
26
|
+
| "redirect"
|
|
27
|
+
| "cp"
|
|
28
|
+
| "git_checkout"
|
|
29
|
+
| "git_restore"
|
|
30
|
+
| "git_reset_hard"
|
|
31
|
+
| "find_delete";
|
|
32
|
+
|
|
33
|
+
export interface ProtectedArtifactCommandMatch {
|
|
34
|
+
artifactPath: string;
|
|
35
|
+
commandPath: string;
|
|
36
|
+
reason: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export type DestructiveCommandClassification =
|
|
40
|
+
| { kind: "benign"; matches: [] }
|
|
41
|
+
| {
|
|
42
|
+
kind: "destructive";
|
|
43
|
+
operation: DestructiveCommandOperation;
|
|
44
|
+
matches: ProtectedArtifactCommandMatch[];
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export type ValidationCommandDetection = { kind: "validation"; matched: string } | { kind: "none" };
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Which vocabulary of checking commands a caller wants recognized.
|
|
51
|
+
*
|
|
52
|
+
* `finish-contract` is the strict set: commands that assert something about
|
|
53
|
+
* correctness and fail loudly when it does not hold. It is the default because
|
|
54
|
+
* the consumers that spend it are gates. The finish contract counts a match as
|
|
55
|
+
* a validating turn, and the mutation-report validator counts one as the
|
|
56
|
+
* difference between `pass` and `unmeasured`. A turn whose only command was
|
|
57
|
+
* `git diff` has validated nothing, so admitting read-verification here would
|
|
58
|
+
* hand both gates a way to be satisfied by inspection alone.
|
|
59
|
+
*
|
|
60
|
+
* `grounding` is the wider set: everything strict plus the read-verification
|
|
61
|
+
* and ad-hoc shapes agents actually reach for (`git diff`, `node -e`,
|
|
62
|
+
* `npx vitest`, `tsc --noEmit`). Its consumer, dispatch validation grounding,
|
|
63
|
+
* spends a match on nothing. An unmatched claim there is reported and never
|
|
64
|
+
* downgrades a quality label, so the cost of a miss is noise in the receipt
|
|
65
|
+
* rather than a gate opening. Observed live this session: S3 workers claimed
|
|
66
|
+
* "git diff verification" and grounded 0/1, and a slice-2 coder verified its
|
|
67
|
+
* own fix with `node -e "import(...)"`. Both are real work the strict set
|
|
68
|
+
* cannot name.
|
|
69
|
+
*/
|
|
70
|
+
export type ValidationCommandScope = "finish-contract" | "grounding";
|
|
71
|
+
|
|
72
|
+
interface NormalizedArtifact {
|
|
73
|
+
key: string;
|
|
74
|
+
artifact: ProtectedArtifact;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const COMMAND_SEPARATORS = new Set([";", "&&", "||", "|"]);
|
|
78
|
+
const SHELL_WRAPPERS = new Set(["command", "builtin", "sudo", "doas"]);
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Paths a tool call would mutate, derived from the tool's path argument.
|
|
82
|
+
* Returns at most one path today: write/edit when a path arg is present, and
|
|
83
|
+
* the artifact writers' defaults. Bash mutation targets are handled
|
|
84
|
+
* separately through command classification.
|
|
85
|
+
*/
|
|
86
|
+
export function toolMutationPaths(toolName: string, args: Record<string, unknown> | undefined): string[] {
|
|
87
|
+
if (toolName === ToolNames.Artifact) {
|
|
88
|
+
return [mutationPathArg(args) ?? artifactDefaultPath(args?.kind)];
|
|
89
|
+
}
|
|
90
|
+
if (toolName === ToolNames.Write || toolName === ToolNames.Edit) {
|
|
91
|
+
const candidate = mutationPathArg(args);
|
|
92
|
+
return candidate === null ? [] : [candidate];
|
|
93
|
+
}
|
|
94
|
+
return [];
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Shared protected-artifact decision used by both the orchestrator middleware
|
|
99
|
+
* guard and mediated worker runtimes. Keeping target extraction and bash
|
|
100
|
+
* classification in one function prevents a dispatched worker from applying
|
|
101
|
+
* a weaker interpretation of the same frozen protection state.
|
|
102
|
+
*/
|
|
103
|
+
export function protectedArtifactMutationBlockReason(
|
|
104
|
+
state: ProtectedArtifactState,
|
|
105
|
+
toolName: string,
|
|
106
|
+
args: Record<string, unknown> | undefined,
|
|
107
|
+
): string | null {
|
|
108
|
+
if (state.artifacts.length === 0) return null;
|
|
109
|
+
for (const candidate of toolMutationPaths(toolName, args)) {
|
|
110
|
+
if (isProtectedPath(state, candidate)) {
|
|
111
|
+
return `protected artifact blocked: ${toolName} would modify protected path ${candidate}`;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (toolName !== ToolNames.Bash) return null;
|
|
115
|
+
const command = typeof args?.command === "string" && args.command.length > 0 ? args.command : null;
|
|
116
|
+
if (command === null) return null;
|
|
117
|
+
const classification = classifyDestructiveCommand(command, state.artifacts);
|
|
118
|
+
if (classification.kind === "benign") return null;
|
|
119
|
+
const affected = classification.matches.map((match) => match.artifactPath).join(", ");
|
|
120
|
+
return `protected artifact blocked: ${classification.operation} would affect ${affected}`;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function mutationPathArg(args: Record<string, unknown> | undefined): string | null {
|
|
124
|
+
if (!args) return null;
|
|
125
|
+
const candidate = args.path ?? args.file_path ?? args.filePath;
|
|
126
|
+
return typeof candidate === "string" && candidate.length > 0 ? candidate : null;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export function protectArtifact(state: ProtectedArtifactState, artifact: ProtectedArtifact): ProtectedArtifactState {
|
|
130
|
+
const artifacts = artifactMap(state.artifacts);
|
|
131
|
+
const key = normalizePathKey(artifact.path);
|
|
132
|
+
if (key !== null) artifacts.set(key, cloneArtifact(artifact));
|
|
133
|
+
return stateFromMap(artifacts);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function isProtectedPath(state: ProtectedArtifactState, artifactPath: string): boolean {
|
|
137
|
+
const candidate = normalizePathKey(artifactPath);
|
|
138
|
+
if (candidate === null) return false;
|
|
139
|
+
for (const artifact of normalizedArtifacts(state.artifacts)) {
|
|
140
|
+
if (isSameOrDescendant(candidate, artifact.key)) return true;
|
|
141
|
+
}
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function classifyDestructiveCommand(
|
|
146
|
+
command: string,
|
|
147
|
+
protectedArtifacts: ReadonlyArray<ProtectedArtifact>,
|
|
148
|
+
): DestructiveCommandClassification {
|
|
149
|
+
const artifacts = normalizedArtifacts(protectedArtifacts);
|
|
150
|
+
if (artifacts.length === 0) return { kind: "benign", matches: [] };
|
|
151
|
+
|
|
152
|
+
const tokens = tokenizeShellLike(command);
|
|
153
|
+
for (const segment of splitSegments(tokens)) {
|
|
154
|
+
const redirect = classifyRedirect(segment, artifacts);
|
|
155
|
+
if (redirect.kind === "destructive") return redirect;
|
|
156
|
+
|
|
157
|
+
const commandIndex = commandTokenIndex(segment);
|
|
158
|
+
if (commandIndex === null) continue;
|
|
159
|
+
const executable = basenameToken(segment[commandIndex]);
|
|
160
|
+
if (executable === "rm") {
|
|
161
|
+
const result = classifyPathOperation(
|
|
162
|
+
"rm",
|
|
163
|
+
"rm can remove protected artifacts",
|
|
164
|
+
pathArgs(segment, commandIndex),
|
|
165
|
+
artifacts,
|
|
166
|
+
);
|
|
167
|
+
if (result.kind === "destructive") return result;
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
if (executable === "mv") {
|
|
171
|
+
const result = classifyPathOperation(
|
|
172
|
+
"mv",
|
|
173
|
+
"mv can move or overwrite protected artifacts",
|
|
174
|
+
pathArgs(segment, commandIndex),
|
|
175
|
+
artifacts,
|
|
176
|
+
);
|
|
177
|
+
if (result.kind === "destructive") return result;
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
if (executable === "truncate") {
|
|
181
|
+
const result = classifyPathOperation(
|
|
182
|
+
"truncate",
|
|
183
|
+
"truncate can overwrite protected artifacts",
|
|
184
|
+
pathArgs(segment, commandIndex),
|
|
185
|
+
artifacts,
|
|
186
|
+
);
|
|
187
|
+
if (result.kind === "destructive") return result;
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
if (executable === "cp") {
|
|
191
|
+
const args = pathArgs(segment, commandIndex);
|
|
192
|
+
const destination = args.at(-1);
|
|
193
|
+
const result = classifyPathOperation(
|
|
194
|
+
"cp",
|
|
195
|
+
"cp can overwrite protected artifacts",
|
|
196
|
+
destination === undefined ? [] : [destination],
|
|
197
|
+
artifacts,
|
|
198
|
+
);
|
|
199
|
+
if (result.kind === "destructive") return result;
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
if (executable === "git") {
|
|
203
|
+
const result = classifyGitOperation(segment.slice(commandIndex + 1), artifacts);
|
|
204
|
+
if (result.kind === "destructive") return result;
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
if (executable === "find") {
|
|
208
|
+
const result = classifyFindDelete(segment.slice(commandIndex + 1), artifacts);
|
|
209
|
+
if (result.kind === "destructive") return result;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return { kind: "benign", matches: [] };
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export function detectValidationCommand(
|
|
217
|
+
command: string,
|
|
218
|
+
scope: ValidationCommandScope = "finish-contract",
|
|
219
|
+
): ValidationCommandDetection {
|
|
220
|
+
const tokens = tokenizeShellLike(command);
|
|
221
|
+
for (const segment of splitSegments(tokens)) {
|
|
222
|
+
const commandIndex = commandTokenIndex(segment);
|
|
223
|
+
if (commandIndex === null) continue;
|
|
224
|
+
const executable = basenameToken(segment[commandIndex]);
|
|
225
|
+
const args = segment.slice(commandIndex + 1);
|
|
226
|
+
const matched =
|
|
227
|
+
validationMatch(executable, args) ?? (scope === "grounding" ? groundingMatch(executable, args) : null);
|
|
228
|
+
if (matched !== null) return { kind: "validation", matched };
|
|
229
|
+
}
|
|
230
|
+
return { kind: "none" };
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Returns every path the command would write to: shell redirect targets
|
|
235
|
+
* (`>`, `>>`), all path arguments to `tee`, `mkdir`, and `touch`, the
|
|
236
|
+
* destination argument of `cp`, `mv`, and `ln`, and the file operands of an
|
|
237
|
+
* in-place `sed -i` edit. Standard descriptors like `/dev/null` and fd
|
|
238
|
+
* references like `&1` are filtered out so callers only see real filesystem
|
|
239
|
+
* targets.
|
|
240
|
+
*
|
|
241
|
+
* Used by the action classifier to escalate bash calls that write to a
|
|
242
|
+
* system root or out-of-cwd path through the same confirmation gate as the
|
|
243
|
+
* write tool, and by the finish-contract to decide whether a turn mutated
|
|
244
|
+
* workspace state. Both consumers read the same primitive, so a write pattern
|
|
245
|
+
* this recognizes gates and gate-completes consistently. pi-mono executes the
|
|
246
|
+
* bash command verbatim, so the registry-side check has to happen before the
|
|
247
|
+
* shell runs.
|
|
248
|
+
*/
|
|
249
|
+
export function extractCommandWriteTargets(command: string): string[] {
|
|
250
|
+
const targets: string[] = [];
|
|
251
|
+
for (const segment of expandedSegments(command)) {
|
|
252
|
+
collectRedirectTargets(segment, targets);
|
|
253
|
+
collectInvokedWriteTargets(segment, targets);
|
|
254
|
+
collectInPlaceEditTargets(segment, targets);
|
|
255
|
+
}
|
|
256
|
+
return targets.filter(isInterestingWriteTarget);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/** Shells whose `-c` argument is a script this scanner has to read as a command line. */
|
|
260
|
+
const INNER_SHELLS: ReadonlySet<string> = new Set(["sh", "bash", "zsh", "dash", "ksh"]);
|
|
261
|
+
|
|
262
|
+
/** Depth cap for `sh -c 'sh -c "..."'`; three levels is far past anything real. */
|
|
263
|
+
const INNER_SHELL_MAX_DEPTH = 3;
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* The script a segment hands a shell through `-c`, or null when the segment is
|
|
267
|
+
* not that shape. The tokenizer keeps a quoted script as one token, so without
|
|
268
|
+
* this every scanner here is blind one `sh -c` deep: `sh -c 'echo x >
|
|
269
|
+
* /etc/foo'` exposed no redirect target at all, which is how a recorded drive
|
|
270
|
+
* got a write past the gate that refused the same redirect written plainly
|
|
271
|
+
* (REPORT-dispatch-drive-1.md S1). Flag clusters (`-lc`, `-ec`) count, since
|
|
272
|
+
* the shell reads them the same way.
|
|
273
|
+
*/
|
|
274
|
+
function segmentShellScript(segment: ReadonlyArray<string>): string | null {
|
|
275
|
+
const commandIndex = commandTokenIndex(segment);
|
|
276
|
+
if (commandIndex === null) return null;
|
|
277
|
+
if (!INNER_SHELLS.has(basenameToken(segment[commandIndex]))) return null;
|
|
278
|
+
for (let index = commandIndex + 1; index < segment.length; index += 1) {
|
|
279
|
+
const token = segment[index];
|
|
280
|
+
if (token === undefined) continue;
|
|
281
|
+
if (token.startsWith("-") && token.length > 1) {
|
|
282
|
+
if (!token.slice(1).includes("c")) continue;
|
|
283
|
+
const script = segment[index + 1];
|
|
284
|
+
return script !== undefined && script.length > 0 ? script : null;
|
|
285
|
+
}
|
|
286
|
+
// The first operand of a shell invocation without -c is a script file,
|
|
287
|
+
// whose contents this scanner cannot see anyway.
|
|
288
|
+
return null;
|
|
289
|
+
}
|
|
290
|
+
return null;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* A command's segments, with every `sh -c '<script>'` wrapper followed by the
|
|
295
|
+
* segments of the script it runs. The wrapper segment itself is kept: a
|
|
296
|
+
* scanner that reads its operands (`cp`, `tee`) must still see them.
|
|
297
|
+
*/
|
|
298
|
+
function expandedSegments(command: string, depth = 0): string[][] {
|
|
299
|
+
const segments = splitSegments(tokenizeShellLike(command));
|
|
300
|
+
if (depth >= INNER_SHELL_MAX_DEPTH) return segments;
|
|
301
|
+
const out: string[][] = [];
|
|
302
|
+
for (const segment of segments) {
|
|
303
|
+
out.push(segment);
|
|
304
|
+
const script = segmentShellScript(segment);
|
|
305
|
+
if (script !== null) out.push(...expandedSegments(script, depth + 1));
|
|
306
|
+
}
|
|
307
|
+
return out;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* The script when the whole command is one `sh -c '<script>'` invocation and
|
|
312
|
+
* nothing else. The policy engine recognizes such a command by its inner
|
|
313
|
+
* script rather than treating `sh` as an unrecognized executable.
|
|
314
|
+
*/
|
|
315
|
+
export function inlineShellScript(command: string): string | null {
|
|
316
|
+
const segments = splitSegments(tokenizeShellLike(command));
|
|
317
|
+
if (segments.length !== 1) return null;
|
|
318
|
+
const segment = segments[0];
|
|
319
|
+
if (segment === undefined) return null;
|
|
320
|
+
return segmentShellScript(segment);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Returns the directory each `cd`/`pushd` in the command targets. A bare
|
|
325
|
+
* `cd` (and `cd -`, whose OLDPWD is unset in a fresh shell) is reported as
|
|
326
|
+
* `~`: it goes to the user's home directory. The action classifier resolves
|
|
327
|
+
* these against the workspace root, because a `cd` outside the workspace
|
|
328
|
+
* re-bases every relative path that follows it — the laundering pattern the
|
|
329
|
+
* recorded escape used (`cd /abs/outside && python3 <<EOF ...` writing
|
|
330
|
+
* relative files outside the session workspace).
|
|
331
|
+
*/
|
|
332
|
+
export function extractCommandCdTargets(command: string): string[] {
|
|
333
|
+
const targets: string[] = [];
|
|
334
|
+
for (const segment of expandedSegments(command)) {
|
|
335
|
+
const commandIndex = commandTokenIndex(segment);
|
|
336
|
+
if (commandIndex === null) continue;
|
|
337
|
+
const executable = basenameToken(segment[commandIndex]);
|
|
338
|
+
if (executable !== "cd" && executable !== "pushd") continue;
|
|
339
|
+
const target = pathArgs(segment, commandIndex).at(0);
|
|
340
|
+
targets.push(target ?? "~");
|
|
341
|
+
}
|
|
342
|
+
return targets;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Returns paths that common shell commands would remove from their current
|
|
347
|
+
* location. This intentionally covers only deterministic, path-bearing
|
|
348
|
+
* patterns; broader command admission remains owned by the policy engine.
|
|
349
|
+
*/
|
|
350
|
+
export function extractCommandDeleteTargets(command: string): string[] {
|
|
351
|
+
const targets: string[] = [];
|
|
352
|
+
for (const segment of expandedSegments(command)) {
|
|
353
|
+
const commandIndex = commandTokenIndex(segment);
|
|
354
|
+
if (commandIndex === null) continue;
|
|
355
|
+
const executable = basenameToken(segment[commandIndex]);
|
|
356
|
+
if (executable === "rm") {
|
|
357
|
+
targets.push(...pathArgs(segment, commandIndex));
|
|
358
|
+
continue;
|
|
359
|
+
}
|
|
360
|
+
if (executable === "mv") {
|
|
361
|
+
const args = pathArgs(segment, commandIndex);
|
|
362
|
+
if (args.length >= 2) targets.push(...args.slice(0, -1));
|
|
363
|
+
continue;
|
|
364
|
+
}
|
|
365
|
+
if (executable === "find" && segment.includes("-delete")) {
|
|
366
|
+
targets.push(...findRoots(segment.slice(commandIndex + 1)));
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
return targets.filter(isInterestingWriteTarget);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
const STANDARD_DEV_TARGETS = new Set(["/dev/null", "/dev/stdout", "/dev/stderr", "/dev/tty", "/dev/zero"]);
|
|
373
|
+
|
|
374
|
+
function collectRedirectTargets(segment: ReadonlyArray<string>, out: string[]): void {
|
|
375
|
+
for (let index = 0; index < segment.length - 1; index += 1) {
|
|
376
|
+
const token = segment[index];
|
|
377
|
+
if (token !== ">" && token !== ">>") continue;
|
|
378
|
+
const target = segment[index + 1];
|
|
379
|
+
if (target !== undefined) out.push(target);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
function collectInvokedWriteTargets(segment: ReadonlyArray<string>, out: string[]): void {
|
|
384
|
+
const cmdIndex = commandTokenIndex(segment);
|
|
385
|
+
if (cmdIndex === null) return;
|
|
386
|
+
const executable = basenameToken(segment[cmdIndex]);
|
|
387
|
+
if (executable === "tee") {
|
|
388
|
+
for (const arg of pathArgs(segment, cmdIndex)) out.push(arg);
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
// mkdir and touch create filesystem entries at every path operand. The
|
|
392
|
+
// recorded workspace escape (`mkdir -p /abs/outside && cd ...` in the
|
|
393
|
+
// skill-mastery app-idea battery) rode exactly this blind spot: redirects
|
|
394
|
+
// and tee were classified, directory creation was not.
|
|
395
|
+
if (executable === "mkdir" || executable === "touch") {
|
|
396
|
+
for (const arg of pathArgs(segment, cmdIndex)) out.push(arg);
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
if (executable === "ln") {
|
|
400
|
+
const args = pathArgs(segment, cmdIndex);
|
|
401
|
+
const destination = args.at(-1);
|
|
402
|
+
if (args.length >= 2 && destination !== undefined) out.push(destination);
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
if (executable === "cp" || executable === "mv") {
|
|
406
|
+
const args = pathArgs(segment, cmdIndex);
|
|
407
|
+
const destination = args.at(-1);
|
|
408
|
+
if (args.length >= 2 && destination !== undefined) out.push(destination);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* In-place stream-editor writes: `sed -i` (GNU `-iSUFFIX` / `--in-place` and
|
|
414
|
+
* BSD `-i ''` forms) rewrites its file operands in place, which the redirect and
|
|
415
|
+
* tee/cp/mv detectors miss. Weak models reach for `sed -i` constantly, so
|
|
416
|
+
* recognizing it here lets both the classifier and the finish-contract treat it
|
|
417
|
+
* as the write it is. The sed script operand is dropped (it is not a file), so
|
|
418
|
+
* an address-form script such as `/pat/d` cannot be mistaken for an out-of-cwd
|
|
419
|
+
* write target.
|
|
420
|
+
*/
|
|
421
|
+
function collectInPlaceEditTargets(segment: ReadonlyArray<string>, out: string[]): void {
|
|
422
|
+
const cmdIndex = commandTokenIndex(segment);
|
|
423
|
+
if (cmdIndex === null) return;
|
|
424
|
+
if (basenameToken(segment[cmdIndex]) !== "sed") return;
|
|
425
|
+
if (!hasSedInPlaceFlag(segment, cmdIndex)) return;
|
|
426
|
+
for (const operand of sedFileOperands(segment, cmdIndex)) out.push(operand);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
function hasSedInPlaceFlag(segment: ReadonlyArray<string>, cmdIndex: number): boolean {
|
|
430
|
+
for (let index = cmdIndex + 1; index < segment.length; index += 1) {
|
|
431
|
+
const token = segment[index];
|
|
432
|
+
if (token === undefined) continue;
|
|
433
|
+
if (COMMAND_SEPARATORS.has(token)) break;
|
|
434
|
+
if (token === "--") break;
|
|
435
|
+
if (token === "--in-place" || token.startsWith("--in-place=")) return true;
|
|
436
|
+
if (token.startsWith("--")) continue;
|
|
437
|
+
// A short-option cluster carrying `i` (`-i`, `-i.bak`, `-ni`) requests
|
|
438
|
+
// in-place editing; sed's other short flags (`-n`, `-e`, `-r`, ...) do not.
|
|
439
|
+
if (token.startsWith("-") && token.length > 1 && token.slice(1).includes("i")) return true;
|
|
440
|
+
}
|
|
441
|
+
return false;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
/**
|
|
445
|
+
* File operands of a sed invocation, with the inline script dropped. `-e`/`-f`/
|
|
446
|
+
* `--expression`/`--file` supply the script explicitly, so when one is present
|
|
447
|
+
* every bare operand is a file; otherwise the first bare operand is the script.
|
|
448
|
+
*/
|
|
449
|
+
function sedFileOperands(segment: ReadonlyArray<string>, cmdIndex: number): string[] {
|
|
450
|
+
const operands: string[] = [];
|
|
451
|
+
let sawScriptFlag = false;
|
|
452
|
+
let endOfOptions = false;
|
|
453
|
+
for (let index = cmdIndex + 1; index < segment.length; index += 1) {
|
|
454
|
+
const token = segment[index];
|
|
455
|
+
if (token === undefined) continue;
|
|
456
|
+
if (COMMAND_SEPARATORS.has(token)) break;
|
|
457
|
+
if (!endOfOptions && token === "--") {
|
|
458
|
+
endOfOptions = true;
|
|
459
|
+
continue;
|
|
460
|
+
}
|
|
461
|
+
if (!endOfOptions && token.startsWith("-") && token.length > 1) {
|
|
462
|
+
if (token === "-e" || token === "-f") {
|
|
463
|
+
sawScriptFlag = true;
|
|
464
|
+
index += 1;
|
|
465
|
+
continue;
|
|
466
|
+
}
|
|
467
|
+
if (token === "-l") {
|
|
468
|
+
index += 1;
|
|
469
|
+
continue;
|
|
470
|
+
}
|
|
471
|
+
if (token === "--expression" || token === "--file") {
|
|
472
|
+
sawScriptFlag = true;
|
|
473
|
+
index += 1;
|
|
474
|
+
continue;
|
|
475
|
+
}
|
|
476
|
+
if (token.startsWith("--expression=") || token.startsWith("--file=")) {
|
|
477
|
+
sawScriptFlag = true;
|
|
478
|
+
continue;
|
|
479
|
+
}
|
|
480
|
+
continue;
|
|
481
|
+
}
|
|
482
|
+
operands.push(token);
|
|
483
|
+
}
|
|
484
|
+
if (!sawScriptFlag && operands.length > 0) operands.shift();
|
|
485
|
+
return operands;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
function isInterestingWriteTarget(target: string): boolean {
|
|
489
|
+
if (target.length === 0) return false;
|
|
490
|
+
if (target.startsWith("&")) return false;
|
|
491
|
+
if (STANDARD_DEV_TARGETS.has(target)) return false;
|
|
492
|
+
if (target.startsWith("/dev/fd/")) return false;
|
|
493
|
+
return true;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
function classifyRedirect(
|
|
497
|
+
segment: ReadonlyArray<string>,
|
|
498
|
+
artifacts: ReadonlyArray<NormalizedArtifact>,
|
|
499
|
+
): DestructiveCommandClassification {
|
|
500
|
+
for (let index = 0; index < segment.length; index += 1) {
|
|
501
|
+
if (segment[index] !== ">") continue;
|
|
502
|
+
const target = segment[index + 1];
|
|
503
|
+
if (target === undefined) continue;
|
|
504
|
+
const matches = matchesForPaths([target], artifacts, "target", "redirect can overwrite protected artifacts");
|
|
505
|
+
if (matches.length > 0) {
|
|
506
|
+
return {
|
|
507
|
+
kind: "destructive",
|
|
508
|
+
operation: "redirect",
|
|
509
|
+
matches,
|
|
510
|
+
};
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
return { kind: "benign", matches: [] };
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
function classifyGitOperation(
|
|
517
|
+
args: ReadonlyArray<string>,
|
|
518
|
+
artifacts: ReadonlyArray<NormalizedArtifact>,
|
|
519
|
+
): DestructiveCommandClassification {
|
|
520
|
+
const subcommand = args[0];
|
|
521
|
+
if (subcommand === "reset" && args.includes("--hard")) {
|
|
522
|
+
return {
|
|
523
|
+
kind: "destructive",
|
|
524
|
+
operation: "git_reset_hard",
|
|
525
|
+
matches: artifacts.map(({ artifact }) => ({
|
|
526
|
+
artifactPath: artifact.path,
|
|
527
|
+
commandPath: ".",
|
|
528
|
+
reason: "git reset --hard can overwrite protected artifacts",
|
|
529
|
+
})),
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
if (subcommand === "checkout" && args.includes("--")) {
|
|
534
|
+
const paths = args.slice(args.indexOf("--") + 1);
|
|
535
|
+
const matches = matchesForPaths(paths, artifacts, "intersects", "git checkout -- can overwrite protected artifacts");
|
|
536
|
+
if (matches.length > 0) {
|
|
537
|
+
return {
|
|
538
|
+
kind: "destructive",
|
|
539
|
+
operation: "git_checkout",
|
|
540
|
+
matches,
|
|
541
|
+
};
|
|
542
|
+
}
|
|
543
|
+
return { kind: "benign", matches: [] };
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
if (subcommand === "restore") {
|
|
547
|
+
const matches = matchesForPaths(
|
|
548
|
+
pathArgs(args.slice(1), -1),
|
|
549
|
+
artifacts,
|
|
550
|
+
"intersects",
|
|
551
|
+
"git restore can overwrite protected artifacts",
|
|
552
|
+
);
|
|
553
|
+
if (matches.length > 0) {
|
|
554
|
+
return {
|
|
555
|
+
kind: "destructive",
|
|
556
|
+
operation: "git_restore",
|
|
557
|
+
matches,
|
|
558
|
+
};
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
return { kind: "benign", matches: [] };
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
function classifyFindDelete(
|
|
566
|
+
args: ReadonlyArray<string>,
|
|
567
|
+
artifacts: ReadonlyArray<NormalizedArtifact>,
|
|
568
|
+
): DestructiveCommandClassification {
|
|
569
|
+
if (!args.includes("-delete")) return { kind: "benign", matches: [] };
|
|
570
|
+
const roots = findRoots(args);
|
|
571
|
+
const matches = matchesForPaths(
|
|
572
|
+
roots.length === 0 ? ["."] : roots,
|
|
573
|
+
artifacts,
|
|
574
|
+
"intersects",
|
|
575
|
+
"find -delete can remove protected artifacts",
|
|
576
|
+
);
|
|
577
|
+
if (matches.length > 0) {
|
|
578
|
+
return {
|
|
579
|
+
kind: "destructive",
|
|
580
|
+
operation: "find_delete",
|
|
581
|
+
matches,
|
|
582
|
+
};
|
|
583
|
+
}
|
|
584
|
+
return { kind: "benign", matches: [] };
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
function findRoots(args: ReadonlyArray<string>): string[] {
|
|
588
|
+
const roots: string[] = [];
|
|
589
|
+
for (const token of args) {
|
|
590
|
+
if (token === "-delete" || token.startsWith("-") || token === "(" || token === "!" || token === "not") break;
|
|
591
|
+
if (token === "--") continue;
|
|
592
|
+
roots.push(token);
|
|
593
|
+
}
|
|
594
|
+
return roots.length === 0 ? ["."] : roots;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
function classifyPathOperation(
|
|
598
|
+
operation: DestructiveCommandOperation,
|
|
599
|
+
reason: string,
|
|
600
|
+
paths: ReadonlyArray<string>,
|
|
601
|
+
artifacts: ReadonlyArray<NormalizedArtifact>,
|
|
602
|
+
): DestructiveCommandClassification {
|
|
603
|
+
const matches = matchesForPaths(paths, artifacts, "intersects", reason);
|
|
604
|
+
if (matches.length === 0) return { kind: "benign", matches: [] };
|
|
605
|
+
return {
|
|
606
|
+
kind: "destructive",
|
|
607
|
+
operation,
|
|
608
|
+
matches,
|
|
609
|
+
};
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
function matchesForPaths(
|
|
613
|
+
commandPaths: ReadonlyArray<string>,
|
|
614
|
+
artifacts: ReadonlyArray<NormalizedArtifact>,
|
|
615
|
+
mode: "target" | "intersects",
|
|
616
|
+
reason: string,
|
|
617
|
+
): ProtectedArtifactCommandMatch[] {
|
|
618
|
+
const matches: ProtectedArtifactCommandMatch[] = [];
|
|
619
|
+
const seen = new Set<string>();
|
|
620
|
+
for (const commandPath of commandPaths) {
|
|
621
|
+
for (const artifact of artifacts) {
|
|
622
|
+
if (!pathMatchesArtifact(commandPath, artifact.key, mode)) continue;
|
|
623
|
+
const key = `${artifact.key}\0${commandPath}\0${reason}`;
|
|
624
|
+
if (seen.has(key)) continue;
|
|
625
|
+
seen.add(key);
|
|
626
|
+
matches.push({
|
|
627
|
+
artifactPath: artifact.artifact.path,
|
|
628
|
+
commandPath,
|
|
629
|
+
reason,
|
|
630
|
+
});
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
matches.sort(compareMatches);
|
|
634
|
+
return matches;
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
function pathMatchesArtifact(commandPath: string, artifactKey: string, mode: "target" | "intersects"): boolean {
|
|
638
|
+
const wildcardRoot = wildcardRootKey(commandPath);
|
|
639
|
+
if (wildcardRoot !== null) {
|
|
640
|
+
return isSameOrDescendant(artifactKey, wildcardRoot);
|
|
641
|
+
}
|
|
642
|
+
const commandKey = normalizePathKey(commandPath);
|
|
643
|
+
if (commandKey === null) return false;
|
|
644
|
+
if (mode === "target") return isSameOrDescendant(commandKey, artifactKey);
|
|
645
|
+
return isSameOrDescendant(commandKey, artifactKey) || isSameOrDescendant(artifactKey, commandKey);
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
function validationMatch(executable: string, args: ReadonlyArray<string>): string | null {
|
|
649
|
+
if (executable === "npm") {
|
|
650
|
+
if (args[0] === "test") return "npm test";
|
|
651
|
+
const script = args[0] === "run" && typeof args[1] === "string" ? args[1] : null;
|
|
652
|
+
if (script !== null && isVerificationScriptName(script)) return `npm run ${script}`;
|
|
653
|
+
}
|
|
654
|
+
if (executable === "pytest") return "pytest";
|
|
655
|
+
if (isPythonExecutable(executable) && moduleArg(args) === "pytest") return "python -m pytest";
|
|
656
|
+
if (executable === "cargo" && args[0] === "test") return "cargo test";
|
|
657
|
+
if (executable === "go" && args[0] === "test") return "go test";
|
|
658
|
+
if (executable === "ctest") return "ctest";
|
|
659
|
+
if (executable === "make" && args[0] === "test") return "make test";
|
|
660
|
+
if (executable === "ninja" && args[0] === "test") return "ninja test";
|
|
661
|
+
if (executable === "mvn" && args[0] === "test") return "mvn test";
|
|
662
|
+
if ((executable === "gradle" || executable === "gradlew") && args[0] === "test") return "gradle test";
|
|
663
|
+
return null;
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
/**
|
|
667
|
+
* The `grounding`-only half of the vocabulary. Every rule here is an exact
|
|
668
|
+
* leading-command match on a canonicalized executable, never a substring guess,
|
|
669
|
+
* so a command that merely mentions `tsc` or `diff` in an argument stays
|
|
670
|
+
* unrecognized. Failing to match is the safe direction for this scope.
|
|
671
|
+
*/
|
|
672
|
+
function groundingMatch(executable: string, args: ReadonlyArray<string>): string | null {
|
|
673
|
+
if (executable === "git") {
|
|
674
|
+
if (args[0] === "diff") return "git diff";
|
|
675
|
+
if (args[0] === "status") return "git status";
|
|
676
|
+
return null;
|
|
677
|
+
}
|
|
678
|
+
if (executable === "node") {
|
|
679
|
+
if (args.includes("--test")) return "node --test";
|
|
680
|
+
if (args.includes("-e") || args.includes("--eval")) return "node -e";
|
|
681
|
+
return null;
|
|
682
|
+
}
|
|
683
|
+
if (executable === "tsc") return typescriptCheckMatch(args);
|
|
684
|
+
if (executable === "npx") {
|
|
685
|
+
const inner = npxInvocation(args);
|
|
686
|
+
return inner === null ? null : npxRunnerMatch(inner.executable, inner.args);
|
|
687
|
+
}
|
|
688
|
+
return null;
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
/** Test runners recognized behind `npx`, where the runner name is the whole claim. */
|
|
692
|
+
const NPX_TEST_RUNNERS: ReadonlySet<string> = new Set(["vitest", "jest", "mocha"]);
|
|
693
|
+
|
|
694
|
+
function npxRunnerMatch(executable: string, args: ReadonlyArray<string>): string | null {
|
|
695
|
+
if (NPX_TEST_RUNNERS.has(executable)) return `npx ${executable}`;
|
|
696
|
+
if (executable === "tsx" && args.includes("--test")) return "npx tsx --test";
|
|
697
|
+
if (executable === "tsc") return typescriptCheckMatch(args);
|
|
698
|
+
return null;
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
/** `tsc --noEmit` is a typecheck; a bare `tsc` is a build that also typechecks. */
|
|
702
|
+
function typescriptCheckMatch(args: ReadonlyArray<string>): string {
|
|
703
|
+
return args.some((arg) => arg.toLowerCase() === "--noemit") ? "tsc --noEmit" : "tsc";
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
/**
|
|
707
|
+
* The command `npx` would run, with npx's own flags consumed. Flags that take a
|
|
708
|
+
* separate value (`-p react`, `--package=x` is self-contained) must not be
|
|
709
|
+
* mistaken for the command name.
|
|
710
|
+
*/
|
|
711
|
+
function npxInvocation(args: ReadonlyArray<string>): { executable: string; args: ReadonlyArray<string> } | null {
|
|
712
|
+
const VALUE_FLAGS = new Set(["-p", "--package", "-c", "--call", "--shell"]);
|
|
713
|
+
let index = 0;
|
|
714
|
+
while (index < args.length) {
|
|
715
|
+
const token = args[index];
|
|
716
|
+
if (token === undefined) return null;
|
|
717
|
+
if (VALUE_FLAGS.has(token)) {
|
|
718
|
+
index += 2;
|
|
719
|
+
continue;
|
|
720
|
+
}
|
|
721
|
+
if (token.startsWith("-")) {
|
|
722
|
+
index += 1;
|
|
723
|
+
continue;
|
|
724
|
+
}
|
|
725
|
+
return { executable: basenameToken(token), args: args.slice(index + 1) };
|
|
726
|
+
}
|
|
727
|
+
return null;
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
function moduleArg(args: ReadonlyArray<string>): string | null {
|
|
731
|
+
for (let index = 0; index < args.length - 1; index += 1) {
|
|
732
|
+
if (args[index] === "-m") return args[index + 1] ?? null;
|
|
733
|
+
}
|
|
734
|
+
return null;
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
function isPythonExecutable(executable: string): boolean {
|
|
738
|
+
return executable === "python" || executable === "python3" || /^python3\.\d+$/.test(executable);
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
function pathArgs(segment: ReadonlyArray<string>, commandIndex: number): string[] {
|
|
742
|
+
const args: string[] = [];
|
|
743
|
+
let endOfOptions = false;
|
|
744
|
+
for (let index = commandIndex + 1; index < segment.length; index += 1) {
|
|
745
|
+
const token = segment[index];
|
|
746
|
+
if (token === undefined) continue;
|
|
747
|
+
if (COMMAND_SEPARATORS.has(token)) break;
|
|
748
|
+
if (!endOfOptions && token === "--") {
|
|
749
|
+
endOfOptions = true;
|
|
750
|
+
continue;
|
|
751
|
+
}
|
|
752
|
+
if (!endOfOptions && token.startsWith("-")) continue;
|
|
753
|
+
if (token === ">" || token === ">>" || token === "<" || token === "<<") {
|
|
754
|
+
index += 1;
|
|
755
|
+
continue;
|
|
756
|
+
}
|
|
757
|
+
args.push(token);
|
|
758
|
+
}
|
|
759
|
+
return args;
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
export function tokenizeShellLike(command: string): string[] {
|
|
763
|
+
const tokens: string[] = [];
|
|
764
|
+
let current = "";
|
|
765
|
+
let quote: "'" | '"' | null = null;
|
|
766
|
+
|
|
767
|
+
const pushCurrent = (): void => {
|
|
768
|
+
if (current.length === 0) return;
|
|
769
|
+
tokens.push(current);
|
|
770
|
+
current = "";
|
|
771
|
+
};
|
|
772
|
+
|
|
773
|
+
for (let index = 0; index < command.length; index += 1) {
|
|
774
|
+
const char = command[index];
|
|
775
|
+
if (char === undefined) continue;
|
|
776
|
+
if (quote !== null) {
|
|
777
|
+
if (char === quote) {
|
|
778
|
+
quote = null;
|
|
779
|
+
continue;
|
|
780
|
+
}
|
|
781
|
+
if (quote === '"' && char === "\\" && index + 1 < command.length) {
|
|
782
|
+
index += 1;
|
|
783
|
+
current += command[index] ?? "";
|
|
784
|
+
continue;
|
|
785
|
+
}
|
|
786
|
+
current += char;
|
|
787
|
+
continue;
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
if (char === "'" || char === '"') {
|
|
791
|
+
quote = char;
|
|
792
|
+
continue;
|
|
793
|
+
}
|
|
794
|
+
if (char === "\\" && index + 1 < command.length) {
|
|
795
|
+
index += 1;
|
|
796
|
+
current += command[index] ?? "";
|
|
797
|
+
continue;
|
|
798
|
+
}
|
|
799
|
+
if (/\s/.test(char)) {
|
|
800
|
+
pushCurrent();
|
|
801
|
+
if (char === "\n") tokens.push(";");
|
|
802
|
+
continue;
|
|
803
|
+
}
|
|
804
|
+
if (char === ";") {
|
|
805
|
+
pushCurrent();
|
|
806
|
+
tokens.push(";");
|
|
807
|
+
continue;
|
|
808
|
+
}
|
|
809
|
+
if (char === "&" && command[index + 1] === "&") {
|
|
810
|
+
pushCurrent();
|
|
811
|
+
tokens.push("&&");
|
|
812
|
+
index += 1;
|
|
813
|
+
continue;
|
|
814
|
+
}
|
|
815
|
+
if (char === "|") {
|
|
816
|
+
pushCurrent();
|
|
817
|
+
if (command[index + 1] === "|") {
|
|
818
|
+
tokens.push("||");
|
|
819
|
+
index += 1;
|
|
820
|
+
} else {
|
|
821
|
+
tokens.push("|");
|
|
822
|
+
}
|
|
823
|
+
continue;
|
|
824
|
+
}
|
|
825
|
+
if (char === ">") {
|
|
826
|
+
pushCurrent();
|
|
827
|
+
if (command[index + 1] === ">") {
|
|
828
|
+
tokens.push(">>");
|
|
829
|
+
index += 1;
|
|
830
|
+
} else {
|
|
831
|
+
tokens.push(">");
|
|
832
|
+
}
|
|
833
|
+
continue;
|
|
834
|
+
}
|
|
835
|
+
if (char === "<") {
|
|
836
|
+
pushCurrent();
|
|
837
|
+
if (command[index + 1] === "<") {
|
|
838
|
+
tokens.push("<<");
|
|
839
|
+
index += 1;
|
|
840
|
+
} else {
|
|
841
|
+
tokens.push("<");
|
|
842
|
+
}
|
|
843
|
+
continue;
|
|
844
|
+
}
|
|
845
|
+
current += char;
|
|
846
|
+
}
|
|
847
|
+
pushCurrent();
|
|
848
|
+
return tokens;
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
function splitSegments(tokens: ReadonlyArray<string>): string[][] {
|
|
852
|
+
const segments: string[][] = [];
|
|
853
|
+
let current: string[] = [];
|
|
854
|
+
for (const token of tokens) {
|
|
855
|
+
if (COMMAND_SEPARATORS.has(token)) {
|
|
856
|
+
if (current.length > 0) segments.push(current);
|
|
857
|
+
current = [];
|
|
858
|
+
continue;
|
|
859
|
+
}
|
|
860
|
+
current.push(token);
|
|
861
|
+
}
|
|
862
|
+
if (current.length > 0) segments.push(current);
|
|
863
|
+
return segments;
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
function commandTokenIndex(segment: ReadonlyArray<string>): number | null {
|
|
867
|
+
let index = 0;
|
|
868
|
+
while (index < segment.length) {
|
|
869
|
+
const token = segment[index];
|
|
870
|
+
if (token === undefined) return null;
|
|
871
|
+
if (isEnvAssignment(token)) {
|
|
872
|
+
index += 1;
|
|
873
|
+
continue;
|
|
874
|
+
}
|
|
875
|
+
if (token === "env") {
|
|
876
|
+
index += 1;
|
|
877
|
+
while (
|
|
878
|
+
index < segment.length &&
|
|
879
|
+
(segment[index]?.startsWith("-") === true || isEnvAssignment(segment[index] ?? ""))
|
|
880
|
+
) {
|
|
881
|
+
index += 1;
|
|
882
|
+
}
|
|
883
|
+
continue;
|
|
884
|
+
}
|
|
885
|
+
if (SHELL_WRAPPERS.has(token)) {
|
|
886
|
+
index += 1;
|
|
887
|
+
while (index < segment.length && segment[index]?.startsWith("-") === true) index += 1;
|
|
888
|
+
continue;
|
|
889
|
+
}
|
|
890
|
+
return index;
|
|
891
|
+
}
|
|
892
|
+
return null;
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
function isEnvAssignment(token: string): boolean {
|
|
896
|
+
return /^[A-Za-z_][A-Za-z0-9_]*=/.test(token);
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
function basenameToken(token: string | undefined): string {
|
|
900
|
+
if (token === undefined) return "";
|
|
901
|
+
const normalized = token.replace(/\\/g, "/");
|
|
902
|
+
const basename = normalized.slice(normalized.lastIndexOf("/") + 1);
|
|
903
|
+
return basename.toLowerCase();
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
function artifactMap(artifacts: ReadonlyArray<ProtectedArtifact>): Map<string, ProtectedArtifact> {
|
|
907
|
+
const out = new Map<string, ProtectedArtifact>();
|
|
908
|
+
for (const artifact of artifacts) {
|
|
909
|
+
const key = normalizePathKey(artifact.path);
|
|
910
|
+
if (key !== null) out.set(key, cloneArtifact(artifact));
|
|
911
|
+
}
|
|
912
|
+
return out;
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
function stateFromMap(artifacts: ReadonlyMap<string, ProtectedArtifact>): ProtectedArtifactState {
|
|
916
|
+
return {
|
|
917
|
+
artifacts: Array.from(artifacts.entries())
|
|
918
|
+
.sort(([left], [right]) => compareStrings(left, right))
|
|
919
|
+
.map(([, artifact]) => cloneArtifact(artifact)),
|
|
920
|
+
};
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
function normalizedArtifacts(artifacts: ReadonlyArray<ProtectedArtifact>): NormalizedArtifact[] {
|
|
924
|
+
const out = Array.from(artifactMap(artifacts).entries()).map(([key, artifact]) => ({ key, artifact }));
|
|
925
|
+
out.sort((left, right) => compareStrings(left.key, right.key));
|
|
926
|
+
return out;
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
function cloneArtifact(artifact: ProtectedArtifact): ProtectedArtifact {
|
|
930
|
+
const cloned: ProtectedArtifact = {
|
|
931
|
+
path: artifact.path,
|
|
932
|
+
protectedAt: artifact.protectedAt,
|
|
933
|
+
reason: artifact.reason,
|
|
934
|
+
source: artifact.source,
|
|
935
|
+
};
|
|
936
|
+
if (artifact.validationCommand !== undefined) cloned.validationCommand = artifact.validationCommand;
|
|
937
|
+
if (artifact.validationExitCode !== undefined) cloned.validationExitCode = artifact.validationExitCode;
|
|
938
|
+
return cloned;
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
function normalizePathKey(input: string): string | null {
|
|
942
|
+
const trimmed = input.trim();
|
|
943
|
+
if (trimmed.length === 0) return null;
|
|
944
|
+
if (isWindowsAbsolutePath(trimmed) && path.sep !== "\\") {
|
|
945
|
+
return toSlashKey(path.win32.normalize(trimmed));
|
|
946
|
+
}
|
|
947
|
+
const resolved = path.isAbsolute(trimmed) ? trimmed : path.resolve(trimmed);
|
|
948
|
+
return toSlashKey(canonicalizeExistingPath(resolved));
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
function wildcardRootKey(input: string): string | null {
|
|
952
|
+
const normalizedInput = toSlashKey(input.trim());
|
|
953
|
+
const firstWildcard = firstWildcardIndex(normalizedInput);
|
|
954
|
+
if (firstWildcard === null) return null;
|
|
955
|
+
const prefix = normalizedInput.slice(0, firstWildcard);
|
|
956
|
+
const slash = prefix.lastIndexOf("/");
|
|
957
|
+
const root = slash >= 0 ? prefix.slice(0, slash + 1) : ".";
|
|
958
|
+
return normalizePathKey(root);
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
function firstWildcardIndex(input: string): number | null {
|
|
962
|
+
const indexes = ["*", "?", "["].map((char) => input.indexOf(char)).filter((index) => index >= 0);
|
|
963
|
+
if (indexes.length === 0) return null;
|
|
964
|
+
return Math.min(...indexes);
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
function isWindowsAbsolutePath(input: string): boolean {
|
|
968
|
+
return /^[A-Za-z]:[\\/]/.test(input);
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
function toSlashKey(input: string): string {
|
|
972
|
+
return input.replace(/\\/g, "/");
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
function isSameOrDescendant(candidate: string, parent: string): boolean {
|
|
976
|
+
if (candidate === parent) return true;
|
|
977
|
+
const relative = path.posix.relative(parent, candidate);
|
|
978
|
+
return relative !== "" && !relative.startsWith("..") && !path.posix.isAbsolute(relative);
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
function compareMatches(left: ProtectedArtifactCommandMatch, right: ProtectedArtifactCommandMatch): number {
|
|
982
|
+
return (
|
|
983
|
+
compareStrings(left.artifactPath, right.artifactPath) ||
|
|
984
|
+
compareStrings(left.commandPath, right.commandPath) ||
|
|
985
|
+
compareStrings(left.reason, right.reason)
|
|
986
|
+
);
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
function compareStrings(left: string, right: string): number {
|
|
990
|
+
if (left < right) return -1;
|
|
991
|
+
if (left > right) return 1;
|
|
992
|
+
return 0;
|
|
993
|
+
}
|