@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,898 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scratch git worktrees for the compete dispatch topology.
|
|
3
|
+
*
|
|
4
|
+
* Each candidate builds in its own worktree on its own branch
|
|
5
|
+
* (`clio/compete/<group>/<n>`), created from the repository HEAD under
|
|
6
|
+
* `<root>/.clio-coder/worktrees/<group>/candidate-<n>`. The path sits inside the
|
|
7
|
+
* project root because remote fleet nodes share the filesystem and doctor
|
|
8
|
+
* preflight verifies path parity only for the project root; `.clio-coder/` is
|
|
9
|
+
* ignored, so candidate churn never dirties the repository status.
|
|
10
|
+
*
|
|
11
|
+
* A group is claimed by a durable owner manifest before the first git
|
|
12
|
+
* worktree mutation. Cleanup requires that exact claim and uses canonical,
|
|
13
|
+
* segment-aware path checks. The claim also leases every admitted worker to
|
|
14
|
+
* the coordinator process. On restart, a dead coordinator's exact worker
|
|
15
|
+
* processes are terminated before its active group is made cleanup-ready;
|
|
16
|
+
* live owners, preserved winners, and malformed claims are never inferred to
|
|
17
|
+
* be abandoned.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { execFileSync } from "node:child_process";
|
|
21
|
+
import { randomBytes } from "node:crypto";
|
|
22
|
+
import {
|
|
23
|
+
existsSync,
|
|
24
|
+
lstatSync,
|
|
25
|
+
mkdirSync,
|
|
26
|
+
readdirSync,
|
|
27
|
+
readFileSync,
|
|
28
|
+
realpathSync,
|
|
29
|
+
renameSync,
|
|
30
|
+
rmdirSync,
|
|
31
|
+
rmSync,
|
|
32
|
+
unlinkSync,
|
|
33
|
+
writeFileSync,
|
|
34
|
+
} from "node:fs";
|
|
35
|
+
import { hostname } from "node:os";
|
|
36
|
+
import { isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
37
|
+
import type { RunKind } from "../domains/dispatch/types.js";
|
|
38
|
+
|
|
39
|
+
export interface CandidateWorktree {
|
|
40
|
+
index: number;
|
|
41
|
+
branch: string;
|
|
42
|
+
path: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export type CompeteGroupState = "active" | "cleanup-ready" | "winner-preserved";
|
|
46
|
+
|
|
47
|
+
/** Proof that this exact directory was claimed as one compete transaction. */
|
|
48
|
+
export interface CompeteGroupOwnership {
|
|
49
|
+
root: string;
|
|
50
|
+
group: string;
|
|
51
|
+
directory: string;
|
|
52
|
+
token: string;
|
|
53
|
+
state: CompeteGroupState;
|
|
54
|
+
winnerIndex?: number;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface CompeteRecoveryResult {
|
|
58
|
+
cleaned: string[];
|
|
59
|
+
preserved: string[];
|
|
60
|
+
failed: Array<{ group: string; message: string }>;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface CompeteRecoveryOptions {
|
|
64
|
+
/** Keep these quiesced active groups until their pending judge output is resolved. */
|
|
65
|
+
preserveActiveGroups?: ReadonlySet<string>;
|
|
66
|
+
/** Fail-closed journal fallback: quiesce, but retain, every abandoned active group. */
|
|
67
|
+
preserveAllActive?: boolean;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
interface CompeteGroupManifest {
|
|
71
|
+
version: 2;
|
|
72
|
+
kind: string;
|
|
73
|
+
root: string;
|
|
74
|
+
group: string;
|
|
75
|
+
token: string;
|
|
76
|
+
state: CompeteGroupState;
|
|
77
|
+
createdAt: string;
|
|
78
|
+
updatedAt: string;
|
|
79
|
+
winnerIndex?: number;
|
|
80
|
+
owner: CompeteProcessLease;
|
|
81
|
+
runs: CompeteRunLease[];
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
interface CompeteProcessLease {
|
|
85
|
+
host: string;
|
|
86
|
+
pid: number;
|
|
87
|
+
birthToken: string | null;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
interface CompeteRunLease {
|
|
91
|
+
runId: string;
|
|
92
|
+
pid: number | null;
|
|
93
|
+
birthToken: string | null;
|
|
94
|
+
processGroup: boolean;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export interface CompeteRunAdmission {
|
|
98
|
+
runId: string;
|
|
99
|
+
pid: number | null;
|
|
100
|
+
runtimeKind: RunKind;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const COMPETE_PARENT_SEGMENTS = [".clio-coder", "worktrees"] as const;
|
|
104
|
+
const COMPETE_MANIFEST_FILE = ".clio-coder-compete-owner.json";
|
|
105
|
+
const COMPETE_MANIFEST_KIND = "clio-compete-group";
|
|
106
|
+
const COMPETE_COMMIT_IDENTITY = "clio-compete";
|
|
107
|
+
|
|
108
|
+
const SAFE_GROUP = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
|
|
109
|
+
const PROCESS_EXIT_GRACE_MS = 750;
|
|
110
|
+
const PROCESS_POLL_MS = 25;
|
|
111
|
+
|
|
112
|
+
function git(root: string, args: string[]): string {
|
|
113
|
+
return execFileSync("git", ["-C", root, ...args], {
|
|
114
|
+
encoding: "utf8",
|
|
115
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
116
|
+
timeout: 30_000,
|
|
117
|
+
}).trim();
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function errorMessage(err: unknown): string {
|
|
121
|
+
return err instanceof Error ? err.message : String(err);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
interface ProcessSnapshot {
|
|
125
|
+
alive: boolean;
|
|
126
|
+
birthToken: string | null;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Return a PID-reuse-resistant process identity where the host exposes one.
|
|
131
|
+
* Linux's kernel start ticks are stable for the lifetime of a process. The
|
|
132
|
+
* portable fallback uses `ps` start time; if neither is available we retain
|
|
133
|
+
* liveness but refuse to signal a live PID during restart recovery.
|
|
134
|
+
*/
|
|
135
|
+
function processSnapshot(pid: number): ProcessSnapshot {
|
|
136
|
+
if (!Number.isSafeInteger(pid) || pid <= 0) return { alive: false, birthToken: null };
|
|
137
|
+
try {
|
|
138
|
+
process.kill(pid, 0);
|
|
139
|
+
} catch (err) {
|
|
140
|
+
if ((err as NodeJS.ErrnoException).code !== "EPERM") return { alive: false, birthToken: null };
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
try {
|
|
144
|
+
const stat = readFileSync(`/proc/${pid}/stat`, "utf8").trim();
|
|
145
|
+
const close = stat.lastIndexOf(")");
|
|
146
|
+
if (close > 0) {
|
|
147
|
+
// Fields after the command name start at kernel field 3. Field 3 is
|
|
148
|
+
// process state and field 22 (index 19 here) is starttime in ticks.
|
|
149
|
+
const fields = stat
|
|
150
|
+
.slice(close + 1)
|
|
151
|
+
.trim()
|
|
152
|
+
.split(/\s+/u);
|
|
153
|
+
if (fields[0] === "Z") return { alive: false, birthToken: fields[19] ?? null };
|
|
154
|
+
const startTicks = fields[19];
|
|
155
|
+
if (startTicks !== undefined && /^\d+$/u.test(startTicks)) {
|
|
156
|
+
return { alive: true, birthToken: `linux:${startTicks}` };
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
} catch {
|
|
160
|
+
// Non-Linux host or procfs unavailable; try the portable fallback.
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
try {
|
|
164
|
+
const started = execFileSync("ps", ["-o", "lstart=", "-p", String(pid)], {
|
|
165
|
+
encoding: "utf8",
|
|
166
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
167
|
+
timeout: 2_000,
|
|
168
|
+
}).trim();
|
|
169
|
+
if (started.length > 0) return { alive: true, birthToken: `ps:${started}` };
|
|
170
|
+
} catch {
|
|
171
|
+
// The PID exists, but it cannot be identified strongly enough to kill.
|
|
172
|
+
}
|
|
173
|
+
return { alive: true, birthToken: null };
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function currentProcessLease(): CompeteProcessLease {
|
|
177
|
+
return {
|
|
178
|
+
host: hostname(),
|
|
179
|
+
pid: process.pid,
|
|
180
|
+
birthToken: processSnapshot(process.pid).birthToken,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function validProcessLease(value: unknown): value is CompeteProcessLease {
|
|
185
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
186
|
+
const lease = value as Record<string, unknown>;
|
|
187
|
+
return (
|
|
188
|
+
typeof lease.host === "string" &&
|
|
189
|
+
lease.host.length > 0 &&
|
|
190
|
+
typeof lease.pid === "number" &&
|
|
191
|
+
Number.isSafeInteger(lease.pid) &&
|
|
192
|
+
lease.pid > 0 &&
|
|
193
|
+
(lease.birthToken === null || typeof lease.birthToken === "string")
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function validRunLease(value: unknown): value is CompeteRunLease {
|
|
198
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
199
|
+
const lease = value as Record<string, unknown>;
|
|
200
|
+
return (
|
|
201
|
+
typeof lease.runId === "string" &&
|
|
202
|
+
lease.runId.length > 0 &&
|
|
203
|
+
(lease.pid === null || (typeof lease.pid === "number" && Number.isSafeInteger(lease.pid) && lease.pid > 0)) &&
|
|
204
|
+
(lease.birthToken === null || typeof lease.birthToken === "string") &&
|
|
205
|
+
typeof lease.processGroup === "boolean"
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
function ownerIsAlive(owner: CompeteProcessLease): boolean {
|
|
210
|
+
if (owner.host !== hostname()) return true;
|
|
211
|
+
const snapshot = processSnapshot(owner.pid);
|
|
212
|
+
if (!snapshot.alive) return false;
|
|
213
|
+
// A null identity cannot distinguish PID reuse, so preserving is the only
|
|
214
|
+
// safe choice. Supported hosts normally provide a token above.
|
|
215
|
+
if (owner.birthToken === null || snapshot.birthToken === null) return true;
|
|
216
|
+
return owner.birthToken === snapshot.birthToken;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function waitForProcessExit(pid: number, birthToken: string): boolean {
|
|
220
|
+
const deadline = Date.now() + PROCESS_EXIT_GRACE_MS;
|
|
221
|
+
const sleeper = new Int32Array(new SharedArrayBuffer(4));
|
|
222
|
+
while (Date.now() < deadline) {
|
|
223
|
+
const snapshot = processSnapshot(pid);
|
|
224
|
+
if (!snapshot.alive || snapshot.birthToken !== birthToken) return true;
|
|
225
|
+
Atomics.wait(sleeper, 0, 0, PROCESS_POLL_MS);
|
|
226
|
+
}
|
|
227
|
+
const finalSnapshot = processSnapshot(pid);
|
|
228
|
+
return !finalSnapshot.alive || finalSnapshot.birthToken !== birthToken;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/** Terminate only the exact process identity durably leased to this group. */
|
|
232
|
+
function terminateRunLease(lease: CompeteRunLease): boolean {
|
|
233
|
+
if (lease.pid === null) return true;
|
|
234
|
+
const snapshot = processSnapshot(lease.pid);
|
|
235
|
+
if (!snapshot.alive) return true;
|
|
236
|
+
if (lease.birthToken === null || snapshot.birthToken === null) return false;
|
|
237
|
+
if (lease.birthToken !== snapshot.birthToken) return true;
|
|
238
|
+
|
|
239
|
+
const target = lease.processGroup && process.platform !== "win32" ? -lease.pid : lease.pid;
|
|
240
|
+
try {
|
|
241
|
+
process.kill(target, "SIGTERM");
|
|
242
|
+
} catch (err) {
|
|
243
|
+
if ((err as NodeJS.ErrnoException).code === "ESRCH") return true;
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
if (waitForProcessExit(lease.pid, lease.birthToken)) return true;
|
|
247
|
+
try {
|
|
248
|
+
process.kill(target, "SIGKILL");
|
|
249
|
+
} catch (err) {
|
|
250
|
+
if ((err as NodeJS.ErrnoException).code === "ESRCH") return true;
|
|
251
|
+
return false;
|
|
252
|
+
}
|
|
253
|
+
return waitForProcessExit(lease.pid, lease.birthToken);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
function validateGroup(group: string): void {
|
|
257
|
+
if (!SAFE_GROUP.test(group) || group === "." || group === "..") {
|
|
258
|
+
throw new Error(`invalid compete group '${group}'`);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
function canonicalRoot(root: string): string {
|
|
263
|
+
return realpathSync(root);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
function competeParent(root: string): string {
|
|
267
|
+
return join(root, ...COMPETE_PARENT_SEGMENTS);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
function groupDirectory(root: string, group: string): string {
|
|
271
|
+
validateGroup(group);
|
|
272
|
+
return join(competeParent(root), group);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
function manifestPath(directory: string): string {
|
|
276
|
+
return join(directory, COMPETE_MANIFEST_FILE);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function isPlainDirectory(path: string): boolean {
|
|
280
|
+
try {
|
|
281
|
+
const stat = lstatSync(path);
|
|
282
|
+
return stat.isDirectory() && !stat.isSymbolicLink();
|
|
283
|
+
} catch {
|
|
284
|
+
return false;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
function isCanonicalDirectoryAt(path: string): boolean {
|
|
289
|
+
if (!isPlainDirectory(path)) return false;
|
|
290
|
+
try {
|
|
291
|
+
return relative(realpathSync(path), resolve(path)) === "";
|
|
292
|
+
} catch {
|
|
293
|
+
return false;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Whether `candidate` is strictly below `parent` after canonical resolution.
|
|
299
|
+
* `relative()` makes the decision by path segment, so `/group-a2` can never
|
|
300
|
+
* be mistaken for a child of `/group-a` as it can with textual startsWith.
|
|
301
|
+
*/
|
|
302
|
+
export function isCanonicalPathInside(parent: string, candidate: string): boolean {
|
|
303
|
+
let canonicalParent: string;
|
|
304
|
+
let canonicalCandidate: string;
|
|
305
|
+
try {
|
|
306
|
+
canonicalParent = realpathSync(parent);
|
|
307
|
+
} catch {
|
|
308
|
+
canonicalParent = resolve(parent);
|
|
309
|
+
}
|
|
310
|
+
try {
|
|
311
|
+
canonicalCandidate = realpathSync(candidate);
|
|
312
|
+
} catch {
|
|
313
|
+
canonicalCandidate = resolve(candidate);
|
|
314
|
+
}
|
|
315
|
+
const rel = relative(canonicalParent, canonicalCandidate);
|
|
316
|
+
return rel.length > 0 && rel !== ".." && !rel.startsWith(`..${sep}`) && !isAbsolute(rel);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
function manifestFromUnknown(value: unknown): CompeteGroupManifest | null {
|
|
320
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return null;
|
|
321
|
+
const manifest = value as Record<string, unknown>;
|
|
322
|
+
if (
|
|
323
|
+
manifest.version !== 2 ||
|
|
324
|
+
manifest.kind !== COMPETE_MANIFEST_KIND ||
|
|
325
|
+
typeof manifest.root !== "string" ||
|
|
326
|
+
typeof manifest.group !== "string" ||
|
|
327
|
+
typeof manifest.token !== "string" ||
|
|
328
|
+
manifest.token.length === 0 ||
|
|
329
|
+
(manifest.state !== "active" && manifest.state !== "cleanup-ready" && manifest.state !== "winner-preserved") ||
|
|
330
|
+
typeof manifest.createdAt !== "string" ||
|
|
331
|
+
typeof manifest.updatedAt !== "string"
|
|
332
|
+
) {
|
|
333
|
+
return null;
|
|
334
|
+
}
|
|
335
|
+
if (
|
|
336
|
+
!validProcessLease(manifest.owner) ||
|
|
337
|
+
!Array.isArray(manifest.runs) ||
|
|
338
|
+
!manifest.runs.every(validRunLease) ||
|
|
339
|
+
new Set(manifest.runs.map((run) => run.runId)).size !== manifest.runs.length
|
|
340
|
+
) {
|
|
341
|
+
return null;
|
|
342
|
+
}
|
|
343
|
+
if (
|
|
344
|
+
manifest.winnerIndex !== undefined &&
|
|
345
|
+
(typeof manifest.winnerIndex !== "number" || !Number.isInteger(manifest.winnerIndex) || manifest.winnerIndex < 1)
|
|
346
|
+
) {
|
|
347
|
+
return null;
|
|
348
|
+
}
|
|
349
|
+
return manifest as unknown as CompeteGroupManifest;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
function readManifest(root: string, group: string): CompeteGroupManifest | null {
|
|
353
|
+
const canonical = canonicalRoot(root);
|
|
354
|
+
const directory = groupDirectory(canonical, group);
|
|
355
|
+
if (!isCanonicalDirectoryAt(directory)) return null;
|
|
356
|
+
try {
|
|
357
|
+
const parsed = JSON.parse(readFileSync(manifestPath(directory), "utf8")) as unknown;
|
|
358
|
+
const manifest = manifestFromUnknown(parsed);
|
|
359
|
+
if (manifest === null || manifest.root !== canonical || manifest.group !== group) return null;
|
|
360
|
+
return manifest;
|
|
361
|
+
} catch {
|
|
362
|
+
return null;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
function ownershipFromManifest(manifest: CompeteGroupManifest): CompeteGroupOwnership {
|
|
367
|
+
return {
|
|
368
|
+
root: manifest.root,
|
|
369
|
+
group: manifest.group,
|
|
370
|
+
directory: groupDirectory(manifest.root, manifest.group),
|
|
371
|
+
token: manifest.token,
|
|
372
|
+
state: manifest.state,
|
|
373
|
+
...(manifest.winnerIndex !== undefined ? { winnerIndex: manifest.winnerIndex } : {}),
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
function assertOwnership(ownership: CompeteGroupOwnership): CompeteGroupManifest {
|
|
378
|
+
const manifest = readManifest(ownership.root, ownership.group);
|
|
379
|
+
if (manifest === null || manifest.token !== ownership.token) {
|
|
380
|
+
throw new Error(`compete group ${ownership.group} has no matching ownership manifest; refusing cleanup`);
|
|
381
|
+
}
|
|
382
|
+
if (resolve(ownership.directory) !== resolve(groupDirectory(manifest.root, manifest.group))) {
|
|
383
|
+
throw new Error(`compete group ${ownership.group} ownership path changed; refusing cleanup`);
|
|
384
|
+
}
|
|
385
|
+
return manifest;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
function replaceManifest(ownership: CompeteGroupOwnership, manifest: CompeteGroupManifest): void {
|
|
389
|
+
assertOwnership(ownership);
|
|
390
|
+
const destination = manifestPath(ownership.directory);
|
|
391
|
+
const temporary = `${destination}.${randomBytes(6).toString("hex")}.tmp`;
|
|
392
|
+
try {
|
|
393
|
+
writeFileSync(temporary, `${JSON.stringify(manifest, null, 2)}\n`, { encoding: "utf8", flag: "wx" });
|
|
394
|
+
renameSync(temporary, destination);
|
|
395
|
+
} finally {
|
|
396
|
+
if (existsSync(temporary)) rmSync(temporary, { force: true });
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
export function isGitRepository(root: string): boolean {
|
|
401
|
+
try {
|
|
402
|
+
return git(root, ["rev-parse", "--is-inside-work-tree"]) === "true";
|
|
403
|
+
} catch {
|
|
404
|
+
return false;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
function competeBranch(group: string, index: number): string {
|
|
409
|
+
validateGroup(group);
|
|
410
|
+
if (!Number.isInteger(index) || index < 1) throw new Error(`invalid compete candidate index ${index}`);
|
|
411
|
+
return `clio/compete/${group}/${index}`;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/** Claim the group before creating a branch or candidate worktree. */
|
|
415
|
+
export function claimCompeteGroup(root: string, group: string): CompeteGroupOwnership {
|
|
416
|
+
const canonical = canonicalRoot(root);
|
|
417
|
+
const directory = groupDirectory(canonical, group);
|
|
418
|
+
const parent = competeParent(canonical);
|
|
419
|
+
mkdirSync(parent, { recursive: true });
|
|
420
|
+
if (!isCanonicalDirectoryAt(parent)) {
|
|
421
|
+
throw new Error(`compete parent ${parent} is not a canonical local directory`);
|
|
422
|
+
}
|
|
423
|
+
mkdirSync(directory);
|
|
424
|
+
if (!isCanonicalDirectoryAt(directory)) {
|
|
425
|
+
throw new Error(`compete group directory ${directory} is not canonical`);
|
|
426
|
+
}
|
|
427
|
+
const now = new Date().toISOString();
|
|
428
|
+
const manifest: CompeteGroupManifest = {
|
|
429
|
+
version: 2,
|
|
430
|
+
kind: COMPETE_MANIFEST_KIND,
|
|
431
|
+
root: canonical,
|
|
432
|
+
group,
|
|
433
|
+
token: randomBytes(16).toString("hex"),
|
|
434
|
+
state: "active",
|
|
435
|
+
createdAt: now,
|
|
436
|
+
updatedAt: now,
|
|
437
|
+
owner: currentProcessLease(),
|
|
438
|
+
runs: [],
|
|
439
|
+
};
|
|
440
|
+
try {
|
|
441
|
+
writeFileSync(manifestPath(directory), `${JSON.stringify(manifest, null, 2)}\n`, {
|
|
442
|
+
encoding: "utf8",
|
|
443
|
+
flag: "wx",
|
|
444
|
+
});
|
|
445
|
+
} catch (err) {
|
|
446
|
+
// mkdirSync above proved this invocation created the directory. Roll back
|
|
447
|
+
// only that still-empty claim; never sweep a pre-existing directory.
|
|
448
|
+
try {
|
|
449
|
+
rmdirSync(directory);
|
|
450
|
+
} catch {
|
|
451
|
+
// A partial or externally modified claim is now unproven and is kept.
|
|
452
|
+
}
|
|
453
|
+
throw err;
|
|
454
|
+
}
|
|
455
|
+
return ownershipFromManifest(manifest);
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
/** Load an exact durable claim, or null when ownership cannot be proven. */
|
|
459
|
+
export function loadCompeteGroup(root: string, group: string): CompeteGroupOwnership | null {
|
|
460
|
+
validateGroup(group);
|
|
461
|
+
const manifest = readManifest(root, group);
|
|
462
|
+
return manifest === null ? null : ownershipFromManifest(manifest);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/**
|
|
466
|
+
* Durably attach an admitted dispatch process to its compete transaction.
|
|
467
|
+
* The dispatch extension invokes this before returning the run handle, which
|
|
468
|
+
* closes the coordinator-crash window between process admission and tool-side
|
|
469
|
+
* bookkeeping.
|
|
470
|
+
*/
|
|
471
|
+
export function registerCompeteGroupRun(ownership: CompeteGroupOwnership, admission: CompeteRunAdmission): void {
|
|
472
|
+
const current = assertOwnership(ownership);
|
|
473
|
+
if (current.state !== "active") {
|
|
474
|
+
throw new Error(`compete group ${ownership.group} is ${current.state}; refusing new run ${admission.runId}`);
|
|
475
|
+
}
|
|
476
|
+
if (admission.runId.length === 0) throw new Error("worktree transaction run id cannot be empty");
|
|
477
|
+
if (admission.pid !== null && (!Number.isSafeInteger(admission.pid) || admission.pid <= 0)) {
|
|
478
|
+
throw new Error(`worktree transaction run ${admission.runId} has invalid pid ${admission.pid}`);
|
|
479
|
+
}
|
|
480
|
+
const lease: CompeteRunLease = {
|
|
481
|
+
runId: admission.runId,
|
|
482
|
+
pid: admission.pid,
|
|
483
|
+
birthToken: admission.pid === null ? null : processSnapshot(admission.pid).birthToken,
|
|
484
|
+
processGroup: admission.runtimeKind === "acp-delegation" && process.platform !== "win32",
|
|
485
|
+
};
|
|
486
|
+
const next: CompeteGroupManifest = {
|
|
487
|
+
...current,
|
|
488
|
+
runs: [...current.runs.filter((run) => run.runId !== admission.runId), lease],
|
|
489
|
+
updatedAt: new Date().toISOString(),
|
|
490
|
+
};
|
|
491
|
+
replaceManifest(ownership, next);
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
/** Mark one leased process settled; stale leases remain safe to probe after a crash. */
|
|
495
|
+
export function settleCompeteGroupRun(ownership: CompeteGroupOwnership, runId: string): void {
|
|
496
|
+
const current = assertOwnership(ownership);
|
|
497
|
+
if (current.state !== "active") return;
|
|
498
|
+
if (!current.runs.some((run) => run.runId === runId)) return;
|
|
499
|
+
const next: CompeteGroupManifest = {
|
|
500
|
+
...current,
|
|
501
|
+
runs: current.runs.filter((run) => run.runId !== runId),
|
|
502
|
+
updatedAt: new Date().toISOString(),
|
|
503
|
+
};
|
|
504
|
+
replaceManifest(ownership, next);
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
export function markCompeteGroupCleanupReady(ownership: CompeteGroupOwnership): CompeteGroupOwnership {
|
|
508
|
+
const current = assertOwnership(ownership);
|
|
509
|
+
const next: CompeteGroupManifest = {
|
|
510
|
+
...current,
|
|
511
|
+
state: "cleanup-ready",
|
|
512
|
+
updatedAt: new Date().toISOString(),
|
|
513
|
+
};
|
|
514
|
+
Reflect.deleteProperty(next, "winnerIndex");
|
|
515
|
+
replaceManifest(ownership, next);
|
|
516
|
+
return ownershipFromManifest(next);
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
export function markCompeteGroupWinnerPreserved(
|
|
520
|
+
ownership: CompeteGroupOwnership,
|
|
521
|
+
winnerIndex: number,
|
|
522
|
+
): CompeteGroupOwnership {
|
|
523
|
+
competeBranch(ownership.group, winnerIndex);
|
|
524
|
+
const current = assertOwnership(ownership);
|
|
525
|
+
const next: CompeteGroupManifest = {
|
|
526
|
+
...current,
|
|
527
|
+
state: "winner-preserved",
|
|
528
|
+
winnerIndex,
|
|
529
|
+
updatedAt: new Date().toISOString(),
|
|
530
|
+
};
|
|
531
|
+
replaceManifest(ownership, next);
|
|
532
|
+
return ownershipFromManifest(next);
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
/**
|
|
536
|
+
* Create one worktree for `index` from an explicit baseline commit. The
|
|
537
|
+
* baseline is a parameter rather than HEAD so every candidate in a compete
|
|
538
|
+
* transaction starts from the same approved state.
|
|
539
|
+
*/
|
|
540
|
+
export function createCandidateWorktree(
|
|
541
|
+
ownership: CompeteGroupOwnership,
|
|
542
|
+
index: number,
|
|
543
|
+
baseline: string,
|
|
544
|
+
): CandidateWorktree {
|
|
545
|
+
assertOwnership(ownership);
|
|
546
|
+
const branch = competeBranch(ownership.group, index);
|
|
547
|
+
const path = join(ownership.directory, `candidate-${index}`);
|
|
548
|
+
if (!isCanonicalPathInside(ownership.directory, path)) {
|
|
549
|
+
throw new Error(`candidate ${index} path escapes compete group ${ownership.group}`);
|
|
550
|
+
}
|
|
551
|
+
git(ownership.root, ["worktree", "add", "-b", branch, path, baseline]);
|
|
552
|
+
return { index, branch, path };
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
/**
|
|
556
|
+
* Seal a candidate's work as one commit on its branch. Returns false when the
|
|
557
|
+
* builder changed nothing (an empty candidate is a legitimate ranking fact).
|
|
558
|
+
*/
|
|
559
|
+
export function commitCandidateWork(worktree: CandidateWorktree, message: string): boolean {
|
|
560
|
+
git(worktree.path, ["add", "-A"]);
|
|
561
|
+
const staged = git(worktree.path, ["status", "--porcelain"]);
|
|
562
|
+
if (staged.length === 0) return false;
|
|
563
|
+
git(worktree.path, [
|
|
564
|
+
"-c",
|
|
565
|
+
`user.name=${COMPETE_COMMIT_IDENTITY}`,
|
|
566
|
+
"-c",
|
|
567
|
+
`user.email=${COMPETE_COMMIT_IDENTITY}@local`,
|
|
568
|
+
"commit",
|
|
569
|
+
"-m",
|
|
570
|
+
message,
|
|
571
|
+
"--no-verify",
|
|
572
|
+
]);
|
|
573
|
+
return true;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
/** One-line stat summary of what a candidate branch changed relative to HEAD. */
|
|
577
|
+
export function candidateDiffStat(root: string, branch: string): string {
|
|
578
|
+
try {
|
|
579
|
+
return git(root, ["diff", "--shortstat", `HEAD...${branch}`]) || "no changes";
|
|
580
|
+
} catch {
|
|
581
|
+
return "diff unavailable";
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
/**
|
|
586
|
+
* Return protected parent-checkout paths changed by a candidate branch. The
|
|
587
|
+
* diff disables rename detection so both sides of a rename are considered;
|
|
588
|
+
* path ownership is decided by canonical path segments, never text prefixes.
|
|
589
|
+
*/
|
|
590
|
+
export function protectedPathsChangedByCompeteBranch(
|
|
591
|
+
root: string,
|
|
592
|
+
branch: string,
|
|
593
|
+
protectedPaths: ReadonlyArray<string>,
|
|
594
|
+
): string[] {
|
|
595
|
+
const canonical = canonicalRoot(root);
|
|
596
|
+
const protectedInside = protectedPaths
|
|
597
|
+
.map((path) => resolve(path))
|
|
598
|
+
.filter((path) => {
|
|
599
|
+
const rel = relative(canonical, path);
|
|
600
|
+
return rel.length > 0 && rel !== ".." && !rel.startsWith(`..${sep}`) && !isAbsolute(rel);
|
|
601
|
+
});
|
|
602
|
+
if (protectedInside.length === 0) return [];
|
|
603
|
+
const changed = git(canonical, ["diff", "--name-only", "-z", "--no-renames", `HEAD...${branch}`])
|
|
604
|
+
.split("\0")
|
|
605
|
+
.filter((path) => path.length > 0)
|
|
606
|
+
.map((path) => resolve(canonical, path));
|
|
607
|
+
const blocked = new Set<string>();
|
|
608
|
+
for (const candidate of changed) {
|
|
609
|
+
for (const protectedPath of protectedInside) {
|
|
610
|
+
const rel = relative(protectedPath, candidate);
|
|
611
|
+
if (
|
|
612
|
+
candidate === protectedPath ||
|
|
613
|
+
(rel.length > 0 && rel !== ".." && !rel.startsWith(`..${sep}`) && !isAbsolute(rel))
|
|
614
|
+
) {
|
|
615
|
+
blocked.add(protectedPath);
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
return [...blocked].sort();
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
function registeredWorktreePaths(root: string): string[] {
|
|
623
|
+
const listing = git(root, ["worktree", "list", "--porcelain", "-z"]);
|
|
624
|
+
return listing
|
|
625
|
+
.split("\0")
|
|
626
|
+
.filter((entry) => entry.startsWith("worktree "))
|
|
627
|
+
.map((entry) => entry.slice("worktree ".length))
|
|
628
|
+
.filter((path): path is string => path !== undefined && path.length > 0);
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
function exactGroupBranches(root: string, group: string): string[] {
|
|
632
|
+
return git(root, ["branch", "--list", "--format=%(refname:short)"])
|
|
633
|
+
.split("\n")
|
|
634
|
+
.filter((branch) => {
|
|
635
|
+
const parts = branch.split("/");
|
|
636
|
+
return (
|
|
637
|
+
parts.length === 4 &&
|
|
638
|
+
parts[0] === "clio" &&
|
|
639
|
+
parts[1] === "compete" &&
|
|
640
|
+
parts[2] === group &&
|
|
641
|
+
/^\d+$/.test(parts[3] ?? "")
|
|
642
|
+
);
|
|
643
|
+
});
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
function removeRegisteredWorktree(root: string, path: string): void {
|
|
647
|
+
try {
|
|
648
|
+
git(root, ["worktree", "remove", "--force", path]);
|
|
649
|
+
} catch {
|
|
650
|
+
if (existsSync(path)) rmSync(path, { recursive: true, force: true });
|
|
651
|
+
git(root, ["worktree", "prune"]);
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
export function removeCandidateWorktree(
|
|
656
|
+
ownership: CompeteGroupOwnership,
|
|
657
|
+
worktree: CandidateWorktree,
|
|
658
|
+
deleteBranch: boolean,
|
|
659
|
+
): void {
|
|
660
|
+
assertOwnership(ownership);
|
|
661
|
+
const expectedPath = join(ownership.directory, `candidate-${worktree.index}`);
|
|
662
|
+
const expectedBranch = competeBranch(ownership.group, worktree.index);
|
|
663
|
+
if (
|
|
664
|
+
resolve(worktree.path) !== resolve(expectedPath) ||
|
|
665
|
+
worktree.branch !== expectedBranch ||
|
|
666
|
+
!isCanonicalPathInside(ownership.directory, worktree.path)
|
|
667
|
+
) {
|
|
668
|
+
throw new Error(`candidate ${worktree.index} does not belong to compete group ${ownership.group}`);
|
|
669
|
+
}
|
|
670
|
+
removeRegisteredWorktree(ownership.root, worktree.path);
|
|
671
|
+
if (deleteBranch && exactGroupBranches(ownership.root, ownership.group).includes(worktree.branch)) {
|
|
672
|
+
git(ownership.root, ["branch", "-D", worktree.branch]);
|
|
673
|
+
}
|
|
674
|
+
const stillRegistered = registeredWorktreePaths(ownership.root).some(
|
|
675
|
+
(path) => resolve(path) === resolve(worktree.path),
|
|
676
|
+
);
|
|
677
|
+
const branchRemains = deleteBranch && exactGroupBranches(ownership.root, ownership.group).includes(worktree.branch);
|
|
678
|
+
if (stillRegistered || existsSync(worktree.path) || branchRemains) {
|
|
679
|
+
throw new Error(`failed to remove candidate ${worktree.index} from compete group ${ownership.group}`);
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
/**
|
|
684
|
+
* Merge the winning candidate branch into the current branch. Fast-forward
|
|
685
|
+
* is impossible by construction (the candidate branched from HEAD and HEAD
|
|
686
|
+
* may have moved), so a regular merge commit is created; a conflict aborts
|
|
687
|
+
* the merge and reports failure so the operator decides.
|
|
688
|
+
*/
|
|
689
|
+
export function mergeWinnerBranch(root: string, branch: string): { ok: true } | { ok: false; reason: string } {
|
|
690
|
+
try {
|
|
691
|
+
git(root, [
|
|
692
|
+
"-c",
|
|
693
|
+
`user.name=${COMPETE_COMMIT_IDENTITY}`,
|
|
694
|
+
"-c",
|
|
695
|
+
`user.email=${COMPETE_COMMIT_IDENTITY}@local`,
|
|
696
|
+
"merge",
|
|
697
|
+
"--no-edit",
|
|
698
|
+
"--no-verify",
|
|
699
|
+
branch,
|
|
700
|
+
]);
|
|
701
|
+
return { ok: true };
|
|
702
|
+
} catch (err) {
|
|
703
|
+
try {
|
|
704
|
+
git(root, ["merge", "--abort"]);
|
|
705
|
+
} catch {
|
|
706
|
+
// No merge in progress; nothing to abort.
|
|
707
|
+
}
|
|
708
|
+
return { ok: false, reason: err instanceof Error ? (err.message.split("\n")[0] ?? "merge failed") : String(err) };
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
/**
|
|
713
|
+
* Remove exactly one proven compete group. Registered worktrees are selected
|
|
714
|
+
* by canonical segment containment and branches by parsed path segments;
|
|
715
|
+
* neither operation uses a textual prefix or wildcard containing the group.
|
|
716
|
+
* The owner manifest is removed last so an interrupted cleanup remains
|
|
717
|
+
* recoverable.
|
|
718
|
+
*/
|
|
719
|
+
function cleanupWorktreeGroup(ownership: CompeteGroupOwnership): void {
|
|
720
|
+
assertOwnership(ownership);
|
|
721
|
+
for (const path of registeredWorktreePaths(ownership.root)) {
|
|
722
|
+
if (!isCanonicalPathInside(ownership.directory, path)) continue;
|
|
723
|
+
removeRegisteredWorktree(ownership.root, path);
|
|
724
|
+
}
|
|
725
|
+
git(ownership.root, ["worktree", "prune"]);
|
|
726
|
+
|
|
727
|
+
const registeredRemain = registeredWorktreePaths(ownership.root).filter((path) =>
|
|
728
|
+
isCanonicalPathInside(ownership.directory, path),
|
|
729
|
+
);
|
|
730
|
+
if (registeredRemain.length > 0) {
|
|
731
|
+
throw new Error(
|
|
732
|
+
`failed to remove ${registeredRemain.length} registered worktree(s) for compete group ${ownership.group}`,
|
|
733
|
+
);
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
for (const branch of exactGroupBranches(ownership.root, ownership.group)) {
|
|
737
|
+
git(ownership.root, ["branch", "-D", branch]);
|
|
738
|
+
}
|
|
739
|
+
const branchesRemain = exactGroupBranches(ownership.root, ownership.group);
|
|
740
|
+
if (branchesRemain.length > 0) {
|
|
741
|
+
throw new Error(`failed to remove ${branchesRemain.length} branch(es) for compete group ${ownership.group}`);
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
// Re-verify the manifest immediately before deleting the exact directory.
|
|
745
|
+
// Remove every other owned entry first, then unlink the manifest last. A
|
|
746
|
+
// crash during recursive content removal therefore leaves recovery proof.
|
|
747
|
+
assertOwnership(ownership);
|
|
748
|
+
for (const entry of readdirSync(ownership.directory)) {
|
|
749
|
+
if (entry === COMPETE_MANIFEST_FILE) continue;
|
|
750
|
+
rmSync(join(ownership.directory, entry), { recursive: true, force: true });
|
|
751
|
+
}
|
|
752
|
+
assertOwnership(ownership);
|
|
753
|
+
const unexpected = readdirSync(ownership.directory).filter((entry) => entry !== COMPETE_MANIFEST_FILE);
|
|
754
|
+
if (unexpected.length > 0) {
|
|
755
|
+
throw new Error(`compete group ${ownership.group} changed during cleanup; ownership is preserved`);
|
|
756
|
+
}
|
|
757
|
+
unlinkSync(manifestPath(ownership.directory));
|
|
758
|
+
rmdirSync(ownership.directory);
|
|
759
|
+
// Never recursively delete the shared parent: another process may claim a
|
|
760
|
+
// new group between an emptiness check and removal.
|
|
761
|
+
try {
|
|
762
|
+
rmdirSync(competeParent(ownership.root));
|
|
763
|
+
} catch {
|
|
764
|
+
// Non-empty (another group) or already absent.
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
export function cleanupCompeteGroup(ownership: CompeteGroupOwnership): void {
|
|
769
|
+
cleanupWorktreeGroup(ownership);
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
/**
|
|
773
|
+
* Finish an abandoned compete transaction after its pending judge output has
|
|
774
|
+
* been authenticated and parsed. A recovered winner is preserved for an
|
|
775
|
+
* operator rather than auto-merged: restart recovery restores evidence and a
|
|
776
|
+
* safe decision point, but never invents authority for a Git mutation.
|
|
777
|
+
*/
|
|
778
|
+
export function settleRecoveredCompeteDecision(
|
|
779
|
+
root: string,
|
|
780
|
+
group: string,
|
|
781
|
+
winnerIndex: number | null,
|
|
782
|
+
): CompeteGroupOwnership | null {
|
|
783
|
+
let ownership = loadCompeteGroup(root, group);
|
|
784
|
+
if (ownership === null) return null;
|
|
785
|
+
if (ownership.state === "cleanup-ready") {
|
|
786
|
+
cleanupWorktreeGroup(ownership);
|
|
787
|
+
return null;
|
|
788
|
+
}
|
|
789
|
+
if (ownership.state === "winner-preserved") {
|
|
790
|
+
if (winnerIndex !== null && ownership.winnerIndex === winnerIndex) return ownership;
|
|
791
|
+
throw new Error(`compete group ${group} was already preserved with a different winner`);
|
|
792
|
+
}
|
|
793
|
+
const manifest = assertOwnership(ownership);
|
|
794
|
+
if (ownerIsAlive(manifest.owner)) {
|
|
795
|
+
throw new Error(`compete group ${group} still has a live coordinator; refusing restart settlement`);
|
|
796
|
+
}
|
|
797
|
+
const unterminated = manifest.runs.filter((run) => !terminateRunLease(run));
|
|
798
|
+
if (unterminated.length > 0) {
|
|
799
|
+
throw new Error(`could not safely terminate ${unterminated.length} leased compete worker(s) for ${group}`);
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
if (winnerIndex === null) {
|
|
803
|
+
ownership = markCompeteGroupCleanupReady(ownership);
|
|
804
|
+
cleanupWorktreeGroup(ownership);
|
|
805
|
+
return null;
|
|
806
|
+
}
|
|
807
|
+
const winnerBranch = competeBranch(group, winnerIndex);
|
|
808
|
+
const branches = exactGroupBranches(ownership.root, group);
|
|
809
|
+
const winnerPath = join(ownership.directory, `candidate-${winnerIndex}`);
|
|
810
|
+
if (
|
|
811
|
+
!branches.includes(winnerBranch) ||
|
|
812
|
+
!registeredWorktreePaths(ownership.root).some((path) => resolve(path) === resolve(winnerPath))
|
|
813
|
+
) {
|
|
814
|
+
throw new Error(`recovered winner ${winnerBranch} has no intact candidate worktree`);
|
|
815
|
+
}
|
|
816
|
+
ownership = markCompeteGroupWinnerPreserved(ownership, winnerIndex);
|
|
817
|
+
for (const branch of branches) {
|
|
818
|
+
const index = Number.parseInt(branch.split("/").at(-1) ?? "", 10);
|
|
819
|
+
if (index === winnerIndex) continue;
|
|
820
|
+
removeCandidateWorktree(ownership, { index, branch, path: join(ownership.directory, `candidate-${index}`) }, true);
|
|
821
|
+
}
|
|
822
|
+
return ownership;
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
/**
|
|
826
|
+
* Recover restart leftovers without guessing ownership.
|
|
827
|
+
*
|
|
828
|
+
* - cleanup-ready groups are already proven quiescent and are swept;
|
|
829
|
+
* - active groups whose coordinator lease is dead first terminate every
|
|
830
|
+
* exact, PID-reuse-checked worker lease, then transition and sweep;
|
|
831
|
+
* - live/remote owners, preserved winners, and malformed entries remain
|
|
832
|
+
* untouched.
|
|
833
|
+
*
|
|
834
|
+
* This function is safe at orchestrator startup and before every compete
|
|
835
|
+
* operation. A failed termination keeps the ownership proof and worktrees.
|
|
836
|
+
*/
|
|
837
|
+
export function recoverCleanupReadyCompeteGroups(
|
|
838
|
+
root: string,
|
|
839
|
+
options: CompeteRecoveryOptions = {},
|
|
840
|
+
): CompeteRecoveryResult {
|
|
841
|
+
const canonical = canonicalRoot(root);
|
|
842
|
+
const parent = competeParent(canonical);
|
|
843
|
+
const result: CompeteRecoveryResult = { cleaned: [], preserved: [], failed: [] };
|
|
844
|
+
if (!isPlainDirectory(parent)) return result;
|
|
845
|
+
for (const entry of readdirSync(parent, { withFileTypes: true })) {
|
|
846
|
+
if (!entry.isDirectory() || entry.isSymbolicLink()) {
|
|
847
|
+
result.preserved.push(entry.name);
|
|
848
|
+
continue;
|
|
849
|
+
}
|
|
850
|
+
let ownership: CompeteGroupOwnership | null = null;
|
|
851
|
+
let manifest: CompeteGroupManifest | null = null;
|
|
852
|
+
try {
|
|
853
|
+
manifest = readManifest(canonical, entry.name);
|
|
854
|
+
ownership = manifest === null ? null : ownershipFromManifest(manifest);
|
|
855
|
+
} catch {
|
|
856
|
+
// Invalid directory names and malformed claims are unproven.
|
|
857
|
+
}
|
|
858
|
+
if (ownership === null || manifest === null) {
|
|
859
|
+
result.preserved.push(entry.name);
|
|
860
|
+
continue;
|
|
861
|
+
}
|
|
862
|
+
if (ownership.state === "winner-preserved") {
|
|
863
|
+
result.preserved.push(entry.name);
|
|
864
|
+
continue;
|
|
865
|
+
}
|
|
866
|
+
if (ownership.state === "active") {
|
|
867
|
+
if (ownerIsAlive(manifest.owner)) {
|
|
868
|
+
result.preserved.push(entry.name);
|
|
869
|
+
continue;
|
|
870
|
+
}
|
|
871
|
+
const unterminated = manifest.runs.filter((run) => !terminateRunLease(run));
|
|
872
|
+
if (unterminated.length > 0) {
|
|
873
|
+
result.failed.push({
|
|
874
|
+
group: entry.name,
|
|
875
|
+
message: `could not safely terminate ${unterminated.length} leased compete worker(s)`,
|
|
876
|
+
});
|
|
877
|
+
continue;
|
|
878
|
+
}
|
|
879
|
+
if (options.preserveAllActive === true || options.preserveActiveGroups?.has(entry.name) === true) {
|
|
880
|
+
result.preserved.push(entry.name);
|
|
881
|
+
continue;
|
|
882
|
+
}
|
|
883
|
+
try {
|
|
884
|
+
ownership = markCompeteGroupCleanupReady(ownership);
|
|
885
|
+
} catch (err) {
|
|
886
|
+
result.failed.push({ group: entry.name, message: errorMessage(err) });
|
|
887
|
+
continue;
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
try {
|
|
891
|
+
cleanupWorktreeGroup(ownership);
|
|
892
|
+
result.cleaned.push(entry.name);
|
|
893
|
+
} catch (err) {
|
|
894
|
+
result.failed.push({ group: entry.name, message: errorMessage(err) });
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
return result;
|
|
898
|
+
}
|