@iowarp/clio-coder 0.3.1 → 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 +90 -2
- package/CONTRIBUTING.md +23 -23
- package/README.md +284 -613
- package/dist/{acp-FPR54DGL.js → acp-BIYHVZIM.js} +43 -53
- package/dist/{agents-OGPIHPJH.js → agents-YT6SSRIT.js} +43 -26
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-IC3K6NIZ.js → auth-5TWEIYDN.js} +20 -12
- package/dist/{chunk-PV4JUBVJ.js → chunk-2EHAIA3X.js} +40 -21
- package/dist/{chunk-IS3ONKU3.js → chunk-2IR2NMPA.js} +6 -4
- package/dist/chunk-2SFS6XQE.js +122 -0
- package/dist/chunk-2VTFPG5O.js +48 -0
- package/dist/{chunk-MAR7Y6HW.js → chunk-3ZXDFGR5.js} +23 -16
- package/dist/chunk-4BJ5BYCE.js +61 -0
- package/dist/{chunk-474KN5II.js → chunk-4BPJXDWC.js} +111 -181
- package/dist/chunk-4KLWL3UC.js +18 -0
- package/dist/chunk-4VP4KH3K.js +962 -0
- package/dist/chunk-4ZG3XFUR.js +77 -0
- package/dist/chunk-5B2AEOW5.js +5407 -0
- package/dist/{chunk-K2ITRMHZ.js → chunk-5TSRNF4G.js} +6 -138
- package/dist/{chunk-OLBBMFRD.js → chunk-5UUP6MWO.js} +24 -62
- 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-TEKV33Q5.js → chunk-77VKQEHF.js} +65 -33
- package/dist/chunk-7CR24IG7.js +242 -0
- package/dist/{chunk-M5T5VO65.js → chunk-7EYHLWU7.js} +837 -635
- package/dist/chunk-7MNJORFF.js +22 -0
- package/dist/{chunk-KY56HMHH.js → chunk-A3CYT5EX.js} +125 -31
- package/dist/chunk-AGYYIBLL.js +1069 -0
- package/dist/chunk-AO4RKG4M.js +277 -0
- package/dist/{chunk-GB6QRBXN.js → chunk-APJ265NV.js} +54 -1187
- package/dist/chunk-ARBGF5F7.js +174 -0
- package/dist/{chunk-673JJUWJ.js → chunk-BMEMKKIT.js} +2 -2
- package/dist/chunk-CBCAPZAA.js +229 -0
- package/dist/chunk-CMZWFGD2.js +352 -0
- package/dist/chunk-ECH6PKUQ.js +39 -0
- package/dist/chunk-ED4KHGC3.js +143 -0
- package/dist/chunk-EKMEHE4H.js +340 -0
- package/dist/{chunk-RPTR2H26.js → chunk-EPVUXGXG.js} +21 -15
- 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-ZPY3JZ5E.js → chunk-GGXXDWE4.js} +183 -1233
- package/dist/chunk-HC4CLZ2Y.js +68 -0
- package/dist/{chunk-LU4TK2PR.js → chunk-HFSBBKSQ.js} +5 -56
- package/dist/{chunk-PIUMUEMV.js → chunk-HKIYEGME.js} +10 -6
- package/dist/chunk-I4HZDVNP.js +73 -0
- package/dist/{chunk-4QKXUHSR.js → chunk-IGLFWIYI.js} +70 -20
- package/dist/chunk-IKCO5N3L.js +162 -0
- package/dist/chunk-IR4CFBFN.js +56 -0
- package/dist/{chunk-PFEFKVGL.js → chunk-J5HN4RYU.js} +13 -11
- package/dist/{chunk-R5KLMSBV.js → chunk-J5Q24KAG.js} +2 -2
- package/dist/{chunk-K5XEMXTI.js → chunk-JVCV3ICN.js} +1 -1
- package/dist/chunk-KJ5LWLOE.js +1077 -0
- package/dist/chunk-LBMZMYH2.js +285 -0
- package/dist/{chunk-G34LV2PF.js → chunk-LBNRH5WM.js} +84 -170
- package/dist/{chunk-H6F6BYOH.js → chunk-LZSJBIVT.js} +7003 -7434
- package/dist/{chunk-HQQID6OA.js → chunk-M6SHUN7Q.js} +5 -5
- package/dist/chunk-MAW544W2.js +1882 -0
- package/dist/chunk-MBS4V7ZP.js +217 -0
- package/dist/{chunk-FST4FYJB.js → chunk-MFFY33HR.js} +99 -140
- package/dist/chunk-MNA4JGU4.js +255 -0
- package/dist/chunk-MQSRRFWA.js +3428 -0
- package/dist/{chunk-BSU2YIWB.js → chunk-MVVUPGPW.js} +131 -136
- package/dist/chunk-OAO4GE4M.js +619 -0
- package/dist/chunk-OHHN2SO4.js +5135 -0
- package/dist/chunk-OKGUZO2U.js +34 -0
- package/dist/{chunk-GAEBEQVI.js → chunk-OOJYHWRB.js} +32 -346
- package/dist/{chunk-Q5WJOSJ7.js → chunk-OQ33BKR3.js} +2 -1
- package/dist/chunk-OQE5J4C6.js +73 -0
- package/dist/{chunk-KKNLWXI6.js → chunk-ORBHGJC5.js} +8 -8
- package/dist/chunk-POHLU5DW.js +1186 -0
- package/dist/chunk-QKMUKYO7.js +4961 -0
- package/dist/{chunk-ASND7OZK.js → chunk-QTYWRVRA.js} +13 -13
- package/dist/{chunk-EYOKLTMF.js → chunk-SRF2PJNW.js} +17 -3
- package/dist/chunk-SST6Z5JA.js +80 -0
- package/dist/chunk-STBPMHSX.js +2456 -0
- package/dist/chunk-T6YILFSB.js +80 -0
- package/dist/chunk-TZTZS7QK.js +227 -0
- package/dist/chunk-UOV2BYIW.js +107 -0
- package/dist/{chunk-Q3RUPKEJ.js → chunk-V4RXGQ5Q.js} +58 -189
- 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-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-RDLVBZEO.js → chunk-YCWGATWI.js} +6 -4
- package/dist/chunk-YHZX5GEU.js +193 -0
- package/dist/chunk-YXLYO42X.js +91 -0
- package/dist/{chunk-NMOX6HFD.js → chunk-ZDOOVTXZ.js} +29 -77
- package/dist/chunk-ZI647VB5.js +37 -0
- package/dist/{chunk-C4PTHK7P.js → chunk-ZWLZP4ZT.js} +5 -5
- package/dist/cli/index.js +62 -54
- 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-DMAOEKFB.js → components-KELWS457.js} +11 -6
- package/dist/{config-IRUQ7SE4.js → config-GTLUW2PR.js} +92 -55
- package/dist/configure-R6A64DHX.js +42 -0
- package/dist/context-5VKGUVJJ.js +866 -0
- package/dist/{context-3KWFLHJG.js → context-JFZEJ7W5.js} +15 -13
- package/dist/{context-5RADCKTR.js → context-RW5HC47S.js} +71 -35
- package/dist/{context-clear-7TSNPAAI.js → context-clear-6ZHBAZZT.js} +54 -28
- package/dist/{context-index-W4RLWOQH.js → context-index-BZ4UYMTC.js} +30 -24
- package/dist/dispatch-runner-VKBRCWQC.js +1997 -0
- package/dist/{docs-5AWSPS37.js → docs-2C2LTVT2.js} +23 -10
- package/dist/{doctor-UC5NAJYQ.js → doctor-KI767GSN.js} +27 -17
- package/dist/{eval-U6TJHRLX.js → eval-XSSNATB4.js} +29 -16
- package/dist/{evidence-YEGUW4L3.js → evidence-UA6AWDQQ.js} +46 -26
- package/dist/{evolve-TXARCTPG.js → evolve-QNTFGV6Z.js} +45 -25
- package/dist/{extensions-OZFJ3A3G.js → extensions-QVDOHDGJ.js} +16 -7
- package/dist/{fleet-6G3DHNYE.js → fleet-Q7UOMUSG.js} +163 -54
- package/dist/{fleet-preflight-DSNT37JK.js → fleet-preflight-DDN536IT.js} +7 -4
- package/dist/{init-KZ5QTF6M.js → init-WBB65ZHQ.js} +69 -32
- package/dist/{memory-73ESV5YC.js → memory-MD3O64RI.js} +48 -27
- package/dist/{models-A4PVNWJK.js → models-BZU34YWD.js} +39 -25
- package/dist/monitor-MEQA5C3I.js +661 -0
- package/dist/{chunk-FCIH3BIZ.js → orchestrator-CGFKEP27.js} +11832 -8687
- package/dist/{paths-C4H6IV77.js → paths-UXLN5YYZ.js} +10 -5
- package/dist/{preload-6WVMHX3A.js → preload-P6DGH2PZ.js} +2 -2
- package/dist/{reset-BGW6OGMV.js → reset-L2FQEE3E.js} +16 -10
- package/dist/{run-YTPEYQOH.js → run-IV4Q6RLN.js} +101 -61
- package/dist/{share-YIFFV4NQ.js → share-S5BZQC5I.js} +15 -8
- package/dist/{skills-2V6RA3OQ.js → skills-LQEKRDTN.js} +34 -14
- package/dist/{skills-eval-S2TVJO4F.js → skills-eval-3DC4HEWS.js} +70 -34
- package/dist/steer-GGWFUJUD.js +77 -0
- package/dist/{targets-TYXLPB23.js → targets-C4SSGQOB.js} +43 -27
- package/dist/terminal-lease-IT5JW2NR.js +395 -0
- package/dist/{trace-GGOJ6Q6Z.js → trace-PNCASAXC.js} +41 -16
- package/dist/{chunk-N6F52NLF.js → tree-sitter-HGKH6LG4.js} +28 -2306
- package/dist/{uninstall-LLLT4F4W.js → uninstall-FZCQCDKC.js} +10 -5
- package/dist/{upgrade-33G2LMM5.js → upgrade-7TT7SQ3G.js} +45 -25
- package/dist/{usage-ZAFSXKKG.js → usage-GV4PKT3M.js} +62 -31
- package/dist/verify-G6V4D2G7.js +716 -0
- package/dist/web-fetch-2YHJ3KTG.js +638 -0
- package/dist/{wiki-generate-NUQCVOQ3.js → wiki-generate-DQF6Z66B.js} +74 -34
- package/dist/worker/entry.js +221 -36
- package/dist/workspace-G4ZWUIPR.js +22 -0
- package/docs/README.md +22 -17
- package/docs/acp.md +168 -16
- package/docs/alcf-provider.md +1 -1
- package/docs/architecture.md +136 -7
- package/docs/artifact-versions.md +1 -1
- package/docs/built-in-agents.md +1 -1
- package/docs/capacity-and-scheduling.md +1 -1
- package/docs/commands-and-modes.md +114 -71
- package/docs/config-knobs-audit.md +1 -3
- package/docs/configuration-and-targets.md +174 -46
- package/docs/context-engine.md +29 -6
- package/docs/development-pipeline.md +26 -1
- package/docs/dispatch-architecture-rationale.md +1 -1
- package/docs/documentation-coverage.md +2 -2
- package/docs/documentation-guide.md +1 -1
- package/docs/environment-variables.md +13 -5
- package/docs/eval-runner.md +1 -1
- package/docs/evals-internal.md +1 -1
- package/docs/evidence-and-memory.md +6 -2
- package/docs/evolution.md +2 -2
- package/docs/exit-codes-and-output.md +15 -9
- package/docs/extensions-and-sharing.md +9 -9
- package/docs/fleet-dispatch.md +7 -5
- package/docs/git-commit-provenance.md +120 -0
- package/docs/glossary.md +1 -1
- package/docs/installation-and-lifecycle.md +34 -27
- package/docs/middleware-and-components.md +1 -1
- package/docs/model-catalog.md +45 -14
- package/docs/observability.md +8 -5
- package/docs/performance-methodology.md +491 -0
- package/docs/pi-boundary.md +72 -0
- package/docs/proactive-memory.md +3 -3
- package/docs/prompt-envelope-and-tools.md +24 -3
- package/docs/provider-adapter-cookbook.md +57 -4
- package/docs/release-cut-checklist.md +129 -115
- package/docs/safety-model.md +9 -5
- package/docs/scientific-validation.md +3 -3
- package/docs/session-lifecycle.md +55 -12
- package/docs/skills-marketplace.md +12 -8
- package/docs/time-conventions.md +1 -1
- package/docs/tool-usage.md +3 -3
- package/docs/trace-store.md +1 -1
- package/docs/troubleshooting.md +10 -7
- package/docs/tui-design.md +47 -10
- package/docs/worker-dispatch-mechanics.md +1 -1
- package/package.json +19 -22
- package/skills/coding/ast-grep/SKILL.md +136 -0
- package/skills/coding/ast-grep/evals.md +56 -0
- package/skills/coding/ast-grep/references/rule_reference.md +297 -0
- package/skills/coding/coding-standards/SKILL.md +113 -0
- package/skills/coding/coding-standards/evals.md +34 -0
- package/skills/coding/prototype/SKILL.md +86 -0
- package/skills/coding/prototype/evals.md +42 -0
- package/skills/coding/prototype/references/LOGIC.md +67 -0
- package/skills/coding/prototype/references/UI.md +112 -0
- package/skills/coding/tdd/SKILL.md +101 -0
- package/skills/coding/tdd/evals.md +41 -0
- package/skills/coding/tdd/references/mocking.md +59 -0
- package/skills/coding/tdd/references/tests.md +77 -0
- package/skills/context/context-handoff/SKILL.md +126 -0
- package/skills/context/context-handoff/evals.md +57 -0
- package/skills/context/context-handoff/scripts/new-handoff.sh +26 -0
- package/skills/context/context-prime/SKILL.md +95 -0
- package/skills/context/context-prime/evals.md +54 -0
- package/skills/meta/clio-dev/SKILL.md +91 -0
- package/skills/meta/clio-dev/evals.md +45 -0
- package/skills/meta/clio-test/SKILL.md +130 -0
- package/skills/meta/clio-test/evals.md +43 -0
- package/skills/meta/clio-test/references/harness.md +97 -0
- package/skills/meta/clio-test/references/test-map.md +59 -0
- package/skills/meta/credentials/SKILL.md +125 -0
- package/skills/meta/credentials/evals.md +104 -0
- package/skills/meta/find-skills/SKILL.md +72 -0
- package/skills/meta/find-skills/evals.md +47 -0
- package/skills/meta/herdr/SKILL.md +127 -0
- package/skills/meta/herdr/evals.md +38 -0
- package/skills/meta/skill-craft/SKILL.md +102 -0
- package/skills/meta/skill-craft/evals.md +41 -0
- package/skills/planning/architecture/SKILL.md +129 -0
- package/skills/planning/architecture/evals.md +36 -0
- package/skills/planning/backlog/SKILL.md +90 -0
- package/skills/planning/backlog/evals.md +43 -0
- package/skills/planning/prd/SKILL.md +82 -0
- package/skills/planning/prd/evals.md +49 -0
- package/skills/planning/product-intent/SKILL.md +112 -0
- package/skills/planning/product-intent/evals.md +36 -0
- package/skills/planning/tech-spec/SKILL.md +115 -0
- package/skills/planning/tech-spec/evals.md +47 -0
- package/skills/registry.yaml +136 -0
- package/skills/research/arxiv-literature/SKILL.md +104 -0
- package/skills/research/arxiv-literature/evals.md +58 -0
- package/skills/research/experiment-protocol/SKILL.md +122 -0
- package/skills/research/experiment-protocol/evals.md +91 -0
- package/skills/research/scientific-debugging/SKILL.md +119 -0
- package/skills/research/scientific-debugging/evals.md +138 -0
- package/skills/research/scientific-modernization/SKILL.md +138 -0
- package/skills/research/scientific-modernization/evals.md +84 -0
- package/skills/workflow/design-council/SKILL.md +139 -0
- package/skills/workflow/design-council/evals.md +97 -0
- package/skills/workflow/grill-me/SKILL.md +186 -0
- package/skills/workflow/grill-me/evals.md +78 -0
- package/skills/workflow/workflow-distiller/SKILL.md +136 -0
- package/skills/workflow/workflow-distiller/evals.md +107 -0
- package/src/cli/acp.ts +31 -4
- package/src/cli/clio.ts +68 -6
- package/src/cli/config-inspect.ts +28 -22
- package/src/cli/configure.ts +47 -9
- package/src/cli/context-clear.ts +2 -2
- package/src/cli/context-index.ts +21 -23
- package/src/cli/context.ts +13 -8
- package/src/cli/default-target.ts +9 -17
- package/src/cli/docs.ts +11 -5
- package/src/cli/evidence.ts +4 -1
- package/src/cli/extensions.ts +10 -1
- package/src/cli/fleet.ts +47 -6
- package/src/cli/index.ts +55 -26
- package/src/cli/memory.ts +3 -1
- package/src/cli/models.ts +1 -1
- package/src/cli/modes/json-stream.ts +37 -1
- package/src/cli/modes/print.ts +24 -9
- package/src/cli/run.ts +2 -2
- package/src/cli/skills-eval.ts +23 -8
- package/src/cli/skills.ts +19 -4
- package/src/cli/targets.ts +4 -0
- package/src/cli/text-layout.ts +15 -5
- package/src/cli/trace.ts +62 -14
- package/src/cli/upgrade.ts +18 -2
- package/src/cli/usage.ts +10 -3
- package/src/cli/wiki-generate.ts +2 -1
- package/src/core/agent-environment.ts +7 -0
- package/src/core/bash-exec.ts +72 -1
- package/src/core/boot-trace.ts +9 -4
- package/src/core/bus-events.ts +20 -4
- package/src/core/commit-attribution.ts +157 -0
- package/src/core/compile-cache.ts +159 -0
- package/src/core/config.ts +131 -2
- package/src/core/defaults.ts +39 -5
- package/src/core/domain-loader.ts +12 -5
- package/src/core/git-commit-attribution.ts +362 -0
- package/src/core/incomplete-installation.ts +45 -0
- package/src/core/response-schema.ts +1 -1
- package/src/core/safe-exec.ts +13 -1
- package/src/core/settings-layers.ts +155 -21
- package/src/core/skill-activation.ts +1 -1
- package/src/core/startup-timer.ts +3 -3
- package/src/core/state-file-lock.ts +13 -1
- package/src/core/termination.ts +78 -5
- package/src/domains/config/classify.ts +15 -3
- package/src/domains/config/extension.ts +19 -13
- package/src/domains/config/index.ts +10 -0
- package/src/domains/config/keybindings.ts +42 -6
- package/src/domains/context/bootstrap-prompt.ts +1 -1
- package/src/domains/context/bootstrap.ts +111 -18
- package/src/domains/context/clear.ts +16 -11
- package/src/domains/context/clio-md.ts +111 -9
- package/src/domains/context/codewiki/artifact.ts +400 -0
- package/src/domains/context/codewiki/build-worker-protocol.ts +24 -0
- package/src/domains/context/codewiki/build-worker.ts +54 -0
- package/src/domains/context/codewiki/coordinator.ts +182 -0
- package/src/domains/context/codewiki/indexer.ts +59 -144
- package/src/domains/context/codewiki/paths.ts +67 -0
- package/src/domains/context/codewiki/schema.ts +80 -0
- package/src/domains/context/codewiki/tree-sitter.ts +1 -1
- package/src/domains/context/contract.ts +11 -5
- package/src/domains/context/extension.ts +94 -143
- package/src/domains/context/fingerprint.ts +3 -1
- package/src/domains/context/index.ts +12 -22
- package/src/domains/context/project-metadata.ts +19 -0
- package/src/domains/context/prompt-context.ts +9 -10
- package/src/domains/context/refresh.ts +29 -21
- package/src/domains/context/runtime.ts +17 -0
- package/src/domains/context/wiki/generate.ts +39 -34
- package/src/domains/context/wiki/plan.ts +1 -1
- package/src/domains/context/wiki/prompts.ts +21 -8
- package/src/domains/dispatch/code-step.ts +20 -1
- package/src/domains/dispatch/extension.ts +158 -21
- package/src/domains/dispatch/failure-classification.ts +6 -0
- package/src/domains/dispatch/fleet-commit-attribution.ts +56 -0
- package/src/domains/dispatch/orphan-recovery.ts +50 -8
- package/src/domains/dispatch/receipt-integrity.ts +5 -0
- package/src/domains/dispatch/state.ts +31 -6
- package/src/domains/dispatch/transport.ts +2 -1
- package/src/domains/dispatch/types.ts +14 -0
- package/src/domains/dispatch/worker-spawn.ts +21 -2
- package/src/domains/eval/metrics/context.ts +1 -1
- package/src/domains/eval/types.ts +0 -1
- package/src/domains/evidence/build.ts +41 -1
- package/src/domains/lifecycle/migrations/2026-08-18-lmstudio-runtime-id.ts +52 -0
- package/src/domains/lifecycle/migrations/index.ts +24 -4
- package/src/domains/middleware/hooks-io.ts +12 -0
- package/src/domains/middleware/skills-reminder.ts +30 -15
- package/src/domains/prompts/compiler.ts +142 -84
- package/src/domains/prompts/contract.ts +18 -2
- package/src/domains/prompts/extension.ts +39 -7
- package/src/domains/prompts/fragment-loader.ts +0 -1
- package/src/domains/prompts/fragments/identity/clio.md +2 -4
- package/src/domains/prompts/fragments/identity/docs-routing.md +10 -0
- package/src/domains/prompts/fragments/identity/self-awareness.md +1 -45
- package/src/domains/prompts/fragments/operating/contract.md +4 -50
- package/src/domains/prompts/fragments/operating/delegation.md +42 -0
- package/src/domains/prompts/fragments/operating/skills.md +26 -0
- package/src/domains/prompts/fragments/operating/worker.md +16 -0
- package/src/domains/prompts/fragments/safety/auto-edit.md +5 -5
- package/src/domains/prompts/fragments/safety/full-auto.md +3 -3
- package/src/domains/prompts/fragments/safety/read-only.md +4 -4
- package/src/domains/prompts/fragments/safety/suggest.md +2 -2
- package/src/domains/prompts/fragments/wiki/page.md +10 -0
- package/src/domains/prompts/fragments/wiki/plan.md +10 -0
- package/src/domains/prompts/preload.ts +3 -3
- package/src/domains/providers/auth/api-key.ts +1 -1
- package/src/domains/providers/auth/backend-file.ts +20 -10
- package/src/domains/providers/auth/backend-memory.ts +59 -4
- package/src/domains/providers/auth/boot-status.ts +65 -0
- package/src/domains/providers/auth/oauth.ts +2 -1
- package/src/domains/providers/auth/storage.ts +97 -38
- package/src/domains/providers/capabilities.ts +12 -4
- package/src/domains/providers/contract.ts +15 -4
- package/src/domains/providers/extension.ts +18 -6
- package/src/domains/providers/model-runtime-capabilities.ts +15 -4
- package/src/domains/providers/models/local-models/clio-local-coding-targets.yaml +118 -35
- package/src/domains/providers/plugins.ts +5 -3
- package/src/domains/providers/probe/fingerprint.ts +25 -5
- package/src/domains/providers/registry.ts +31 -10
- package/src/domains/providers/runtimes/boot-manifest.ts +55 -0
- package/src/domains/providers/runtimes/builtins.ts +2 -2
- package/src/domains/providers/runtimes/common/lmstudio-http.ts +423 -0
- package/src/domains/providers/runtimes/common/local-synth.ts +6 -7
- package/src/domains/providers/runtimes/local-native/lmstudio.ts +241 -0
- package/src/domains/providers/support.ts +6 -3
- package/src/domains/providers/types/local-model-quirks.ts +7 -9
- package/src/domains/providers/types/runtime-descriptor.ts +12 -1
- package/src/domains/providers/types/target-descriptor.ts +22 -0
- package/src/domains/resources/contract.ts +0 -1
- package/src/domains/resources/extension.ts +1 -3
- package/src/domains/resources/loader.ts +3 -4
- package/src/domains/resources/prompts/loader.ts +16 -2
- package/src/domains/resources/prompts/substitute.ts +1 -65
- package/src/domains/resources/skills/content-hash.ts +2 -0
- package/src/domains/resources/skills/install.ts +17 -0
- package/src/domains/resources/skills/loader.ts +17 -10
- package/src/domains/resources/skills/marketplace.ts +55 -9
- package/src/domains/safety/action-classifier.ts +4 -2
- package/src/domains/safety/audit.ts +8 -2
- package/src/domains/safety/extension.ts +1 -1
- package/src/domains/session/compaction/branch-summary.ts +3 -2
- package/src/domains/session/compaction/cut-point.ts +2 -1
- package/src/domains/session/compaction/tokens.ts +2 -1
- package/src/domains/session/context-ledger.ts +14 -0
- package/src/domains/session/contract.ts +15 -0
- package/src/domains/session/decision-board.ts +190 -0
- package/src/domains/session/entries.ts +66 -3
- package/src/domains/session/extension.ts +93 -12
- package/src/domains/session/retry.ts +10 -18
- package/src/domains/session/session-artifacts.ts +107 -0
- package/src/domains/session/task-board.ts +207 -13
- package/src/domains/session/tree/active-path.ts +44 -5
- package/src/domains/session/tree/fork.ts +26 -27
- package/src/domains/session/tree/preview.ts +2 -2
- package/src/domains/session/workspace/git-probe.ts +17 -11
- package/src/domains/user-tasks/store.ts +297 -0
- package/src/engine/acp/errors.ts +96 -0
- package/src/engine/acp/server.ts +1728 -146
- package/src/engine/acp/transport.ts +135 -14
- package/src/engine/acp/types.ts +26 -0
- package/src/engine/agent.ts +3 -3
- package/src/engine/ai.ts +32 -27
- package/src/engine/alcf-oauth.ts +26 -19
- package/src/engine/api-registry.ts +223 -0
- package/src/engine/apis/index.ts +3 -7
- package/src/engine/apis/llamacpp-residency.ts +49 -9
- package/src/engine/apis/lmstudio-residency.ts +5 -21
- package/src/engine/apis/lmstudio.ts +243 -0
- package/src/engine/apis/ollama-native.ts +24 -3
- package/src/engine/apis/openai-completions.ts +170 -91
- package/src/engine/apis/residency.ts +139 -3
- package/src/engine/apis/types.ts +16 -0
- package/src/engine/env-api-keys.ts +98 -0
- package/src/engine/gemma-channel-filter.ts +223 -0
- package/src/engine/instrumented-tui.ts +192 -0
- package/src/engine/messages.ts +14 -0
- package/src/engine/models.ts +42 -0
- package/src/engine/oauth.ts +16 -12
- package/src/engine/prompt-templates.ts +1 -0
- package/src/engine/provider-payload.ts +16 -59
- package/src/engine/strip-tokenizer-sentinels.ts +1 -1
- package/src/engine/truncate.ts +9 -0
- package/src/engine/tui.ts +17 -9
- package/src/engine/types.ts +3 -6
- package/src/engine/worker-runtime-capabilities.ts +5 -0
- package/src/engine/worker-runtime.ts +1 -1
- package/src/engine/worker-tools.ts +9 -4
- package/src/entry/boot-options.ts +50 -0
- package/src/entry/orchestrator.ts +288 -150
- package/src/interactive/application-controller.ts +89 -2
- package/src/interactive/chat-loop.ts +266 -41
- package/src/interactive/chat-panel.ts +173 -47
- package/src/interactive/chat-renderer.ts +262 -72
- package/src/interactive/clio-editor.ts +3 -8
- package/src/interactive/command-fallbacks.ts +2 -2
- package/src/interactive/context-overlay.ts +27 -1
- package/src/interactive/editor-submit.ts +228 -24
- package/src/interactive/export-html/ansi-to-html.ts +161 -0
- package/src/interactive/export-html/index.ts +51 -0
- package/src/interactive/export-html/template.ts +45 -0
- package/src/interactive/export-html/tool-renderer.ts +54 -0
- package/src/interactive/footer/dashboard.ts +4 -0
- package/src/interactive/footer/notifications.ts +1 -1
- package/src/interactive/footer/widgets.ts +20 -2
- package/src/interactive/footer-panel.ts +2 -2
- package/src/interactive/format-time.ts +14 -2
- package/src/interactive/interactive-application.ts +201 -17
- package/src/interactive/interactive-event-projection.ts +6 -1
- package/src/interactive/interactive-input-runtime.ts +50 -4
- package/src/interactive/interactive-presentation.ts +151 -19
- package/src/interactive/interactive-shell.ts +268 -14
- package/src/interactive/interactive-slash-runtime.ts +176 -114
- package/src/interactive/interactive-tickers.ts +38 -7
- package/src/interactive/keybinding-manager.ts +1 -1
- package/src/interactive/layout.ts +40 -3
- package/src/interactive/overlay-frame.ts +1 -1
- package/src/interactive/overlay-general-openers.ts +58 -1
- package/src/interactive/overlay-key-routing.ts +3 -0
- package/src/interactive/overlay-lifecycle.ts +13 -0
- package/src/interactive/overlay-permission-lifecycle.ts +2 -1
- package/src/interactive/overlay-session-lifecycle.ts +69 -12
- package/src/interactive/overlays/decisions.ts +300 -0
- package/src/interactive/overlays/help-reference.ts +15 -10
- package/src/interactive/overlays/model-selector.ts +34 -16
- package/src/interactive/overlays/session-selector.ts +18 -0
- package/src/interactive/overlays/settings.ts +105 -17
- package/src/interactive/overlays/skills-hub.ts +4 -4
- package/src/interactive/overlays/tree-selector.ts +41 -6
- package/src/interactive/render-trace.ts +499 -90
- package/src/interactive/renderers/compaction-summary.ts +2 -2
- package/src/interactive/renderers/diff.ts +115 -104
- package/src/interactive/renderers/mermaid.ts +53 -0
- package/src/interactive/renderers/tool-execution.ts +386 -133
- package/src/interactive/renderers/worker-entry.ts +20 -4
- package/src/interactive/session-switch-settlement.ts +10 -0
- package/src/interactive/slash-autocomplete.ts +6 -114
- package/src/interactive/slash-commands.ts +135 -47
- package/src/interactive/slash-spec.ts +9 -38
- package/src/interactive/status/controller.ts +5 -1
- package/src/interactive/stdout-backpressure.ts +99 -0
- package/src/interactive/stream-pacer.ts +530 -0
- package/src/interactive/stream-pacing-policy.ts +66 -0
- package/src/interactive/tasks-overlay.ts +368 -14
- package/src/interactive/terminal-lease.ts +485 -0
- package/src/interactive/theme/tokens.ts +1 -1
- package/src/interactive/turn-context.ts +4 -3
- package/src/interactive/turn-persistence.ts +30 -13
- package/src/interactive/turn-queues.ts +12 -0
- package/src/interactive/turn-recovery.ts +25 -8
- package/src/interactive/turn-runtime.ts +79 -12
- package/src/interactive/turn-state.ts +10 -0
- package/src/interactive/view/artifacts.ts +114 -4
- package/src/interactive/view/view-overlay.ts +3 -0
- package/src/interactive/welcome-dashboard.ts +17 -16
- package/src/interactive/worker-receipts.ts +52 -3
- package/src/interactive/worker-stream.ts +5 -1
- package/src/tools/agent-tools.ts +23 -3
- package/src/tools/artifact.ts +2 -2
- package/src/tools/ask-user.ts +23 -13
- package/src/tools/bash.ts +30 -2
- package/src/tools/bootstrap.ts +34 -431
- package/src/tools/builtin-tool-catalog.ts +265 -0
- package/src/tools/codewiki/code-nav-surface.ts +29 -0
- package/src/tools/codewiki/code-nav.ts +8 -22
- package/src/tools/codewiki/shared.ts +41 -38
- package/src/tools/context/docs-engine.ts +14 -3
- package/src/tools/context/index.ts +107 -28
- package/src/tools/context/surface.ts +19 -0
- package/src/tools/core-bootstrap.ts +168 -0
- package/src/tools/credential-present.ts +5 -5
- package/src/tools/dispatch-admission.ts +533 -0
- package/src/tools/dispatch-background.ts +54 -0
- package/src/tools/dispatch-event-text.ts +6 -0
- package/src/tools/dispatch-plan.ts +9 -4
- package/src/tools/dispatch-run-events.ts +238 -0
- package/src/tools/dispatch-runner.ts +2370 -0
- package/src/tools/dispatch-scout-admission.ts +295 -0
- package/src/tools/dispatch-types.ts +77 -0
- package/src/tools/dispatch.ts +67 -3161
- package/src/tools/find.ts +4 -2
- package/src/tools/grep.ts +2 -2
- package/src/tools/lazy-tool.ts +60 -0
- package/src/tools/ledger.ts +3 -3
- package/src/tools/monitor-surface.ts +36 -0
- package/src/tools/monitor.ts +2 -32
- package/src/tools/observers.ts +2 -2
- package/src/tools/registry.ts +39 -27
- package/src/tools/safe-exec.ts +2 -2
- package/src/tools/steer-surface.ts +17 -0
- package/src/tools/steer.ts +2 -13
- package/src/tools/tasks.ts +108 -11
- package/src/tools/truncate.ts +25 -184
- package/src/tools/verify/frontend.ts +3 -1
- package/src/tools/verify/index.ts +3 -38
- package/src/tools/verify/surface.ts +46 -0
- package/src/tools/web-fetch-surface.ts +23 -0
- package/src/tools/web-fetch.ts +2 -20
- package/src/tools/write.ts +7 -2
- package/src/worker/entry.ts +39 -2
- package/src/worker/spec-contract.ts +26 -5
- package/dist/chunk-7SS2CTV2.js +0 -61361
- package/dist/chunk-DKGKUHFA.js +0 -924
- package/dist/chunk-GEP36Y4X.js +0 -12796
- package/dist/chunk-XYWBQRDM.js +0 -137
- package/dist/clio-BZVGEUFJ.js +0 -58
- package/dist/configure-S7S6F6CL.js +0 -32
- package/docs/html/agents_blueprint.html +0 -936
- package/docs/html/alcf_blueprint.html +0 -324
- package/docs/html/architecture_blueprint.html +0 -850
- package/docs/html/commands_blueprint.html +0 -939
- package/docs/html/config_knobs_audit_blueprint.html +0 -178
- package/docs/html/configuration_blueprint.html +0 -1080
- package/docs/html/context_blueprint.html +0 -603
- package/docs/html/documentation_blueprint.html +0 -832
- package/docs/html/environment_blueprint.html +0 -404
- package/docs/html/eval_blueprint.html +0 -743
- package/docs/html/evals_internal_blueprint.html +0 -190
- package/docs/html/evolution_blueprint.html +0 -674
- package/docs/html/extensions_blueprint.html +0 -2065
- package/docs/html/fleet_dispatch_blueprint.html +0 -286
- package/docs/html/index.html +0 -919
- package/docs/html/lifecycle_blueprint.html +0 -723
- package/docs/html/memory_blueprint.html +0 -699
- package/docs/html/middleware_blueprint.html +0 -664
- package/docs/html/models_blueprint.html +0 -2366
- package/docs/html/observability_blueprint.html +0 -683
- package/docs/html/provider_adapter_blueprint.html +0 -245
- package/docs/html/safety_blueprint.html +0 -1386
- package/docs/html/shared.css +0 -571
- package/docs/html/shared.js +0 -143
- package/docs/html/skills_blueprint.html +0 -671
- package/docs/html/soak_blueprint.html +0 -182
- package/docs/html/tool_usage_blueprint.html +0 -350
- package/docs/html/tools_blueprint.html +0 -2249
- package/docs/html/trace_blueprint.html +0 -235
- package/docs/html/tui_design_blueprint.html +0 -374
- package/docs/html/validation_blueprint.html +0 -961
- package/docs/html/worker_dispatch_blueprint.html +0 -231
- package/src/core/release.ts +0 -2
- package/src/domains/providers/runtimes/common/lmstudio-logger.ts +0 -32
- package/src/domains/providers/runtimes/local-native/lmstudio-native.ts +0 -491
- package/src/engine/apis/lmstudio-native.ts +0 -1438
- package/src/engine/apis/thinking-replay.ts +0 -11
- package/src/tools/string-enum.ts +0 -15
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import { CLIO_MIN_CONTEXT_WINDOW, CLIO_MIN_MAX_OUTPUT_TOKENS } from "../../../../core/context-floor.js";
|
|
2
|
+
import type { Api, Model } from "../../../../engine/types.js";
|
|
3
|
+
import type { CapabilityFlags, ThinkingLevel } from "../../types/capability-flags.js";
|
|
4
|
+
import type { KnowledgeBaseHit } from "../../types/knowledge-base.js";
|
|
5
|
+
import type { ProbeContext, ProbeModelStatus, ProbeResult, RuntimeDescriptor } from "../../types/runtime-descriptor.js";
|
|
6
|
+
import type { TargetDescriptor } from "../../types/target-descriptor.js";
|
|
7
|
+
import {
|
|
8
|
+
foldLmStudioModels,
|
|
9
|
+
greetLmStudio,
|
|
10
|
+
type LmStudioCatalog,
|
|
11
|
+
type LmStudioLoadedInstance,
|
|
12
|
+
type LmStudioModelInfo,
|
|
13
|
+
listLmStudioModels,
|
|
14
|
+
lmStudioReasoningLevels,
|
|
15
|
+
loadedContextLength,
|
|
16
|
+
parseLmStudioV1Models,
|
|
17
|
+
resolveLmStudioInstance,
|
|
18
|
+
} from "../common/lmstudio-http.js";
|
|
19
|
+
import { synthLocalModel, withV1 } from "../common/local-synth.js";
|
|
20
|
+
|
|
21
|
+
const defaultCapabilities: CapabilityFlags = {
|
|
22
|
+
chat: true,
|
|
23
|
+
tools: true,
|
|
24
|
+
toolCallFormat: "openai",
|
|
25
|
+
structuredOutputs: "json-schema",
|
|
26
|
+
reasoning: true,
|
|
27
|
+
vision: true,
|
|
28
|
+
audio: false,
|
|
29
|
+
embeddings: false,
|
|
30
|
+
rerank: false,
|
|
31
|
+
fim: false,
|
|
32
|
+
contextWindow: CLIO_MIN_CONTEXT_WINDOW,
|
|
33
|
+
maxTokens: CLIO_MIN_MAX_OUTPUT_TOKENS,
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const reasoningOptionsByTargetModel = new Map<string, ReadonlyArray<string>>();
|
|
37
|
+
|
|
38
|
+
function reasoningOptionsKey(target: TargetDescriptor, modelId: string): string {
|
|
39
|
+
const url = (target.url ?? "").replace(/^ws:/u, "http:").replace(/^wss:/u, "https:").replace(/\/$/u, "");
|
|
40
|
+
return `${target.id}|${url}|${modelId}`;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function rememberReasoningOptions(target: TargetDescriptor, models: ReadonlyArray<LmStudioModelInfo>): void {
|
|
44
|
+
const prefix = reasoningOptionsKey(target, "");
|
|
45
|
+
for (const key of reasoningOptionsByTargetModel.keys()) {
|
|
46
|
+
if (key.startsWith(prefix)) reasoningOptionsByTargetModel.delete(key);
|
|
47
|
+
}
|
|
48
|
+
for (const model of models) {
|
|
49
|
+
if (!model.reasoningOptions) continue;
|
|
50
|
+
reasoningOptionsByTargetModel.set(reasoningOptionsKey(target, model.key), model.reasoningOptions);
|
|
51
|
+
for (const instance of model.loadedInstances) {
|
|
52
|
+
reasoningOptionsByTargetModel.set(reasoningOptionsKey(target, instance.id), model.reasoningOptions);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function configuredModel(target: TargetDescriptor): string | undefined {
|
|
58
|
+
const id = target.defaultModel?.trim();
|
|
59
|
+
return id && id.length > 0 ? id : undefined;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function resolveModel(
|
|
63
|
+
models: ReadonlyArray<LmStudioModelInfo>,
|
|
64
|
+
id: string | undefined,
|
|
65
|
+
): { model: LmStudioModelInfo; instance?: LmStudioLoadedInstance } | null {
|
|
66
|
+
if (id) {
|
|
67
|
+
for (const model of models) {
|
|
68
|
+
if (model.key === id) return { model, ...(model.loadedInstances[0] ? { instance: model.loadedInstances[0] } : {}) };
|
|
69
|
+
const instance = model.loadedInstances.find((entry) => entry.id === id);
|
|
70
|
+
if (instance) return { model, instance };
|
|
71
|
+
}
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
const model = models.find((entry) => entry.loadedInstances.length > 0) ?? models[0];
|
|
75
|
+
return model ? { model, ...(model.loadedInstances[0] ? { instance: model.loadedInstances[0] } : {}) } : null;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function capabilities(model: LmStudioModelInfo, instance?: LmStudioLoadedInstance): Partial<CapabilityFlags> {
|
|
79
|
+
const out: Partial<CapabilityFlags> = {};
|
|
80
|
+
if (model.vision !== undefined) out.vision = model.vision;
|
|
81
|
+
if (model.tools !== undefined) out.tools = model.tools;
|
|
82
|
+
if (model.reasoning !== undefined) out.reasoning = model.reasoning;
|
|
83
|
+
else if (model.reasoningOptions !== undefined)
|
|
84
|
+
out.reasoning = model.reasoningOptions.some((option) => option !== "off");
|
|
85
|
+
const contextWindow = loadedContextLength(instance) ?? model.maxContextLength;
|
|
86
|
+
if (contextWindow !== undefined) out.contextWindow = contextWindow;
|
|
87
|
+
return out;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function statusFor(
|
|
91
|
+
model: LmStudioModelInfo,
|
|
92
|
+
instance: LmStudioLoadedInstance | undefined,
|
|
93
|
+
reasoningLevels: ReadonlyArray<ThinkingLevel>,
|
|
94
|
+
): ProbeModelStatus {
|
|
95
|
+
const status: ProbeModelStatus = {
|
|
96
|
+
state: instance ? "loaded" : "unloaded",
|
|
97
|
+
key: model.key,
|
|
98
|
+
reasoningLevels,
|
|
99
|
+
};
|
|
100
|
+
if (instance) {
|
|
101
|
+
status.instanceId = instance.id;
|
|
102
|
+
status.loadConfig = instance.config;
|
|
103
|
+
const contextLength = loadedContextLength(instance);
|
|
104
|
+
if (contextLength !== undefined) status.contextLength = contextLength;
|
|
105
|
+
}
|
|
106
|
+
return status;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function probeFromCatalog(catalog: LmStudioCatalog, target: TargetDescriptor): ProbeResult {
|
|
110
|
+
if (!catalog.ok) {
|
|
111
|
+
return {
|
|
112
|
+
ok: false,
|
|
113
|
+
...(catalog.latencyMs !== undefined ? { latencyMs: catalog.latencyMs } : {}),
|
|
114
|
+
error: catalog.error ?? "LM Studio model listing failed",
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
const models = foldLmStudioModels(catalog.models);
|
|
118
|
+
rememberReasoningOptions(target, models);
|
|
119
|
+
const ids: string[] = [];
|
|
120
|
+
const modelCapabilities: Record<string, Partial<CapabilityFlags>> = {};
|
|
121
|
+
const modelStates: Record<string, ProbeModelStatus> = {};
|
|
122
|
+
for (const model of models) {
|
|
123
|
+
const levels = lmStudioReasoningLevels(model.reasoningOptions);
|
|
124
|
+
const keyInstance = model.loadedInstances[0];
|
|
125
|
+
modelCapabilities[model.key] = capabilities(model, keyInstance);
|
|
126
|
+
modelStates[model.key] = statusFor(model, keyInstance, levels);
|
|
127
|
+
for (const instance of model.loadedInstances) {
|
|
128
|
+
if (!ids.includes(instance.id)) ids.push(instance.id);
|
|
129
|
+
modelCapabilities[instance.id] = capabilities(model, instance);
|
|
130
|
+
const instanceStatus = statusFor(model, instance, levels);
|
|
131
|
+
modelStates[instance.id] = instanceStatus;
|
|
132
|
+
const resolution = resolveLmStudioInstance(target, models, instance.id, configuredModel(target));
|
|
133
|
+
instanceStatus.detail =
|
|
134
|
+
resolution.peerTargets.length > 0
|
|
135
|
+
? `loaded on ${target.id}; also loaded on ${resolution.peerTargets.join(", ")}`
|
|
136
|
+
: `loaded on ${target.id}`;
|
|
137
|
+
}
|
|
138
|
+
if (model.loadedInstances.length === 0) {
|
|
139
|
+
ids.push(model.key);
|
|
140
|
+
const keyStatus = modelStates[model.key];
|
|
141
|
+
if (keyStatus) keyStatus.detail = "not loaded (LM Studio will load it on first use)";
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
const selected = resolveModel(models, configuredModel(target));
|
|
145
|
+
const result: ProbeResult = {
|
|
146
|
+
ok: true,
|
|
147
|
+
models: ids,
|
|
148
|
+
modelCapabilities,
|
|
149
|
+
modelStates,
|
|
150
|
+
serverVersion:
|
|
151
|
+
catalog.tier === "0.4+"
|
|
152
|
+
? "LM Studio API 0.4+"
|
|
153
|
+
: catalog.tier === "0.3.x"
|
|
154
|
+
? "LM Studio API 0.3.x"
|
|
155
|
+
: "LM Studio OpenAI-compatible API",
|
|
156
|
+
surfaces: {
|
|
157
|
+
openaiChat: "/v1/chat/completions",
|
|
158
|
+
...(catalog.tier === "0.4+" ? { nativeV1: "/api/v1/models" } : {}),
|
|
159
|
+
...(catalog.tier === "0.3.x" ? { nativeV0: "/api/v0/models" } : {}),
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
if (catalog.latencyMs !== undefined) result.latencyMs = catalog.latencyMs;
|
|
163
|
+
if (selected) {
|
|
164
|
+
result.discoveredCapabilities = capabilities(selected.model, selected.instance);
|
|
165
|
+
result.capabilityModelId = configuredModel(target) ?? selected.model.key;
|
|
166
|
+
}
|
|
167
|
+
const loaded = models.flatMap((model) =>
|
|
168
|
+
model.loadedInstances.map((instance) => {
|
|
169
|
+
const context = loadedContextLength(instance);
|
|
170
|
+
return `${model.key} as ${instance.id}${context ? ` at ${context} tokens` : ""}`;
|
|
171
|
+
}),
|
|
172
|
+
);
|
|
173
|
+
result.notes = [
|
|
174
|
+
`LM Studio surface tier ${catalog.tier ?? "unknown"}`,
|
|
175
|
+
`Surfaces: ${Object.values(result.surfaces ?? {}).join(", ")}`,
|
|
176
|
+
...(loaded.length > 0 ? [`Loaded instances: ${loaded.join(", ")}`] : []),
|
|
177
|
+
];
|
|
178
|
+
return result;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export function probeResultFromV1Models(data: unknown, target: TargetDescriptor, latencyMs?: number): ProbeResult {
|
|
182
|
+
const models = parseLmStudioV1Models(data);
|
|
183
|
+
if (!models) return { ok: false, error: "LM Studio /api/v1/models response has no models array" };
|
|
184
|
+
return probeFromCatalog({ ok: true, models, tier: "0.4+", ...(latencyMs !== undefined ? { latencyMs } : {}) }, target);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const lmstudioRuntime: RuntimeDescriptor = {
|
|
188
|
+
id: "lmstudio",
|
|
189
|
+
aliases: ["lmstudio-native"],
|
|
190
|
+
displayName: "LM Studio",
|
|
191
|
+
kind: "http",
|
|
192
|
+
tier: "local-native",
|
|
193
|
+
apiFamily: "openai-completions",
|
|
194
|
+
auth: "api-key",
|
|
195
|
+
defaultCapabilities,
|
|
196
|
+
async probe(target, ctx): Promise<ProbeResult> {
|
|
197
|
+
const [greeting, catalog] = await Promise.all([greetLmStudio(target, ctx), listLmStudioModels(target, ctx)]);
|
|
198
|
+
if (!greeting.ok && catalog.tier !== "0.3.x") {
|
|
199
|
+
return {
|
|
200
|
+
ok: false,
|
|
201
|
+
...(greeting.latencyMs !== undefined ? { latencyMs: greeting.latencyMs } : {}),
|
|
202
|
+
error: `URL did not identify itself as LM Studio: ${greeting.error ?? "greeting missing"}`,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
return probeFromCatalog(catalog, target);
|
|
206
|
+
},
|
|
207
|
+
async probeModels(target: TargetDescriptor, ctx: ProbeContext): Promise<string[]> {
|
|
208
|
+
const catalog = await listLmStudioModels(target, ctx);
|
|
209
|
+
return probeFromCatalog(catalog, target).models ?? [];
|
|
210
|
+
},
|
|
211
|
+
synthesizeModel(target: TargetDescriptor, wireModelId: string, kb: KnowledgeBaseHit | null): Model<Api> {
|
|
212
|
+
const canonicalTarget = target.runtime === "lmstudio" ? target : { ...target, runtime: "lmstudio" };
|
|
213
|
+
const model = synthLocalModel({
|
|
214
|
+
target: canonicalTarget,
|
|
215
|
+
wireModelId,
|
|
216
|
+
kb,
|
|
217
|
+
defaultCapabilities,
|
|
218
|
+
apiFamily: "openai-completions",
|
|
219
|
+
provider: "lmstudio",
|
|
220
|
+
baseUrlForTarget: (url) => withV1(url.replace(/^ws:/u, "http:").replace(/^wss:/u, "https:")),
|
|
221
|
+
});
|
|
222
|
+
const metadata = (
|
|
223
|
+
model as Model<Api> & {
|
|
224
|
+
clio?: {
|
|
225
|
+
chatTemplateKwargsUnsupported?: boolean;
|
|
226
|
+
lmstudioReasoningOptions?: ReadonlyArray<string>;
|
|
227
|
+
lmstudioDefaultModel?: string;
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
).clio;
|
|
231
|
+
if (metadata) {
|
|
232
|
+
metadata.chatTemplateKwargsUnsupported = true;
|
|
233
|
+
if (target.defaultModel) metadata.lmstudioDefaultModel = target.defaultModel;
|
|
234
|
+
const options = reasoningOptionsByTargetModel.get(reasoningOptionsKey(canonicalTarget, wireModelId));
|
|
235
|
+
if (options) metadata.lmstudioReasoningOptions = options;
|
|
236
|
+
}
|
|
237
|
+
return model;
|
|
238
|
+
},
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
export default lmstudioRuntime;
|
|
@@ -55,7 +55,7 @@ const SUMMARY_BY_RUNTIME_ID: Readonly<Record<string, string>> = {
|
|
|
55
55
|
"openai-codex": "ChatGPT Plus/Pro via Codex OAuth",
|
|
56
56
|
openrouter: "OpenRouter API",
|
|
57
57
|
"ollama-native": "Ollama native API",
|
|
58
|
-
|
|
58
|
+
lmstudio: "LM Studio chat over OpenAI-compatible REST with native REST model management",
|
|
59
59
|
llamacpp: "llama.cpp server (auto-detect surface)",
|
|
60
60
|
"anthropic-compat": "Generic Anthropic-compatible REST",
|
|
61
61
|
"openai-compat": "Generic OpenAI-compatible REST",
|
|
@@ -151,7 +151,7 @@ export function defaultModelForRuntime(runtimeId: string): string | undefined {
|
|
|
151
151
|
* about which ids matter.
|
|
152
152
|
*/
|
|
153
153
|
export function describeRuntimeModels(entry: ProviderSupportEntry, sample: number): string {
|
|
154
|
-
if (entry.modelSource === "catalog") return `${entry.modelHints.length} in
|
|
154
|
+
if (entry.modelSource === "catalog") return `${entry.modelHints.length} in catalog`;
|
|
155
155
|
if (entry.modelHints.length === 0) return "-";
|
|
156
156
|
return entry.modelHints.slice(0, sample).join(", ");
|
|
157
157
|
}
|
|
@@ -206,7 +206,10 @@ export function configuredTargetsForRuntime(
|
|
|
206
206
|
settings: Readonly<ClioSettings>,
|
|
207
207
|
runtimeId: string,
|
|
208
208
|
): ReadonlyArray<TargetDescriptor> {
|
|
209
|
-
|
|
209
|
+
const canonical = getRuntimeIfRegistered(runtimeId)?.id ?? runtimeId;
|
|
210
|
+
return settings.targets.filter(
|
|
211
|
+
(target) => (getRuntimeIfRegistered(target.runtime)?.id ?? target.runtime) === canonical,
|
|
212
|
+
);
|
|
210
213
|
}
|
|
211
214
|
|
|
212
215
|
export function resolveProviderReference(
|
|
@@ -6,11 +6,9 @@
|
|
|
6
6
|
* into a typed shape that flows through `model.clio.quirks` at synth time.
|
|
7
7
|
*
|
|
8
8
|
* Field naming follows the Hugging Face / model-card terminology so the YAML
|
|
9
|
-
* can be authored against the source-of-truth card.
|
|
10
|
-
* these into
|
|
11
|
-
* -
|
|
12
|
-
* `repeatPenalty`, `llamaKCacheQuantizationType`.
|
|
13
|
-
* - LM Studio's OpenAI-compat surface accepts `top_p`, `top_k`, `min_p`,
|
|
9
|
+
* can be authored against the source-of-truth card. The OpenAI adapter
|
|
10
|
+
* translates these into pi-ai sampling parameters at consumption:
|
|
11
|
+
* - OpenAI-compatible surfaces accept `top_p`, `top_k`, `min_p`,
|
|
14
12
|
* `repeat_penalty`.
|
|
15
13
|
*/
|
|
16
14
|
|
|
@@ -81,7 +79,7 @@ function isRecord(value: unknown): value is Record<string, unknown> {
|
|
|
81
79
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
82
80
|
}
|
|
83
81
|
|
|
84
|
-
|
|
82
|
+
function asKvCacheQuant(value: unknown): KvCacheQuant | false | undefined {
|
|
85
83
|
if (value === false) return false;
|
|
86
84
|
if (typeof value !== "string") return undefined;
|
|
87
85
|
return (KV_CACHE_QUANTS as ReadonlyArray<string>).includes(value) ? (value as KvCacheQuant) : undefined;
|
|
@@ -122,9 +120,9 @@ function extractSamplingProfile(raw: unknown): SamplingProfile | undefined {
|
|
|
122
120
|
if (topK !== undefined) out.topK = topK;
|
|
123
121
|
const minP = asPositive(raw.minP);
|
|
124
122
|
if (minP !== undefined) out.minP = minP;
|
|
125
|
-
// Catalog YAML may use either `repeatPenalty` (
|
|
126
|
-
// `repetitionPenalty` (HF model-card term); accept both,
|
|
127
|
-
// spelling when both are present.
|
|
123
|
+
// Catalog YAML may use either `repeatPenalty` (engine field name) or
|
|
124
|
+
// `repetitionPenalty` (HF model-card term); accept both, preferring the
|
|
125
|
+
// engine spelling when both are present.
|
|
128
126
|
const rp = asPenalty(raw.repeatPenalty) ?? asPenalty(raw.repetitionPenalty);
|
|
129
127
|
if (rp !== undefined) out.repeatPenalty = rp;
|
|
130
128
|
const pp = asPenalty(raw.presencePenalty);
|
|
@@ -17,7 +17,6 @@ export type RuntimeApiFamily =
|
|
|
17
17
|
| "bedrock-converse-stream"
|
|
18
18
|
| "google-generative-ai"
|
|
19
19
|
| "google-vertex"
|
|
20
|
-
| "lmstudio-native"
|
|
21
20
|
| "mistral-conversations"
|
|
22
21
|
| "ollama-native"
|
|
23
22
|
| "rerank-http"
|
|
@@ -53,6 +52,8 @@ export interface ProbeSurfaceMap {
|
|
|
53
52
|
rerank?: string;
|
|
54
53
|
completion?: string;
|
|
55
54
|
infill?: string;
|
|
55
|
+
nativeV1?: string;
|
|
56
|
+
nativeV0?: string;
|
|
56
57
|
}
|
|
57
58
|
|
|
58
59
|
export type ProbeModelLoadState = "loaded" | "loading" | "unloaded" | "failed" | "unknown";
|
|
@@ -76,6 +77,14 @@ export interface ProbeModelStatus {
|
|
|
76
77
|
*/
|
|
77
78
|
sizeVramBytes?: number;
|
|
78
79
|
sizeBytes?: number;
|
|
80
|
+
/** Downloaded model key that owns this configured id or loaded instance. */
|
|
81
|
+
key?: string;
|
|
82
|
+
/** Loaded instance id selected for this model, when one exists. */
|
|
83
|
+
instanceId?: string;
|
|
84
|
+
/** Load configuration echoed by LM Studio for the selected instance. */
|
|
85
|
+
loadConfig?: Readonly<Record<string, unknown>>;
|
|
86
|
+
/** Reasoning levels accepted by this model after LM Studio option clamping. */
|
|
87
|
+
reasoningLevels?: ReadonlyArray<"off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">;
|
|
79
88
|
}
|
|
80
89
|
|
|
81
90
|
export interface ProbeResult {
|
|
@@ -115,6 +124,8 @@ export interface ReasoningProbeResult {
|
|
|
115
124
|
|
|
116
125
|
export interface RuntimeDescriptor {
|
|
117
126
|
id: string;
|
|
127
|
+
/** Deprecated or compatibility ids that resolve to this descriptor object. */
|
|
128
|
+
aliases?: ReadonlyArray<string>;
|
|
118
129
|
displayName: string;
|
|
119
130
|
kind: RuntimeKind;
|
|
120
131
|
tier?: RuntimeTier;
|
|
@@ -18,6 +18,27 @@ export interface TargetPricing {
|
|
|
18
18
|
// unrenamed by rebrand decision so existing `lifecycle:` lines keep working.
|
|
19
19
|
export type TargetLifecycle = "user-managed" | "clio-managed";
|
|
20
20
|
|
|
21
|
+
export interface LmStudioLoadSettings {
|
|
22
|
+
contextLength?: number;
|
|
23
|
+
flashAttention?: boolean;
|
|
24
|
+
evalBatchSize?: number;
|
|
25
|
+
numExperts?: number;
|
|
26
|
+
offloadKvCacheToGpu?: boolean;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export type LmStudioReasoningSetting = "auto" | "off" | "on" | "low" | "medium" | "high";
|
|
30
|
+
|
|
31
|
+
export interface LmStudioRequestSettings {
|
|
32
|
+
ttlSeconds?: number;
|
|
33
|
+
draftModel?: string;
|
|
34
|
+
reasoning?: LmStudioReasoningSetting;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface LmStudioTargetSettings {
|
|
38
|
+
load?: LmStudioLoadSettings;
|
|
39
|
+
request?: LmStudioRequestSettings;
|
|
40
|
+
}
|
|
41
|
+
|
|
21
42
|
/**
|
|
22
43
|
* Persisted target specification from settings.yaml (`targets:`). It binds a
|
|
23
44
|
* user-facing target id to a RuntimeDescriptor id, target URL/auth metadata,
|
|
@@ -35,4 +56,5 @@ export interface TargetDescriptor {
|
|
|
35
56
|
lifecycle?: TargetLifecycle;
|
|
36
57
|
gateway?: boolean;
|
|
37
58
|
pricing?: TargetPricing;
|
|
59
|
+
lmstudio?: LmStudioTargetSettings;
|
|
38
60
|
}
|
|
@@ -19,7 +19,6 @@ export interface ResourcesContract extends DomainContract {
|
|
|
19
19
|
): { text: string; pendingSkillRequests: PendingSkillRequest[] };
|
|
20
20
|
prompts(cwd?: string): ResourceList<PromptTemplate>;
|
|
21
21
|
expandPromptTemplate(text: string, cwd?: string): PromptTemplateExpansion;
|
|
22
|
-
themes(): ResourceList<never>;
|
|
23
22
|
resolvePath(value: string, cwd?: string): string;
|
|
24
23
|
reload(): Promise<void>;
|
|
25
24
|
}
|
|
@@ -10,6 +10,7 @@ export function createResourcesBundle(
|
|
|
10
10
|
const config = (): ConfigContract | undefined => context.getContract<ConfigContract>("config");
|
|
11
11
|
const loader = createResourcesLoader({
|
|
12
12
|
...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
|
|
13
|
+
...(options.reservedPromptNames !== undefined ? { reservedPromptNames: options.reservedPromptNames } : {}),
|
|
13
14
|
skills: () => ({
|
|
14
15
|
...skillOptions(config()?.get().skills.trustProjectCompatRoots === true, options),
|
|
15
16
|
}),
|
|
@@ -35,9 +36,6 @@ export function createResourcesBundle(
|
|
|
35
36
|
expandPromptTemplate(text, cwd) {
|
|
36
37
|
return loader.expandPromptTemplate(text, cwd);
|
|
37
38
|
},
|
|
38
|
-
themes() {
|
|
39
|
-
return loader.themes();
|
|
40
|
-
},
|
|
41
39
|
resolvePath(value, cwd) {
|
|
42
40
|
return loader.resolvePath(value, cwd);
|
|
43
41
|
},
|
|
@@ -25,6 +25,8 @@ export interface ResourceList<T> {
|
|
|
25
25
|
|
|
26
26
|
export interface ResourceLoaderOptions {
|
|
27
27
|
cwd?: string;
|
|
28
|
+
/** Slash-command names prompt templates may not claim. */
|
|
29
|
+
reservedPromptNames?: ReadonlySet<string>;
|
|
28
30
|
skills?: () => Pick<LoadSkillsInput, "trustProjectCompatRoots" | "disableDiscovery" | "explicitSkillPaths">;
|
|
29
31
|
}
|
|
30
32
|
|
|
@@ -38,7 +40,6 @@ export interface ResourcesLoader {
|
|
|
38
40
|
): { text: string; pendingSkillRequests: PendingSkillRequest[] };
|
|
39
41
|
prompts(cwd?: string): ResourceList<PromptTemplate>;
|
|
40
42
|
expandPromptTemplate(text: string, cwd?: string): PromptTemplateExpansion;
|
|
41
|
-
themes(): ResourceList<never>;
|
|
42
43
|
resolvePath(value: string, cwd?: string): string;
|
|
43
44
|
reload(): Promise<void>;
|
|
44
45
|
}
|
|
@@ -53,6 +54,7 @@ export function createResourcesLoader(options: ResourceLoaderOptions = {}): Reso
|
|
|
53
54
|
// trust decision whichever kind is read out of it.
|
|
54
55
|
const promptOptions = (cwd: string): LoadPromptTemplatesInput => ({
|
|
55
56
|
cwd,
|
|
57
|
+
...(options.reservedPromptNames !== undefined ? { reservedNames: options.reservedPromptNames } : {}),
|
|
56
58
|
...(skillOptions().trustProjectCompatRoots !== undefined
|
|
57
59
|
? { trustProjectCompatRoots: skillOptions().trustProjectCompatRoots === true }
|
|
58
60
|
: {}),
|
|
@@ -73,9 +75,6 @@ export function createResourcesLoader(options: ResourceLoaderOptions = {}): Reso
|
|
|
73
75
|
expandPromptTemplate(text, cwd = defaultCwd) {
|
|
74
76
|
return expandPromptTemplateInput(text, loadPromptTemplates(promptOptions(cwd)));
|
|
75
77
|
},
|
|
76
|
-
themes() {
|
|
77
|
-
return { items: [], diagnostics: [] };
|
|
78
|
-
},
|
|
79
78
|
resolvePath(value, cwd = defaultCwd) {
|
|
80
79
|
return expandConfigPath(value, { cwd });
|
|
81
80
|
},
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
3
|
import path from "node:path";
|
|
4
|
+
import { parseCommandArgs, substituteArgs } from "../../../engine/prompt-templates.js";
|
|
4
5
|
import { INTEROP_AGENT_KINDS } from "../../interop/registry.js";
|
|
5
6
|
import {
|
|
6
7
|
type ResourceCandidate,
|
|
@@ -18,7 +19,6 @@ import {
|
|
|
18
19
|
stringField,
|
|
19
20
|
} from "../common-loader.js";
|
|
20
21
|
import { projectCompatTrusted } from "../skills/loader.js";
|
|
21
|
-
import { parseCommandArgs, substituteArgs } from "./substitute.js";
|
|
22
22
|
|
|
23
23
|
export interface PromptTemplate {
|
|
24
24
|
name: string;
|
|
@@ -51,6 +51,8 @@ export interface LoadPromptTemplatesInput {
|
|
|
51
51
|
home?: string;
|
|
52
52
|
/** Opt in to model-visible project compatibility roots (.claude/commands, .codex/prompts). */
|
|
53
53
|
trustProjectCompatRoots?: boolean;
|
|
54
|
+
/** Names owned by another command registry and unavailable to templates. */
|
|
55
|
+
reservedNames?: ReadonlySet<string>;
|
|
54
56
|
}
|
|
55
57
|
|
|
56
58
|
export type PromptTemplateExpansion =
|
|
@@ -189,8 +191,20 @@ export function loadPromptTemplates(input: LoadPromptTemplatesInput = {}): Promp
|
|
|
189
191
|
const diagnostics: ResourceDiagnostic[] = [];
|
|
190
192
|
const candidates = roots.flatMap((root) => loadPromptRoot(root, diagnostics));
|
|
191
193
|
const resolved = resolveResourceCollisions(candidates);
|
|
194
|
+
const items: PromptTemplate[] = [];
|
|
195
|
+
for (const template of resolved.winners) {
|
|
196
|
+
if (input.reservedNames?.has(template.name) === true) {
|
|
197
|
+
diagnostics.push({
|
|
198
|
+
type: "collision",
|
|
199
|
+
message: `prompt template /${template.name} conflicts with the built-in slash command /${template.name} and was ignored`,
|
|
200
|
+
path: template.filePath,
|
|
201
|
+
});
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
items.push(template);
|
|
205
|
+
}
|
|
192
206
|
return {
|
|
193
|
-
items:
|
|
207
|
+
items: items.sort((a, b) => a.name.localeCompare(b.name)),
|
|
194
208
|
diagnostics: [...diagnostics, ...resolved.diagnostics],
|
|
195
209
|
};
|
|
196
210
|
}
|
|
@@ -1,65 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
const args: string[] = [];
|
|
3
|
-
let current = "";
|
|
4
|
-
let hasToken = false;
|
|
5
|
-
let quote: "'" | '"' | null = null;
|
|
6
|
-
|
|
7
|
-
const push = (): void => {
|
|
8
|
-
if (!hasToken) return;
|
|
9
|
-
args.push(current);
|
|
10
|
-
current = "";
|
|
11
|
-
hasToken = false;
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
for (let i = 0; i < input.length; i += 1) {
|
|
15
|
-
const ch = input[i];
|
|
16
|
-
if (!ch) continue;
|
|
17
|
-
if (quote) {
|
|
18
|
-
if (ch === quote) {
|
|
19
|
-
quote = null;
|
|
20
|
-
} else {
|
|
21
|
-
current += ch;
|
|
22
|
-
}
|
|
23
|
-
continue;
|
|
24
|
-
}
|
|
25
|
-
if (ch === "'" || ch === `"`) {
|
|
26
|
-
quote = ch;
|
|
27
|
-
hasToken = true;
|
|
28
|
-
continue;
|
|
29
|
-
}
|
|
30
|
-
if (/\s/.test(ch)) {
|
|
31
|
-
push();
|
|
32
|
-
continue;
|
|
33
|
-
}
|
|
34
|
-
current += ch;
|
|
35
|
-
hasToken = true;
|
|
36
|
-
}
|
|
37
|
-
push();
|
|
38
|
-
|
|
39
|
-
return args;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function sliceArgs(args: ReadonlyArray<string>, startText: string, lengthText: string | undefined): string {
|
|
43
|
-
const start = Number.parseInt(startText, 10);
|
|
44
|
-
if (!Number.isFinite(start) || start <= 0) return "";
|
|
45
|
-
const zeroBased = start - 1;
|
|
46
|
-
if (lengthText === undefined) return args.slice(zeroBased).join(" ");
|
|
47
|
-
const length = Number.parseInt(lengthText, 10);
|
|
48
|
-
if (!Number.isFinite(length) || length <= 0) return "";
|
|
49
|
-
return args.slice(zeroBased, zeroBased + length).join(" ");
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export function substituteArgs(content: string, args: ReadonlyArray<string>): string {
|
|
53
|
-
const allArgs = args.join(" ");
|
|
54
|
-
return content
|
|
55
|
-
.replace(/\$\{@:(\d+)(?::(\d+))?\}/g, (_match, start: string, length: string | undefined) =>
|
|
56
|
-
sliceArgs(args, start, length),
|
|
57
|
-
)
|
|
58
|
-
.replace(/\$ARGUMENTS/g, allArgs)
|
|
59
|
-
.replace(/\$@/g, allArgs)
|
|
60
|
-
.replace(/\$(\d+)/g, (_match, indexText: string) => {
|
|
61
|
-
const index = Number.parseInt(indexText, 10);
|
|
62
|
-
if (!Number.isFinite(index) || index <= 0) return "";
|
|
63
|
-
return args[index - 1] ?? "";
|
|
64
|
-
});
|
|
65
|
-
}
|
|
1
|
+
export { parseCommandArgs, substituteArgs } from "../../../engine/prompt-templates.js";
|
|
@@ -117,6 +117,16 @@ export function parseSkillSourceSpec(source: string): SkillSourceSpec | null {
|
|
|
117
117
|
return { kind: "local", path: path.resolve(expanded), original: trimmed };
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
+
/**
|
|
121
|
+
* Whether this process is running inside a dispatched worker rather than the
|
|
122
|
+
* operator's own interactive session. `worker/entry.ts` sets this on itself at
|
|
123
|
+
* launch, so it rides the environment into every bash-tool child a worker
|
|
124
|
+
* spawns, including a `clio-coder skills install` a worker runs directly.
|
|
125
|
+
*/
|
|
126
|
+
function installingAsWorker(): boolean {
|
|
127
|
+
return process.env.CLIO_CODER_WORKER_RUN === "1";
|
|
128
|
+
}
|
|
129
|
+
|
|
120
130
|
function yamlQuote(value: string): string {
|
|
121
131
|
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
122
132
|
}
|
|
@@ -126,6 +136,8 @@ interface ProvenanceFields {
|
|
|
126
136
|
installedAt: string;
|
|
127
137
|
updatedAt?: string;
|
|
128
138
|
installedHash: string;
|
|
139
|
+
/** Who ran the install: a dispatched worker, or (unmarked) the operator. */
|
|
140
|
+
installedBy?: "worker";
|
|
129
141
|
}
|
|
130
142
|
|
|
131
143
|
/**
|
|
@@ -152,6 +164,7 @@ function injectProvenanceFrontmatter(rawText: string, fields: ProvenanceFields):
|
|
|
152
164
|
`installed-hash: ${yamlQuote(fields.installedHash)}`,
|
|
153
165
|
// Audit is a human decision; installs always land unreviewed.
|
|
154
166
|
"audit: unknown",
|
|
167
|
+
...(fields.installedBy ? [`installed-by: ${yamlQuote(fields.installedBy)}`] : []),
|
|
155
168
|
];
|
|
156
169
|
const clioIndex = kept.findIndex((line) => /^clio:/.test(line));
|
|
157
170
|
if (clioIndex >= 0 && !/^clio:\s*$/.test(kept[clioIndex] as string)) {
|
|
@@ -317,6 +330,7 @@ export function installSkillFromSource(input: InstallSkillInput): InstallSkillRe
|
|
|
317
330
|
sourceUrl: spec.original,
|
|
318
331
|
installedAt: new Date().toISOString(),
|
|
319
332
|
installedHash,
|
|
333
|
+
...(installingAsWorker() ? { installedBy: "worker" as const } : {}),
|
|
320
334
|
}),
|
|
321
335
|
"utf8",
|
|
322
336
|
);
|
|
@@ -384,6 +398,9 @@ function updateOne(skill: Skill, force: boolean): SkillUpdateReport {
|
|
|
384
398
|
installedAt: skill.provenance?.installedAt ?? new Date().toISOString(),
|
|
385
399
|
updatedAt: new Date().toISOString(),
|
|
386
400
|
installedHash: remoteHash,
|
|
401
|
+
// Who installed a skill is set once; an update, worker- or
|
|
402
|
+
// operator-run, does not change who put it there originally.
|
|
403
|
+
...(skill.provenance?.installedBy ? { installedBy: skill.provenance.installedBy } : {}),
|
|
387
404
|
}),
|
|
388
405
|
"utf8",
|
|
389
406
|
);
|
|
@@ -67,6 +67,8 @@ export interface SkillProvenance {
|
|
|
67
67
|
/** Content hash of the upstream SKILL.md at install time, provenance-stripped. */
|
|
68
68
|
installedHash?: string;
|
|
69
69
|
audit?: "pass" | "warn" | "fail" | "unknown";
|
|
70
|
+
/** Who ran the install: a dispatched worker, or (unmarked) the operator. */
|
|
71
|
+
installedBy?: "worker";
|
|
70
72
|
}
|
|
71
73
|
|
|
72
74
|
export interface Skill {
|
|
@@ -479,7 +481,18 @@ function extractProvenance(frontmatter: Record<string, unknown>): SkillProvenanc
|
|
|
479
481
|
const auditRaw = field("audit");
|
|
480
482
|
const audit =
|
|
481
483
|
auditRaw === "pass" || auditRaw === "warn" || auditRaw === "fail" || auditRaw === "unknown" ? auditRaw : undefined;
|
|
482
|
-
|
|
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
|
+
)
|
|
483
496
|
return undefined;
|
|
484
497
|
return {
|
|
485
498
|
...(installUrl ? { installUrl } : {}),
|
|
@@ -489,6 +502,7 @@ function extractProvenance(frontmatter: Record<string, unknown>): SkillProvenanc
|
|
|
489
502
|
...(updatedAt ? { updatedAt } : {}),
|
|
490
503
|
...(installedHash ? { installedHash } : {}),
|
|
491
504
|
...(audit ? { audit } : {}),
|
|
505
|
+
...(installedBy ? { installedBy } : {}),
|
|
492
506
|
};
|
|
493
507
|
}
|
|
494
508
|
|
|
@@ -881,15 +895,8 @@ export function modelVisibleSkills(skills: ReadonlyArray<Skill>): Skill[] {
|
|
|
881
895
|
|
|
882
896
|
export function parseSkillCommand(input: string): { name: string; args: string } | null {
|
|
883
897
|
const trimmed = input.trim();
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
: trimmed.startsWith("/skills:")
|
|
887
|
-
? "/skills:"
|
|
888
|
-
: trimmed.startsWith("/skill ")
|
|
889
|
-
? "/skill "
|
|
890
|
-
: null;
|
|
891
|
-
if (!prefix) return null;
|
|
892
|
-
const rest = trimmed.slice(prefix.length).trim();
|
|
898
|
+
if (!trimmed.startsWith("/skill ")) return null;
|
|
899
|
+
const rest = trimmed.slice("/skill ".length).trim();
|
|
893
900
|
const separator = rest.search(/\s/);
|
|
894
901
|
const name = separator === -1 ? rest : rest.slice(0, separator);
|
|
895
902
|
if (name.length === 0) return null;
|