@iowarp/clio-coder 0.4.1 → 0.4.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 +92 -0
- package/CONTRIBUTING.md +59 -36
- package/README.md +404 -472
- package/SECURITY.md +2 -1
- package/dist/{acp-ZILU3AUO.js → acp-TMDQZDIG.js} +7 -7
- package/dist/{agents-HYWGBGQR.js → agents-5N5NG3XG.js} +28 -28
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-N3QT7CBO.js → auth-Z5CCBXKQ.js} +8 -9
- package/dist/{builtins-UJLMOVOV.js → builtins-K6TNDT24.js} +4 -4
- package/dist/{chunk-GVQJ5CCZ.js → chunk-2HFQNRV3.js} +7 -7
- package/dist/{chunk-QMXC4JB7.js → chunk-2NHR3NAY.js} +163 -1401
- package/dist/chunk-2X4RYJTJ.js +39 -0
- package/dist/{chunk-Y45G3AXC.js → chunk-2Z2IKEXI.js} +6 -10
- package/dist/{chunk-EIMVLWB3.js → chunk-34BHNEE3.js} +7 -3
- package/dist/{chunk-GIZNH63R.js → chunk-35MSIRKH.js} +9 -4
- package/dist/chunk-3EBYEESD.js +314 -0
- package/dist/{chunk-CTJ4RNAA.js → chunk-3F7VUY77.js} +2 -2
- package/dist/{chunk-AP73CFDC.js → chunk-3KIPBMUA.js} +2 -2
- package/dist/{chunk-J5LZHVIT.js → chunk-3M6DQK6S.js} +113 -35
- package/dist/{chunk-VEGN6WIQ.js → chunk-462T4EGZ.js} +2 -2
- package/dist/{chunk-AFKWHWXF.js → chunk-4JDLP6ZS.js} +33 -16
- package/dist/{chunk-6FN3E6KX.js → chunk-4O6MANBS.js} +2 -2
- package/dist/{chunk-AKB4GYDL.js → chunk-54ODD65L.js} +5 -5
- package/dist/{chunk-BBTJOK6Y.js → chunk-5KW52TEP.js} +3 -3
- package/dist/{chunk-6CCS4G3W.js → chunk-5PFYMY2V.js} +2 -2
- package/dist/chunk-77QIVUZB.js +1334 -0
- package/dist/{chunk-7OBGU7UB.js → chunk-7BHIY2MW.js} +7 -13
- package/dist/{chunk-3QSOM6PA.js → chunk-AZ4WMN4W.js} +2 -2
- package/dist/{chunk-6NJQITNH.js → chunk-B74PXLU7.js} +6 -3
- package/dist/{chunk-R23Z6K6I.js → chunk-B7HM5Z7T.js} +15 -15
- package/dist/{chunk-R32CLGZ6.js → chunk-BO7Y52RY.js} +81 -20
- package/dist/{chunk-UEDMSP56.js → chunk-BYMNWQ7O.js} +123 -148
- package/dist/{chunk-ZJLUDYFY.js → chunk-CRFOIAX3.js} +4 -4
- package/dist/{chunk-2NM363SV.js → chunk-CYZW7JHJ.js} +7 -7
- package/dist/{chunk-6HMJX2VU.js → chunk-DYHAXKHD.js} +38 -10
- package/dist/{chunk-THYWACCR.js → chunk-DZAW46HP.js} +3 -3
- package/dist/{chunk-FYUN5KZ3.js → chunk-DZEK6CJN.js} +17 -17
- package/dist/{chunk-3I5NY75V.js → chunk-E7GT7O5N.js} +5 -5
- package/dist/{chunk-VKFQTNDV.js → chunk-F2I26BDK.js} +4 -4
- package/dist/{chunk-HLW2MRKE.js → chunk-F4EKGO4N.js} +3 -1
- package/dist/{chunk-IXJT6DCX.js → chunk-FVDGR2ZL.js} +3 -3
- package/dist/{chunk-TZSKNMZG.js → chunk-GTUD2WMY.js} +2 -1
- package/dist/{chunk-7EPLI7VL.js → chunk-HIICAHCJ.js} +2 -2
- package/dist/{chunk-E67WX76H.js → chunk-HKMD33FO.js} +29 -80
- package/dist/chunk-HLAFFSEK.js +360 -0
- package/dist/{chunk-UAPGZHYC.js → chunk-I64IFBLB.js} +9 -2
- package/dist/{chunk-XKA2ICR3.js → chunk-I66ZTYNP.js} +440 -175
- package/dist/{chunk-7PWAODYW.js → chunk-I7XBWTYH.js} +2 -2
- package/dist/{chunk-PVAMAVBB.js → chunk-IDNA72AH.js} +102 -2
- package/dist/{chunk-GCSMB2KY.js → chunk-IKOZFYBN.js} +1 -1
- package/dist/{chunk-2VG7KLYV.js → chunk-IKSLQ4XV.js} +5460 -3241
- package/dist/{chunk-QKIFBZKT.js → chunk-IMXMHHMQ.js} +166 -25
- package/dist/{chunk-74YWRRU5.js → chunk-JBCS7CRR.js} +2 -2
- package/dist/{chunk-BDPT6GTK.js → chunk-JWJGP5DQ.js} +2 -2
- package/dist/{chunk-K6BF4U2H.js → chunk-KKOJXO6R.js} +62 -14
- package/dist/chunk-KPXDY6QF.js +47 -0
- package/dist/{chunk-ABLSQ6JX.js → chunk-LJID3DYZ.js} +7 -1
- package/dist/{chunk-VKRH2TCS.js → chunk-M2DAX4F6.js} +2 -2
- package/dist/{chunk-6I5ILFOF.js → chunk-M2WXEHER.js} +2 -2
- package/dist/{chunk-YPI3QQCF.js → chunk-MCEPRMZW.js} +2 -4
- package/dist/{chunk-N5UK64DP.js → chunk-MCMZMDAC.js} +2 -2
- package/dist/{chunk-Y4CAGMM6.js → chunk-MNJGS2IN.js} +5 -6
- package/dist/{chunk-TVHHYFHE.js → chunk-NEDJ26B5.js} +2 -2
- package/dist/{chunk-U2WB7TZS.js → chunk-NMJXSHBJ.js} +97 -85
- package/dist/{chunk-HUAS7ITX.js → chunk-O3YUNJZ2.js} +13 -21
- package/dist/{chunk-MA3H6DM5.js → chunk-P75RZCJW.js} +25 -3
- package/dist/{chunk-IG7BCQBA.js → chunk-PGF63K6I.js} +2 -2
- package/dist/chunk-PJX3WQUQ.js +42 -0
- package/dist/{chunk-6DWBAZ5U.js → chunk-Q4XWMHX6.js} +4 -6
- package/dist/{chunk-OJTRZGR3.js → chunk-QQLGQY2A.js} +8 -8
- package/dist/{chunk-J4HBWF6Y.js → chunk-RLYRBIYQ.js} +115 -20
- package/dist/{chunk-NLFAQR7Z.js → chunk-S66XZJOF.js} +3 -23
- package/dist/{chunk-C537JADH.js → chunk-SSEYRH53.js} +6 -7
- package/dist/chunk-SZAA6XDG.js +30 -0
- package/dist/{chunk-MOPSG2X7.js → chunk-TPEQIQIE.js} +6 -6
- package/dist/{chunk-JA5QWE4Z.js → chunk-UBRFI4HS.js} +1879 -1650
- package/dist/{chunk-BTGG6BG2.js → chunk-UH347SHR.js} +154 -15
- package/dist/{chunk-5YHDIDBP.js → chunk-UH632ZYL.js} +2 -2
- package/dist/{chunk-BWW4HLO4.js → chunk-UXCU4E3T.js} +8 -6
- package/dist/{chunk-6VC4OV3Z.js → chunk-VIA6RFQZ.js} +3 -11
- package/dist/{chunk-ZAZB4JMW.js → chunk-VKPAQYEB.js} +27 -8
- package/dist/{chunk-UXN6JT4W.js → chunk-W4YEMFBX.js} +2 -2
- package/dist/{chunk-TD3PGPQA.js → chunk-W6NIE6OW.js} +2 -2
- package/dist/{chunk-TVH4ONAM.js → chunk-X7IARSHT.js} +3 -3
- package/dist/{chunk-PJJ6MY27.js → chunk-XE3PCIXH.js} +3 -3
- package/dist/{chunk-FEFIFZTL.js → chunk-XGDPUNND.js} +2 -2
- package/dist/{chunk-SCYB3HA4.js → chunk-XOXV5GKE.js} +51 -16
- package/dist/{chunk-QTFGO774.js → chunk-XQRY4DTA.js} +24 -11
- package/dist/{chunk-BJGUKIG4.js → chunk-YJISEZKC.js} +2 -2
- package/dist/{chunk-GPPB3JBE.js → chunk-ZGNYYXQ6.js} +2 -2
- package/dist/{chunk-SINK3QR6.js → chunk-ZNT2M6TG.js} +7 -7
- package/dist/{chunk-7RY5VZPH.js → chunk-ZW4HH5JJ.js} +6 -6
- package/dist/cli/index.js +33 -32
- package/dist/{clio-IT3G3VQH.js → clio-7VB377CC.js} +7 -7
- package/dist/{code-nav-RK6S7F6E.js → code-nav-YVLCYA7V.js} +85 -17
- package/dist/{config-3QZRWZJF.js → config-4HVOS65E.js} +88 -43
- package/dist/{configure-FL7Y3KJF.js → configure-PIWO7B24.js} +10 -10
- package/dist/{context-5HE7ODYK.js → context-IYEHL3WQ.js} +33 -31
- package/dist/{context-XNHL75JV.js → context-KQYIWPWT.js} +47 -34
- package/dist/{context-KYQFRVDC.js → context-N6ZE3LGJ.js} +11 -11
- package/dist/{context-clear-N545L53A.js → context-clear-G4OGZJDS.js} +33 -31
- package/dist/{context-working-set-QHKXSV2F.js → context-working-set-BWLF6LJP.js} +7 -7
- package/dist/{dispatch-runner-RGIE5PCT.js → dispatch-runner-2QQAITS3.js} +38 -38
- package/dist/{docs-5NAF6AU7.js → docs-PD3EXDKU.js} +21 -20
- package/dist/{doctor-ZGPEGHIP.js → doctor-LHBD36VU.js} +23 -22
- package/dist/{eval-GXLL44RD.js → eval-C45FYRJ6.js} +21 -20
- package/dist/{eval-inventory-HBWSWQOK.js → eval-inventory-6DEJPLBF.js} +2 -2
- package/dist/{evidence-HWLBRH3Q.js → evidence-6SHONYAF.js} +30 -28
- package/dist/{evolve-FTZBMNVW.js → evolve-KRKMV72X.js} +30 -28
- package/dist/{extensions-VHRBEID7.js → extensions-KPZ2UHBB.js} +5 -3
- package/dist/{fleet-CKZHJWZJ.js → fleet-IVTCKDHT.js} +62 -61
- package/dist/{fleet-commands-EXDXBMV6.js → fleet-commands-EDWL3IT7.js} +5 -5
- package/dist/{fleet-decisions-OTHB6KRL.js → fleet-decisions-YP3YEFGK.js} +4 -4
- package/dist/{fleet-graph-YTEZUCUT.js → fleet-graph-ZFWKHY2M.js} +16 -14
- package/dist/{fleet-inspect-SS6YMDCK.js → fleet-inspect-FVUNCBML.js} +31 -29
- package/dist/{fleet-preflight-PBY4VYOM.js → fleet-preflight-UN5XED4R.js} +2 -2
- package/dist/{fleet-validate-KMEM5L3S.js → fleet-validate-XOWC4HSX.js} +17 -15
- package/dist/{fleet-verify-QD5M7E7Q.js → fleet-verify-UN3SODEL.js} +30 -28
- package/dist/{fleet-view-WAMJYNDT.js → fleet-view-TWHJKCN6.js} +31 -29
- package/dist/{init-5XQRBOFV.js → init-T2QORQ3Y.js} +50 -49
- package/dist/{interop-34TVO25M.js → interop-IN5I2A66.js} +5 -5
- package/dist/{library-3QY6KF57.js → library-LSCATDLZ.js} +15 -13
- package/dist/{memory-L4UTIIIW.js → memory-HYOKAGGJ.js} +31 -29
- package/dist/{models-ZVX3QOWE.js → models-2GPMFYCM.js} +22 -21
- package/dist/{monitor-CEKVSYTS.js → monitor-E4ASVUJH.js} +34 -32
- package/dist/{orchestrator-77BAP6BC.js → orchestrator-DDMPR3PY.js} +984 -583
- package/dist/{panes-7STHOAUJ.js → panes-E3RUXOW5.js} +4 -4
- package/dist/{panes-SHAUIRXY.js → panes-IXKLOKA2.js} +23 -8
- package/dist/{reset-EOLM7GVE.js → reset-OAQP3W4O.js} +4 -4
- package/dist/{resources-74GKTLSF.js → resources-OTRSN34L.js} +15 -13
- package/dist/{run-HBAUJNNZ.js → run-5DEYH5QK.js} +60 -59
- package/dist/{share-G3APVLVP.js → share-IHWTLO3M.js} +19 -15
- package/dist/{skills-35HHUKCR.js → skills-IYMXMKW4.js} +17 -15
- package/dist/{skills-eval-QN4HSHDC.js → skills-eval-DROHSJAR.js} +36 -36
- package/dist/{skills-inventory-J357J34F.js → skills-inventory-D7X4L4ZX.js} +15 -13
- package/dist/{slash-commands-JZZCQA32.js → slash-commands-QBM7UZ3B.js} +21 -18
- package/dist/{steer-XAVHJM22.js → steer-Z5DO23FJ.js} +2 -2
- package/dist/{targets-DSM6CY3M.js → targets-P2FUC4IL.js} +25 -28
- package/dist/{terminal-lease-JOPFUVEM.js → terminal-lease-YREJ3JX2.js} +5 -5
- package/dist/{tools-MKNWVPBH.js → tools-5B7RO6MV.js} +4 -4
- package/dist/{trace-ECQ7TIYZ.js → trace-YMGMUM6A.js} +55 -7
- package/dist/{upgrade-H7TOM7YL.js → upgrade-PXK3S2YM.js} +11 -9
- package/dist/{usage-X52N3IDJ.js → usage-ME5MPXGX.js} +36 -34
- package/dist/{verifiers-EJTVVSMA.js → verifiers-BVZ7IWOO.js} +5 -5
- package/dist/{verify-YJL6XET2.js → verify-5K7ZKQFC.js} +4 -4
- package/dist/{web-fetch-MPIFL3LL.js → web-fetch-MPARV2K7.js} +2 -2
- package/dist/{wiki-generate-4NDZTQ4B.js → wiki-generate-F5W5QTYY.js} +48 -47
- package/dist/{with-panes-OBOBFIIR.js → with-panes-BYOJCLAM.js} +51 -255
- package/dist/worker/entry.js +45 -30
- package/docs/README.md +176 -81
- package/docs/{acp.md → architecture/acp.md} +36 -20
- package/docs/{alcf-provider.md → architecture/alcf-provider.md} +8 -5
- package/docs/{architecture.md → architecture/architecture.md} +43 -22
- package/docs/{artifact-placement.md → architecture/artifact-placement.md} +26 -23
- package/docs/architecture/artifact-versions.md +90 -0
- package/docs/{capacity-and-scheduling.md → architecture/capacity-and-scheduling.md} +26 -13
- package/docs/{context-engine.md → architecture/context-engine.md} +25 -25
- package/docs/{context-working-set.md → architecture/context-working-set.md} +13 -10
- package/docs/{dispatch-architecture-rationale.md → architecture/dispatch-architecture-rationale.md} +12 -9
- package/docs/{dispatch-typed-intent.md → architecture/dispatch-typed-intent.md} +68 -46
- package/docs/{evidence-and-memory.md → architecture/evidence-and-memory.md} +23 -16
- package/docs/{middleware-and-components.md → architecture/middleware-and-components.md} +11 -5
- package/docs/{model-catalog.md → architecture/model-catalog.md} +40 -17
- package/docs/{observability.md → architecture/observability.md} +26 -13
- package/docs/{pi-boundary.md → architecture/pi-boundary.md} +24 -11
- package/docs/{prompt-envelope-and-tools.md → architecture/prompt-envelope-and-tools.md} +55 -20
- package/docs/{provider-adapter-cookbook.md → architecture/provider-adapter-cookbook.md} +35 -24
- package/docs/{safety-model.md → architecture/safety-model.md} +20 -15
- package/docs/{session-lifecycle.md → architecture/session-lifecycle.md} +8 -5
- package/docs/architecture/time-conventions.md +125 -0
- package/docs/{trace-store.md → architecture/trace-store.md} +13 -5
- package/docs/{tui-design.md → architecture/tui-design.md} +13 -13
- package/docs/{worker-dispatch-mechanics.md → architecture/worker-dispatch-mechanics.md} +27 -30
- package/docs/{built-in-agents.md → guide/built-in-agents.md} +50 -34
- package/docs/{commands-and-modes.md → guide/commands-and-modes.md} +65 -60
- package/docs/{configuration-and-targets.md → guide/configuration-and-targets.md} +227 -289
- package/docs/guide/configuration-reference.md +1158 -0
- package/docs/{environment-variables.md → guide/environment-variables.md} +31 -28
- package/docs/{exit-codes-and-output.md → guide/exit-codes-and-output.md} +6 -3
- package/docs/{extensions-and-sharing.md → guide/extensions-and-sharing.md} +41 -14
- package/docs/{fleet-dispatch.md → guide/fleet-dispatch.md} +39 -43
- package/docs/{glossary.md → guide/glossary.md} +14 -11
- package/docs/{installation-and-lifecycle.md → guide/installation-and-lifecycle.md} +44 -13
- package/docs/guide/panes-and-files.md +290 -0
- package/docs/{proactive-memory.md → guide/proactive-memory.md} +79 -66
- package/docs/{resource-library.md → guide/resource-library.md} +13 -4
- package/docs/{skills-marketplace.md → guide/skills-marketplace.md} +7 -3
- package/docs/{tool-usage.md → guide/tool-usage.md} +87 -23
- package/docs/{troubleshooting.md → guide/troubleshooting.md} +9 -4
- package/docs/{config-knobs-audit.md → history/config-knobs-audit.md} +11 -11
- package/docs/{release-cut-checklist.md → history/release-cut-checklist.md} +29 -2
- package/docs/{development-pipeline.md → process/development-pipeline.md} +24 -26
- package/docs/process/documentation-coverage.md +100 -0
- package/docs/process/documentation-guide.md +187 -0
- package/docs/{eval-runner.md → process/eval-runner.md} +41 -50
- package/docs/{evals-internal.md → process/evals-internal.md} +10 -10
- package/docs/{evolution.md → process/evolution.md} +2 -2
- package/docs/{fleet-demo-runbook.md → process/fleet-demo-runbook.md} +11 -7
- package/docs/{git-commit-provenance.md → process/git-commit-provenance.md} +11 -4
- package/docs/{performance-methodology.md → process/performance-methodology.md} +87 -69
- package/docs/{scientific-validation.md → process/scientific-validation.md} +4 -4
- package/evals/README.md +2 -2
- package/package.json +9 -7
- package/skills/README.md +46 -37
- package/skills/coding/ast-grep/SKILL.md +2 -2
- package/skills/coding/coding-standards/SKILL.md +2 -2
- package/skills/coding/prototype/SKILL.md +2 -2
- package/skills/coding/tdd/SKILL.md +2 -2
- package/skills/context/context-handoff/SKILL.md +2 -2
- package/skills/context/context-prime/SKILL.md +2 -2
- package/skills/git/file-ticket/SKILL.md +2 -2
- package/skills/git/fix-issue/SKILL.md +3 -3
- package/skills/git/resolve-merge-conflicts/SKILL.md +2 -2
- package/skills/git/ship/SKILL.md +2 -2
- package/skills/git/worktree-create/SKILL.md +2 -2
- package/skills/git/worktree-merge/SKILL.md +2 -2
- package/skills/meta/clio-coder-dev/SKILL.md +9 -5
- package/skills/meta/clio-coder-dev/evals.md +3 -2
- package/skills/meta/clio-coder-test/SKILL.md +102 -95
- package/skills/meta/clio-coder-test/evals.md +9 -4
- package/skills/meta/clio-coder-test/references/harness.md +100 -124
- package/skills/meta/clio-coder-test/references/test-map.md +77 -50
- package/skills/meta/credentials/SKILL.md +2 -2
- package/skills/meta/find-skills/SKILL.md +2 -2
- package/skills/meta/herdr/SKILL.md +2 -2
- package/skills/meta/skill-craft/SKILL.md +22 -16
- package/skills/planning/architecture/SKILL.md +2 -2
- package/skills/planning/backlog/SKILL.md +2 -2
- package/skills/planning/prd/SKILL.md +2 -2
- package/skills/planning/product-intent/SKILL.md +2 -2
- package/skills/planning/tech-spec/SKILL.md +2 -2
- package/skills/registry.yaml +62 -62
- package/skills/research/arxiv-literature/SKILL.md +2 -2
- package/skills/research/experiment-protocol/SKILL.md +2 -2
- package/skills/research/scientific-debugging/SKILL.md +2 -2
- package/skills/research/scientific-modernization/SKILL.md +2 -2
- package/skills/skill-marketplace.json +62 -62
- package/skills/workflow/cut-it/SKILL.md +2 -2
- package/skills/workflow/design-council/SKILL.md +2 -2
- package/skills/workflow/grill-me/SKILL.md +2 -2
- package/skills/workflow/workflow-distiller/SKILL.md +2 -2
- package/src/cli/args.ts +2 -2
- package/src/cli/bootstrap-generate.ts +1 -1
- package/src/cli/config-inspect.ts +65 -12
- package/src/cli/configure.ts +0 -4
- package/src/cli/docs.ts +22 -14
- package/src/cli/doctor-naming.ts +5 -5
- package/src/cli/doctor-toolchain.ts +3 -3
- package/src/cli/eval.ts +1 -2
- package/src/cli/extensions.ts +2 -1
- package/src/cli/fleet.ts +1 -1
- package/src/cli/index.ts +2 -1
- package/src/cli/internal-dispatch.ts +3 -4
- package/src/cli/panes.ts +19 -5
- package/src/cli/run.ts +2 -2
- package/src/cli/share.ts +5 -1
- package/src/cli/skills-eval.ts +3 -3
- package/src/cli/targets.ts +2 -6
- package/src/cli/trace.ts +55 -4
- package/src/cli/wiki-generate.ts +1 -1
- package/src/core/artifact-paths.ts +1 -1
- package/src/core/bash-exec.ts +131 -86
- package/src/core/bus-events.ts +51 -6
- package/src/core/config.ts +5 -1
- package/src/core/defaults.ts +7 -4
- package/src/core/dispatch-outcome.ts +16 -0
- package/src/core/guardrails.ts +10 -49
- package/src/core/prompt-hint.ts +9 -0
- package/src/domains/agents/builtins/architect.md +2 -3
- package/src/domains/agents/builtins/coder.md +3 -2
- package/src/domains/agents/builtins/debugger.md +2 -2
- package/src/domains/agents/builtins/documenter.md +2 -2
- package/src/domains/agents/builtins/git-master.md +1 -1
- package/src/domains/agents/builtins/oracle.md +1 -1
- package/src/domains/agents/builtins/provenance.md +1 -1
- package/src/domains/agents/builtins/researcher.md +1 -1
- package/src/domains/agents/builtins/scout.md +1 -1
- package/src/domains/agents/builtins/tester.md +2 -2
- package/src/domains/agents/builtins/verifier.md +2 -2
- package/src/domains/agents/builtins/wiki-writer.md +1 -1
- package/src/domains/agents/catalog.ts +12 -14
- package/src/domains/agents/contract.ts +2 -0
- package/src/domains/agents/extension.ts +23 -1
- package/src/domains/config/keybindings.ts +8 -0
- package/src/domains/context/extension.ts +0 -3
- package/src/domains/context/working-set/path-index.ts +1 -0
- package/src/domains/dispatch/capability-match.ts +10 -0
- package/src/domains/dispatch/extension.ts +105 -22
- package/src/domains/dispatch/host-verification.ts +435 -39
- package/src/domains/dispatch/intent-requirements.ts +10 -0
- package/src/domains/dispatch/intent.ts +18 -1
- package/src/domains/dispatch/path-scope.ts +235 -24
- package/src/domains/dispatch/run-event-journal.ts +4 -15
- package/src/domains/dispatch/state.ts +2 -3
- package/src/domains/dispatch/transport.ts +45 -21
- package/src/domains/dispatch/types.ts +55 -3
- package/src/domains/eval/artifacts/store.ts +5 -0
- package/src/domains/eval/store.ts +8 -1
- package/src/domains/evidence/trust-status.ts +10 -1
- package/src/domains/extensions/contract.ts +15 -1
- package/src/domains/extensions/discovery.ts +238 -41
- package/src/domains/extensions/extension.ts +105 -6
- package/src/domains/extensions/index.ts +24 -0
- package/src/domains/extensions/integrity.ts +189 -0
- package/src/domains/extensions/manager.ts +17 -1
- package/src/domains/extensions/resource-path.ts +27 -0
- package/src/domains/extensions/resources.ts +18 -38
- package/src/domains/extensions/snapshot-store.ts +39 -0
- package/src/domains/extensions/snapshot.ts +180 -0
- package/src/domains/extensions/state.ts +385 -57
- package/src/domains/extensions/types.ts +118 -1
- package/src/domains/lifecycle/migrations/2026-09-01-extension-install-digests.ts +27 -0
- package/src/domains/lifecycle/migrations/index.ts +2 -0
- package/src/domains/lifecycle/naming-resources.ts +19 -4
- package/src/domains/lifecycle/naming-yazi.ts +10 -5
- package/src/domains/middleware/contract.ts +26 -0
- package/src/domains/middleware/extension.ts +24 -24
- package/src/domains/middleware/hook-receipts.ts +27 -4
- package/src/domains/middleware/hooks-io.ts +65 -32
- package/src/domains/middleware/hooks.ts +64 -0
- package/src/domains/middleware/index.ts +28 -4
- package/src/domains/middleware/registrations.ts +326 -0
- package/src/domains/middleware/runtime.ts +28 -0
- package/src/domains/middleware/snapshot.ts +20 -7
- package/src/domains/mux/contract.ts +38 -0
- package/src/domains/mux/detect.ts +6 -13
- package/src/domains/mux/index.ts +1 -1
- package/src/domains/mux/operations.ts +44 -5
- package/src/domains/mux/yazi/assets/yazi.toml +2 -2
- package/src/domains/mux/yazi/session.ts +53 -4
- package/src/domains/mux/yazi/theme.ts +117 -17
- package/src/domains/observability/contract.ts +10 -11
- package/src/domains/observability/extension.ts +11 -3
- package/src/domains/observability/projection.ts +14 -90
- package/src/domains/observability/trace-store.ts +43 -7
- package/src/domains/prompts/compiler.ts +73 -53
- package/src/domains/prompts/contract.ts +15 -3
- package/src/domains/prompts/extension.ts +97 -9
- package/src/domains/prompts/fragments/identity/clio-worker.md +1 -3
- package/src/domains/prompts/fragments/identity/clio.md +6 -12
- package/src/domains/prompts/fragments/identity/docs-routing.md +1 -2
- package/src/domains/prompts/fragments/identity/self-awareness.md +3 -11
- package/src/domains/prompts/fragments/operating/contract.md +7 -15
- package/src/domains/prompts/fragments/operating/delegation.md +32 -34
- package/src/domains/prompts/fragments/operating/skills.md +10 -24
- package/src/domains/prompts/fragments/operating/worker.md +1 -8
- package/src/domains/providers/index.ts +1 -1
- package/src/domains/providers/model-runtime-capabilities.ts +85 -21
- package/src/domains/providers/models/local-models/clio-coder-local-coding-targets.yaml +669 -104
- package/src/domains/providers/runtime-resolution.ts +31 -0
- package/src/domains/providers/runtimes/common/probe-helpers.ts +7 -2
- package/src/domains/providers/runtimes/local-native/llamacpp.ts +9 -1
- package/src/domains/providers/types/cost-provenance.ts +19 -0
- package/src/domains/providers/types/local-model-quirks.ts +85 -37
- package/src/domains/resources/skills/loader.ts +16 -19
- package/src/domains/safety/call-target.ts +1 -1
- package/src/domains/safety/loop-detector.ts +7 -4
- package/src/domains/session/task-board.ts +10 -9
- package/src/domains/share/archive.ts +164 -7
- package/src/engine/acp/server.ts +62 -9
- package/src/engine/apis/llamacpp-residency.ts +3 -4
- package/src/engine/apis/lmstudio.ts +3 -3
- package/src/engine/apis/ollama-native.ts +6 -6
- package/src/engine/apis/openai-completions.ts +28 -25
- package/src/engine/apis/output-budget.ts +8 -18
- package/src/engine/apis/residency.ts +8 -27
- package/src/engine/gemma-channel-filter.ts +19 -0
- package/src/engine/loop-guard.ts +92 -12
- package/src/engine/worker-runtime.ts +40 -11
- package/src/engine/worker-tools.ts +3 -1
- package/src/entry/extension-hook-sources.ts +28 -0
- package/src/entry/extension-reload.ts +309 -0
- package/src/entry/orchestrator.ts +59 -35
- package/src/interactive/application-controller.ts +2 -1
- package/src/interactive/bus-notices.ts +8 -1
- package/src/interactive/chat-loop-messages.ts +3 -13
- package/src/interactive/chat-loop.ts +10 -1
- package/src/interactive/chat-panel.ts +36 -13
- package/src/interactive/chat-renderer.ts +71 -7
- package/src/interactive/dispatch-board.ts +6 -11
- package/src/interactive/footer/widgets.ts +13 -0
- package/src/interactive/interactive-application.ts +39 -4
- package/src/interactive/interactive-input-runtime.ts +4 -0
- package/src/interactive/interactive-presentation.ts +2 -2
- package/src/interactive/interactive-slash-runtime.ts +2 -0
- package/src/interactive/overlays/extensions.ts +9 -1
- package/src/interactive/overlays/help-reference.ts +13 -0
- package/src/interactive/overlays/settings.ts +27 -16
- package/src/interactive/panes-runtime.ts +111 -35
- package/src/interactive/prompt-cache-identity.ts +88 -0
- package/src/interactive/slash-commands.ts +129 -14
- package/src/interactive/stream-pacing-policy.ts +0 -23
- package/src/interactive/turn-context.ts +30 -15
- package/src/interactive/yazi-bridge.ts +60 -6
- package/src/tools/agent-tools.ts +30 -1
- package/src/tools/artifact.ts +2 -2
- package/src/tools/ask-user.ts +3 -3
- package/src/tools/bash.ts +1 -1
- package/src/tools/bootstrap.ts +4 -0
- package/src/tools/builtin-tool-catalog.ts +52 -22
- package/src/tools/codewiki/code-nav-surface.ts +6 -0
- package/src/tools/codewiki/code-nav.ts +99 -13
- package/src/tools/context/docs-engine.ts +20 -7
- package/src/tools/context/index.ts +29 -12
- package/src/tools/core-bootstrap.ts +28 -6
- package/src/tools/credential-present.ts +1 -2
- package/src/tools/dispatch-arguments.ts +5 -1
- package/src/tools/dispatch-plan.ts +48 -4
- package/src/tools/dispatch-run-events.ts +1 -1
- package/src/tools/dispatch-schema.ts +338 -0
- package/src/tools/dispatch-types.ts +3 -0
- package/src/tools/dispatch.ts +9 -254
- package/src/tools/ledger.ts +3 -5
- package/src/tools/monitor-surface.ts +5 -13
- package/src/tools/observation.ts +4 -5
- package/src/tools/panes-surface.ts +4 -11
- package/src/tools/panes.ts +4 -2
- package/src/tools/policy.ts +15 -2
- package/src/tools/read.ts +5 -6
- package/src/tools/registry.ts +30 -7
- package/src/tools/result-shaping.ts +18 -14
- package/src/tools/steer-surface.ts +1 -1
- package/src/tools/tasks.ts +1 -1
- package/src/tools/truncate.ts +6 -5
- package/src/tools/verify/surface.ts +6 -12
- package/src/tools/web-fetch-surface.ts +1 -3
- package/dist/chunk-5QIAJV2D.js +0 -48
- package/dist/chunk-JZWT5J3Y.js +0 -814
- package/dist/chunk-K7VKOLQQ.js +0 -15
- package/dist/chunk-PMZCIOCJ.js +0 -25
- package/dist/chunk-SUW5DORT.js +0 -819
- package/dist/chunk-UOV2BYIW.js +0 -107
- package/dist/chunk-WR6U3OVP.js +0 -45
- package/docs/artifact-versions.md +0 -67
- package/docs/documentation-coverage.md +0 -46
- package/docs/documentation-guide.md +0 -167
- package/docs/time-conventions.md +0 -101
|
@@ -27,6 +27,19 @@ export interface ExtensionDiagnostic {
|
|
|
27
27
|
path?: string;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
export interface ExtensionProvenance {
|
|
31
|
+
id: string;
|
|
32
|
+
scope: ExtensionScope;
|
|
33
|
+
/** Path recorded in install state, when known. */
|
|
34
|
+
sourcePath?: string;
|
|
35
|
+
/** Canonical filesystem identity of the installed package root. */
|
|
36
|
+
canonicalRoot: string;
|
|
37
|
+
/** SHA-256 of the manifest bytes covered by the installed-tree digest. */
|
|
38
|
+
manifestDigest: string;
|
|
39
|
+
/** Installed-tree digest recorded at install and reverified on this load. */
|
|
40
|
+
contentDigest: string;
|
|
41
|
+
}
|
|
42
|
+
|
|
30
43
|
export interface InstalledExtension {
|
|
31
44
|
id: string;
|
|
32
45
|
name: string;
|
|
@@ -36,14 +49,28 @@ export interface InstalledExtension {
|
|
|
36
49
|
rootPath: string;
|
|
37
50
|
manifestPath: string;
|
|
38
51
|
enabled: boolean;
|
|
52
|
+
/** Whether the complete manifest and declared resource tree are valid. */
|
|
53
|
+
valid: boolean;
|
|
39
54
|
/** Whether this package admits the running Clio version. */
|
|
40
55
|
compatible: boolean;
|
|
41
56
|
effective: boolean;
|
|
57
|
+
/** The single admission decision for extension-owned resources and hooks. */
|
|
58
|
+
loadable: boolean;
|
|
59
|
+
/** Present exactly when the installed tree and manifest bytes were reverified. */
|
|
60
|
+
provenance?: ExtensionProvenance;
|
|
61
|
+
/** Digest observed while checking installed content on this load. */
|
|
62
|
+
observedContentDigest?: string;
|
|
42
63
|
resources: ExtensionManifestResources;
|
|
43
64
|
overriddenBy?: ExtensionScope;
|
|
44
65
|
diagnostics: ExtensionDiagnostic[];
|
|
45
66
|
}
|
|
46
67
|
|
|
68
|
+
export type LoadableExtension = InstalledExtension & { loadable: true; provenance: ExtensionProvenance };
|
|
69
|
+
|
|
70
|
+
export function isLoadableExtension(entry: InstalledExtension): entry is LoadableExtension {
|
|
71
|
+
return entry.loadable && entry.provenance !== undefined;
|
|
72
|
+
}
|
|
73
|
+
|
|
47
74
|
export interface ExtensionCandidate {
|
|
48
75
|
path: string;
|
|
49
76
|
manifestPath?: string;
|
|
@@ -58,8 +85,88 @@ export interface ExtensionResourceRoot {
|
|
|
58
85
|
path: string;
|
|
59
86
|
rootPath: string;
|
|
60
87
|
source: string;
|
|
88
|
+
provenance: ExtensionProvenance;
|
|
89
|
+
/** Zero denotes an ephemeral, uncommitted projection. */
|
|
90
|
+
generation: number;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export interface ExtensionHookSource {
|
|
94
|
+
provenance: ExtensionProvenance;
|
|
95
|
+
/** SHA-256 of the captured hooks.yaml bytes. */
|
|
96
|
+
declarationsDigest: string;
|
|
97
|
+
/** Parsed captured YAML, or an empty list when parsing failed. */
|
|
98
|
+
declarations: unknown;
|
|
99
|
+
parseError?: string;
|
|
61
100
|
}
|
|
62
101
|
|
|
102
|
+
export interface ExtensionSnapshotDiagnostics {
|
|
103
|
+
entries: ReadonlyArray<ExtensionDiagnostic & { extensionId?: string }>;
|
|
104
|
+
truncated: number;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export interface ExtensionSnapshot {
|
|
108
|
+
version: 1;
|
|
109
|
+
generation: number;
|
|
110
|
+
cwd: string;
|
|
111
|
+
builtAt: string;
|
|
112
|
+
/** Content identity; generation, timestamp, and diagnostic text are excluded. */
|
|
113
|
+
digest: string;
|
|
114
|
+
packages: ReadonlyArray<InstalledExtension>;
|
|
115
|
+
resourceRoots: Readonly<Record<ExtensionResourceKind, ReadonlyArray<ExtensionResourceRoot>>>;
|
|
116
|
+
hookSources: ReadonlyArray<ExtensionHookSource>;
|
|
117
|
+
diagnostics: ExtensionSnapshotDiagnostics;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export type ExtensionReloadRejectionReason = "build-failed" | "reentrant" | "stale" | "workspace-changed";
|
|
121
|
+
|
|
122
|
+
export interface ExtensionReloadRejection {
|
|
123
|
+
status: "rejected";
|
|
124
|
+
reason: ExtensionReloadRejectionReason;
|
|
125
|
+
/** Generation that remains committed. */
|
|
126
|
+
generation: number;
|
|
127
|
+
diagnostics: ExtensionSnapshotDiagnostics;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* A fully built and validated generation that has not been published. The
|
|
132
|
+
* bundle holds at most one candidate at a time. `publish` is one reference
|
|
133
|
+
* assignment that never validates, refuses, throws, or calls out; the caller
|
|
134
|
+
* checks `current()` on the same stack immediately before it. `discard`
|
|
135
|
+
* releases the candidate without any visible change.
|
|
136
|
+
*/
|
|
137
|
+
export interface ExtensionReloadCandidate {
|
|
138
|
+
generation: number;
|
|
139
|
+
previousGeneration: number;
|
|
140
|
+
snapshot: ExtensionSnapshot;
|
|
141
|
+
/** False when the candidate digest equals the committed digest. */
|
|
142
|
+
changed: boolean;
|
|
143
|
+
added: ReadonlyArray<string>;
|
|
144
|
+
removed: ReadonlyArray<string>;
|
|
145
|
+
modified: ReadonlyArray<string>;
|
|
146
|
+
/** True while this is the in-flight candidate and the committed snapshot it was diffed against is still live. */
|
|
147
|
+
current(): boolean;
|
|
148
|
+
publish(): void;
|
|
149
|
+
discard(): void;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export type ExtensionReloadPrepareResult =
|
|
153
|
+
| { status: "prepared"; candidate: ExtensionReloadCandidate }
|
|
154
|
+
| ExtensionReloadRejection;
|
|
155
|
+
|
|
156
|
+
export interface ExtensionReloadCommitted {
|
|
157
|
+
status: "committed";
|
|
158
|
+
generation: number;
|
|
159
|
+
previousGeneration: number;
|
|
160
|
+
changed: boolean;
|
|
161
|
+
digest: string;
|
|
162
|
+
added: ReadonlyArray<string>;
|
|
163
|
+
removed: ReadonlyArray<string>;
|
|
164
|
+
modified: ReadonlyArray<string>;
|
|
165
|
+
diagnostics: ExtensionSnapshotDiagnostics;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export type ExtensionReloadResult = ExtensionReloadCommitted | ExtensionReloadRejection;
|
|
169
|
+
|
|
63
170
|
export interface ExtensionListOptions {
|
|
64
171
|
scope?: ExtensionScope;
|
|
65
172
|
cwd?: string;
|
|
@@ -72,17 +179,27 @@ export interface ExtensionInstallOptions extends ExtensionListOptions {
|
|
|
72
179
|
|
|
73
180
|
export interface ExtensionInstallResult {
|
|
74
181
|
extension?: InstalledExtension;
|
|
182
|
+
recovery?: { stateBackup?: string; packageBackup?: string };
|
|
75
183
|
diagnostics: ExtensionDiagnostic[];
|
|
76
184
|
}
|
|
77
185
|
|
|
78
186
|
export interface ExtensionMutationResult {
|
|
79
187
|
extension?: InstalledExtension;
|
|
80
188
|
removed?: { id: string; scope: ExtensionScope; path: string };
|
|
189
|
+
recovery?: { stateBackup?: string; packageBackup?: string };
|
|
81
190
|
diagnostics: ExtensionDiagnostic[];
|
|
82
191
|
}
|
|
83
192
|
|
|
193
|
+
export interface ExtensionStateUpgradeReport {
|
|
194
|
+
scope: ExtensionScope;
|
|
195
|
+
statePath: string;
|
|
196
|
+
backupPath?: string;
|
|
197
|
+
upgraded: string[];
|
|
198
|
+
refused: Array<{ id: string; reason: string }>;
|
|
199
|
+
}
|
|
200
|
+
|
|
84
201
|
export interface ExtensionState {
|
|
85
202
|
version: 1;
|
|
86
203
|
disabled: string[];
|
|
87
|
-
installed: Record<string, { installedAt: string; source?: string }>;
|
|
204
|
+
installed: Record<string, { installedAt: string; source?: string; contentDigest?: string }>;
|
|
88
205
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { mkdirSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { safeResourceWrite } from "../../../core/safe-resource-write.js";
|
|
4
|
+
import { upgradeLegacyExtensionInstallState } from "../../extensions/state.js";
|
|
5
|
+
import type { Migration } from "./index.js";
|
|
6
|
+
|
|
7
|
+
export const EXTENSION_INSTALL_DIGESTS_MIGRATION_ID = "2026-09-01-extension-install-digests";
|
|
8
|
+
|
|
9
|
+
function migrateExtensionInstallDigests(stateDir: string, cwd = process.cwd()): void {
|
|
10
|
+
const scopes = upgradeLegacyExtensionInstallState(cwd);
|
|
11
|
+
const reportDir = join(stateDir, "migration-reports");
|
|
12
|
+
mkdirSync(reportDir, { recursive: true });
|
|
13
|
+
safeResourceWrite(
|
|
14
|
+
join(reportDir, `${EXTENSION_INSTALL_DIGESTS_MIGRATION_ID}.json`),
|
|
15
|
+
`${JSON.stringify({ migration: EXTENSION_INSTALL_DIGESTS_MIGRATION_ID, scopes }, null, 2)}\n`,
|
|
16
|
+
{ encoding: "utf8", mode: 0o644 },
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const migration: Migration = {
|
|
21
|
+
id: EXTENSION_INSTALL_DIGESTS_MIGRATION_ID,
|
|
22
|
+
async up(stateDir: string): Promise<void> {
|
|
23
|
+
migrateExtensionInstallDigests(stateDir);
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export default migration;
|
|
@@ -34,6 +34,7 @@ import { join } from "node:path";
|
|
|
34
34
|
|
|
35
35
|
import lmStudioRuntimeId from "./2026-08-18-lmstudio-runtime-id.js";
|
|
36
36
|
import clioCoderNaming from "./2026-09-01-clio-coder-naming.js";
|
|
37
|
+
import extensionInstallDigests from "./2026-09-01-extension-install-digests.js";
|
|
37
38
|
import retirePanesKnobs from "./2026-09-01-retire-panes-knobs.js";
|
|
38
39
|
import settingsV2 from "./2026-09-01-settings-v2.js";
|
|
39
40
|
|
|
@@ -61,6 +62,7 @@ export interface MigrationRunResult {
|
|
|
61
62
|
// migration independently and for manifest continuity; it is a no-op on v2.
|
|
62
63
|
const REGISTRY: ReadonlyArray<Migration> = Object.freeze([
|
|
63
64
|
settingsV2,
|
|
65
|
+
extensionInstallDigests,
|
|
64
66
|
clioCoderNaming,
|
|
65
67
|
retirePanesKnobs,
|
|
66
68
|
lmStudioRuntimeId,
|
|
@@ -9,12 +9,14 @@ import {
|
|
|
9
9
|
statSync,
|
|
10
10
|
writeFileSync,
|
|
11
11
|
} from "node:fs";
|
|
12
|
+
import { homedir } from "node:os";
|
|
12
13
|
import path from "node:path";
|
|
13
14
|
|
|
14
15
|
import { parse as parseYaml } from "yaml";
|
|
15
16
|
import { resolvePackageRoot } from "../../core/package-root.js";
|
|
16
17
|
import { fsyncDirectory } from "../../core/safe-resource-write.js";
|
|
17
18
|
import { resolveClioDirs } from "../../core/xdg.js";
|
|
19
|
+
import { INTEROP_AGENT_KINDS } from "../interop/registry.js";
|
|
18
20
|
import { normalizedSkillHash, stripProvenanceFrontmatter } from "../resources/skills/content-hash.js";
|
|
19
21
|
|
|
20
22
|
const LEGACY_SKILL_NAMES = [
|
|
@@ -35,6 +37,8 @@ export interface NamingResourceReport {
|
|
|
35
37
|
export interface NamingResourceOptions {
|
|
36
38
|
cwd?: string;
|
|
37
39
|
configDir?: string;
|
|
40
|
+
/** Home directory whose interop skill roots are inspected; defaults to the OS home. */
|
|
41
|
+
home?: string;
|
|
38
42
|
packageRoot?: string;
|
|
39
43
|
fix?: boolean;
|
|
40
44
|
}
|
|
@@ -206,14 +210,25 @@ function collectSkillFiles(root: string, current = root): string[] {
|
|
|
206
210
|
return out;
|
|
207
211
|
}
|
|
208
212
|
|
|
209
|
-
/**
|
|
213
|
+
/**
|
|
214
|
+
* Read-only inventory of released skill metadata keys in every root the skill
|
|
215
|
+
* loader reads: the Clio user and project roots plus each interop agent's
|
|
216
|
+
* user and project compatibility roots (`.claude/skills`, `.agents/skills`,
|
|
217
|
+
* ...). The loader warns for a legacy key in any of them, so the doctor has to
|
|
218
|
+
* look where the loader looks or it reports "canonical" while boot warns.
|
|
219
|
+
*/
|
|
210
220
|
export function inspectSkillMetadataNaming(
|
|
211
|
-
options: Pick<NamingResourceOptions, "cwd" | "configDir"> = {},
|
|
221
|
+
options: Pick<NamingResourceOptions, "cwd" | "configDir" | "home"> = {},
|
|
212
222
|
): SkillMetadataNamingInspection[] {
|
|
213
223
|
const cwd = options.cwd ?? process.cwd();
|
|
214
224
|
const configDir = options.configDir ?? resolveClioDirs().config;
|
|
215
|
-
const
|
|
216
|
-
|
|
225
|
+
const home = options.home ?? homedir();
|
|
226
|
+
const roots = new Set<string>([path.join(configDir, "skills"), path.join(cwd, ".clio-coder", "skills")]);
|
|
227
|
+
for (const kind of INTEROP_AGENT_KINDS) {
|
|
228
|
+
if (kind.userSkillRoot !== undefined) roots.add(path.join(home, kind.userSkillRoot));
|
|
229
|
+
if (kind.projectSkillRoot !== undefined) roots.add(path.join(cwd, kind.projectSkillRoot));
|
|
230
|
+
}
|
|
231
|
+
return [...roots].flatMap((root) =>
|
|
217
232
|
collectSkillFiles(root).map((file) => ({
|
|
218
233
|
path: file,
|
|
219
234
|
legacyMetadataKey: /^clio:\s*(?:#.*)?$/mu.test(readFileSync(file, "utf8")),
|
|
@@ -54,10 +54,14 @@ export function regenerateYaziNamingProfile(options: YaziNamingOptions = {}): Ya
|
|
|
54
54
|
const cacheDir = options.cacheDir ?? resolveClioDirs().cache;
|
|
55
55
|
const before = inspectYaziNaming(cacheDir);
|
|
56
56
|
if (!before.present) {
|
|
57
|
-
return {
|
|
57
|
+
return {
|
|
58
|
+
...before,
|
|
59
|
+
status: "absent",
|
|
60
|
+
detail: "managed files pane profile is absent; next open writes canonical names",
|
|
61
|
+
};
|
|
58
62
|
}
|
|
59
63
|
if (before.legacyEvents === 0 && before.legacyEnvironmentNames === 0) {
|
|
60
|
-
return { ...before, status: "canonical", detail: "managed
|
|
64
|
+
return { ...before, status: "canonical", detail: "managed files pane profile already uses canonical names" };
|
|
61
65
|
}
|
|
62
66
|
const yaziPath = options.yaziPath === undefined ? resolveToolBinary("yazi").binaryPath : options.yaziPath;
|
|
63
67
|
const yaPath = options.yaPath === undefined ? resolveToolBinary("ya").binaryPath : options.yaPath;
|
|
@@ -66,7 +70,8 @@ export function regenerateYaziNamingProfile(options: YaziNamingOptions = {}): Ya
|
|
|
66
70
|
return {
|
|
67
71
|
...before,
|
|
68
72
|
status: "removed-unresolved",
|
|
69
|
-
detail:
|
|
73
|
+
detail:
|
|
74
|
+
"legacy managed profile removed; the files pane engine is unresolved, so the next managed open will regenerate it",
|
|
70
75
|
};
|
|
71
76
|
}
|
|
72
77
|
const profile = ensureYaziProfile({ yaziPath, yaPath, profileDir: before.profileDir });
|
|
@@ -74,8 +79,8 @@ export function regenerateYaziNamingProfile(options: YaziNamingOptions = {}): Ya
|
|
|
74
79
|
return {
|
|
75
80
|
...before,
|
|
76
81
|
status: "regeneration-failed",
|
|
77
|
-
detail: "legacy managed profile removed, but
|
|
82
|
+
detail: "legacy managed profile removed, but the files pane engine rejected the regenerated profile",
|
|
78
83
|
};
|
|
79
84
|
}
|
|
80
|
-
return { ...before, status: "regenerated", detail: "managed
|
|
85
|
+
return { ...before, status: "regenerated", detail: "managed files pane profile regenerated with canonical names" };
|
|
81
86
|
}
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
MiddlewareRegistrationOwner,
|
|
3
|
+
PrepareRegistrationReplacementResult,
|
|
4
|
+
ReplaceRegistrationsReport,
|
|
5
|
+
} from "./registrations.js";
|
|
1
6
|
import type { MiddlewareDiagnosticSink, MiddlewareHookRegistration } from "./runtime.js";
|
|
2
7
|
import type {
|
|
3
8
|
MiddlewareEffect,
|
|
@@ -32,4 +37,25 @@ export interface MiddlewareContract {
|
|
|
32
37
|
* stderr writer default.
|
|
33
38
|
*/
|
|
34
39
|
setDiagnosticSink(sink: MiddlewareDiagnosticSink): void;
|
|
40
|
+
/**
|
|
41
|
+
* Validate an owner's replacement registration set against the current
|
|
42
|
+
* builtin and host ids and build its evaluation list without publishing.
|
|
43
|
+
* Rejected when `generation` is not strictly greater than the owner's
|
|
44
|
+
* active generation. The returned replacement publishes with one reference
|
|
45
|
+
* assignment that cannot refuse or call out, so a composition root can publish it
|
|
46
|
+
* back-to-back with another domain's generation on the same stack.
|
|
47
|
+
*/
|
|
48
|
+
prepareRegistrationReplacement(
|
|
49
|
+
owner: MiddlewareRegistrationOwner,
|
|
50
|
+
generation: number,
|
|
51
|
+
registrations: ReadonlyArray<MiddlewareHookRegistration>,
|
|
52
|
+
): PrepareRegistrationReplacementResult;
|
|
53
|
+
/** Prepare, check currentness, publish, then emit any conflict diagnostics. */
|
|
54
|
+
replaceRegistrations(
|
|
55
|
+
owner: MiddlewareRegistrationOwner,
|
|
56
|
+
generation: number,
|
|
57
|
+
registrations: ReadonlyArray<MiddlewareHookRegistration>,
|
|
58
|
+
): ReplaceRegistrationsReport;
|
|
59
|
+
/** Active generation for an owner; 0 when nothing was ever applied. */
|
|
60
|
+
ownedGeneration(owner: MiddlewareRegistrationOwner): number;
|
|
35
61
|
}
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
resolveHookBudgetTunablesFromEnv,
|
|
7
7
|
} from "./budget.js";
|
|
8
8
|
import type { MiddlewareContract } from "./contract.js";
|
|
9
|
+
import { createMiddlewareRegistrationTable } from "./registrations.js";
|
|
9
10
|
import { cloneMiddlewareRule, listMiddlewareRuleDefinitions } from "./rules.js";
|
|
10
11
|
import {
|
|
11
12
|
type MiddlewareDiagnosticSink,
|
|
@@ -14,6 +15,7 @@ import {
|
|
|
14
15
|
registrationFromRuleDefinition,
|
|
15
16
|
runMiddlewareAsyncRegistrations,
|
|
16
17
|
runMiddlewareRegistrations,
|
|
18
|
+
writeMiddlewareDiagnosticToStderr,
|
|
17
19
|
} from "./runtime.js";
|
|
18
20
|
import { createMiddlewareSnapshot } from "./snapshot.js";
|
|
19
21
|
|
|
@@ -54,18 +56,28 @@ export interface MiddlewareBundleOptions {
|
|
|
54
56
|
|
|
55
57
|
export function createMiddlewareBundle(options: MiddlewareBundleOptions = {}): DomainBundle<MiddlewareContract> {
|
|
56
58
|
const ruleDefinitions = combineRuleDefinitions(listMiddlewareRuleDefinitions(), options.ruleDefinitions ?? []);
|
|
57
|
-
const registrations = combineRegistrations(ruleDefinitions, options.registrations ?? []);
|
|
58
|
-
const registeredIds = new Set(registrations.map((registration) => registration.id));
|
|
59
59
|
let diagnosticSink = options.onDiagnostic;
|
|
60
|
+
// Declarative rules are the fixed tier; construction-time coded
|
|
61
|
+
// registrations are the first host entries, deduplicated first-wins across
|
|
62
|
+
// the shared id namespace exactly as before.
|
|
63
|
+
const table = createMiddlewareRegistrationTable({
|
|
64
|
+
fixed: ruleDefinitions.map(registrationFromRuleDefinition),
|
|
65
|
+
diagnosticSink: () => diagnosticSink ?? writeMiddlewareDiagnosticToStderr,
|
|
66
|
+
});
|
|
67
|
+
for (const registration of options.registrations ?? []) table.registerHook(registration);
|
|
60
68
|
const budgetTracker = options.budgetTracker ?? createEnvHookBudgetTracker();
|
|
61
69
|
const contract: MiddlewareContract = {
|
|
62
70
|
runHook(input) {
|
|
71
|
+
// Capture the list once; a replacement published mid-evaluation
|
|
72
|
+
// takes effect for the next evaluation, never this one.
|
|
73
|
+
const registrations = table.list();
|
|
63
74
|
return runMiddlewareRegistrations(input, registrations, {
|
|
64
75
|
budgetTracker,
|
|
65
76
|
...(diagnosticSink !== undefined ? { onDiagnostic: diagnosticSink } : {}),
|
|
66
77
|
});
|
|
67
78
|
},
|
|
68
79
|
runAsyncHook(input, priorEffects = []) {
|
|
80
|
+
const registrations = table.list();
|
|
69
81
|
return runMiddlewareAsyncRegistrations(input, registrations, priorEffects, {
|
|
70
82
|
...(diagnosticSink !== undefined ? { onDiagnostic: diagnosticSink } : {}),
|
|
71
83
|
});
|
|
@@ -77,13 +89,20 @@ export function createMiddlewareBundle(options: MiddlewareBundleOptions = {}): D
|
|
|
77
89
|
return createMiddlewareSnapshot(ruleDefinitions.map((definition) => definition.rule));
|
|
78
90
|
},
|
|
79
91
|
registerHook(registration) {
|
|
80
|
-
|
|
81
|
-
registeredIds.add(registration.id);
|
|
82
|
-
registrations.push(registration);
|
|
92
|
+
table.registerHook(registration);
|
|
83
93
|
},
|
|
84
94
|
setDiagnosticSink(sink) {
|
|
85
95
|
diagnosticSink = sink;
|
|
86
96
|
},
|
|
97
|
+
prepareRegistrationReplacement(owner, generation, registrations) {
|
|
98
|
+
return table.prepareReplacement(owner, generation, registrations);
|
|
99
|
+
},
|
|
100
|
+
replaceRegistrations(owner, generation, registrations) {
|
|
101
|
+
return table.replaceRegistrations(owner, generation, registrations);
|
|
102
|
+
},
|
|
103
|
+
ownedGeneration(owner) {
|
|
104
|
+
return table.ownedGeneration(owner);
|
|
105
|
+
},
|
|
87
106
|
};
|
|
88
107
|
return {
|
|
89
108
|
extension: {
|
|
@@ -108,22 +127,3 @@ function combineRuleDefinitions(
|
|
|
108
127
|
}
|
|
109
128
|
return combined;
|
|
110
129
|
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* One ordered evaluation list: declarative rules first (builtin, then
|
|
114
|
-
* composition-root), then coded registrations, deduplicated across the shared
|
|
115
|
-
* id namespace with the earlier entry winning.
|
|
116
|
-
*/
|
|
117
|
-
function combineRegistrations(
|
|
118
|
-
ruleDefinitions: ReadonlyArray<MiddlewareRuleDefinition>,
|
|
119
|
-
coded: ReadonlyArray<MiddlewareHookRegistration>,
|
|
120
|
-
): MiddlewareHookRegistration[] {
|
|
121
|
-
const seen = new Set<string>(ruleDefinitions.map((definition) => definition.rule.id));
|
|
122
|
-
const combined: MiddlewareHookRegistration[] = ruleDefinitions.map(registrationFromRuleDefinition);
|
|
123
|
-
for (const registration of coded) {
|
|
124
|
-
if (seen.has(registration.id)) continue;
|
|
125
|
-
seen.add(registration.id);
|
|
126
|
-
combined.push(registration);
|
|
127
|
-
}
|
|
128
|
-
return combined;
|
|
129
|
-
}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Durable receipt log for user-defined middleware hooks. Every hook execution
|
|
3
|
-
* emits a {@link HookReceipt}; this log keeps a bounded in-memory ring
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
3
|
+
* emits a {@link HookReceipt}; this log keeps a bounded in-memory ring and
|
|
4
|
+
* persists it atomically through safeResourceWrite. Writes are throttled so a
|
|
5
|
+
* per-tool-call cadence never turns into per-call disk I/O; `flush()` forces a
|
|
6
|
+
* final write at shutdown. `clio-coder config inspect` reads the persisted
|
|
7
|
+
* snapshot back with {@link readPersistedHookReceipts}, since it runs as its
|
|
8
|
+
* own process and has no access to a running session's in-memory ring.
|
|
7
9
|
*/
|
|
8
10
|
|
|
11
|
+
import { readFileSync } from "node:fs";
|
|
9
12
|
import { safeResourceWrite } from "../../core/safe-resource-write.js";
|
|
10
13
|
import type { HookReceipt } from "./hooks.js";
|
|
11
14
|
|
|
@@ -68,3 +71,23 @@ export function createHookReceiptLog(options: HookReceiptLogOptions = {}): HookR
|
|
|
68
71
|
},
|
|
69
72
|
};
|
|
70
73
|
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Read a log's persisted snapshot back, for a process that never held the
|
|
77
|
+
* live log (`config inspect` runs as its own invocation). A log that has
|
|
78
|
+
* never persisted yet reads as empty, not an error.
|
|
79
|
+
*/
|
|
80
|
+
export function readPersistedHookReceipts(persistPath: string): HookReceipt[] {
|
|
81
|
+
let raw: string;
|
|
82
|
+
try {
|
|
83
|
+
raw = readFileSync(persistPath, "utf8");
|
|
84
|
+
} catch (error) {
|
|
85
|
+
if ((error as NodeJS.ErrnoException).code === "ENOENT") return [];
|
|
86
|
+
throw error;
|
|
87
|
+
}
|
|
88
|
+
const parsed = JSON.parse(raw) as Partial<PersistedReceipts>;
|
|
89
|
+
if (parsed.version !== 1 || !Array.isArray(parsed.receipts)) {
|
|
90
|
+
throw new Error(`${persistPath}: unrecognized hook receipt log shape`);
|
|
91
|
+
}
|
|
92
|
+
return parsed.receipts;
|
|
93
|
+
}
|
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Loading for user-defined middleware hooks and the production command
|
|
3
|
+
* runner. Hooks live in dedicated, secrets-free files so they stay out of the
|
|
4
|
+
* strict settings schema:
|
|
5
5
|
*
|
|
6
6
|
* - `.clio-coder/hooks.yaml` committed project hooks (origin "project"),
|
|
7
7
|
* - `.clio-coder/hooks.local.yaml` gitignored local hooks (origin "project.local"),
|
|
8
8
|
* - `<extensionRoot>/hooks.yaml` hooks shipped by an installed extension.
|
|
9
9
|
*
|
|
10
|
+
* Project files are read from disk here. Extension declarations are never
|
|
11
|
+
* read here: they arrive already parsed as a captured source set that the
|
|
12
|
+
* composition root adapts from the extension snapshot, which captured the
|
|
13
|
+
* bytes during install-digest verification, so a hooks.yaml rewritten after
|
|
14
|
+
* verification cannot be admitted until the next generation re-verifies the
|
|
15
|
+
* tree. Middleware never sees extension-domain types.
|
|
16
|
+
*
|
|
10
17
|
* Reads are best-effort: a missing file is skipped silently, and a malformed
|
|
11
18
|
* file is reported as an issue without aborting anything.
|
|
12
19
|
*/
|
|
@@ -26,6 +33,7 @@ import {
|
|
|
26
33
|
type UserHookCommandRunner,
|
|
27
34
|
type UserHookDeclarationBatch,
|
|
28
35
|
type UserHookLoadResult,
|
|
36
|
+
type UserHookPackageProvenance,
|
|
29
37
|
type UserHookSource,
|
|
30
38
|
userHookToRegistration,
|
|
31
39
|
} from "./hooks.js";
|
|
@@ -43,15 +51,27 @@ export interface ReadHookSourcesResult {
|
|
|
43
51
|
fileIssues: HookFileIssue[];
|
|
44
52
|
}
|
|
45
53
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
54
|
+
/** One package's hook declarations, captured by the supplier from verified bytes. */
|
|
55
|
+
export interface CapturedHookDeclarations {
|
|
56
|
+
provenance: UserHookPackageProvenance;
|
|
57
|
+
/** SHA-256 of the captured hooks.yaml bytes. */
|
|
58
|
+
declarationsDigest: string;
|
|
59
|
+
/** Parsed declarations, or an empty list when parsing failed. */
|
|
60
|
+
declarations: unknown;
|
|
61
|
+
parseError?: string;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** The captured declarations of one supplier generation. */
|
|
65
|
+
export interface CapturedHookSourceSet {
|
|
66
|
+
/** 0 for an ephemeral (uncommitted) build. */
|
|
67
|
+
generation: number;
|
|
68
|
+
sources: ReadonlyArray<CapturedHookDeclarations>;
|
|
49
69
|
}
|
|
50
70
|
|
|
51
71
|
export interface ReadHookSourcesOptions {
|
|
52
72
|
cwd: string;
|
|
53
|
-
/**
|
|
54
|
-
|
|
73
|
+
/** Captured extension declarations; absent means no extension hooks. */
|
|
74
|
+
capturedSources?: CapturedHookSourceSet;
|
|
55
75
|
}
|
|
56
76
|
|
|
57
77
|
function readBatch(
|
|
@@ -86,14 +106,23 @@ export function readHookSources(options: ReadHookSourcesOptions): ReadHookSource
|
|
|
86
106
|
const fileIssues: HookFileIssue[] = [];
|
|
87
107
|
const batches: UserHookDeclarationBatch[] = [];
|
|
88
108
|
|
|
89
|
-
|
|
109
|
+
const captured = options.capturedSources;
|
|
110
|
+
for (const entry of captured?.sources ?? []) {
|
|
90
111
|
const source: UserHookSource = {
|
|
91
112
|
origin: "extension",
|
|
92
|
-
sourcePath: `${
|
|
93
|
-
sourceId:
|
|
113
|
+
sourcePath: `${entry.provenance.id}:hooks.yaml`,
|
|
114
|
+
sourceId: entry.provenance.id,
|
|
115
|
+
extension: {
|
|
116
|
+
provenance: entry.provenance,
|
|
117
|
+
generation: captured?.generation ?? 0,
|
|
118
|
+
declarationsDigest: entry.declarationsDigest,
|
|
119
|
+
},
|
|
94
120
|
};
|
|
95
|
-
|
|
96
|
-
|
|
121
|
+
if (entry.parseError !== undefined) {
|
|
122
|
+
fileIssues.push({ source, message: `failed to parse ${source.sourcePath}: ${entry.parseError}` });
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
batches.push({ source, declarations: entry.declarations });
|
|
97
126
|
}
|
|
98
127
|
|
|
99
128
|
const projectBatch = readBatch(
|
|
@@ -113,44 +142,48 @@ export function readHookSources(options: ReadHookSourcesOptions): ReadHookSource
|
|
|
113
142
|
return { batches, fileIssues };
|
|
114
143
|
}
|
|
115
144
|
|
|
116
|
-
export interface
|
|
145
|
+
export interface BuildUserHookRegistrationsOptions {
|
|
117
146
|
cwd: string;
|
|
118
147
|
/** Absolute workspace root a command `cwd` must resolve under; defaults to `cwd`. */
|
|
119
148
|
workspaceRoot?: string;
|
|
120
|
-
|
|
121
|
-
registerHook: (registration: MiddlewareHookRegistration) => void;
|
|
149
|
+
capturedSources?: CapturedHookSourceSet;
|
|
122
150
|
recordReceipt: HookReceiptSink;
|
|
123
151
|
/** Injected for tests; defaults to the spawnSync runner. */
|
|
124
152
|
runCommand?: UserHookCommandRunner;
|
|
125
153
|
now?: () => number;
|
|
126
154
|
}
|
|
127
155
|
|
|
128
|
-
export interface
|
|
156
|
+
export interface BuildUserHookRegistrationsResult extends UserHookLoadResult {
|
|
129
157
|
fileIssues: HookFileIssue[];
|
|
158
|
+
/** One registration per admitted hook, in merged precedence order. Nothing is registered here. */
|
|
159
|
+
registrations: MiddlewareHookRegistration[];
|
|
130
160
|
}
|
|
131
161
|
|
|
132
162
|
/**
|
|
133
|
-
* Read
|
|
134
|
-
*
|
|
135
|
-
*
|
|
163
|
+
* Read project files, merge them with the captured extension declarations,
|
|
164
|
+
* normalize, and build one registration per admitted hook. Pure with respect
|
|
165
|
+
* to the middleware contract: the caller decides when the set is published,
|
|
166
|
+
* which is what lets extension and hook state publish on one stack. The
|
|
167
|
+
* returned hooks and issues feed `clio-coder config inspect`. Best-effort
|
|
168
|
+
* throughout: a malformed file or hook is reported, never thrown.
|
|
136
169
|
*/
|
|
137
|
-
export function
|
|
170
|
+
export function buildUserHookRegistrations(
|
|
171
|
+
options: BuildUserHookRegistrationsOptions,
|
|
172
|
+
): BuildUserHookRegistrationsResult {
|
|
138
173
|
const workspaceRoot = options.workspaceRoot ?? options.cwd;
|
|
139
174
|
const readOptions: ReadHookSourcesOptions = { cwd: options.cwd };
|
|
140
|
-
if (options.
|
|
175
|
+
if (options.capturedSources !== undefined) readOptions.capturedSources = options.capturedSources;
|
|
141
176
|
const { batches, fileIssues } = readHookSources(readOptions);
|
|
142
177
|
const loaded = loadUserHooks(batches, { workspaceRoot });
|
|
143
178
|
const runCommand = options.runCommand ?? spawnSyncCommandRunner();
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
}
|
|
153
|
-
return { ...loaded, fileIssues };
|
|
179
|
+
const registrations = loaded.hooks.map((hook) =>
|
|
180
|
+
userHookToRegistration(hook, {
|
|
181
|
+
recordReceipt: options.recordReceipt,
|
|
182
|
+
runCommand,
|
|
183
|
+
...(options.now !== undefined ? { now: options.now } : {}),
|
|
184
|
+
}),
|
|
185
|
+
);
|
|
186
|
+
return { ...loaded, fileIssues, registrations };
|
|
154
187
|
}
|
|
155
188
|
|
|
156
189
|
/**
|