@iowarp/clio-coder 0.3.1 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +233 -373
- package/CONTRIBUTING.md +23 -23
- package/README.md +284 -613
- package/dist/{acp-FPR54DGL.js → acp-P2AQILE2.js} +43 -53
- package/dist/{agents-OGPIHPJH.js → agents-72W3BI7I.js} +43 -26
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-IC3K6NIZ.js → auth-5TWEIYDN.js} +20 -12
- package/dist/chunk-2DJ2KNFG.js +2095 -0
- package/dist/{chunk-IS3ONKU3.js → chunk-2IR2NMPA.js} +6 -4
- package/dist/chunk-2SFS6XQE.js +122 -0
- package/dist/{chunk-PV4JUBVJ.js → chunk-2TLUCQVG.js} +40 -21
- package/dist/chunk-2VTFPG5O.js +48 -0
- package/dist/chunk-4BJ5BYCE.js +61 -0
- package/dist/{chunk-474KN5II.js → chunk-4BPJXDWC.js} +111 -181
- package/dist/chunk-4VP4KH3K.js +962 -0
- package/dist/chunk-4XUGQOHA.js +797 -0
- package/dist/chunk-4ZG3XFUR.js +77 -0
- package/dist/chunk-5B2AEOW5.js +5407 -0
- package/dist/{chunk-K2ITRMHZ.js → chunk-5TSRNF4G.js} +6 -138
- package/dist/{chunk-4QKXUHSR.js → chunk-5UFT4SUX.js} +70 -20
- package/dist/{chunk-OLBBMFRD.js → chunk-5UUP6MWO.js} +24 -62
- package/dist/chunk-65DEGPJ6.js +52 -0
- package/dist/chunk-6EJMN2Y3.js +17 -0
- package/dist/chunk-6N5PTWMY.js +136 -0
- package/dist/chunk-6SGHMWE3.js +277 -0
- package/dist/chunk-6XLNIQDB.js +27 -0
- package/dist/chunk-7CR24IG7.js +242 -0
- package/dist/chunk-7MNJORFF.js +22 -0
- package/dist/{chunk-KY56HMHH.js → chunk-A3CYT5EX.js} +125 -31
- package/dist/chunk-AGYYIBLL.js +1069 -0
- package/dist/{chunk-GB6QRBXN.js → chunk-APJ265NV.js} +54 -1187
- package/dist/{chunk-673JJUWJ.js → chunk-BMEMKKIT.js} +2 -2
- package/dist/chunk-CBCAPZAA.js +229 -0
- package/dist/chunk-CMZWFGD2.js +352 -0
- package/dist/chunk-COU2UHX6.js +400 -0
- package/dist/chunk-DSELYM6W.js +1077 -0
- package/dist/chunk-DUYJ5IO6.js +644 -0
- package/dist/chunk-ECH6PKUQ.js +39 -0
- package/dist/chunk-ED4KHGC3.js +143 -0
- package/dist/chunk-EKMEHE4H.js +340 -0
- package/dist/chunk-FCSXB6T2.js +338 -0
- package/dist/chunk-FJ3H4MN5.js +48 -0
- package/dist/{chunk-RPTR2H26.js → chunk-FNTMWMX5.js} +21 -15
- package/dist/chunk-FQ4SKYE4.js +29 -0
- package/dist/chunk-G4BMMOKF.js +182 -0
- package/dist/{chunk-ZPY3JZ5E.js → chunk-GGXXDWE4.js} +183 -1233
- package/dist/chunk-HC4CLZ2Y.js +68 -0
- package/dist/{chunk-LU4TK2PR.js → chunk-HFSBBKSQ.js} +5 -56
- package/dist/{chunk-PIUMUEMV.js → chunk-HKIYEGME.js} +10 -6
- package/dist/chunk-I4HZDVNP.js +73 -0
- package/dist/chunk-IKCO5N3L.js +162 -0
- package/dist/chunk-IR4CFBFN.js +56 -0
- package/dist/{chunk-R5KLMSBV.js → chunk-J5Q24KAG.js} +2 -2
- package/dist/chunk-J7CWMCQD.js +255 -0
- package/dist/{chunk-K5XEMXTI.js → chunk-JVCV3ICN.js} +1 -1
- package/dist/chunk-KZWTDYJF.js +217 -0
- package/dist/chunk-LBMZMYH2.js +285 -0
- package/dist/{chunk-G34LV2PF.js → chunk-LM5TQCJZ.js} +84 -170
- package/dist/chunk-LW6DSM3M.js +5135 -0
- package/dist/chunk-LWLEKMDQ.js +3482 -0
- package/dist/{chunk-H6F6BYOH.js → chunk-LZSJBIVT.js} +7003 -7434
- package/dist/{chunk-HQQID6OA.js → chunk-M6SHUN7Q.js} +5 -5
- package/dist/{chunk-FST4FYJB.js → chunk-MFFY33HR.js} +99 -140
- package/dist/{chunk-BSU2YIWB.js → chunk-MVVUPGPW.js} +131 -136
- package/dist/chunk-OAO4GE4M.js +619 -0
- package/dist/{chunk-Q3RUPKEJ.js → chunk-OC7FIQPC.js} +58 -189
- package/dist/chunk-OKGUZO2U.js +34 -0
- package/dist/{chunk-GAEBEQVI.js → chunk-OOJYHWRB.js} +32 -346
- package/dist/{chunk-Q5WJOSJ7.js → chunk-OQ33BKR3.js} +2 -1
- package/dist/chunk-OQE5J4C6.js +73 -0
- package/dist/{chunk-KKNLWXI6.js → chunk-ORBHGJC5.js} +8 -8
- package/dist/{chunk-MAR7Y6HW.js → chunk-PAJK6MAQ.js} +23 -16
- package/dist/{chunk-M5T5VO65.js → chunk-PIWWS5BL.js} +837 -635
- package/dist/chunk-POHLU5DW.js +1186 -0
- package/dist/chunk-QKMUKYO7.js +4961 -0
- package/dist/chunk-SRDMMSEP.js +16405 -0
- package/dist/chunk-SST6Z5JA.js +80 -0
- package/dist/chunk-STBPMHSX.js +2456 -0
- package/dist/chunk-T6YILFSB.js +80 -0
- package/dist/chunk-TZK7PACC.js +174 -0
- package/dist/chunk-TZTZS7QK.js +227 -0
- package/dist/{chunk-ASND7OZK.js → chunk-UFIIWP2H.js} +13 -13
- package/dist/chunk-UOV2BYIW.js +107 -0
- package/dist/{chunk-PFEFKVGL.js → chunk-V6RTAOC2.js} +13 -11
- package/dist/chunk-VAKQQHWR.js +434 -0
- package/dist/chunk-VG7TBQIY.js +128 -0
- package/dist/chunk-VJWL6YS5.js +244 -0
- package/dist/{chunk-EYOKLTMF.js → chunk-VPAYEGVX.js} +17 -3
- package/dist/chunk-WEH5XRJQ.js +32 -0
- package/dist/chunk-X4RCMKVQ.js +641 -0
- package/dist/{chunk-TEKV33Q5.js → chunk-X6IAEBZR.js} +65 -33
- package/dist/chunk-XBXAASKX.js +18 -0
- package/dist/chunk-XN3L4EYL.js +46 -0
- package/dist/{chunk-RDLVBZEO.js → chunk-YCWGATWI.js} +6 -4
- package/dist/chunk-YHZX5GEU.js +193 -0
- package/dist/chunk-YXLYO42X.js +91 -0
- package/dist/{chunk-NMOX6HFD.js → chunk-ZDOOVTXZ.js} +29 -77
- package/dist/chunk-ZI647VB5.js +37 -0
- package/dist/{chunk-C4PTHK7P.js → chunk-ZWLZP4ZT.js} +5 -5
- package/dist/chunk-ZWMF7253.js +1882 -0
- package/dist/cli/index.js +62 -54
- package/dist/clio-JOU4FXVA.js +25 -0
- package/dist/code-nav-7AX6FYE6.js +600 -0
- package/dist/codewiki/build-worker.js +66 -0
- package/dist/compile-cache-CVJMMODC.js +18 -0
- package/dist/{components-DMAOEKFB.js → components-KELWS457.js} +11 -6
- package/dist/{config-IRUQ7SE4.js → config-XCDVKR23.js} +92 -55
- package/dist/configure-4GAP54ZW.js +42 -0
- package/dist/{context-5RADCKTR.js → context-4UOGGLQ5.js} +71 -35
- package/dist/context-5VKGUVJJ.js +866 -0
- package/dist/{context-3KWFLHJG.js → context-77FM5DV5.js} +15 -13
- package/dist/{context-clear-7TSNPAAI.js → context-clear-XXJRLCJJ.js} +54 -28
- package/dist/{context-index-W4RLWOQH.js → context-index-BZ4UYMTC.js} +30 -24
- package/dist/dispatch-runner-QPRDDBDX.js +1997 -0
- package/dist/{docs-5AWSPS37.js → docs-2C2LTVT2.js} +23 -10
- package/dist/{doctor-UC5NAJYQ.js → doctor-HR46URBJ.js} +27 -17
- package/dist/{eval-U6TJHRLX.js → eval-XSSNATB4.js} +29 -16
- package/dist/{evidence-YEGUW4L3.js → evidence-6HG2PY2B.js} +46 -26
- package/dist/{evolve-TXARCTPG.js → evolve-K7YU3NCY.js} +45 -25
- package/dist/{extensions-OZFJ3A3G.js → extensions-QVDOHDGJ.js} +16 -7
- package/dist/{fleet-6G3DHNYE.js → fleet-VY3HHKN6.js} +163 -54
- package/dist/{fleet-preflight-DSNT37JK.js → fleet-preflight-DDN536IT.js} +7 -4
- package/dist/{init-KZ5QTF6M.js → init-JYGXI3FK.js} +69 -32
- package/dist/{memory-73ESV5YC.js → memory-WFZMGYHX.js} +48 -27
- package/dist/{models-A4PVNWJK.js → models-I5QWSEOM.js} +39 -25
- package/dist/monitor-GE4ID3IA.js +661 -0
- package/dist/{chunk-FCIH3BIZ.js → orchestrator-EM5MC3HM.js} +15979 -12407
- package/dist/{paths-C4H6IV77.js → paths-UXLN5YYZ.js} +10 -5
- package/dist/{preload-6WVMHX3A.js → preload-P6DGH2PZ.js} +2 -2
- package/dist/{reset-BGW6OGMV.js → reset-L2FQEE3E.js} +16 -10
- package/dist/{run-YTPEYQOH.js → run-ZU3QMZPZ.js} +101 -61
- package/dist/{share-YIFFV4NQ.js → share-S5BZQC5I.js} +15 -8
- package/dist/{skills-2V6RA3OQ.js → skills-X5VXCRNQ.js} +34 -14
- package/dist/{skills-eval-S2TVJO4F.js → skills-eval-WKIHWTHR.js} +70 -34
- package/dist/steer-GGWFUJUD.js +77 -0
- package/dist/{targets-TYXLPB23.js → targets-SNCPI2NR.js} +43 -27
- package/dist/terminal-lease-BNAHVHBS.js +395 -0
- package/dist/{trace-GGOJ6Q6Z.js → trace-PNCASAXC.js} +41 -16
- package/dist/{chunk-N6F52NLF.js → tree-sitter-HGKH6LG4.js} +28 -2306
- package/dist/{uninstall-LLLT4F4W.js → uninstall-FZCQCDKC.js} +10 -5
- package/dist/{upgrade-33G2LMM5.js → upgrade-JQHHPQ4K.js} +45 -25
- package/dist/{usage-ZAFSXKKG.js → usage-OR4O5SMZ.js} +62 -31
- package/dist/verify-375KUB3Y.js +716 -0
- package/dist/web-fetch-2YHJ3KTG.js +638 -0
- package/dist/{wiki-generate-NUQCVOQ3.js → wiki-generate-UEXP2ARI.js} +74 -34
- package/dist/worker/entry.js +221 -36
- package/dist/workspace-G4ZWUIPR.js +22 -0
- package/docs/README.md +22 -17
- package/docs/acp.md +168 -16
- package/docs/alcf-provider.md +1 -1
- package/docs/architecture.md +136 -7
- package/docs/artifact-versions.md +1 -1
- package/docs/built-in-agents.md +1 -1
- package/docs/capacity-and-scheduling.md +1 -1
- package/docs/commands-and-modes.md +114 -71
- package/docs/config-knobs-audit.md +1 -3
- package/docs/configuration-and-targets.md +174 -46
- package/docs/context-engine.md +29 -6
- package/docs/development-pipeline.md +26 -1
- package/docs/dispatch-architecture-rationale.md +1 -1
- package/docs/documentation-coverage.md +2 -2
- package/docs/documentation-guide.md +1 -1
- package/docs/environment-variables.md +13 -5
- package/docs/eval-runner.md +1 -1
- package/docs/evals-internal.md +1 -1
- package/docs/evidence-and-memory.md +6 -2
- package/docs/evolution.md +2 -2
- package/docs/exit-codes-and-output.md +15 -9
- package/docs/extensions-and-sharing.md +9 -9
- package/docs/fleet-dispatch.md +7 -5
- package/docs/git-commit-provenance.md +120 -0
- package/docs/glossary.md +1 -1
- package/docs/installation-and-lifecycle.md +34 -27
- package/docs/middleware-and-components.md +1 -1
- package/docs/model-catalog.md +45 -14
- package/docs/observability.md +8 -5
- package/docs/performance-methodology.md +491 -0
- package/docs/pi-boundary.md +72 -0
- package/docs/proactive-memory.md +3 -3
- package/docs/prompt-envelope-and-tools.md +24 -3
- package/docs/provider-adapter-cookbook.md +57 -4
- package/docs/release-cut-checklist.md +129 -115
- package/docs/safety-model.md +9 -5
- package/docs/scientific-validation.md +3 -3
- package/docs/session-lifecycle.md +55 -12
- package/docs/skills-marketplace.md +12 -8
- package/docs/time-conventions.md +1 -1
- package/docs/tool-usage.md +3 -3
- package/docs/trace-store.md +1 -1
- package/docs/troubleshooting.md +10 -7
- package/docs/tui-design.md +47 -10
- package/docs/worker-dispatch-mechanics.md +1 -1
- package/package.json +19 -22
- package/skills/coding/ast-grep/SKILL.md +136 -0
- package/skills/coding/ast-grep/evals.md +56 -0
- package/skills/coding/ast-grep/references/rule_reference.md +297 -0
- package/skills/coding/coding-standards/SKILL.md +113 -0
- package/skills/coding/coding-standards/evals.md +34 -0
- package/skills/coding/prototype/SKILL.md +86 -0
- package/skills/coding/prototype/evals.md +42 -0
- package/skills/coding/prototype/references/LOGIC.md +67 -0
- package/skills/coding/prototype/references/UI.md +112 -0
- package/skills/coding/tdd/SKILL.md +101 -0
- package/skills/coding/tdd/evals.md +41 -0
- package/skills/coding/tdd/references/mocking.md +59 -0
- package/skills/coding/tdd/references/tests.md +77 -0
- package/skills/context/context-handoff/SKILL.md +126 -0
- package/skills/context/context-handoff/evals.md +57 -0
- package/skills/context/context-handoff/scripts/new-handoff.sh +26 -0
- package/skills/context/context-prime/SKILL.md +95 -0
- package/skills/context/context-prime/evals.md +54 -0
- package/skills/meta/clio-dev/SKILL.md +91 -0
- package/skills/meta/clio-dev/evals.md +45 -0
- package/skills/meta/clio-test/SKILL.md +130 -0
- package/skills/meta/clio-test/evals.md +43 -0
- package/skills/meta/clio-test/references/harness.md +97 -0
- package/skills/meta/clio-test/references/test-map.md +59 -0
- package/skills/meta/credentials/SKILL.md +125 -0
- package/skills/meta/credentials/evals.md +104 -0
- package/skills/meta/find-skills/SKILL.md +72 -0
- package/skills/meta/find-skills/evals.md +47 -0
- package/skills/meta/herdr/SKILL.md +127 -0
- package/skills/meta/herdr/evals.md +38 -0
- package/skills/meta/skill-craft/SKILL.md +102 -0
- package/skills/meta/skill-craft/evals.md +41 -0
- package/skills/planning/architecture/SKILL.md +129 -0
- package/skills/planning/architecture/evals.md +36 -0
- package/skills/planning/backlog/SKILL.md +90 -0
- package/skills/planning/backlog/evals.md +43 -0
- package/skills/planning/prd/SKILL.md +82 -0
- package/skills/planning/prd/evals.md +49 -0
- package/skills/planning/product-intent/SKILL.md +112 -0
- package/skills/planning/product-intent/evals.md +36 -0
- package/skills/planning/tech-spec/SKILL.md +115 -0
- package/skills/planning/tech-spec/evals.md +47 -0
- package/skills/registry.yaml +136 -0
- package/skills/research/arxiv-literature/SKILL.md +104 -0
- package/skills/research/arxiv-literature/evals.md +58 -0
- package/skills/research/experiment-protocol/SKILL.md +122 -0
- package/skills/research/experiment-protocol/evals.md +91 -0
- package/skills/research/scientific-debugging/SKILL.md +119 -0
- package/skills/research/scientific-debugging/evals.md +138 -0
- package/skills/research/scientific-modernization/SKILL.md +138 -0
- package/skills/research/scientific-modernization/evals.md +84 -0
- package/skills/workflow/design-council/SKILL.md +139 -0
- package/skills/workflow/design-council/evals.md +97 -0
- package/skills/workflow/grill-me/SKILL.md +186 -0
- package/skills/workflow/grill-me/evals.md +78 -0
- package/skills/workflow/workflow-distiller/SKILL.md +136 -0
- package/skills/workflow/workflow-distiller/evals.md +107 -0
- package/src/cli/acp.ts +31 -4
- package/src/cli/clio.ts +68 -6
- package/src/cli/config-inspect.ts +28 -22
- package/src/cli/configure.ts +47 -9
- package/src/cli/context-clear.ts +2 -2
- package/src/cli/context-index.ts +21 -23
- package/src/cli/context.ts +13 -8
- package/src/cli/default-target.ts +9 -17
- package/src/cli/docs.ts +11 -5
- package/src/cli/evidence.ts +4 -1
- package/src/cli/extensions.ts +10 -1
- package/src/cli/fleet.ts +47 -6
- package/src/cli/index.ts +55 -26
- package/src/cli/memory.ts +3 -1
- package/src/cli/models.ts +1 -1
- package/src/cli/modes/json-stream.ts +37 -1
- package/src/cli/modes/print.ts +24 -9
- package/src/cli/run.ts +2 -2
- package/src/cli/skills-eval.ts +23 -8
- package/src/cli/skills.ts +19 -4
- package/src/cli/targets.ts +4 -0
- package/src/cli/text-layout.ts +15 -5
- package/src/cli/trace.ts +62 -14
- package/src/cli/upgrade.ts +18 -2
- package/src/cli/usage.ts +10 -3
- package/src/cli/wiki-generate.ts +2 -1
- package/src/core/agent-environment.ts +7 -0
- package/src/core/bash-exec.ts +72 -1
- package/src/core/boot-trace.ts +9 -4
- package/src/core/bus-events.ts +20 -4
- package/src/core/commit-attribution.ts +157 -0
- package/src/core/compile-cache.ts +159 -0
- package/src/core/config.ts +131 -2
- package/src/core/defaults.ts +39 -5
- package/src/core/domain-loader.ts +12 -5
- package/src/core/git-commit-attribution.ts +387 -0
- package/src/core/incomplete-installation.ts +45 -0
- package/src/core/response-schema.ts +1 -1
- package/src/core/safe-exec.ts +13 -1
- package/src/core/settings-layers.ts +155 -21
- package/src/core/skill-activation.ts +1 -1
- package/src/core/startup-timer.ts +3 -3
- package/src/core/state-file-lock.ts +13 -1
- package/src/core/termination.ts +78 -5
- package/src/domains/config/classify.ts +15 -3
- package/src/domains/config/extension.ts +19 -13
- package/src/domains/config/index.ts +10 -0
- package/src/domains/config/keybindings.ts +45 -9
- package/src/domains/context/bootstrap-prompt.ts +1 -1
- package/src/domains/context/bootstrap.ts +111 -18
- package/src/domains/context/clear.ts +16 -11
- package/src/domains/context/clio-md.ts +111 -9
- package/src/domains/context/codewiki/artifact.ts +400 -0
- package/src/domains/context/codewiki/build-worker-protocol.ts +24 -0
- package/src/domains/context/codewiki/build-worker.ts +54 -0
- package/src/domains/context/codewiki/coordinator.ts +182 -0
- package/src/domains/context/codewiki/indexer.ts +59 -144
- package/src/domains/context/codewiki/paths.ts +67 -0
- package/src/domains/context/codewiki/schema.ts +80 -0
- package/src/domains/context/codewiki/tree-sitter.ts +1 -1
- package/src/domains/context/contract.ts +11 -5
- package/src/domains/context/extension.ts +94 -143
- package/src/domains/context/fingerprint.ts +3 -1
- package/src/domains/context/index.ts +12 -22
- package/src/domains/context/project-metadata.ts +19 -0
- package/src/domains/context/prompt-context.ts +9 -10
- package/src/domains/context/refresh.ts +29 -21
- package/src/domains/context/runtime.ts +17 -0
- package/src/domains/context/wiki/generate.ts +39 -34
- package/src/domains/context/wiki/plan.ts +1 -1
- package/src/domains/context/wiki/prompts.ts +21 -8
- package/src/domains/dispatch/code-step.ts +20 -1
- package/src/domains/dispatch/extension.ts +158 -21
- package/src/domains/dispatch/failure-classification.ts +6 -0
- package/src/domains/dispatch/fleet-commit-attribution.ts +56 -0
- package/src/domains/dispatch/orphan-recovery.ts +50 -8
- package/src/domains/dispatch/receipt-integrity.ts +5 -0
- package/src/domains/dispatch/state.ts +31 -6
- package/src/domains/dispatch/transport.ts +2 -1
- package/src/domains/dispatch/types.ts +14 -0
- package/src/domains/dispatch/worker-spawn.ts +21 -2
- package/src/domains/eval/metrics/context.ts +1 -1
- package/src/domains/eval/types.ts +0 -1
- package/src/domains/evidence/build.ts +41 -1
- package/src/domains/lifecycle/migrations/2026-08-18-lmstudio-runtime-id.ts +52 -0
- package/src/domains/lifecycle/migrations/index.ts +24 -4
- package/src/domains/middleware/hooks-io.ts +12 -0
- package/src/domains/middleware/skills-reminder.ts +30 -15
- package/src/domains/prompts/compiler.ts +142 -84
- package/src/domains/prompts/contract.ts +18 -2
- package/src/domains/prompts/extension.ts +39 -7
- package/src/domains/prompts/fragment-loader.ts +0 -1
- package/src/domains/prompts/fragments/identity/clio.md +2 -4
- package/src/domains/prompts/fragments/identity/docs-routing.md +10 -0
- package/src/domains/prompts/fragments/identity/self-awareness.md +1 -45
- package/src/domains/prompts/fragments/operating/contract.md +4 -50
- package/src/domains/prompts/fragments/operating/delegation.md +42 -0
- package/src/domains/prompts/fragments/operating/skills.md +26 -0
- package/src/domains/prompts/fragments/operating/worker.md +16 -0
- package/src/domains/prompts/fragments/safety/auto-edit.md +5 -5
- package/src/domains/prompts/fragments/safety/full-auto.md +3 -3
- package/src/domains/prompts/fragments/safety/read-only.md +4 -4
- package/src/domains/prompts/fragments/safety/suggest.md +2 -2
- package/src/domains/prompts/fragments/wiki/page.md +10 -0
- package/src/domains/prompts/fragments/wiki/plan.md +10 -0
- package/src/domains/prompts/preload.ts +3 -3
- package/src/domains/providers/auth/api-key.ts +1 -1
- package/src/domains/providers/auth/backend-file.ts +20 -10
- package/src/domains/providers/auth/backend-memory.ts +59 -4
- package/src/domains/providers/auth/boot-status.ts +65 -0
- package/src/domains/providers/auth/oauth.ts +2 -1
- package/src/domains/providers/auth/storage.ts +97 -38
- package/src/domains/providers/capabilities.ts +12 -4
- package/src/domains/providers/contract.ts +15 -4
- package/src/domains/providers/extension.ts +18 -6
- package/src/domains/providers/model-runtime-capabilities.ts +15 -4
- package/src/domains/providers/models/local-models/clio-local-coding-targets.yaml +118 -35
- package/src/domains/providers/plugins.ts +5 -3
- package/src/domains/providers/probe/fingerprint.ts +25 -5
- package/src/domains/providers/registry.ts +31 -10
- package/src/domains/providers/runtimes/boot-manifest.ts +55 -0
- package/src/domains/providers/runtimes/builtins.ts +2 -2
- package/src/domains/providers/runtimes/common/lmstudio-http.ts +423 -0
- package/src/domains/providers/runtimes/common/local-synth.ts +6 -7
- package/src/domains/providers/runtimes/local-native/lmstudio.ts +241 -0
- package/src/domains/providers/support.ts +6 -3
- package/src/domains/providers/types/local-model-quirks.ts +7 -9
- package/src/domains/providers/types/runtime-descriptor.ts +12 -1
- package/src/domains/providers/types/target-descriptor.ts +22 -0
- package/src/domains/resources/contract.ts +0 -1
- package/src/domains/resources/extension.ts +1 -3
- package/src/domains/resources/loader.ts +3 -4
- package/src/domains/resources/prompts/loader.ts +16 -2
- package/src/domains/resources/prompts/substitute.ts +1 -65
- package/src/domains/resources/skills/content-hash.ts +2 -0
- package/src/domains/resources/skills/install.ts +17 -0
- package/src/domains/resources/skills/loader.ts +17 -10
- package/src/domains/resources/skills/marketplace.ts +55 -9
- package/src/domains/safety/action-classifier.ts +4 -2
- package/src/domains/safety/audit.ts +8 -2
- package/src/domains/safety/extension.ts +1 -1
- package/src/domains/session/compaction/branch-summary.ts +3 -2
- package/src/domains/session/compaction/cut-point.ts +2 -1
- package/src/domains/session/compaction/tokens.ts +2 -1
- package/src/domains/session/context-ledger.ts +14 -0
- package/src/domains/session/contract.ts +15 -0
- package/src/domains/session/decision-board.ts +190 -0
- package/src/domains/session/entries.ts +66 -3
- package/src/domains/session/extension.ts +93 -12
- package/src/domains/session/retry.ts +10 -18
- package/src/domains/session/session-artifacts.ts +107 -0
- package/src/domains/session/task-board.ts +207 -13
- package/src/domains/session/tree/active-path.ts +44 -5
- package/src/domains/session/tree/fork.ts +26 -27
- package/src/domains/session/tree/preview.ts +2 -2
- package/src/domains/session/workspace/git-probe.ts +17 -11
- package/src/domains/user-tasks/store.ts +297 -0
- package/src/engine/acp/errors.ts +96 -0
- package/src/engine/acp/server.ts +1728 -146
- package/src/engine/acp/transport.ts +135 -14
- package/src/engine/acp/types.ts +26 -0
- package/src/engine/agent.ts +3 -3
- package/src/engine/ai.ts +32 -27
- package/src/engine/alcf-oauth.ts +26 -19
- package/src/engine/api-registry.ts +223 -0
- package/src/engine/apis/index.ts +3 -7
- package/src/engine/apis/llamacpp-residency.ts +49 -9
- package/src/engine/apis/lmstudio-residency.ts +5 -21
- package/src/engine/apis/lmstudio.ts +243 -0
- package/src/engine/apis/ollama-native.ts +24 -3
- package/src/engine/apis/openai-completions.ts +170 -91
- package/src/engine/apis/residency.ts +139 -3
- package/src/engine/apis/types.ts +16 -0
- package/src/engine/env-api-keys.ts +98 -0
- package/src/engine/gemma-channel-filter.ts +223 -0
- package/src/engine/instrumented-tui.ts +192 -0
- package/src/engine/messages.ts +14 -0
- package/src/engine/models.ts +42 -0
- package/src/engine/oauth.ts +16 -12
- package/src/engine/prompt-templates.ts +1 -0
- package/src/engine/provider-payload.ts +16 -59
- package/src/engine/strip-tokenizer-sentinels.ts +1 -1
- package/src/engine/truncate.ts +9 -0
- package/src/engine/tui.ts +17 -9
- package/src/engine/types.ts +3 -6
- package/src/engine/worker-runtime-capabilities.ts +5 -0
- package/src/engine/worker-runtime.ts +1 -1
- package/src/engine/worker-tools.ts +9 -4
- package/src/entry/boot-options.ts +50 -0
- package/src/entry/orchestrator.ts +288 -150
- package/src/interactive/application-controller.ts +89 -2
- package/src/interactive/chat-loop.ts +266 -41
- package/src/interactive/chat-panel.ts +715 -278
- package/src/interactive/chat-renderer.ts +306 -85
- package/src/interactive/clio-editor.ts +3 -8
- package/src/interactive/command-fallbacks.ts +2 -2
- package/src/interactive/context-overlay.ts +27 -1
- package/src/interactive/editor-submit.ts +253 -24
- package/src/interactive/export-html/ansi-to-html.ts +161 -0
- package/src/interactive/export-html/index.ts +51 -0
- package/src/interactive/export-html/template.ts +45 -0
- package/src/interactive/export-html/tool-renderer.ts +54 -0
- package/src/interactive/footer/dashboard.ts +4 -0
- package/src/interactive/footer/notifications.ts +1 -1
- package/src/interactive/footer/widgets.ts +42 -22
- package/src/interactive/footer-panel.ts +8 -3
- package/src/interactive/format-time.ts +14 -2
- package/src/interactive/interactive-application.ts +203 -17
- package/src/interactive/interactive-event-projection.ts +18 -1
- package/src/interactive/interactive-input-runtime.ts +50 -4
- package/src/interactive/interactive-presentation.ts +151 -19
- package/src/interactive/interactive-shell.ts +268 -14
- package/src/interactive/interactive-slash-runtime.ts +184 -117
- package/src/interactive/interactive-tickers.ts +38 -7
- package/src/interactive/keybinding-manager.ts +1 -1
- package/src/interactive/layout.ts +40 -3
- package/src/interactive/overlay-frame.ts +1 -1
- package/src/interactive/overlay-general-openers.ts +58 -1
- package/src/interactive/overlay-key-routing.ts +3 -0
- package/src/interactive/overlay-lifecycle.ts +13 -0
- package/src/interactive/overlay-permission-lifecycle.ts +2 -1
- package/src/interactive/overlay-session-lifecycle.ts +69 -12
- package/src/interactive/overlays/ask-user.ts +146 -24
- package/src/interactive/overlays/decisions.ts +300 -0
- package/src/interactive/overlays/help-reference.ts +15 -10
- package/src/interactive/overlays/model-selector.ts +34 -16
- package/src/interactive/overlays/session-selector.ts +18 -0
- package/src/interactive/overlays/settings.ts +105 -17
- package/src/interactive/overlays/skills-hub.ts +4 -4
- package/src/interactive/overlays/tree-selector.ts +41 -6
- package/src/interactive/render-trace.ts +499 -90
- package/src/interactive/renderers/compaction-summary.ts +2 -2
- package/src/interactive/renderers/diff.ts +115 -104
- package/src/interactive/renderers/mermaid.ts +53 -0
- package/src/interactive/renderers/tool-execution.ts +516 -168
- package/src/interactive/renderers/worker-entry.ts +20 -4
- package/src/interactive/session-switch-settlement.ts +10 -0
- package/src/interactive/slash-autocomplete.ts +6 -114
- package/src/interactive/slash-commands.ts +135 -47
- package/src/interactive/slash-spec.ts +9 -38
- package/src/interactive/status/controller.ts +5 -1
- package/src/interactive/status/index.ts +12 -1
- package/src/interactive/status/reasoning.ts +87 -0
- package/src/interactive/status/summary.ts +13 -2
- package/src/interactive/stdout-backpressure.ts +99 -0
- package/src/interactive/stream-pacer.ts +530 -0
- package/src/interactive/stream-pacing-policy.ts +66 -0
- package/src/interactive/tasks-overlay.ts +368 -14
- package/src/interactive/terminal-lease.ts +485 -0
- package/src/interactive/theme/tokens.ts +1 -1
- package/src/interactive/transcript-detail.ts +120 -0
- package/src/interactive/turn-context.ts +4 -3
- package/src/interactive/turn-persistence.ts +30 -13
- package/src/interactive/turn-queues.ts +12 -0
- package/src/interactive/turn-recovery.ts +25 -8
- package/src/interactive/turn-runtime.ts +79 -12
- package/src/interactive/turn-state.ts +10 -0
- package/src/interactive/view/artifacts.ts +114 -4
- package/src/interactive/view/view-overlay.ts +3 -0
- package/src/interactive/welcome-dashboard.ts +17 -16
- package/src/interactive/worker-receipts.ts +52 -3
- package/src/interactive/worker-stream.ts +5 -1
- package/src/tools/agent-tools.ts +23 -3
- package/src/tools/artifact.ts +2 -2
- package/src/tools/ask-user.ts +23 -13
- package/src/tools/bash.ts +30 -2
- package/src/tools/bootstrap.ts +34 -431
- package/src/tools/builtin-tool-catalog.ts +271 -0
- package/src/tools/codewiki/code-nav-surface.ts +29 -0
- package/src/tools/codewiki/code-nav.ts +8 -22
- package/src/tools/codewiki/shared.ts +41 -38
- package/src/tools/context/docs-engine.ts +14 -3
- package/src/tools/context/index.ts +107 -28
- package/src/tools/context/surface.ts +19 -0
- package/src/tools/core-bootstrap.ts +168 -0
- package/src/tools/credential-present.ts +5 -5
- package/src/tools/dispatch-admission.ts +533 -0
- package/src/tools/dispatch-background.ts +54 -0
- package/src/tools/dispatch-event-text.ts +6 -0
- package/src/tools/dispatch-plan.ts +9 -4
- package/src/tools/dispatch-run-events.ts +238 -0
- package/src/tools/dispatch-runner.ts +2370 -0
- package/src/tools/dispatch-scout-admission.ts +295 -0
- package/src/tools/dispatch-types.ts +77 -0
- package/src/tools/dispatch.ts +67 -3161
- package/src/tools/find.ts +4 -2
- package/src/tools/grep.ts +2 -2
- package/src/tools/lazy-tool.ts +60 -0
- package/src/tools/ledger.ts +3 -3
- package/src/tools/monitor-surface.ts +36 -0
- package/src/tools/monitor.ts +2 -32
- package/src/tools/observers.ts +2 -2
- package/src/tools/presentation.ts +107 -0
- package/src/tools/registry.ts +45 -27
- package/src/tools/safe-exec.ts +2 -2
- package/src/tools/steer-surface.ts +17 -0
- package/src/tools/steer.ts +2 -13
- package/src/tools/tasks.ts +108 -11
- package/src/tools/truncate.ts +25 -184
- package/src/tools/verify/frontend.ts +3 -1
- package/src/tools/verify/index.ts +3 -38
- package/src/tools/verify/surface.ts +46 -0
- package/src/tools/web-fetch-surface.ts +23 -0
- package/src/tools/web-fetch.ts +2 -20
- package/src/tools/write.ts +7 -2
- package/src/worker/entry.ts +39 -2
- package/src/worker/spec-contract.ts +26 -5
- package/dist/chunk-7SS2CTV2.js +0 -61361
- package/dist/chunk-DKGKUHFA.js +0 -924
- package/dist/chunk-GEP36Y4X.js +0 -12796
- package/dist/chunk-XYWBQRDM.js +0 -137
- package/dist/clio-BZVGEUFJ.js +0 -58
- package/dist/configure-S7S6F6CL.js +0 -32
- package/docs/html/agents_blueprint.html +0 -936
- package/docs/html/alcf_blueprint.html +0 -324
- package/docs/html/architecture_blueprint.html +0 -850
- package/docs/html/commands_blueprint.html +0 -939
- package/docs/html/config_knobs_audit_blueprint.html +0 -178
- package/docs/html/configuration_blueprint.html +0 -1080
- package/docs/html/context_blueprint.html +0 -603
- package/docs/html/documentation_blueprint.html +0 -832
- package/docs/html/environment_blueprint.html +0 -404
- package/docs/html/eval_blueprint.html +0 -743
- package/docs/html/evals_internal_blueprint.html +0 -190
- package/docs/html/evolution_blueprint.html +0 -674
- package/docs/html/extensions_blueprint.html +0 -2065
- package/docs/html/fleet_dispatch_blueprint.html +0 -286
- package/docs/html/index.html +0 -919
- package/docs/html/lifecycle_blueprint.html +0 -723
- package/docs/html/memory_blueprint.html +0 -699
- package/docs/html/middleware_blueprint.html +0 -664
- package/docs/html/models_blueprint.html +0 -2366
- package/docs/html/observability_blueprint.html +0 -683
- package/docs/html/provider_adapter_blueprint.html +0 -245
- package/docs/html/safety_blueprint.html +0 -1386
- package/docs/html/shared.css +0 -571
- package/docs/html/shared.js +0 -143
- package/docs/html/skills_blueprint.html +0 -671
- package/docs/html/soak_blueprint.html +0 -182
- package/docs/html/tool_usage_blueprint.html +0 -350
- package/docs/html/tools_blueprint.html +0 -2249
- package/docs/html/trace_blueprint.html +0 -235
- package/docs/html/tui_design_blueprint.html +0 -374
- package/docs/html/validation_blueprint.html +0 -961
- package/docs/html/worker_dispatch_blueprint.html +0 -231
- package/src/core/release.ts +0 -2
- package/src/domains/providers/runtimes/common/lmstudio-logger.ts +0 -32
- package/src/domains/providers/runtimes/local-native/lmstudio-native.ts +0 -491
- package/src/engine/apis/lmstudio-native.ts +0 -1438
- package/src/engine/apis/thinking-replay.ts +0 -11
- package/src/tools/string-enum.ts +0 -15
|
@@ -21,7 +21,16 @@
|
|
|
21
21
|
import { existsSync, readFileSync } from "node:fs";
|
|
22
22
|
import { join } from "node:path";
|
|
23
23
|
import { parse as parseYaml } from "yaml";
|
|
24
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
applySettingsDelta,
|
|
26
|
+
type ClioSettings,
|
|
27
|
+
type SettingsIssue,
|
|
28
|
+
type SettingsMutator,
|
|
29
|
+
SettingsValidationError,
|
|
30
|
+
settingsPath,
|
|
31
|
+
updateSavedSettingsDocument,
|
|
32
|
+
validateSettings,
|
|
33
|
+
} from "./config.js";
|
|
25
34
|
|
|
26
35
|
export type SettingsOrigin = "built-in" | "user" | "project" | "project.local" | "cli";
|
|
27
36
|
|
|
@@ -29,6 +38,7 @@ export interface SettingsLayerIssue {
|
|
|
29
38
|
origin: SettingsOrigin;
|
|
30
39
|
path: string;
|
|
31
40
|
message: string;
|
|
41
|
+
kind?: SettingsIssue["kind"];
|
|
32
42
|
}
|
|
33
43
|
|
|
34
44
|
export interface SettingsLayerInfo {
|
|
@@ -45,6 +55,9 @@ export interface LayeredSettings {
|
|
|
45
55
|
layers: SettingsLayerInfo[];
|
|
46
56
|
}
|
|
47
57
|
|
|
58
|
+
const STRICT_USER_ISSUES = Symbol("strict-user-issues");
|
|
59
|
+
type InternalLayeredSettings = LayeredSettings & { [STRICT_USER_ISSUES]: SettingsIssue[] };
|
|
60
|
+
|
|
48
61
|
// Keys whose presence in a project layer means a credential leaked into a
|
|
49
62
|
// committed file. `auth` carries target headers and api keys; the rest cover
|
|
50
63
|
// stray secrets. Stripped from project layers with a diagnostic.
|
|
@@ -54,6 +67,18 @@ function isRecord(value: unknown): value is Record<string, unknown> {
|
|
|
54
67
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
55
68
|
}
|
|
56
69
|
|
|
70
|
+
function deepEquals(a: unknown, b: unknown): boolean {
|
|
71
|
+
if (a === b) return true;
|
|
72
|
+
if (Array.isArray(a) || Array.isArray(b)) {
|
|
73
|
+
if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return false;
|
|
74
|
+
return a.every((entry, index) => deepEquals(entry, b[index]));
|
|
75
|
+
}
|
|
76
|
+
if (!isRecord(a) || !isRecord(b)) return false;
|
|
77
|
+
const keys = Object.keys(a);
|
|
78
|
+
if (keys.length !== Object.keys(b).length) return false;
|
|
79
|
+
return keys.every((key) => key in b && deepEquals(a[key], b[key]));
|
|
80
|
+
}
|
|
81
|
+
|
|
57
82
|
interface RawLayer {
|
|
58
83
|
origin: SettingsOrigin;
|
|
59
84
|
path: string;
|
|
@@ -62,16 +87,33 @@ interface RawLayer {
|
|
|
62
87
|
|
|
63
88
|
function readRawLayer(origin: SettingsOrigin, path: string, issues: SettingsLayerIssue[]): RawLayer {
|
|
64
89
|
if (!existsSync(path)) return { origin, path, blob: undefined };
|
|
90
|
+
let text: string;
|
|
91
|
+
try {
|
|
92
|
+
text = readFileSync(path, "utf8");
|
|
93
|
+
} catch (err) {
|
|
94
|
+
issues.push({
|
|
95
|
+
origin,
|
|
96
|
+
path: "(root)",
|
|
97
|
+
message: `unreadable: ${err instanceof Error ? err.message : String(err)}`,
|
|
98
|
+
kind: "unreadable",
|
|
99
|
+
});
|
|
100
|
+
return { origin, path, blob: undefined };
|
|
101
|
+
}
|
|
65
102
|
let parsed: unknown;
|
|
66
103
|
try {
|
|
67
|
-
parsed = parseYaml(
|
|
104
|
+
parsed = parseYaml(text);
|
|
68
105
|
} catch (err) {
|
|
69
|
-
issues.push({
|
|
106
|
+
issues.push({
|
|
107
|
+
origin,
|
|
108
|
+
path: "(root)",
|
|
109
|
+
message: `invalid YAML: ${err instanceof Error ? err.message : String(err)}`,
|
|
110
|
+
kind: "syntax",
|
|
111
|
+
});
|
|
70
112
|
return { origin, path, blob: undefined };
|
|
71
113
|
}
|
|
72
114
|
if (parsed === null || parsed === undefined) return { origin, path, blob: {} };
|
|
73
115
|
if (!isRecord(parsed)) {
|
|
74
|
-
issues.push({ origin, path, message: "settings file must be a mapping at the root" });
|
|
116
|
+
issues.push({ origin, path: "(root)", message: "settings file must be a mapping at the root" });
|
|
75
117
|
return { origin, path, blob: undefined };
|
|
76
118
|
}
|
|
77
119
|
return { origin, path, blob: parsed };
|
|
@@ -146,22 +188,20 @@ export interface ReadLayeredSettingsOptions {
|
|
|
146
188
|
userPath?: string;
|
|
147
189
|
}
|
|
148
190
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
191
|
+
interface PreparedLayers {
|
|
192
|
+
projectFile: string;
|
|
193
|
+
localFile: string;
|
|
194
|
+
projectRaw: RawLayer;
|
|
195
|
+
localRaw: RawLayer;
|
|
196
|
+
project: RawLayer;
|
|
197
|
+
local: RawLayer;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function prepareProjectLayers(cwd: string, issues: SettingsLayerIssue[]): PreparedLayers {
|
|
158
201
|
const projectFile = join(cwd, ".clio-coder", "settings.yaml");
|
|
159
202
|
const localFile = join(cwd, ".clio-coder", "settings.local.yaml");
|
|
160
|
-
|
|
161
|
-
const user = readRawLayer("user", userFile, issues);
|
|
162
203
|
const projectRaw = readRawLayer("project", projectFile, issues);
|
|
163
204
|
const localRaw = readRawLayer("project.local", localFile, issues);
|
|
164
|
-
|
|
165
205
|
const project: RawLayer = {
|
|
166
206
|
...projectRaw,
|
|
167
207
|
blob:
|
|
@@ -176,24 +216,118 @@ export function readLayeredSettings(cwd: string, options: ReadLayeredSettingsOpt
|
|
|
176
216
|
? undefined
|
|
177
217
|
: (stripCredentials(localRaw.blob, "project.local", "", issues) as Record<string, unknown>),
|
|
178
218
|
};
|
|
219
|
+
return { projectFile, localFile, projectRaw, localRaw, project, local };
|
|
220
|
+
}
|
|
179
221
|
|
|
180
|
-
|
|
222
|
+
function validateLayerStack(
|
|
223
|
+
user: RawLayer,
|
|
224
|
+
prepared: PreparedLayers,
|
|
225
|
+
issues: SettingsLayerIssue[],
|
|
226
|
+
): { settings: ClioSettings; sources: Record<string, SettingsOrigin> } {
|
|
227
|
+
const { merged, sources } = mergeLayersWithSources([user, prepared.project, prepared.local]);
|
|
181
228
|
const validation = validateSettings(merged);
|
|
182
229
|
for (const issue of validation.issues) {
|
|
183
230
|
issues.push({ origin: settingsSourceFor(sources, issue.path), path: issue.path, message: issue.message });
|
|
184
231
|
}
|
|
232
|
+
return { settings: validation.settings, sources };
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Read and layer settings for `cwd`, returning the validated effective settings
|
|
237
|
+
* plus per-leaf source attribution. Never throws: validation issues and layer
|
|
238
|
+
* problems are returned, and the effective settings always validate (invalid
|
|
239
|
+
* merges fall back to the schema defaults for the offending keys).
|
|
240
|
+
*/
|
|
241
|
+
export function readLayeredSettings(cwd: string, options: ReadLayeredSettingsOptions = {}): LayeredSettings {
|
|
242
|
+
const issues: SettingsLayerIssue[] = [];
|
|
243
|
+
const userFile = options.userPath ?? settingsPath();
|
|
244
|
+
const user = readRawLayer("user", userFile, issues);
|
|
245
|
+
const prepared = prepareProjectLayers(cwd, issues);
|
|
246
|
+
const { settings, sources } = validateLayerStack(user, prepared, issues);
|
|
185
247
|
|
|
248
|
+
const strictUserIssues =
|
|
249
|
+
user.blob === undefined
|
|
250
|
+
? []
|
|
251
|
+
: validateSettings(user.blob).issues.map((issue) => ({
|
|
252
|
+
path: issue.path,
|
|
253
|
+
message: issue.message,
|
|
254
|
+
...(issue.kind ? { kind: issue.kind } : {}),
|
|
255
|
+
}));
|
|
186
256
|
return {
|
|
187
|
-
settings
|
|
257
|
+
settings,
|
|
188
258
|
sources,
|
|
189
259
|
issues,
|
|
190
260
|
layers: [
|
|
191
261
|
{ origin: "built-in", path: "(defaults)", present: true },
|
|
192
262
|
{ origin: "user", path: userFile, present: user.blob !== undefined },
|
|
193
|
-
{ origin: "project", path: projectFile, present: projectRaw.blob !== undefined },
|
|
194
|
-
{ origin: "project.local", path: localFile, present: localRaw.blob !== undefined },
|
|
263
|
+
{ origin: "project", path: prepared.projectFile, present: prepared.projectRaw.blob !== undefined },
|
|
264
|
+
{ origin: "project.local", path: prepared.localFile, present: prepared.localRaw.blob !== undefined },
|
|
195
265
|
],
|
|
196
|
-
|
|
266
|
+
[STRICT_USER_ISSUES]: strictUserIssues,
|
|
267
|
+
} as InternalLayeredSettings;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Read the complete effective stack once while retaining settings.yaml's
|
|
272
|
+
* strict launch gate. Project-layer issues remain diagnostics, matching the
|
|
273
|
+
* established best-effort workspace overlay contract.
|
|
274
|
+
*/
|
|
275
|
+
export function readStrictLayeredSettings(cwd: string, options: ReadLayeredSettingsOptions = {}): LayeredSettings {
|
|
276
|
+
const layered = readLayeredSettings(cwd, options) as InternalLayeredSettings;
|
|
277
|
+
const reportedUserIssues = layered.issues
|
|
278
|
+
.filter((issue) => issue.origin === "user")
|
|
279
|
+
.map(({ path, message, kind }): SettingsIssue => ({ path, message, ...(kind ? { kind } : {}) }));
|
|
280
|
+
const userIssues = [...reportedUserIssues, ...layered[STRICT_USER_ISSUES]].filter(
|
|
281
|
+
(issue, index, all) =>
|
|
282
|
+
all.findIndex(
|
|
283
|
+
(candidate) =>
|
|
284
|
+
candidate.path === issue.path && candidate.message === issue.message && candidate.kind === issue.kind,
|
|
285
|
+
) === index,
|
|
286
|
+
);
|
|
287
|
+
if (userIssues.length > 0) throw new SettingsValidationError(userIssues);
|
|
288
|
+
return layered;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Atomically persist a mutation of the effective workspace settings into the
|
|
293
|
+
* user layer. The candidate user document is re-layered with the same project
|
|
294
|
+
* files before it is written. This preserves references to project-only
|
|
295
|
+
* targets while refusing a mutation that a higher-precedence project leaf
|
|
296
|
+
* would silently override.
|
|
297
|
+
*/
|
|
298
|
+
export function updateLayeredSettings(cwd: string, mutate: SettingsMutator): ClioSettings {
|
|
299
|
+
let committed: ClioSettings | null = null;
|
|
300
|
+
updateSavedSettingsDocument((saved) => {
|
|
301
|
+
const userValidation = validateSettings(saved);
|
|
302
|
+
if (userValidation.issues.length > 0) throw new SettingsValidationError(userValidation.issues);
|
|
303
|
+
const issues: SettingsLayerIssue[] = [];
|
|
304
|
+
const prepared = prepareProjectLayers(cwd, issues);
|
|
305
|
+
const user: RawLayer = {
|
|
306
|
+
origin: "user",
|
|
307
|
+
path: settingsPath(),
|
|
308
|
+
blob: isRecord(saved) ? saved : {},
|
|
309
|
+
};
|
|
310
|
+
const before = validateLayerStack(user, prepared, issues).settings;
|
|
311
|
+
const candidate = structuredClone(before);
|
|
312
|
+
const next = mutate(candidate) ?? candidate;
|
|
313
|
+
const candidateValidation = validateSettings(JSON.parse(JSON.stringify(next)));
|
|
314
|
+
if (candidateValidation.issues.length > 0) throw new SettingsValidationError(candidateValidation.issues);
|
|
315
|
+
|
|
316
|
+
const nextSaved = applySettingsDelta(saved, before, candidateValidation.settings);
|
|
317
|
+
const finalIssues: SettingsLayerIssue[] = [];
|
|
318
|
+
const final = validateLayerStack(
|
|
319
|
+
{ origin: "user", path: settingsPath(), blob: isRecord(nextSaved) ? nextSaved : {} },
|
|
320
|
+
prepared,
|
|
321
|
+
finalIssues,
|
|
322
|
+
).settings;
|
|
323
|
+
if (!deepEquals(final, candidateValidation.settings)) {
|
|
324
|
+
throw new Error("a higher-precedence project setting prevents this settings update");
|
|
325
|
+
}
|
|
326
|
+
committed = final;
|
|
327
|
+
return nextSaved;
|
|
328
|
+
});
|
|
329
|
+
if (committed === null) throw new Error("layered settings update did not commit");
|
|
330
|
+
return committed;
|
|
197
331
|
}
|
|
198
332
|
|
|
199
333
|
/**
|
|
@@ -7,7 +7,7 @@ export type PendingSkillRequestSource = "slash-command" | "selector" | "marketpl
|
|
|
7
7
|
* reminder, and the operator-gate denial all cite this exact line so the
|
|
8
8
|
* model learns a single protocol.
|
|
9
9
|
*/
|
|
10
|
-
export const SKILL_SUGGESTION_ANCHOR = "Suggested skill: /skill
|
|
10
|
+
export const SKILL_SUGGESTION_ANCHOR = "Suggested skill: /skill <name>";
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* The part of the anchor a real reply keeps once `<name>` is substituted.
|
|
@@ -15,13 +15,13 @@ export class StartupTimer {
|
|
|
15
15
|
private readonly start = performance.now();
|
|
16
16
|
private readonly marks: Mark[] = [];
|
|
17
17
|
|
|
18
|
-
constructor() {
|
|
19
|
-
|
|
18
|
+
constructor(private readonly trace: (phase: string) => void = traceBoot) {
|
|
19
|
+
this.trace("boot start");
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
mark(name: string): void {
|
|
23
23
|
this.marks.push({ name, at: performance.now() - this.start });
|
|
24
|
-
|
|
24
|
+
this.trace(name);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
snapshot(): { totalMs: number; marks: ReadonlyArray<Mark> } {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { closeSync, mkdirSync, openSync, readFileSync, statSync, unlinkSync, utimesSync, writeSync } from "node:fs";
|
|
2
2
|
import { hostname } from "node:os";
|
|
3
3
|
import { dirname } from "node:path";
|
|
4
|
+
import { setTimeout as sleep } from "node:timers/promises";
|
|
4
5
|
import { processAlive, processBirthToken } from "./process-identity.js";
|
|
5
6
|
|
|
6
7
|
/**
|
|
@@ -36,6 +37,8 @@ export const FILE_LOCK_ACQUIRE_TIMEOUT_MS = 20_000;
|
|
|
36
37
|
export interface StateFileLockOptions {
|
|
37
38
|
/** Acquisition budget. Default `FILE_LOCK_ACQUIRE_TIMEOUT_MS`. */
|
|
38
39
|
timeoutMs?: number;
|
|
40
|
+
/** Cancel an asynchronous lock wait and never enter or commit its critical section. */
|
|
41
|
+
signal?: AbortSignal;
|
|
39
42
|
/**
|
|
40
43
|
* `run-unlocked` runs `fn` anyway when the lock cannot be taken. Residency
|
|
41
44
|
* mutations need it: serializing them is an optimization and must never fail
|
|
@@ -158,9 +161,11 @@ export function withStateFileLockSync<T>(targetPath: string, fn: () => T, option
|
|
|
158
161
|
const timeoutMs = options.timeoutMs ?? FILE_LOCK_ACQUIRE_TIMEOUT_MS;
|
|
159
162
|
let held = false;
|
|
160
163
|
try {
|
|
164
|
+
options.signal?.throwIfAborted();
|
|
161
165
|
mkdirSync(dirname(lockPath), { recursive: true });
|
|
162
166
|
const deadlineMs = Date.now() + timeoutMs;
|
|
163
167
|
for (let attempt = 1; !tryAcquire(lockPath); attempt += 1) {
|
|
168
|
+
options.signal?.throwIfAborted();
|
|
164
169
|
if (Date.now() > deadlineMs) throw timeoutError(lockPath, timeoutMs);
|
|
165
170
|
// Atomics.wait rather than a timer: the callers of this variant are
|
|
166
171
|
// inside host APIs that cannot yield.
|
|
@@ -168,6 +173,7 @@ export function withStateFileLockSync<T>(targetPath: string, fn: () => T, option
|
|
|
168
173
|
}
|
|
169
174
|
held = true;
|
|
170
175
|
} catch (err) {
|
|
176
|
+
options.signal?.throwIfAborted();
|
|
171
177
|
if (options.onAcquireFailure !== "run-unlocked") throw err;
|
|
172
178
|
}
|
|
173
179
|
try {
|
|
@@ -186,15 +192,21 @@ export async function withStateFileLock<T>(
|
|
|
186
192
|
const timeoutMs = options.timeoutMs ?? FILE_LOCK_ACQUIRE_TIMEOUT_MS;
|
|
187
193
|
let held = false;
|
|
188
194
|
try {
|
|
195
|
+
options.signal?.throwIfAborted();
|
|
189
196
|
mkdirSync(dirname(lockPath), { recursive: true });
|
|
190
197
|
const deadlineMs = Date.now() + timeoutMs;
|
|
191
198
|
for (let attempt = 1; !tryAcquire(lockPath); attempt += 1) {
|
|
199
|
+
options.signal?.throwIfAborted();
|
|
192
200
|
if (Date.now() > deadlineMs) throw timeoutError(lockPath, timeoutMs);
|
|
193
201
|
const base = backoffMs(attempt);
|
|
194
|
-
|
|
202
|
+
const delayMs = base + Math.floor(Math.random() * base);
|
|
203
|
+
if (options.signal) await sleep(delayMs, undefined, { signal: options.signal });
|
|
204
|
+
else await sleep(delayMs);
|
|
195
205
|
}
|
|
196
206
|
held = true;
|
|
207
|
+
options.signal?.throwIfAborted();
|
|
197
208
|
} catch (err) {
|
|
209
|
+
options.signal?.throwIfAborted();
|
|
198
210
|
if (options.onAcquireFailure !== "run-unlocked") throw err;
|
|
199
211
|
}
|
|
200
212
|
const stopRefresh = held ? startRefresh(lockPath) : null;
|
package/src/core/termination.ts
CHANGED
|
@@ -9,6 +9,12 @@
|
|
|
9
9
|
* hanging hook cannot block the TUI from exiting. The cap is 500ms by
|
|
10
10
|
* default and can be overridden via CLIO_CODER_SHUTDOWN_HOOK_MS for tests.
|
|
11
11
|
* Timed-out hooks are logged and shutdown continues to the next hook.
|
|
12
|
+
*
|
|
13
|
+
* Every diagnostic here is written after the TUI has stopped: the interactive
|
|
14
|
+
* controller stops the terminal before it calls shutdown(), and the signal path
|
|
15
|
+
* stops it from a drain hook, which precedes persist. The renderer is gone, so
|
|
16
|
+
* a diagnostic goes to stderr and is wrapped to the terminal width so it does
|
|
17
|
+
* not overrun the frame the TUI just handed back.
|
|
12
18
|
*/
|
|
13
19
|
|
|
14
20
|
import { BusChannels } from "./bus-events.js";
|
|
@@ -27,6 +33,46 @@ const SIGNAL_EXIT_CODES: Partial<Record<NodeJS.Signals, number>> = {
|
|
|
27
33
|
SIGTERM: 143,
|
|
28
34
|
};
|
|
29
35
|
|
|
36
|
+
/**
|
|
37
|
+
* Break `text` into lines no wider than `width` columns, at spaces where
|
|
38
|
+
* possible and mid-word when a single token is wider than the terminal.
|
|
39
|
+
*/
|
|
40
|
+
export function wrapToWidth(text: string, width: number): string[] {
|
|
41
|
+
if (!Number.isFinite(width) || width < 1) return [text];
|
|
42
|
+
const lines: string[] = [];
|
|
43
|
+
let current = "";
|
|
44
|
+
for (const word of text.split(/\s+/).filter((w) => w.length > 0)) {
|
|
45
|
+
let token = word;
|
|
46
|
+
while (token.length > width) {
|
|
47
|
+
if (current) {
|
|
48
|
+
lines.push(current);
|
|
49
|
+
current = "";
|
|
50
|
+
}
|
|
51
|
+
lines.push(token.slice(0, width));
|
|
52
|
+
token = token.slice(width);
|
|
53
|
+
}
|
|
54
|
+
if (!current) current = token;
|
|
55
|
+
else if (current.length + 1 + token.length <= width) current = `${current} ${token}`;
|
|
56
|
+
else {
|
|
57
|
+
lines.push(current);
|
|
58
|
+
current = token;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (current) lines.push(current);
|
|
62
|
+
return lines.length > 0 ? lines : [""];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Emit a shutdown notice on stderr, wrapped to the terminal width when stderr
|
|
67
|
+
* or stdout is a TTY. Off a TTY the text goes out unwrapped, since a log
|
|
68
|
+
* consumer wants one record per line.
|
|
69
|
+
*/
|
|
70
|
+
export function writeShutdownNotice(text: string): void {
|
|
71
|
+
const width = process.stderr.columns ?? process.stdout.columns;
|
|
72
|
+
const lines = width === undefined ? [text] : wrapToWidth(text, width);
|
|
73
|
+
process.stderr.write(`${lines.join("\n")}\n`);
|
|
74
|
+
}
|
|
75
|
+
|
|
30
76
|
export function resolveShutdownHookBudgetMs(): number {
|
|
31
77
|
const raw = process.env.CLIO_CODER_SHUTDOWN_HOOK_MS;
|
|
32
78
|
if (raw === undefined) return DEFAULT_SHUTDOWN_HOOK_MS;
|
|
@@ -72,6 +118,8 @@ class TerminationCoordinator {
|
|
|
72
118
|
private readonly persistHooks: Hook[] = [];
|
|
73
119
|
private exitCode = 0;
|
|
74
120
|
private started = false;
|
|
121
|
+
private drained = false;
|
|
122
|
+
private readonly pendingNotices: string[] = [];
|
|
75
123
|
private signalHandler: ((signal: NodeJS.Signals) => void) | null = null;
|
|
76
124
|
|
|
77
125
|
getPhase(): TerminationPhase {
|
|
@@ -116,6 +164,8 @@ class TerminationCoordinator {
|
|
|
116
164
|
log("drain:start");
|
|
117
165
|
await this.runHooks(this.drainHooks, "drain", budgetMs, log);
|
|
118
166
|
log("drain:end");
|
|
167
|
+
this.drained = true;
|
|
168
|
+
this.flushNotices();
|
|
119
169
|
bus.emit(BusChannels.ShutdownDrained, {});
|
|
120
170
|
|
|
121
171
|
this.phase = "terminating";
|
|
@@ -142,13 +192,13 @@ class TerminationCoordinator {
|
|
|
142
192
|
if (!hook) continue;
|
|
143
193
|
const t0 = process.hrtime.bigint();
|
|
144
194
|
const completed = await runWithBudget(hook, budgetMs, (err) => {
|
|
145
|
-
|
|
195
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
196
|
+
writeShutdownNotice(`[clio:termination] ${phase}[${i}] failed: ${message}`);
|
|
197
|
+
if (err instanceof Error && err.stack) log(err.stack);
|
|
146
198
|
});
|
|
147
199
|
const dt = Number(process.hrtime.bigint() - t0) / 1e6;
|
|
148
200
|
if (!completed) {
|
|
149
|
-
|
|
150
|
-
`[clio:termination] ${phase}[${i}] exceeded ${budgetMs}ms budget; abandoning and continuing shutdown\n`,
|
|
151
|
-
);
|
|
201
|
+
writeShutdownNotice(`[clio:termination] ${phase}[${i}] exceeded ${budgetMs}ms budget; shutdown continues`);
|
|
152
202
|
}
|
|
153
203
|
log(` ${phase}[${i}] ${dt.toFixed(1)}ms${completed ? "" : " (timed out)"}`);
|
|
154
204
|
}
|
|
@@ -163,7 +213,7 @@ class TerminationCoordinator {
|
|
|
163
213
|
installSignalHandlers(): void {
|
|
164
214
|
if (this.signalHandler) return;
|
|
165
215
|
const handler = (signal: NodeJS.Signals): void => {
|
|
166
|
-
|
|
216
|
+
this.notice(`Clio Coder: received ${signal}, shutting down...`);
|
|
167
217
|
void this.shutdown(SIGNAL_EXIT_CODES[signal] ?? 143);
|
|
168
218
|
};
|
|
169
219
|
this.signalHandler = handler;
|
|
@@ -172,6 +222,29 @@ class TerminationCoordinator {
|
|
|
172
222
|
process.once("SIGHUP", handler);
|
|
173
223
|
}
|
|
174
224
|
|
|
225
|
+
/**
|
|
226
|
+
* Report something the operator should read after the process is gone,
|
|
227
|
+
* such as which signal ended it. Nothing here knows whether a TUI is on
|
|
228
|
+
* screen, but it does know that the terminal teardown is a drain hook: so
|
|
229
|
+
* until drain has finished the notice is held, and the moment it has, the
|
|
230
|
+
* notice goes to the terminal the TUI just handed back. Written straight
|
|
231
|
+
* away once drain is over, which is the case for a re-armed SIGINT arriving
|
|
232
|
+
* mid-shutdown. A second SIGTERM or SIGHUP inside the drain window takes
|
|
233
|
+
* Node's default action and the held notice dies with the process; that
|
|
234
|
+
* window is bounded by the per-hook budget and the shell reports the kill.
|
|
235
|
+
*/
|
|
236
|
+
notice(text: string): void {
|
|
237
|
+
if (this.drained) {
|
|
238
|
+
writeShutdownNotice(text);
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
this.pendingNotices.push(text);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
private flushNotices(): void {
|
|
245
|
+
for (const text of this.pendingNotices.splice(0)) writeShutdownNotice(text);
|
|
246
|
+
}
|
|
247
|
+
|
|
175
248
|
/**
|
|
176
249
|
* Hand SIGINT to a foreground owner and return the call that takes it back.
|
|
177
250
|
*
|
|
@@ -21,7 +21,14 @@ export interface ConfigDiff {
|
|
|
21
21
|
restartRequired: string[];
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
const HOT_RELOAD_FIELDS = new Set<string>([
|
|
24
|
+
const HOT_RELOAD_FIELDS = new Set<string>([
|
|
25
|
+
"theme",
|
|
26
|
+
"keybindings",
|
|
27
|
+
"autonomy",
|
|
28
|
+
"modelSelector",
|
|
29
|
+
"terminal.smoothStreaming",
|
|
30
|
+
"attribution.gitCommits",
|
|
31
|
+
]);
|
|
25
32
|
|
|
26
33
|
const NEXT_TURN_FIELDS = new Set<string>([
|
|
27
34
|
"identity",
|
|
@@ -52,7 +59,12 @@ const NEXT_TURN_FIELDS = new Set<string>([
|
|
|
52
59
|
"retry",
|
|
53
60
|
]);
|
|
54
61
|
|
|
55
|
-
const RESTART_REQUIRED_FIELDS = new Set<string>([
|
|
62
|
+
const RESTART_REQUIRED_FIELDS = new Set<string>([
|
|
63
|
+
"budget.concurrency",
|
|
64
|
+
"runtimePlugins",
|
|
65
|
+
"terminal.tuiMode",
|
|
66
|
+
"terminal.fullscreenScrollbar",
|
|
67
|
+
]);
|
|
56
68
|
|
|
57
69
|
function matchesPrefix(path: string, fields: Set<string>): boolean {
|
|
58
70
|
if (fields.has(path)) return true;
|
|
@@ -67,8 +79,8 @@ export function diffSettings(prev: ClioSettings, next: ClioSettings): ConfigDiff
|
|
|
67
79
|
const diff: ConfigDiff = { hotReload: [], nextTurn: [], restartRequired: [] };
|
|
68
80
|
for (const p of changed) {
|
|
69
81
|
if (matchesPrefix(p, HOT_RELOAD_FIELDS)) diff.hotReload.push(p);
|
|
70
|
-
else if (matchesPrefix(p, NEXT_TURN_FIELDS)) diff.nextTurn.push(p);
|
|
71
82
|
else if (matchesPrefix(p, RESTART_REQUIRED_FIELDS)) diff.restartRequired.push(p);
|
|
83
|
+
else if (matchesPrefix(p, NEXT_TURN_FIELDS)) diff.nextTurn.push(p);
|
|
72
84
|
else {
|
|
73
85
|
// Unknown field falls back to restartRequired to fail closed.
|
|
74
86
|
diff.restartRequired.push(p);
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { BusChannels, type ConfigChangePayload } from "../../core/bus-events.js";
|
|
2
|
-
import { type ClioSettings, formatSettingsFailure
|
|
2
|
+
import { type ClioSettings, formatSettingsFailure } from "../../core/config.js";
|
|
3
3
|
import type { DomainBundle, DomainContext, DomainExtension } from "../../core/domain-loader.js";
|
|
4
|
-
import {
|
|
4
|
+
import { setGitCommitAttributionEnabled } from "../../core/git-commit-attribution.js";
|
|
5
|
+
import { readStrictLayeredSettings, updateLayeredSettings } from "../../core/settings-layers.js";
|
|
5
6
|
import { assertAgentIdNamespace } from "./agent-namespace.js";
|
|
6
7
|
import { type ChangeKind, diffSettings } from "./classify.js";
|
|
7
8
|
import type { ConfigContract } from "./contract.js";
|
|
@@ -13,7 +14,10 @@ interface NativeAgentNamespace {
|
|
|
13
14
|
list(): ReadonlyArray<{ id: string }>;
|
|
14
15
|
}
|
|
15
16
|
|
|
16
|
-
export function createConfigBundle(
|
|
17
|
+
export function createConfigBundle(
|
|
18
|
+
context: DomainContext,
|
|
19
|
+
initialSettings?: Readonly<ClioSettings>,
|
|
20
|
+
): DomainBundle<ConfigContract> {
|
|
17
21
|
let watcher: ConfigWatcher | null = null;
|
|
18
22
|
let snapshot: ClioSettings | null = null;
|
|
19
23
|
let reloadFailure: string | null = null;
|
|
@@ -62,10 +66,9 @@ export function createConfigBundle(context: DomainContext): DomainBundle<ConfigC
|
|
|
62
66
|
function onWatcherFire(): void {
|
|
63
67
|
let next: ClioSettings;
|
|
64
68
|
try {
|
|
65
|
-
//
|
|
66
|
-
//
|
|
67
|
-
|
|
68
|
-
next = readLayeredSettings(process.cwd()).settings;
|
|
69
|
+
// One file read keeps the strict user-settings gate while workspace
|
|
70
|
+
// overlays retain their established best-effort diagnostics.
|
|
71
|
+
next = readStrictLayeredSettings(process.cwd()).settings;
|
|
69
72
|
} catch (err) {
|
|
70
73
|
// The rejection is the whole effect: `snapshot` is untouched, so the
|
|
71
74
|
// session keeps running on the last good settings.
|
|
@@ -81,6 +84,7 @@ export function createConfigBundle(context: DomainContext): DomainBundle<ConfigC
|
|
|
81
84
|
}
|
|
82
85
|
publishReloadFailure(null);
|
|
83
86
|
snapshot = next;
|
|
87
|
+
setGitCommitAttributionEnabled(next.attribution.gitCommits);
|
|
84
88
|
if (!prev) return;
|
|
85
89
|
const diff = diffSettings(prev, next);
|
|
86
90
|
if (diff.hotReload.length > 0) dispatch("hotReload", { diff, settings: next });
|
|
@@ -90,8 +94,9 @@ export function createConfigBundle(context: DomainContext): DomainBundle<ConfigC
|
|
|
90
94
|
|
|
91
95
|
const extension: DomainExtension = {
|
|
92
96
|
async start() {
|
|
93
|
-
|
|
94
|
-
snapshot =
|
|
97
|
+
if (initialSettings) snapshot = structuredClone(initialSettings);
|
|
98
|
+
else snapshot = readStrictLayeredSettings(process.cwd()).settings;
|
|
99
|
+
setGitCommitAttributionEnabled(snapshot.attribution.gitCommits);
|
|
95
100
|
watcher = startConfigWatcher(() => onWatcherFire());
|
|
96
101
|
},
|
|
97
102
|
async stop() {
|
|
@@ -114,11 +119,12 @@ export function createConfigBundle(context: DomainContext): DomainBundle<ConfigC
|
|
|
114
119
|
const candidate = structuredClone(previous);
|
|
115
120
|
mutate(candidate);
|
|
116
121
|
assertAgentNamespace(candidate);
|
|
117
|
-
//
|
|
118
|
-
//
|
|
119
|
-
|
|
120
|
-
const normalized =
|
|
122
|
+
// Apply the effective-view delta to the user document under one lock,
|
|
123
|
+
// then validate it with the project layers before writing. In particular,
|
|
124
|
+
// a route may name a target supplied only by this workspace.
|
|
125
|
+
const normalized = updateLayeredSettings(process.cwd(), mutate);
|
|
121
126
|
snapshot = normalized;
|
|
127
|
+
setGitCommitAttributionEnabled(normalized.attribution.gitCommits);
|
|
122
128
|
const diff = diffSettings(previous, normalized);
|
|
123
129
|
if (diff.hotReload.length > 0) dispatch("hotReload", { diff, settings: normalized });
|
|
124
130
|
if (diff.nextTurn.length > 0) dispatch("nextTurn", { diff, settings: normalized });
|
|
@@ -7,6 +7,16 @@ export const ConfigDomainModule: DomainModule = {
|
|
|
7
7
|
createExtension: createConfigBundle,
|
|
8
8
|
};
|
|
9
9
|
|
|
10
|
+
/** Bind the one strict startup snapshot without changing other command paths. */
|
|
11
|
+
export function createConfigDomainModule(
|
|
12
|
+
initialSettings: Readonly<import("../../core/config.js").ClioSettings>,
|
|
13
|
+
): DomainModule {
|
|
14
|
+
return {
|
|
15
|
+
manifest: ConfigManifest,
|
|
16
|
+
createExtension: (context) => createConfigBundle(context, initialSettings),
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
10
20
|
export { assertAgentIdNamespace } from "./agent-namespace.js";
|
|
11
21
|
export { type ChangeKind, type ConfigDiff, diffSettings } from "./classify.js";
|
|
12
22
|
export type { ConfigContract } from "./contract.js";
|