@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,985 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { type Dirent, existsSync, readdirSync, readFileSync, realpathSync } from "node:fs";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import type { PendingSkillRequest } from "../../../core/skill-activation.js";
|
|
6
|
+
import { type ToolName, ToolNames } from "../../../core/tool-names.js";
|
|
7
|
+
import { clioConfigDir } from "../../../core/xdg.js";
|
|
8
|
+
import { enabledExtensionResourceRoots } from "../../extensions/index.js";
|
|
9
|
+
import { INTEROP_AGENT_KINDS, interopSourceRank } from "../../interop/registry.js";
|
|
10
|
+
import type { ResourceDiagnostic, ResourceScope, ResourceSourceInfo } from "../collision.js";
|
|
11
|
+
import { readRootEntries, splitYamlFrontmatter, stringField } from "../common-loader.js";
|
|
12
|
+
import { normalizedSkillHash } from "./content-hash.js";
|
|
13
|
+
import { getMarketplaceSkills } from "./marketplace.js";
|
|
14
|
+
|
|
15
|
+
const MAX_NAME_LENGTH = 64;
|
|
16
|
+
const MAX_DESCRIPTION_LENGTH = 1024;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Hard ceiling on a SKILL.md. Above this the file is a payload rather than a
|
|
20
|
+
* document: `loadSkills` runs on every `context(scope="skills")` call and reads
|
|
21
|
+
* and hashes each file whole, so an oversized one is a cost paid per tool call
|
|
22
|
+
* for content no model will ever be shown.
|
|
23
|
+
*/
|
|
24
|
+
const MAX_SKILL_BYTES = 1024 * 1024;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Bytes of skill body the activation path can actually deliver. Mirrors
|
|
28
|
+
* `OBSERVE_SELF_CAPS.contextSkills`, which lives in the tool substrate and must
|
|
29
|
+
* not be imported from a domain; `contracts/skills` asserts the two agree so
|
|
30
|
+
* the mirror cannot drift. A skill over this still loads, because truncation is
|
|
31
|
+
* the activation path's job, but validation says so: an author whose workflow
|
|
32
|
+
* is silently cut in half at runtime has no other way to find out.
|
|
33
|
+
*/
|
|
34
|
+
export const SKILL_ACTIVATION_BODY_CAP_BYTES = 50 * 1024;
|
|
35
|
+
|
|
36
|
+
/** Frontmatter keys with first-class meaning; everything else lands in metadata. */
|
|
37
|
+
const CORE_FRONTMATTER_KEYS = new Set([
|
|
38
|
+
"name",
|
|
39
|
+
"description",
|
|
40
|
+
"disable-model-invocation",
|
|
41
|
+
"allowed-tools",
|
|
42
|
+
"disallowed-tools",
|
|
43
|
+
]);
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Semantic origin of a skill root. Distinct from {@link ResourceScope}, which
|
|
47
|
+
* only encodes collision precedence tiers shared across resource kinds.
|
|
48
|
+
*/
|
|
49
|
+
export type SkillSource =
|
|
50
|
+
| "clio"
|
|
51
|
+
| "agents"
|
|
52
|
+
| "claude"
|
|
53
|
+
| "codex"
|
|
54
|
+
| "copilot"
|
|
55
|
+
| "opencode"
|
|
56
|
+
| "extension"
|
|
57
|
+
| "path"
|
|
58
|
+
| "cli";
|
|
59
|
+
|
|
60
|
+
/** Optional install provenance, captured from frontmatter when present. */
|
|
61
|
+
export interface SkillProvenance {
|
|
62
|
+
installUrl?: string;
|
|
63
|
+
registryId?: string;
|
|
64
|
+
registryUrl?: string;
|
|
65
|
+
installedAt?: string;
|
|
66
|
+
updatedAt?: string;
|
|
67
|
+
/** Content hash of the upstream SKILL.md at install time, provenance-stripped. */
|
|
68
|
+
installedHash?: string;
|
|
69
|
+
audit?: "pass" | "warn" | "fail" | "unknown";
|
|
70
|
+
/** Who ran the install: a dispatched worker, or (unmarked) the operator. */
|
|
71
|
+
installedBy?: "worker";
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface Skill {
|
|
75
|
+
name: string;
|
|
76
|
+
description: string;
|
|
77
|
+
filePath: string;
|
|
78
|
+
baseDir: string;
|
|
79
|
+
content: string;
|
|
80
|
+
sourceInfo: ResourceSourceInfo;
|
|
81
|
+
disableModelInvocation: boolean;
|
|
82
|
+
/** Semantic source root (clio, agents, codex, extension, ...). */
|
|
83
|
+
source: SkillSource;
|
|
84
|
+
/** Mirror of sourceInfo.scope for convenient access. */
|
|
85
|
+
scope: ResourceScope;
|
|
86
|
+
/** sha256 of the raw SKILL.md file content. */
|
|
87
|
+
hash: string;
|
|
88
|
+
/**
|
|
89
|
+
* sha256 of the SKILL.md with install-lifecycle provenance frontmatter
|
|
90
|
+
* stripped. This is the hash pinned in a catalog registry.yaml, so an
|
|
91
|
+
* installed copy compares equal to its audited source regardless of
|
|
92
|
+
* install timestamps.
|
|
93
|
+
*/
|
|
94
|
+
normalizedHash: string;
|
|
95
|
+
/** Directory or file subject the skill was discovered under. */
|
|
96
|
+
pathSubject: string;
|
|
97
|
+
/** Whether the skill is model-visible by default (compat project roots are not). */
|
|
98
|
+
trusted: boolean;
|
|
99
|
+
/** Collision precedence; higher wins. */
|
|
100
|
+
precedence: number;
|
|
101
|
+
/**
|
|
102
|
+
* Tools the skill workflow declares it needs (`allowed-tools` frontmatter).
|
|
103
|
+
* The harness intersects this with host policy after activation; a skill can
|
|
104
|
+
* narrow its surface but never grant tools the host would not allow.
|
|
105
|
+
*/
|
|
106
|
+
allowedTools?: ReadonlyArray<string>;
|
|
107
|
+
/** Tools the skill workflow declares it must not use (`disallowed-tools`). */
|
|
108
|
+
disallowedTools?: ReadonlyArray<string>;
|
|
109
|
+
/** Optional frontmatter fields beyond name/description/disable-model-invocation. */
|
|
110
|
+
metadata: Record<string, unknown>;
|
|
111
|
+
/** Per-skill diagnostics (also aggregated into the list). */
|
|
112
|
+
diagnostics: ResourceDiagnostic[];
|
|
113
|
+
/** Install provenance when the frontmatter records it. */
|
|
114
|
+
provenance?: SkillProvenance;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export interface SkillRoot {
|
|
118
|
+
path: string;
|
|
119
|
+
scope: ResourceScope;
|
|
120
|
+
source?: SkillSource;
|
|
121
|
+
/** sourceInfo.source string, e.g. "config", "agents-user", "extension:user:id". */
|
|
122
|
+
origin?: string;
|
|
123
|
+
/** Collision precedence override; defaults are derived from scope. */
|
|
124
|
+
precedence?: number;
|
|
125
|
+
/** Whether discovered skills are model-visible by default. */
|
|
126
|
+
trusted?: boolean;
|
|
127
|
+
/**
|
|
128
|
+
* Directory every discovered skill must resolve inside. A skill root says
|
|
129
|
+
* what a repository or an operator's machine offers, so a symlink out of it
|
|
130
|
+
* would let a cloned repository offer content it does not contain, under
|
|
131
|
+
* paths that still read as repository-local. `.clio-coder/skills` is trusted
|
|
132
|
+
* unconditionally, so the escape needs no opt-in to reach the model.
|
|
133
|
+
*
|
|
134
|
+
* The anchor is the workspace for a project root and the home directory for
|
|
135
|
+
* a user root, matching `assertWriteBoundaryInsideRoot`: a monorepo may
|
|
136
|
+
* share one skills tree across checkouts, but nothing may reach outside the
|
|
137
|
+
* tree the operator is working in.
|
|
138
|
+
*
|
|
139
|
+
* Undefined disables the check. An extension root is laid out by a package
|
|
140
|
+
* manager that symlinks by design, and an explicit skill path names its own
|
|
141
|
+
* target, so neither has a containing scope to be measured against.
|
|
142
|
+
*/
|
|
143
|
+
containment?: string;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export interface SkillList {
|
|
147
|
+
items: Skill[];
|
|
148
|
+
diagnostics: ResourceDiagnostic[];
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export interface SkillExpansionOptions {
|
|
152
|
+
/** Working directory used for marketplace catalog discovery. */
|
|
153
|
+
cwd?: string;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export interface LoadSkillsInput {
|
|
157
|
+
cwd?: string;
|
|
158
|
+
roots?: ReadonlyArray<SkillRoot>;
|
|
159
|
+
/** Override the user home dir used for shared compatibility roots (testing). */
|
|
160
|
+
home?: string;
|
|
161
|
+
/** Override the Clio config dir used for the user skill root (testing). */
|
|
162
|
+
configDir?: string;
|
|
163
|
+
/** Opt in to model-visible project compatibility roots (.agents/.codex). */
|
|
164
|
+
trustProjectCompatRoots?: boolean;
|
|
165
|
+
/** Disable normal root discovery. Explicit skill paths still load. */
|
|
166
|
+
disableDiscovery?: boolean;
|
|
167
|
+
/** One-shot skill files or directories loaded at CLI precedence. */
|
|
168
|
+
explicitSkillPaths?: ReadonlyArray<string>;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export type SkillExpansion =
|
|
172
|
+
| {
|
|
173
|
+
expanded: false;
|
|
174
|
+
text: string;
|
|
175
|
+
args: string;
|
|
176
|
+
diagnostics: ResourceDiagnostic[];
|
|
177
|
+
}
|
|
178
|
+
| {
|
|
179
|
+
expanded: true;
|
|
180
|
+
text: string;
|
|
181
|
+
args: string;
|
|
182
|
+
skill: Skill;
|
|
183
|
+
triggeredBy: "slash-command";
|
|
184
|
+
diagnostics: ResourceDiagnostic[];
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
/** Collision precedence tiers; higher wins. */
|
|
188
|
+
const SKILL_PRECEDENCE = {
|
|
189
|
+
extension: 10,
|
|
190
|
+
userCompat: 20,
|
|
191
|
+
user: 30,
|
|
192
|
+
projectCompat: 40,
|
|
193
|
+
project: 50,
|
|
194
|
+
cli: 60,
|
|
195
|
+
} as const;
|
|
196
|
+
|
|
197
|
+
function sha256(value: string): string {
|
|
198
|
+
return createHash("sha256").update(value, "utf8").digest("hex");
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function defaultPrecedenceForScope(scope: ResourceScope): number {
|
|
202
|
+
switch (scope) {
|
|
203
|
+
case "package":
|
|
204
|
+
return SKILL_PRECEDENCE.extension;
|
|
205
|
+
case "user":
|
|
206
|
+
return SKILL_PRECEDENCE.user;
|
|
207
|
+
case "project":
|
|
208
|
+
return SKILL_PRECEDENCE.project;
|
|
209
|
+
case "cli":
|
|
210
|
+
return SKILL_PRECEDENCE.cli;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Whether project-scope compatibility roots are model-visible. Prompts share
|
|
216
|
+
* this gate with skills: both substitute another agent's project file into
|
|
217
|
+
* Clio's context, so one opt-in covers both.
|
|
218
|
+
*/
|
|
219
|
+
export function projectCompatTrusted(explicit?: boolean): boolean {
|
|
220
|
+
if (explicit === true) return true;
|
|
221
|
+
return process.env.CLIO_CODER_TRUST_PROJECT_SKILLS === "1";
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Discovery roots, lowest to highest precedence:
|
|
226
|
+
* 1. package/extension skills
|
|
227
|
+
* 2. shared user compat roots, one per interop agent kind that owns a skills directory
|
|
228
|
+
* 3. Clio user root (<config>/skills)
|
|
229
|
+
* 4. the same agents' project roots, trusted only on opt-in
|
|
230
|
+
* 5. Clio project root (.clio-coder/skills)
|
|
231
|
+
*
|
|
232
|
+
* The compatibility roots come from the interop registry rather than a list
|
|
233
|
+
* kept here, so adding an agent to the table is what teaches every reader about
|
|
234
|
+
* it at once.
|
|
235
|
+
*/
|
|
236
|
+
export function defaultSkillRoots(input: LoadSkillsInput = {}): SkillRoot[] {
|
|
237
|
+
const cwd = input.cwd ?? process.cwd();
|
|
238
|
+
const home = input.home ?? homedir();
|
|
239
|
+
const configDir = input.configDir ?? clioConfigDirSafe();
|
|
240
|
+
const trustProject = projectCompatTrusted(input.trustProjectCompatRoots);
|
|
241
|
+
const roots: SkillRoot[] = [];
|
|
242
|
+
|
|
243
|
+
for (const root of enabledExtensionResourceRoots("skills", cwd)) {
|
|
244
|
+
roots.push({
|
|
245
|
+
path: root.path,
|
|
246
|
+
scope: "package",
|
|
247
|
+
source: "extension",
|
|
248
|
+
origin: root.source,
|
|
249
|
+
precedence: SKILL_PRECEDENCE.extension,
|
|
250
|
+
trusted: true,
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
for (const kind of INTEROP_AGENT_KINDS) {
|
|
255
|
+
if (kind.userSkillRoot === undefined || kind.skillSource === undefined) continue;
|
|
256
|
+
roots.push({
|
|
257
|
+
path: path.join(home, kind.userSkillRoot),
|
|
258
|
+
scope: "user",
|
|
259
|
+
source: kind.skillSource,
|
|
260
|
+
origin: `${kind.skillSource}-user`,
|
|
261
|
+
precedence: SKILL_PRECEDENCE.userCompat,
|
|
262
|
+
trusted: true,
|
|
263
|
+
containment: home,
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
if (configDir) {
|
|
268
|
+
roots.push({
|
|
269
|
+
path: path.join(configDir, "skills"),
|
|
270
|
+
scope: "user",
|
|
271
|
+
source: "clio",
|
|
272
|
+
origin: "config",
|
|
273
|
+
precedence: SKILL_PRECEDENCE.user,
|
|
274
|
+
trusted: true,
|
|
275
|
+
containment: home,
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
for (const kind of INTEROP_AGENT_KINDS) {
|
|
280
|
+
if (kind.projectSkillRoot === undefined || kind.skillSource === undefined) continue;
|
|
281
|
+
roots.push({
|
|
282
|
+
path: path.join(cwd, kind.projectSkillRoot),
|
|
283
|
+
scope: "project",
|
|
284
|
+
source: kind.skillSource,
|
|
285
|
+
origin: `${kind.skillSource}-project`,
|
|
286
|
+
precedence: SKILL_PRECEDENCE.projectCompat,
|
|
287
|
+
trusted: trustProject,
|
|
288
|
+
containment: cwd,
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
roots.push({
|
|
293
|
+
path: path.join(cwd, ".clio-coder", "skills"),
|
|
294
|
+
scope: "project",
|
|
295
|
+
source: "clio",
|
|
296
|
+
origin: "project",
|
|
297
|
+
precedence: SKILL_PRECEDENCE.project,
|
|
298
|
+
trusted: true,
|
|
299
|
+
containment: cwd,
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
return roots;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/** Resolve the Clio config dir without throwing if XDG dirs cannot be created. */
|
|
306
|
+
function clioConfigDirSafe(): string | null {
|
|
307
|
+
try {
|
|
308
|
+
return clioConfigDir();
|
|
309
|
+
} catch {
|
|
310
|
+
return null;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
function splitSkillFrontmatter(raw: string): { frontmatter: Record<string, unknown>; body: string } {
|
|
315
|
+
const split = splitYamlFrontmatter(raw);
|
|
316
|
+
if (!split.ok && split.reason === "missing") {
|
|
317
|
+
throw new Error("skill file is missing YAML frontmatter");
|
|
318
|
+
}
|
|
319
|
+
if (!split.ok && split.reason === "missing closing delimiter") {
|
|
320
|
+
throw new Error("skill file is missing a closing YAML frontmatter delimiter");
|
|
321
|
+
}
|
|
322
|
+
if (!split.ok && split.reason === "must be a YAML object") {
|
|
323
|
+
throw new Error("skill frontmatter must be a YAML object");
|
|
324
|
+
}
|
|
325
|
+
if (!split.ok) throw new Error(`skill frontmatter is ${split.reason}`);
|
|
326
|
+
return split;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
function booleanField(frontmatter: Record<string, unknown>, key: string): boolean {
|
|
330
|
+
return frontmatter[key] === true;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Parse a frontmatter tool list. Two spellings are the same declaration and
|
|
335
|
+
* both appear in the roots Clio discovers: a YAML sequence, which every skill
|
|
336
|
+
* Clio ships uses, and one comma-separated scalar, which is what the
|
|
337
|
+
* compatibility roots under `.claude` and `.agents` carry. Reading only the
|
|
338
|
+
* sequence dropped the scalar form silently, so a skill that asked to be
|
|
339
|
+
* confined to four tools ran with the whole surface and no word about it.
|
|
340
|
+
*/
|
|
341
|
+
function rawToolListField(frontmatter: Record<string, unknown>, key: string): string[] | undefined {
|
|
342
|
+
const raw = frontmatter[key];
|
|
343
|
+
const entries =
|
|
344
|
+
typeof raw === "string"
|
|
345
|
+
? raw.split(",")
|
|
346
|
+
: Array.isArray(raw)
|
|
347
|
+
? raw.filter((entry): entry is string => typeof entry === "string")
|
|
348
|
+
: null;
|
|
349
|
+
if (entries === null) return undefined;
|
|
350
|
+
const tools = entries.map((entry) => entry.trim()).filter((entry) => entry.length > 0);
|
|
351
|
+
return tools.length > 0 ? [...new Set(tools)] : undefined;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
const TOOL_NAMES_BY_LOWERCASE = new Map(Object.values(ToolNames).map((name) => [name.toLowerCase(), name]));
|
|
355
|
+
|
|
356
|
+
interface ResolvedToolList {
|
|
357
|
+
/** Declared names Clio recognizes, which are the ones narrowing can enforce. */
|
|
358
|
+
tools: ToolName[];
|
|
359
|
+
/** Declared names that are no tool Clio has. */
|
|
360
|
+
unrecognized: string[];
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* Resolve declared tool names against the tools Clio actually has. Case is
|
|
365
|
+
* normalized because `Bash` and `bash` are the same tool named by two
|
|
366
|
+
* harnesses; nothing else is mapped, because an alias table would let a
|
|
367
|
+
* declaration mean a tool its author never wrote.
|
|
368
|
+
*/
|
|
369
|
+
function resolveDeclaredTools(declared: ReadonlyArray<string>): ResolvedToolList {
|
|
370
|
+
const tools: ToolName[] = [];
|
|
371
|
+
const unrecognized: string[] = [];
|
|
372
|
+
for (const entry of declared) {
|
|
373
|
+
const resolved = TOOL_NAMES_BY_LOWERCASE.get(entry.toLowerCase());
|
|
374
|
+
if (resolved === undefined) unrecognized.push(entry);
|
|
375
|
+
else if (!tools.includes(resolved)) tools.push(resolved);
|
|
376
|
+
}
|
|
377
|
+
return { tools, unrecognized };
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* The tool surface one frontmatter key declares, reduced to what Clio can
|
|
382
|
+
* enforce and reported where it cannot.
|
|
383
|
+
*
|
|
384
|
+
* `allowed-tools` is workflow scoping, not a security boundary: the host
|
|
385
|
+
* admission in `tools/registry.ts` has already decided what this run may call,
|
|
386
|
+
* and narrowing only ever subtracts from it. So an allow-list naming no tool
|
|
387
|
+
* Clio has is not a declaration to enforce as "nothing is permitted"; it is a
|
|
388
|
+
* declaration written for another harness, and honoring it literally would
|
|
389
|
+
* block every call for a reason the operator never chose. It narrows nothing
|
|
390
|
+
* and says so. A denial is kept whenever it resolves, because a denial that
|
|
391
|
+
* fails open is the one direction that matters.
|
|
392
|
+
*/
|
|
393
|
+
function declaredToolSurface(
|
|
394
|
+
frontmatter: Record<string, unknown>,
|
|
395
|
+
key: string,
|
|
396
|
+
filePath: string,
|
|
397
|
+
diagnostics: ResourceDiagnostic[],
|
|
398
|
+
): ToolName[] | undefined {
|
|
399
|
+
const declared = rawToolListField(frontmatter, key);
|
|
400
|
+
if (declared === undefined) return undefined;
|
|
401
|
+
const { tools, unrecognized } = resolveDeclaredTools(declared);
|
|
402
|
+
if (unrecognized.length > 0) {
|
|
403
|
+
diagnostics.push({
|
|
404
|
+
type: "warning",
|
|
405
|
+
message: `${key} names ${unrecognized.length === 1 ? "a tool" : "tools"} Clio does not have: ${unrecognized.join(", ")}`,
|
|
406
|
+
path: filePath,
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
if (tools.length === 0 && key === "allowed-tools") {
|
|
410
|
+
diagnostics.push({
|
|
411
|
+
type: "warning",
|
|
412
|
+
message:
|
|
413
|
+
"allowed-tools names no tool Clio has, so it narrows nothing; declare Clio tool names to confine this skill",
|
|
414
|
+
path: filePath,
|
|
415
|
+
});
|
|
416
|
+
return undefined;
|
|
417
|
+
}
|
|
418
|
+
return tools.length > 0 ? tools : undefined;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
function validationSubject(filePath: string): string {
|
|
422
|
+
return path.basename(filePath) === "SKILL.md" ? path.basename(path.dirname(filePath)) : path.basename(filePath, ".md");
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
function validateNameFormat(name: string): string[] {
|
|
426
|
+
const errors: string[] = [];
|
|
427
|
+
if (name.length > MAX_NAME_LENGTH) errors.push(`name exceeds ${MAX_NAME_LENGTH} characters (${name.length})`);
|
|
428
|
+
if (!/^[a-z0-9-]+$/.test(name)) {
|
|
429
|
+
errors.push("name contains invalid characters (must be lowercase a-z, 0-9, hyphens only)");
|
|
430
|
+
}
|
|
431
|
+
if (name.startsWith("-") || name.endsWith("-")) errors.push("name must not start or end with a hyphen");
|
|
432
|
+
if (name.includes("--")) errors.push("name must not contain consecutive hyphens");
|
|
433
|
+
return errors;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
function validateDescription(description: string | null): string[] {
|
|
437
|
+
if (!description) return ["description is required"];
|
|
438
|
+
if (description.length > MAX_DESCRIPTION_LENGTH) {
|
|
439
|
+
return [`description exceeds ${MAX_DESCRIPTION_LENGTH} characters (${description.length})`];
|
|
440
|
+
}
|
|
441
|
+
return [];
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
function extractMetadata(frontmatter: Record<string, unknown>): Record<string, unknown> {
|
|
445
|
+
const metadata: Record<string, unknown> = {};
|
|
446
|
+
for (const [key, value] of Object.entries(frontmatter)) {
|
|
447
|
+
if (CORE_FRONTMATTER_KEYS.has(key)) continue;
|
|
448
|
+
metadata[key] = value;
|
|
449
|
+
}
|
|
450
|
+
return metadata;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
function extractProvenance(frontmatter: Record<string, unknown>): SkillProvenance | undefined {
|
|
454
|
+
// Provenance lives nested under the reserved `clio:` block; the flat
|
|
455
|
+
// top-level keys remain readable for already-installed copies stamped
|
|
456
|
+
// before the nested form existed.
|
|
457
|
+
const clioRaw = frontmatter.clio;
|
|
458
|
+
const clio =
|
|
459
|
+
clioRaw !== null && typeof clioRaw === "object" && !Array.isArray(clioRaw)
|
|
460
|
+
? (clioRaw as Record<string, unknown>)
|
|
461
|
+
: undefined;
|
|
462
|
+
const field = (...keys: string[]): string | null => {
|
|
463
|
+
for (const key of keys) {
|
|
464
|
+
if (clio) {
|
|
465
|
+
const nested = stringField(clio, key);
|
|
466
|
+
if (nested !== null) return nested;
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
for (const key of keys) {
|
|
470
|
+
const flat = stringField(frontmatter, key);
|
|
471
|
+
if (flat !== null) return flat;
|
|
472
|
+
}
|
|
473
|
+
return null;
|
|
474
|
+
};
|
|
475
|
+
const installUrl = field("source-url", "sourceUrl", "install-url");
|
|
476
|
+
const registryId = field("registry-id", "registryId");
|
|
477
|
+
const registryUrl = field("registry-url", "registryUrl");
|
|
478
|
+
const installedAt = field("installed-at", "installedAt");
|
|
479
|
+
const updatedAt = field("updated-at", "updatedAt");
|
|
480
|
+
const installedHash = field("installed-hash", "installedHash");
|
|
481
|
+
const auditRaw = field("audit");
|
|
482
|
+
const audit =
|
|
483
|
+
auditRaw === "pass" || auditRaw === "warn" || auditRaw === "fail" || auditRaw === "unknown" ? auditRaw : undefined;
|
|
484
|
+
const installedByRaw = field("installed-by", "installedBy");
|
|
485
|
+
const installedBy = installedByRaw === "worker" ? installedByRaw : undefined;
|
|
486
|
+
if (
|
|
487
|
+
!installUrl &&
|
|
488
|
+
!registryId &&
|
|
489
|
+
!registryUrl &&
|
|
490
|
+
!installedAt &&
|
|
491
|
+
!updatedAt &&
|
|
492
|
+
!installedHash &&
|
|
493
|
+
!audit &&
|
|
494
|
+
!installedBy
|
|
495
|
+
)
|
|
496
|
+
return undefined;
|
|
497
|
+
return {
|
|
498
|
+
...(installUrl ? { installUrl } : {}),
|
|
499
|
+
...(registryId ? { registryId } : {}),
|
|
500
|
+
...(registryUrl ? { registryUrl } : {}),
|
|
501
|
+
...(installedAt ? { installedAt } : {}),
|
|
502
|
+
...(updatedAt ? { updatedAt } : {}),
|
|
503
|
+
...(installedHash ? { installedHash } : {}),
|
|
504
|
+
...(audit ? { audit } : {}),
|
|
505
|
+
...(installedBy ? { installedBy } : {}),
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
interface SkillCandidate {
|
|
510
|
+
skill: Skill;
|
|
511
|
+
canonicalPath: string;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
function canonicalizePath(filePath: string): string {
|
|
515
|
+
try {
|
|
516
|
+
return realpathSync.native(filePath);
|
|
517
|
+
} catch {
|
|
518
|
+
return path.resolve(filePath);
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
function pathIsInside(candidate: string, anchor: string): boolean {
|
|
523
|
+
return candidate === anchor || candidate.startsWith(anchor + path.sep);
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
/**
|
|
527
|
+
* The directory this root's skills must resolve inside, canonicalized once so
|
|
528
|
+
* every later comparison is against real paths on both sides.
|
|
529
|
+
*
|
|
530
|
+
* A root the operator placed outside its own declared scope anchors to itself:
|
|
531
|
+
* an XDG config dir on another volume is where the operator put their skills,
|
|
532
|
+
* not an escape, and anchoring it at home would reject every skill under it.
|
|
533
|
+
*/
|
|
534
|
+
function containmentAnchor(root: SkillRoot): string | null {
|
|
535
|
+
if (root.containment === undefined) return null;
|
|
536
|
+
const anchor = canonicalizePath(root.containment);
|
|
537
|
+
const rootReal = canonicalizePath(root.path);
|
|
538
|
+
return pathIsInside(rootReal, anchor) ? anchor : rootReal;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
/**
|
|
542
|
+
* Refuse a discovered entry whose real path leaves the root's containing
|
|
543
|
+
* scope. Rejection rather than a warning, because the escape is invisible in
|
|
544
|
+
* every path the operator is later shown: `filePath` and `baseDir` both keep
|
|
545
|
+
* the symlink's own location, so a loaded escaped skill reads as ordinary
|
|
546
|
+
* repository content while its body and its resource tree come from somewhere
|
|
547
|
+
* the repository never contained.
|
|
548
|
+
*/
|
|
549
|
+
function escapesContainment(fullPath: string, anchor: string | null, diagnostics: ResourceDiagnostic[]): boolean {
|
|
550
|
+
if (anchor === null) return false;
|
|
551
|
+
const resolved = canonicalizePath(fullPath);
|
|
552
|
+
if (pathIsInside(resolved, anchor)) return false;
|
|
553
|
+
diagnostics.push({
|
|
554
|
+
type: "warning",
|
|
555
|
+
message: `skill path resolves to ${resolved}, outside ${anchor}; a skill root may not leave its scope through a symlink`,
|
|
556
|
+
path: fullPath,
|
|
557
|
+
});
|
|
558
|
+
return true;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
function loadSkillFile(
|
|
562
|
+
filePath: string,
|
|
563
|
+
root: SkillRoot,
|
|
564
|
+
): { candidate: SkillCandidate | null; diagnostics: ResourceDiagnostic[] } {
|
|
565
|
+
const diagnostics: ResourceDiagnostic[] = [];
|
|
566
|
+
let bytes: Buffer;
|
|
567
|
+
try {
|
|
568
|
+
bytes = readFileSync(filePath);
|
|
569
|
+
} catch (err) {
|
|
570
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
571
|
+
return {
|
|
572
|
+
candidate: null,
|
|
573
|
+
diagnostics: [{ type: "warning", message: `skill file could not be read: ${reason}`, path: filePath }],
|
|
574
|
+
};
|
|
575
|
+
}
|
|
576
|
+
if (bytes.byteLength > MAX_SKILL_BYTES) {
|
|
577
|
+
return {
|
|
578
|
+
candidate: null,
|
|
579
|
+
diagnostics: [
|
|
580
|
+
{
|
|
581
|
+
type: "warning",
|
|
582
|
+
message: `skill file is ${bytes.byteLength} bytes, over the ${MAX_SKILL_BYTES}-byte limit for a SKILL.md`,
|
|
583
|
+
path: filePath,
|
|
584
|
+
},
|
|
585
|
+
],
|
|
586
|
+
};
|
|
587
|
+
}
|
|
588
|
+
// A SKILL.md becomes model-visible instructions, so it has to be text. utf8
|
|
589
|
+
// decoding never throws: it substitutes U+FFFD, which would turn a binary
|
|
590
|
+
// file into a document of replacement characters that loads and says
|
|
591
|
+
// nothing. Round-tripping is the check that catches it, and a NUL byte is
|
|
592
|
+
// called out separately because that is what a binary file looks like.
|
|
593
|
+
const raw = bytes.toString("utf8");
|
|
594
|
+
if (bytes.includes(0) || !Buffer.from(raw, "utf8").equals(bytes)) {
|
|
595
|
+
return {
|
|
596
|
+
candidate: null,
|
|
597
|
+
diagnostics: [
|
|
598
|
+
{
|
|
599
|
+
type: "warning",
|
|
600
|
+
message: "skill file is not valid UTF-8 text; a SKILL.md is a document, not a binary payload",
|
|
601
|
+
path: filePath,
|
|
602
|
+
},
|
|
603
|
+
],
|
|
604
|
+
};
|
|
605
|
+
}
|
|
606
|
+
if (bytes.byteLength > SKILL_ACTIVATION_BODY_CAP_BYTES) {
|
|
607
|
+
diagnostics.push({
|
|
608
|
+
type: "warning",
|
|
609
|
+
message: `skill file is ${bytes.byteLength} bytes; activation delivers at most ${SKILL_ACTIVATION_BODY_CAP_BYTES}, so the model will not be shown the rest`,
|
|
610
|
+
path: filePath,
|
|
611
|
+
});
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
let parsed: { frontmatter: Record<string, unknown>; body: string };
|
|
615
|
+
try {
|
|
616
|
+
parsed = splitSkillFrontmatter(raw);
|
|
617
|
+
} catch (err) {
|
|
618
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
619
|
+
return { candidate: null, diagnostics: [{ type: "warning", message: reason, path: filePath }] };
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
const pathSubject = validationSubject(filePath);
|
|
623
|
+
const frontmatterName = stringField(parsed.frontmatter, "name");
|
|
624
|
+
const name = frontmatterName ?? pathSubject;
|
|
625
|
+
const description = stringField(parsed.frontmatter, "description");
|
|
626
|
+
|
|
627
|
+
for (const message of validateDescription(description)) diagnostics.push({ type: "warning", message, path: filePath });
|
|
628
|
+
// Name/path mismatch is informational; cross-harness skill folders often differ.
|
|
629
|
+
if (frontmatterName && frontmatterName !== pathSubject) {
|
|
630
|
+
diagnostics.push({
|
|
631
|
+
type: "warning",
|
|
632
|
+
message: `name "${frontmatterName}" differs from path subject "${pathSubject}"; using frontmatter name`,
|
|
633
|
+
path: filePath,
|
|
634
|
+
});
|
|
635
|
+
}
|
|
636
|
+
for (const message of validateNameFormat(name)) diagnostics.push({ type: "warning", message, path: filePath });
|
|
637
|
+
|
|
638
|
+
// Missing description is the only hard rejection; everything else loads with a warning.
|
|
639
|
+
if (!description) return { candidate: null, diagnostics };
|
|
640
|
+
|
|
641
|
+
const baseDir = path.dirname(filePath);
|
|
642
|
+
const scope = root.scope;
|
|
643
|
+
const sourceInfo: ResourceSourceInfo = {
|
|
644
|
+
path: filePath,
|
|
645
|
+
scope,
|
|
646
|
+
...(root.origin ? { source: root.origin } : {}),
|
|
647
|
+
};
|
|
648
|
+
const provenance = extractProvenance(parsed.frontmatter);
|
|
649
|
+
const allowedTools = declaredToolSurface(parsed.frontmatter, "allowed-tools", filePath, diagnostics);
|
|
650
|
+
const disallowedTools = declaredToolSurface(parsed.frontmatter, "disallowed-tools", filePath, diagnostics);
|
|
651
|
+
const skill: Skill = {
|
|
652
|
+
name,
|
|
653
|
+
description,
|
|
654
|
+
filePath,
|
|
655
|
+
baseDir,
|
|
656
|
+
content: parsed.body.trim(),
|
|
657
|
+
sourceInfo,
|
|
658
|
+
disableModelInvocation: booleanField(parsed.frontmatter, "disable-model-invocation"),
|
|
659
|
+
...(allowedTools ? { allowedTools } : {}),
|
|
660
|
+
...(disallowedTools ? { disallowedTools } : {}),
|
|
661
|
+
source: root.source ?? "clio",
|
|
662
|
+
scope,
|
|
663
|
+
hash: sha256(raw),
|
|
664
|
+
normalizedHash: normalizedSkillHash(raw),
|
|
665
|
+
pathSubject,
|
|
666
|
+
trusted: root.trusted ?? true,
|
|
667
|
+
precedence: root.precedence ?? defaultPrecedenceForScope(scope),
|
|
668
|
+
metadata: extractMetadata(parsed.frontmatter),
|
|
669
|
+
diagnostics,
|
|
670
|
+
...(provenance ? { provenance } : {}),
|
|
671
|
+
};
|
|
672
|
+
return { candidate: { skill, canonicalPath: canonicalizePath(filePath) }, diagnostics };
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
function isSkillMarkdownFile(entryName: string): boolean {
|
|
676
|
+
return entryName === "SKILL.md" || entryName.endsWith(".md");
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
function collectSkills(
|
|
680
|
+
root: SkillRoot,
|
|
681
|
+
dir: string,
|
|
682
|
+
diagnostics: ResourceDiagnostic[],
|
|
683
|
+
includeRootFiles: boolean,
|
|
684
|
+
anchor: string | null = containmentAnchor(root),
|
|
685
|
+
): SkillCandidate[] {
|
|
686
|
+
if (!existsSync(dir)) return [];
|
|
687
|
+
if (escapesContainment(dir, anchor, diagnostics)) return [];
|
|
688
|
+
let entries: Dirent<string>[];
|
|
689
|
+
try {
|
|
690
|
+
entries = readdirSync(dir, { withFileTypes: true });
|
|
691
|
+
} catch (err) {
|
|
692
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
693
|
+
diagnostics.push({ type: "warning", message: `skill root could not be read: ${reason}`, path: dir });
|
|
694
|
+
return [];
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
const skillEntry = entries.find((entry) => entry.name === "SKILL.md" && entry.isFile());
|
|
698
|
+
if (skillEntry) {
|
|
699
|
+
const skillPath = path.join(dir, skillEntry.name);
|
|
700
|
+
if (escapesContainment(skillPath, anchor, diagnostics)) return [];
|
|
701
|
+
const loaded = loadSkillFile(skillPath, root);
|
|
702
|
+
diagnostics.push(...loaded.diagnostics);
|
|
703
|
+
return loaded.candidate ? [loaded.candidate] : [];
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
const candidates: SkillCandidate[] = [];
|
|
707
|
+
for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
708
|
+
if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
|
|
709
|
+
const fullPath = path.join(dir, entry.name);
|
|
710
|
+
if (entry.isDirectory() || (entry.isSymbolicLink() && existsSync(path.join(fullPath, "SKILL.md")))) {
|
|
711
|
+
candidates.push(...collectSkills(root, fullPath, diagnostics, false, anchor));
|
|
712
|
+
continue;
|
|
713
|
+
}
|
|
714
|
+
if (!includeRootFiles || (!entry.isFile() && !entry.isSymbolicLink()) || !isSkillMarkdownFile(entry.name)) continue;
|
|
715
|
+
if (escapesContainment(fullPath, anchor, diagnostics)) continue;
|
|
716
|
+
const loaded = loadSkillFile(fullPath, root);
|
|
717
|
+
diagnostics.push(...loaded.diagnostics);
|
|
718
|
+
if (loaded.candidate) candidates.push(loaded.candidate);
|
|
719
|
+
}
|
|
720
|
+
return candidates;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
function loadSkillRoot(root: SkillRoot, diagnostics: ResourceDiagnostic[]): SkillCandidate[] {
|
|
724
|
+
const entries = readRootEntries(root, "skill", diagnostics);
|
|
725
|
+
if (entries.length === 0) return [];
|
|
726
|
+
return collectSkills(root, root.path, diagnostics, true);
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
function explicitSkillRoot(filePath: string): SkillRoot {
|
|
730
|
+
return {
|
|
731
|
+
path: filePath,
|
|
732
|
+
scope: "cli",
|
|
733
|
+
source: "path",
|
|
734
|
+
origin: "explicit-path",
|
|
735
|
+
precedence: SKILL_PRECEDENCE.cli,
|
|
736
|
+
trusted: true,
|
|
737
|
+
};
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
function loadExplicitSkillPath(inputPath: string, diagnostics: ResourceDiagnostic[]): SkillCandidate[] {
|
|
741
|
+
const resolved = path.resolve(inputPath);
|
|
742
|
+
const root = explicitSkillRoot(resolved);
|
|
743
|
+
if (!existsSync(resolved)) {
|
|
744
|
+
diagnostics.push({ type: "warning", message: `explicit skill path does not exist: ${resolved}`, path: resolved });
|
|
745
|
+
return [];
|
|
746
|
+
}
|
|
747
|
+
const skillFile =
|
|
748
|
+
path.basename(resolved) === "SKILL.md" || resolved.endsWith(".md") ? resolved : path.join(resolved, "SKILL.md");
|
|
749
|
+
if (!existsSync(skillFile)) {
|
|
750
|
+
// A directory without its own SKILL.md may be a catalog of skill
|
|
751
|
+
// packages (for example a repo-level skills/ folder); load every
|
|
752
|
+
// immediate child package so validation and registry tooling can
|
|
753
|
+
// operate on the whole catalog with one path.
|
|
754
|
+
const packages = collectSkills(root, resolved, diagnostics, false);
|
|
755
|
+
if (packages.length > 0) return packages;
|
|
756
|
+
diagnostics.push({
|
|
757
|
+
type: "warning",
|
|
758
|
+
message: `explicit skill path is not a SKILL.md file, skill directory, or catalog of skill packages: ${resolved}`,
|
|
759
|
+
path: resolved,
|
|
760
|
+
});
|
|
761
|
+
return [];
|
|
762
|
+
}
|
|
763
|
+
const loaded = loadSkillFile(skillFile, root);
|
|
764
|
+
diagnostics.push(...loaded.diagnostics);
|
|
765
|
+
return loaded.candidate ? [loaded.candidate] : [];
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
/**
|
|
769
|
+
* Ascending order for a set of candidates competing for one name or one
|
|
770
|
+
* canonical file, so the last entry is the winner. Precedence decides first.
|
|
771
|
+
* Two compatibility roots share a precedence tier, and ranking those by path
|
|
772
|
+
* spelling made the winner depend on what the agents happen to be called, so
|
|
773
|
+
* the second key is the registry's own agent order.
|
|
774
|
+
*/
|
|
775
|
+
function compareSkillCandidates(a: Skill, b: Skill): number {
|
|
776
|
+
const precedence = a.precedence - b.precedence;
|
|
777
|
+
if (precedence !== 0) return precedence;
|
|
778
|
+
const rank = interopSourceRank(b.source) - interopSourceRank(a.source);
|
|
779
|
+
if (rank !== 0) return rank;
|
|
780
|
+
return a.filePath.localeCompare(b.filePath);
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
function dedupeCanonicalSkillPaths(
|
|
784
|
+
candidates: ReadonlyArray<SkillCandidate>,
|
|
785
|
+
diagnostics: ResourceDiagnostic[],
|
|
786
|
+
): SkillCandidate[] {
|
|
787
|
+
const byPath = new Map<string, SkillCandidate[]>();
|
|
788
|
+
for (const candidate of candidates) {
|
|
789
|
+
const list = byPath.get(candidate.canonicalPath) ?? [];
|
|
790
|
+
list.push(candidate);
|
|
791
|
+
byPath.set(candidate.canonicalPath, list);
|
|
792
|
+
}
|
|
793
|
+
const winners: SkillCandidate[] = [];
|
|
794
|
+
for (const entries of byPath.values()) {
|
|
795
|
+
if (entries.length === 1) {
|
|
796
|
+
const only = entries[0];
|
|
797
|
+
if (only) winners.push(only);
|
|
798
|
+
continue;
|
|
799
|
+
}
|
|
800
|
+
const sorted = [...entries].sort((a, b) => compareSkillCandidates(a.skill, b.skill));
|
|
801
|
+
const winner = sorted[sorted.length - 1];
|
|
802
|
+
if (!winner) continue;
|
|
803
|
+
winners.push(winner);
|
|
804
|
+
for (const loser of sorted.slice(0, -1)) {
|
|
805
|
+
diagnostics.push({
|
|
806
|
+
type: "warning",
|
|
807
|
+
message: `${loser.skill.name} at ${loser.skill.filePath} resolves to the same canonical skill file as ${winner.skill.filePath}, which is the entry in use`,
|
|
808
|
+
path: loser.skill.filePath,
|
|
809
|
+
});
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
return winners;
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
/** Resolve name collisions by precedence (higher wins), tiebroken by registry order. */
|
|
816
|
+
function resolveSkillCollisions(candidates: ReadonlyArray<SkillCandidate>): {
|
|
817
|
+
winners: Skill[];
|
|
818
|
+
diagnostics: ResourceDiagnostic[];
|
|
819
|
+
} {
|
|
820
|
+
const byName = new Map<string, SkillCandidate[]>();
|
|
821
|
+
for (const candidate of candidates) {
|
|
822
|
+
const key = candidate.skill.name.trim();
|
|
823
|
+
if (key.length === 0) continue;
|
|
824
|
+
const list = byName.get(key) ?? [];
|
|
825
|
+
list.push(candidate);
|
|
826
|
+
byName.set(key, list);
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
const winners: Skill[] = [];
|
|
830
|
+
const diagnostics: ResourceDiagnostic[] = [];
|
|
831
|
+
for (const [name, entries] of byName.entries()) {
|
|
832
|
+
const sorted = [...entries].sort((a, b) => compareSkillCandidates(a.skill, b.skill));
|
|
833
|
+
const winner = sorted[sorted.length - 1];
|
|
834
|
+
if (!winner) continue;
|
|
835
|
+
winners.push(winner.skill);
|
|
836
|
+
for (const loser of sorted.slice(0, -1)) {
|
|
837
|
+
diagnostics.push({
|
|
838
|
+
type: "collision",
|
|
839
|
+
message: `${name} from ${winner.skill.source}/${winner.skill.scope} overrides ${loser.skill.source}/${loser.skill.scope}`,
|
|
840
|
+
path: loser.skill.filePath,
|
|
841
|
+
collision: {
|
|
842
|
+
name,
|
|
843
|
+
winnerPath: winner.skill.filePath,
|
|
844
|
+
loserPath: loser.skill.filePath,
|
|
845
|
+
winnerScope: winner.skill.scope,
|
|
846
|
+
loserScope: loser.skill.scope,
|
|
847
|
+
},
|
|
848
|
+
});
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
return { winners, diagnostics };
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
/** Warn on typed `requires: [skill:name, ...]` entries that resolve to no loaded skill. */
|
|
855
|
+
function requiresDiagnostics(winners: ReadonlyArray<Skill>): ResourceDiagnostic[] {
|
|
856
|
+
const names = new Set(winners.map((skill) => skill.name));
|
|
857
|
+
const out: ResourceDiagnostic[] = [];
|
|
858
|
+
for (const skill of winners) {
|
|
859
|
+
const requires = skill.metadata.requires;
|
|
860
|
+
if (!Array.isArray(requires)) continue;
|
|
861
|
+
for (const entry of requires) {
|
|
862
|
+
if (typeof entry !== "string" || !entry.startsWith("skill:")) continue;
|
|
863
|
+
const dep = entry.slice("skill:".length).trim();
|
|
864
|
+
if (dep.length === 0 || names.has(dep)) continue;
|
|
865
|
+
out.push({
|
|
866
|
+
type: "warning",
|
|
867
|
+
message: `${skill.name} requires skill "${dep}" which is not available`,
|
|
868
|
+
path: skill.filePath,
|
|
869
|
+
});
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
return out;
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
export function loadSkills(input: LoadSkillsInput = {}): SkillList {
|
|
876
|
+
const roots = input.roots ?? (input.disableDiscovery === true ? [] : defaultSkillRoots(input));
|
|
877
|
+
const diagnostics: ResourceDiagnostic[] = [];
|
|
878
|
+
const candidates = [
|
|
879
|
+
...roots.flatMap((root) => loadSkillRoot(root, diagnostics)),
|
|
880
|
+
...(input.explicitSkillPaths ?? []).flatMap((skillPath) => loadExplicitSkillPath(skillPath, diagnostics)),
|
|
881
|
+
];
|
|
882
|
+
const deduped = dedupeCanonicalSkillPaths(candidates, diagnostics);
|
|
883
|
+
const resolved = resolveSkillCollisions(deduped);
|
|
884
|
+
const winners = [...resolved.winners].sort((a, b) => a.name.localeCompare(b.name));
|
|
885
|
+
return {
|
|
886
|
+
items: winners,
|
|
887
|
+
diagnostics: [...diagnostics, ...resolved.diagnostics, ...requiresDiagnostics(winners)],
|
|
888
|
+
};
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
/** Skills the model may see in context(scope=skills) listings and load by name. */
|
|
892
|
+
export function modelVisibleSkills(skills: ReadonlyArray<Skill>): Skill[] {
|
|
893
|
+
return skills.filter((skill) => skill.trusted && !skill.disableModelInvocation);
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
export function parseSkillCommand(input: string): { name: string; args: string } | null {
|
|
897
|
+
const trimmed = input.trim();
|
|
898
|
+
if (!trimmed.startsWith("/skill ")) return null;
|
|
899
|
+
const rest = trimmed.slice("/skill ".length).trim();
|
|
900
|
+
const separator = rest.search(/\s/);
|
|
901
|
+
const name = separator === -1 ? rest : rest.slice(0, separator);
|
|
902
|
+
if (name.length === 0) return null;
|
|
903
|
+
const args = separator === -1 ? "" : rest.slice(separator).trim();
|
|
904
|
+
return { name, args };
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
export function expandSkillInvocationInput(
|
|
908
|
+
input: string,
|
|
909
|
+
skills: SkillList,
|
|
910
|
+
_options: SkillExpansionOptions = {},
|
|
911
|
+
): SkillExpansion {
|
|
912
|
+
const command = parseSkillCommand(input);
|
|
913
|
+
if (!command) return { expanded: false, text: input, args: "", diagnostics: skills.diagnostics };
|
|
914
|
+
const skill = skills.items.find((entry) => entry.name === command.name);
|
|
915
|
+
const args = command.args;
|
|
916
|
+
if (!skill) return { expanded: false, text: input, args, diagnostics: skills.diagnostics };
|
|
917
|
+
return {
|
|
918
|
+
expanded: true,
|
|
919
|
+
text: args,
|
|
920
|
+
args,
|
|
921
|
+
skill,
|
|
922
|
+
triggeredBy: "slash-command",
|
|
923
|
+
diagnostics: skills.diagnostics,
|
|
924
|
+
};
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
export function parsePendingSkillRequests(
|
|
928
|
+
input: string,
|
|
929
|
+
skills: SkillList,
|
|
930
|
+
options: SkillExpansionOptions = {},
|
|
931
|
+
): { text: string; pendingSkillRequests: PendingSkillRequest[] } {
|
|
932
|
+
const command = parseSkillCommand(input);
|
|
933
|
+
if (command) {
|
|
934
|
+
const name = command.name;
|
|
935
|
+
const args = command.args;
|
|
936
|
+
const installedSkill = skills.items.find((entry) => entry.name === name);
|
|
937
|
+
if (installedSkill) {
|
|
938
|
+
return {
|
|
939
|
+
text: args,
|
|
940
|
+
pendingSkillRequests: [
|
|
941
|
+
{
|
|
942
|
+
name,
|
|
943
|
+
args,
|
|
944
|
+
source: "slash-command",
|
|
945
|
+
installed: true,
|
|
946
|
+
filePath: installedSkill.filePath,
|
|
947
|
+
},
|
|
948
|
+
],
|
|
949
|
+
};
|
|
950
|
+
}
|
|
951
|
+
// Check the local marketplace/discovery contract. Empty means unavailable/offline.
|
|
952
|
+
const marketplaceSkill = getMarketplaceSkills(options.cwd ? { cwd: options.cwd } : {}).find((s) => s.name === name);
|
|
953
|
+
if (marketplaceSkill) {
|
|
954
|
+
return {
|
|
955
|
+
text: args,
|
|
956
|
+
pendingSkillRequests: [
|
|
957
|
+
{
|
|
958
|
+
name,
|
|
959
|
+
args,
|
|
960
|
+
source: "marketplace",
|
|
961
|
+
installed: false,
|
|
962
|
+
marketplaceRef: marketplaceSkill.sourceUrl,
|
|
963
|
+
},
|
|
964
|
+
],
|
|
965
|
+
};
|
|
966
|
+
}
|
|
967
|
+
// Not installed and not in marketplace
|
|
968
|
+
return {
|
|
969
|
+
text: args,
|
|
970
|
+
pendingSkillRequests: [
|
|
971
|
+
{
|
|
972
|
+
name,
|
|
973
|
+
args,
|
|
974
|
+
source: "slash-command",
|
|
975
|
+
installed: false,
|
|
976
|
+
},
|
|
977
|
+
],
|
|
978
|
+
};
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
return {
|
|
982
|
+
text: input,
|
|
983
|
+
pendingSkillRequests: [],
|
|
984
|
+
};
|
|
985
|
+
}
|