@iowarp/clio-coder 0.4.3 → 0.4.4
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 +63 -0
- package/README.md +1 -1
- package/dist/{acp-H2NGRPWO.js → acp-WNAYYF4F.js} +4 -5
- package/dist/{agents-TL5LLUQP.js → agents-3OKXHLOI.js} +33 -31
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-E5SW4HMS.js → auth-VKNNMGPU.js} +10 -11
- package/dist/{builtins-IA7V7FUC.js → builtins-WGALA46I.js} +4 -4
- package/dist/{chunk-F5JHEYZM.js → chunk-23L32XTI.js} +10 -7
- package/dist/{chunk-DWUOQKRU.js → chunk-25QBEXRS.js} +2 -2
- package/dist/{chunk-LLDJM5XK.js → chunk-26QSH3EJ.js} +2 -2
- package/dist/{chunk-N2Z7HLVY.js → chunk-2ASED4PZ.js} +10 -10
- package/dist/{chunk-MCEPRMZW.js → chunk-2CU2H6KE.js} +2 -2
- package/dist/chunk-2DSOYNFC.js +108 -0
- package/dist/{chunk-LDJG7DW3.js → chunk-2ZSONWVL.js} +4 -4
- package/dist/{chunk-GI7YYQ3F.js → chunk-36CT5VVL.js} +324 -41
- package/dist/{chunk-4UVU7BJ5.js → chunk-3GY4F45V.js} +2 -2
- package/dist/{chunk-PUVDKJ2Y.js → chunk-3ODX73FK.js} +3 -5
- package/dist/{chunk-IUE3Y34X.js → chunk-3UNOLWNZ.js} +2 -2
- package/dist/{chunk-6PTFB5VS.js → chunk-3UUXNFEX.js} +8 -4
- package/dist/{chunk-2APPQIER.js → chunk-4M6Z5QVF.js} +4 -4
- package/dist/{chunk-K6BSR66V.js → chunk-4NSRCOYP.js} +4 -1
- package/dist/{chunk-JGRC33J2.js → chunk-54X7T7DK.js} +12 -3
- package/dist/{chunk-YQWYVTMC.js → chunk-5636DCO5.js} +4 -4
- package/dist/{chunk-7E7I3WLS.js → chunk-57XXR6DR.js} +23 -22
- package/dist/{chunk-7ZYNNDKC.js → chunk-5TUB6SLS.js} +2 -2
- package/dist/{chunk-VW6DOEDG.js → chunk-6OSVSQL5.js} +11 -2
- package/dist/{chunk-L47TF46W.js → chunk-6PAZTBPA.js} +14 -2
- package/dist/{chunk-XIVNBFZS.js → chunk-6Q3CYFD3.js} +34 -16
- package/dist/{chunk-RSJ25QSL.js → chunk-6QOTUPRG.js} +155 -36
- package/dist/{chunk-JKKCYP3C.js → chunk-6UINWWS6.js} +10 -4
- package/dist/{chunk-WBKFA554.js → chunk-72YIHOZQ.js} +2 -2
- package/dist/{chunk-PAJQJ7BS.js → chunk-75W7L2E2.js} +246 -697
- package/dist/{chunk-RRNP2ANY.js → chunk-7UGL4MB5.js} +4 -4
- package/dist/{chunk-EKCHAPYA.js → chunk-AUPNRN7C.js} +2 -2
- package/dist/{chunk-ZDN3Y73Y.js → chunk-BJVFZO5U.js} +6 -48
- package/dist/{chunk-IWT4SF4R.js → chunk-CUSRQKPU.js} +64 -2
- package/dist/{chunk-SKHCAU7K.js → chunk-DQOVN6KV.js} +3 -2
- package/dist/{chunk-ZWPRK62N.js → chunk-DT3LWJOB.js} +4 -4
- package/dist/chunk-DXKJURES.js +671 -0
- package/dist/{chunk-BEPZRGGU.js → chunk-EL24TAU4.js} +2 -2
- package/dist/{chunk-OML5D5V5.js → chunk-ELWDPP3Y.js} +5 -5
- package/dist/{chunk-NDINPTJ4.js → chunk-ELZVTCGV.js} +5 -4
- package/dist/chunk-EXLD33WO.js +381 -0
- package/dist/{chunk-IJNZMHLA.js → chunk-FEAXX7B6.js} +2 -2
- package/dist/{chunk-TM6LQDI3.js → chunk-FFUPXJC4.js} +74 -323
- package/dist/chunk-GX5WYQO4.js +59 -0
- package/dist/chunk-I2DWJ4GM.js +390 -0
- package/dist/{chunk-TXOTCRLG.js → chunk-I5FWO7L5.js} +5 -5
- package/dist/chunk-IRXAATOX.js +539 -0
- package/dist/chunk-IXIY2H4R.js +44 -0
- package/dist/{chunk-KK4JZPBQ.js → chunk-IZXGRF7P.js} +76 -10
- package/dist/{chunk-5TSRNF4G.js → chunk-JCI2ROMZ.js} +164 -6
- package/dist/{chunk-INY6HTFL.js → chunk-JEIYHLOR.js} +2 -2
- package/dist/{chunk-MUW2BDDH.js → chunk-JQLNNIKT.js} +2 -2
- package/dist/{chunk-XPWWI35G.js → chunk-JSD46VO2.js} +19 -8
- package/dist/{chunk-VA5FNYMT.js → chunk-JT2RFCC5.js} +39 -2
- package/dist/{chunk-V2ANDPVT.js → chunk-K6T2ZAMZ.js} +168 -6
- package/dist/{chunk-B4OAX3SI.js → chunk-KFV5L5SK.js} +13 -6
- package/dist/{chunk-JEQ3XTHC.js → chunk-LLXSDWXS.js} +2 -2
- package/dist/{chunk-E3TPLWFX.js → chunk-LTIKRKFL.js} +3 -3
- package/dist/{chunk-NIQJ66N4.js → chunk-N56KALIC.js} +17 -17
- package/dist/{chunk-JDAY6FIL.js → chunk-NAI6ZFCY.js} +13 -9
- package/dist/{chunk-AF4YM7Z4.js → chunk-NRO2BJRH.js} +2490 -2182
- package/dist/{chunk-WRBAGUNF.js → chunk-NXIMQY5W.js} +2 -2
- package/dist/{chunk-I7ZPNEJM.js → chunk-NXYCB2VD.js} +5 -5
- package/dist/chunk-ODGTEFFI.js +50 -0
- package/dist/{chunk-2VIKGWFZ.js → chunk-OEJSLEPW.js} +2 -2
- package/dist/{chunk-KKOJXO6R.js → chunk-OMQNJVKW.js} +4 -2
- package/dist/{chunk-54CBCGIR.js → chunk-Q4WO54TA.js} +132 -77
- package/dist/{chunk-B4VEBZKF.js → chunk-QUFRYSWI.js} +12 -6
- package/dist/{chunk-42FMPA75.js → chunk-QZWQA4DE.js} +2 -2
- package/dist/{chunk-HEQY7ZFI.js → chunk-RAY4OVGZ.js} +2 -2
- package/dist/{chunk-G76U63X4.js → chunk-RQCKCSRL.js} +7 -7
- package/dist/{chunk-64I3JVYM.js → chunk-RXTN6AKH.js} +2 -2
- package/dist/{chunk-UPZU6GE4.js → chunk-RZDWV63N.js} +3 -3
- package/dist/{chunk-2UH2KFUP.js → chunk-S6PYF2XF.js} +2 -2
- package/dist/{chunk-JSC3U7TI.js → chunk-TOIVGRUX.js} +2 -2
- package/dist/{chunk-7DRAWPTZ.js → chunk-TQAHXW6Y.js} +1 -1
- package/dist/{chunk-JIEGK6UF.js → chunk-U6TMQNSI.js} +48 -4
- package/dist/{chunk-AX2THNSA.js → chunk-UEPWCCTY.js} +4 -4
- package/dist/{chunk-QWGDJJYJ.js → chunk-USR47QNF.js} +4 -4
- package/dist/{chunk-Y3CBHOR6.js → chunk-V6HJFQZE.js} +2 -2
- package/dist/chunk-V76WTFTW.js +318 -0
- package/dist/{chunk-NMJXSHBJ.js → chunk-W54I7H25.js} +2 -2
- package/dist/{chunk-2UG5F4C5.js → chunk-XULDXHTN.js} +24 -12
- package/dist/chunk-XXYSBZIQ.js +283 -0
- package/dist/{chunk-MWUZBSAQ.js → chunk-Y55JBDO5.js} +331 -51
- package/dist/{chunk-W6RRQCPQ.js → chunk-YD5GIKET.js} +4 -4
- package/dist/{chunk-CE5AX47J.js → chunk-YECAMM3D.js} +2 -2
- package/dist/{chunk-WCXUNS7U.js → chunk-YNFKXPEC.js} +6 -6
- package/dist/cli/index.js +36 -35
- package/dist/{clio-CMMK4KRR.js → clio-QLICPCF5.js} +2 -2
- package/dist/{code-nav-MDZNQS33.js → code-nav-IJR2DBPR.js} +6 -6
- package/dist/{components-UCUQ4QXW.js → components-2TGAI2RC.js} +3 -4
- package/dist/{config-SVM5P5YI.js → config-IUA6OYNS.js} +52 -47
- package/dist/{configure-LE3IK2TJ.js → configure-VEPX4NMX.js} +14 -15
- package/dist/{context-VNCR7KAG.js → context-2DKHWH2T.js} +23 -23
- package/dist/{context-2OHRKS42.js → context-4MPR7WKB.js} +48 -42
- package/dist/{context-E3VC7RX5.js → context-BOYF5EJM.js} +11 -11
- package/dist/{context-clear-BW4O37TG.js → context-clear-S4ZJCQUX.js} +48 -42
- package/dist/{context-working-set-VDS25HXZ.js → context-working-set-3I3FYX6Y.js} +8 -8
- package/dist/detail-A7JAVSIG.js +98 -0
- package/dist/{dispatch-runner-5AHT53RF.js → dispatch-runner-RJ5I2F2O.js} +71 -58
- package/dist/{docs-PD3EXDKU.js → docs-SPOV3BAN.js} +3 -5
- package/dist/{doctor-WNNVO6FY.js → doctor-DKICC2SN.js} +54 -31
- package/dist/{eval-7G7SGAYO.js → eval-OQOQUDHK.js} +47 -56
- package/dist/{evidence-VD6736FQ.js → evidence-4DQ25GUQ.js} +53 -150
- package/dist/evidence-4F5USFKH.js +208 -0
- package/dist/{evolve-AL3NGVRL.js → evolve-GSS52E5J.js} +44 -41
- package/dist/{extensions-MOVJ32NM.js → extensions-G7MFLYHT.js} +4 -5
- package/dist/{fleet-QZHUMAGI.js → fleet-Q37YHHAQ.js} +74 -68
- package/dist/{fleet-commands-BAYT5FJZ.js → fleet-commands-G7E4N7SM.js} +14 -11
- package/dist/{fleet-decisions-IREVMRU4.js → fleet-decisions-O7M6QBA2.js} +6 -6
- package/dist/{fleet-graph-YCTT3HTI.js → fleet-graph-TOUBW6OW.js} +13 -13
- package/dist/{fleet-inspect-QVJTDAVB.js → fleet-inspect-SW33JJNI.js} +43 -39
- package/dist/{fleet-preflight-25QAFPK4.js → fleet-preflight-CV2655TW.js} +2 -3
- package/dist/{fleet-validate-5O57AAJ7.js → fleet-validate-KESZX2YH.js} +16 -16
- package/dist/{fleet-verify-CPH2W2T6.js → fleet-verify-UQPMTVE3.js} +42 -38
- package/dist/{fleet-view-SWBR3VGQ.js → fleet-view-MN2VG4MR.js} +43 -39
- package/dist/{init-J477LKZH.js → init-PXEXQSBF.js} +60 -54
- package/dist/{interop-3FCM6XLG.js → interop-ZG5T62U3.js} +6 -7
- package/dist/inventory-C26CFDRR.js +101 -0
- package/dist/{library-QUQEIUG6.js → library-B2W4N74O.js} +16 -17
- package/dist/{memory-SGGSEP65.js → memory-YCANYS5A.js} +45 -42
- package/dist/{models-HEKUAXXK.js → models-GERTU3YI.js} +20 -22
- package/dist/{monitor-HKU57TYQ.js → monitor-CPNIUULB.js} +50 -44
- package/dist/{orchestrator-VDFAEFAI.js → orchestrator-J4BSH4WQ.js} +491 -1182
- package/dist/{panes-DN2SSFOH.js → panes-BOHAEGYC.js} +3 -3
- package/dist/{panes-TALGNPZT.js → panes-NXSLDQZ2.js} +5 -6
- package/dist/{paths-NBMFAIEZ.js → paths-VSUWNC22.js} +3 -4
- package/dist/{reset-EAJFFJVB.js → reset-TNWTB5LU.js} +5 -6
- package/dist/{resources-OVKSEFVE.js → resources-4PXNMD5G.js} +14 -14
- package/dist/{run-7DP7ZF2J.js → run-D6XJ34CN.js} +79 -83
- package/dist/{share-WML67FT3.js → share-2NWMJJEE.js} +14 -15
- package/dist/{skills-SG662R2K.js → skills-KR7WON5G.js} +18 -19
- package/dist/{skills-eval-VVZEUU46.js → skills-eval-O2ZNOLDS.js} +49 -46
- package/dist/{skills-inventory-I2E23GET.js → skills-inventory-ZZOUBK7O.js} +14 -14
- package/dist/{slash-commands-S7MBJDQK.js → slash-commands-ZXPJD64J.js} +32 -23
- package/dist/{steer-2LQOMCPB.js → steer-XA25PSCS.js} +3 -3
- package/dist/{support-CC2UJBJ6.js → support-7EMVWYG2.js} +2 -2
- package/dist/{targets-4QC3HIEW.js → targets-OMH2XCSN.js} +25 -27
- package/dist/tasks-IPAGMEIX.js +36 -0
- package/dist/{terminal-lease-TUHIJ6Y2.js → terminal-lease-C2J3JYRE.js} +4 -4
- package/dist/{tools-TFGJICCU.js → tools-EFFEAIDP.js} +5 -6
- package/dist/{uninstall-5PEVOE5B.js → uninstall-HALS6BLF.js} +7 -8
- package/dist/{upgrade-M4WXY6KN.js → upgrade-MS72RJEP.js} +14 -11
- package/dist/{usage-N7ZNVLEM.js → usage-NHG6MCJM.js} +60 -51
- package/dist/{verifiers-DJTP4XX6.js → verifiers-7AUNVXDY.js} +150 -17
- package/dist/{verify-RWE4PPEK.js → verify-FWYGPKMR.js} +12 -10
- package/dist/{web-fetch-MPARV2K7.js → web-fetch-V4FKSDAV.js} +4 -4
- package/dist/{wiki-generate-C7IQOXSP.js → wiki-generate-743CIGJW.js} +63 -56
- package/dist/{with-panes-4GCGSL7J.js → with-panes-BDQEWBRT.js} +2 -2
- package/dist/worker/entry.js +36 -33
- package/docs/README.md +3 -2
- package/docs/architecture/acp.md +17 -0
- package/docs/architecture/artifact-versions.md +1 -1
- package/docs/architecture/dispatch-typed-intent.md +1 -1
- package/docs/architecture/evidence-and-memory.md +1 -1
- package/docs/architecture/observability.md +7 -1
- package/docs/architecture/prompt-envelope-and-tools.md +15 -5
- package/docs/architecture/safety-model.md +10 -17
- package/docs/architecture/tui-design.md +1 -1
- package/docs/guide/built-in-agents.md +8 -8
- package/docs/guide/commands-and-modes.md +17 -2
- package/docs/guide/configuration-and-targets.md +3 -1
- package/docs/guide/configuration-reference.md +10 -5
- package/docs/guide/environment-variables.md +2 -2
- package/docs/guide/tool-usage.md +78 -3
- package/docs/history/config-knobs-audit.md +2 -2
- package/docs/process/development-pipeline.md +6 -1
- package/docs/process/git-commit-provenance.md +15 -0
- package/docs/process/release-cut-checklist.md +207 -0
- package/docs/process/scientific-validation.md +18 -17
- package/evals/behavioral-machinery-support.ts +1 -0
- package/evals/behavioral-machinery.yaml +1 -1
- package/package.json +1 -1
- package/skills/coding/coding-standards/SKILL.md +14 -4
- package/skills/context/context-handoff/SKILL.md +3 -3
- package/skills/context/context-prime/SKILL.md +3 -3
- package/skills/planning/architecture/SKILL.md +5 -5
- package/skills/planning/backlog/SKILL.md +4 -4
- package/skills/planning/prd/SKILL.md +4 -3
- package/skills/planning/product-intent/SKILL.md +8 -8
- package/skills/planning/tech-spec/SKILL.md +4 -4
- package/skills/registry.yaml +32 -32
- package/skills/research/arxiv-literature/SKILL.md +3 -3
- package/skills/research/experiment-protocol/SKILL.md +3 -3
- package/skills/research/scientific-debugging/SKILL.md +3 -2
- package/skills/research/scientific-modernization/SKILL.md +3 -3
- package/skills/skill-marketplace.json +16 -16
- package/skills/workflow/cut-it/SKILL.md +3 -4
- package/skills/workflow/design-council/SKILL.md +5 -10
- package/skills/workflow/grill-me/SKILL.md +14 -15
- package/skills/workflow/workflow-distiller/SKILL.md +4 -4
- package/src/cli/args.ts +0 -8
- package/src/cli/configure.ts +2 -1
- package/src/cli/doctor-state-size.ts +1 -12
- package/src/cli/doctor-validation-contract.ts +28 -0
- package/src/cli/doctor.ts +5 -0
- package/src/cli/evidence-detail.ts +1 -75
- package/src/cli/evidence-inventory.ts +1 -167
- package/src/cli/index.ts +2 -0
- package/src/cli/run.ts +0 -2
- package/src/cli/targets.ts +1 -1
- package/src/cli/tasks.ts +84 -0
- package/src/cli/upgrade.ts +10 -5
- package/src/cli/usage.ts +6 -0
- package/src/cli/verifiers.ts +147 -1
- package/src/cli/wiki-generate.ts +1 -0
- package/src/core/commit-attribution.ts +41 -1
- package/src/core/git-commit-attribution.ts +46 -3
- package/src/core/run-overrides.ts +0 -5
- package/src/core/skill-activation.ts +3 -0
- package/src/core/tool-names.ts +5 -2
- package/src/domains/agents/builtins/architect.md +1 -1
- package/src/domains/agents/builtins/coder.md +1 -1
- package/src/domains/agents/builtins/documenter.md +1 -1
- package/src/domains/agents/builtins/git-master.md +1 -1
- package/src/domains/agents/builtins/provenance.md +7 -7
- package/src/domains/agents/builtins/tester.md +1 -1
- package/src/domains/agents/builtins/verifier.md +2 -2
- package/src/domains/agents/builtins/wiki-writer.md +4 -3
- package/src/domains/context/extension.ts +31 -7
- package/src/domains/context/refresh.ts +3 -0
- package/src/domains/context/wiki/frontmatter.ts +5 -2
- package/src/domains/context/wiki/generate.ts +6 -0
- package/src/domains/context/wiki/prompts.ts +43 -0
- package/src/domains/dispatch/active-route-planner.ts +4 -0
- package/src/domains/dispatch/code-step.ts +11 -4
- package/src/domains/dispatch/contract.ts +31 -7
- package/src/domains/dispatch/execution-scheduler.ts +2 -0
- package/src/domains/dispatch/extension.ts +50 -27
- package/src/domains/dispatch/fleet-commit-attribution.ts +5 -0
- package/src/domains/dispatch/fleet-run.ts +1 -0
- package/src/domains/dispatch/host-verification.ts +114 -13
- package/src/domains/dispatch/intent.ts +28 -18
- package/src/domains/dispatch/orphan-recovery.ts +2 -0
- package/src/domains/dispatch/receipt-integrity.ts +4 -0
- package/src/domains/dispatch/reservation-store.ts +5 -3
- package/src/domains/dispatch/state.ts +15 -2
- package/src/domains/dispatch/types.ts +17 -2
- package/src/domains/eval/runners/clio-run.ts +12 -9
- package/src/domains/eval/runners/context-index.ts +2 -7
- package/src/domains/eval/runners/context-init.ts +3 -6
- package/src/domains/eval/runners/external-command.ts +29 -11
- package/src/domains/evidence/build.ts +102 -15
- package/src/domains/evidence/detail.ts +69 -0
- package/src/domains/evidence/eval.ts +13 -1
- package/src/domains/evidence/finish-contract-map.ts +5 -1
- package/src/domains/evidence/inventory.ts +167 -0
- package/src/domains/evidence/store.ts +16 -0
- package/src/domains/evidence/types.ts +12 -0
- package/src/domains/extensions/resources.ts +7 -0
- package/src/domains/middleware/marketplace-offer.ts +20 -1
- package/src/domains/middleware/runtime.ts +7 -3
- package/src/domains/mux/detect.ts +3 -6
- package/src/domains/observability/accountability.ts +15 -1
- package/src/domains/observability/contract.ts +52 -7
- package/src/domains/observability/evidence-index.ts +10 -0
- package/src/domains/observability/extension.ts +9 -5
- package/src/domains/observability/projection.ts +394 -45
- package/src/{interactive → domains/observability}/worker-progress.ts +3 -3
- package/src/domains/prompts/fragments/operating/contract.md +2 -0
- package/src/domains/prompts/fragments/wiki/page.md +8 -0
- package/src/domains/providers/model-discovery.ts +1 -4
- package/src/domains/providers/models/local-models/clio-coder-local-coding-targets.yaml +16 -14
- package/src/domains/providers/runtimes/claude/claude-code.ts +9 -0
- package/src/domains/providers/support.ts +1 -1
- package/src/domains/providers/types/runtime-descriptor.ts +1 -1
- package/src/domains/safety/action-classifier.ts +7 -0
- package/src/domains/safety/default-path-policy.ts +2 -0
- package/src/domains/safety/finish-contract-registration.ts +29 -14
- package/src/domains/safety/finish-contract.ts +252 -40
- package/src/domains/safety/index.ts +20 -1
- package/src/domains/safety/policy-engine.ts +26 -6
- package/src/domains/safety/rigor.ts +53 -39
- package/src/domains/safety/validation-contract.ts +388 -0
- package/src/domains/session/archive-readers.ts +10 -1
- package/src/domains/session/decision-board.ts +101 -2
- package/src/domains/session/entries.ts +44 -7
- package/src/domains/session/extension.ts +4 -4
- package/src/domains/session/handoff.ts +2 -1
- package/src/domains/session/manager.ts +2 -3
- package/src/domains/session/task-board.ts +14 -1
- package/src/domains/session/tree/fork.ts +1 -2
- package/src/domains/session/tree/navigator.ts +1 -1
- package/src/domains/user-tasks/acceptance.ts +56 -0
- package/src/domains/user-tasks/active-acceptance.ts +40 -0
- package/src/domains/user-tasks/store.ts +34 -3
- package/src/engine/acp/adapter.ts +24 -6
- package/src/engine/acp/server.ts +21 -4
- package/src/engine/acp/transport.ts +53 -8
- package/src/engine/acp/types.ts +4 -0
- package/src/engine/apis/ollama-native.ts +15 -0
- package/src/engine/claude/subprocess-runtime.ts +107 -60
- package/src/engine/external-subprocess.ts +12 -4
- package/src/entry/orchestrator.ts +11 -2
- package/src/interactive/dispatch-board.ts +46 -717
- package/src/interactive/fleet-run-preview.ts +2 -1
- package/src/interactive/interactive-application.ts +3 -2
- package/src/interactive/interactive-presentation.ts +55 -12
- package/src/interactive/interactive-slash-runtime.ts +2 -1
- package/src/interactive/oracle.ts +5 -2
- package/src/interactive/overlays/fleet-run-approval.ts +3 -2
- package/src/interactive/overlays/message-picker.ts +2 -2
- package/src/interactive/overlays/settings.ts +2 -2
- package/src/interactive/overlays/tree-selector.ts +2 -2
- package/src/interactive/renderers/branch-summary.ts +1 -1
- package/src/interactive/slash-autocomplete.ts +4 -6
- package/src/interactive/slash-commands.ts +25 -39
- package/src/interactive/slash-spec.ts +28 -0
- package/src/interactive/view/artifacts.ts +2 -0
- package/src/interactive/worker-stream.ts +7 -3
- package/src/tools/bootstrap.ts +4 -0
- package/src/tools/builtin-tool-catalog.ts +31 -0
- package/src/tools/compete-worktrees.ts +7 -1
- package/src/tools/core-bootstrap.ts +16 -0
- package/src/tools/decide.ts +136 -0
- package/src/tools/dispatch-admission.ts +21 -0
- package/src/tools/dispatch-plan.ts +5 -2
- package/src/tools/dispatch-runner.ts +15 -1
- package/src/tools/dispatch-types.ts +6 -0
- package/src/tools/evidence.ts +96 -0
- package/src/tools/limitation.ts +76 -0
- package/src/tools/policy.ts +9 -0
- package/src/tools/presentation.ts +3 -0
- package/src/tools/registry.ts +1 -1
- package/src/tools/result-shaping.ts +17 -5
- package/src/tools/task-worktree.ts +13 -3
- package/src/tools/tasks.ts +10 -1
- package/src/tools/verify/authoring.ts +170 -83
- package/src/tools/verify/catalog.ts +122 -5
- package/src/tools/verify/index.ts +2 -1
- package/src/tools/verify/numeric.ts +298 -0
- package/src/tools/verify/perf.ts +143 -0
- package/src/tools/verify/scripts.ts +229 -2
- package/dist/chunk-7DICMOS6.js +0 -313
- package/dist/chunk-RVG5JXAL.js +0 -41
- package/dist/chunk-T56WDKA5.js +0 -183
- package/dist/chunk-VPKWYKEY.js +0 -169
|
@@ -0,0 +1,539 @@
|
|
|
1
|
+
import { createRequire as __clioCreateRequire } from "node:module"; const require = __clioCreateRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
PATH_BOUNDARY_MAX_ENTRIES,
|
|
4
|
+
PathBoundaryError,
|
|
5
|
+
asDirectoryPathBoundary,
|
|
6
|
+
normalizePathBoundaryEntry,
|
|
7
|
+
pathBoundaryCovers,
|
|
8
|
+
resolvePathBoundary
|
|
9
|
+
} from "./chunk-HHV2GANA.js";
|
|
10
|
+
import {
|
|
11
|
+
init_esm_shims
|
|
12
|
+
} from "./chunk-3R73A4XB.js";
|
|
13
|
+
|
|
14
|
+
// src/domains/dispatch/intent.ts
|
|
15
|
+
init_esm_shims();
|
|
16
|
+
import path from "node:path";
|
|
17
|
+
|
|
18
|
+
// src/domains/dispatch/path-scope.ts
|
|
19
|
+
init_esm_shims();
|
|
20
|
+
import { existsSync } from "node:fs";
|
|
21
|
+
var DISPATCH_PATH_TOKEN_RE = /(?:[\w.-]+\/)+[\w.-]+|\b[\w-]+\.[A-Za-z0-9]{1,8}\b/g;
|
|
22
|
+
var HTTP_URL_RE = /\bhttps?:\/\/\S+/gu;
|
|
23
|
+
var POSIX_ABSOLUTE_TOKEN_RE = /(?:^|[\s("'])((?:\/[\w.~+-]+)+)/gu;
|
|
24
|
+
var WINDOWS_ABSOLUTE_TOKEN_RE = /(?:^|[\s("'])([A-Za-z]:[\\/][^\s"']+)/gu;
|
|
25
|
+
var BACKSLASH_PATH_RE = /\b[A-Za-z_.-][\w.-]*\\(?:(?:[\w.-]+\\)+[\w.-]+|[\w-]+\.[A-Za-z0-9]{1,8})\b/gu;
|
|
26
|
+
var DOUBLE_SEPARATOR_PATH_RE = /\b[\w.-]+\/\/[\w./-]+/gu;
|
|
27
|
+
var PARENT_PREFIX_RE = /^(?:\.\.\/)+/u;
|
|
28
|
+
var DispatchPathScopeInferenceError = class extends Error {
|
|
29
|
+
code;
|
|
30
|
+
source;
|
|
31
|
+
token;
|
|
32
|
+
constructor(code, source, token, detail) {
|
|
33
|
+
super(`${code}: ${source} contains ${detail} '${token}'; declare intent explicitly`);
|
|
34
|
+
this.name = "DispatchPathScopeInferenceError";
|
|
35
|
+
this.code = code;
|
|
36
|
+
this.source = source;
|
|
37
|
+
this.token = token;
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
var DECLARED_EVIDENCE = {
|
|
41
|
+
readRoots: {
|
|
42
|
+
provenance: "declared",
|
|
43
|
+
source: "intent.read_roots",
|
|
44
|
+
confidence: "certain",
|
|
45
|
+
reason: "explicit_intent"
|
|
46
|
+
},
|
|
47
|
+
writeRoots: {
|
|
48
|
+
provenance: "declared",
|
|
49
|
+
source: "intent.write_roots",
|
|
50
|
+
confidence: "certain",
|
|
51
|
+
reason: "explicit_intent"
|
|
52
|
+
},
|
|
53
|
+
relevantPaths: {
|
|
54
|
+
provenance: "declared",
|
|
55
|
+
source: "intent.relevant_paths",
|
|
56
|
+
confidence: "certain",
|
|
57
|
+
reason: "explicit_intent"
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
function cloneEvidence(evidence) {
|
|
61
|
+
return { ...evidence };
|
|
62
|
+
}
|
|
63
|
+
function addProvenance(entries, path2, evidence) {
|
|
64
|
+
const current = entries.get(path2);
|
|
65
|
+
if (current === void 0) {
|
|
66
|
+
entries.set(path2, { path: path2, evidence: [cloneEvidence(evidence)] });
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (!current.evidence.some((entry) => entry.source === evidence.source)) {
|
|
70
|
+
current.evidence.push(cloneEvidence(evidence));
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function sortedEntries(entries) {
|
|
74
|
+
return [...entries.values()].sort((left, right) => left.path < right.path ? -1 : left.path > right.path ? 1 : 0).map((entry) => ({ path: entry.path, evidence: entry.evidence.map(cloneEvidence) }));
|
|
75
|
+
}
|
|
76
|
+
function declaredIntentPathProvenance(input) {
|
|
77
|
+
const entries = /* @__PURE__ */ new Map();
|
|
78
|
+
for (const path2 of input.readRoots) addProvenance(entries, path2, DECLARED_EVIDENCE.readRoots);
|
|
79
|
+
for (const path2 of input.writeRoots) addProvenance(entries, path2, DECLARED_EVIDENCE.writeRoots);
|
|
80
|
+
for (const path2 of input.relevantPaths) addProvenance(entries, path2, DECLARED_EVIDENCE.relevantPaths);
|
|
81
|
+
return sortedEntries(entries);
|
|
82
|
+
}
|
|
83
|
+
function inferredPaths(req, root) {
|
|
84
|
+
const paths = /* @__PURE__ */ new Set();
|
|
85
|
+
const droppedTokens = /* @__PURE__ */ new Set();
|
|
86
|
+
const text = `${req.task}
|
|
87
|
+
${req.briefing ?? ""}`;
|
|
88
|
+
for (const match of text.matchAll(DISPATCH_PATH_TOKEN_RE)) {
|
|
89
|
+
const inferred = inferredPathToken(match[0], root);
|
|
90
|
+
if (inferred.kind === "dropped") {
|
|
91
|
+
droppedTokens.add(inferred.token);
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
const token = inferred.kind === "anchored" ? inferred.resolved : inferred.token;
|
|
95
|
+
if (token.startsWith("http://") || token.startsWith("https://")) continue;
|
|
96
|
+
paths.add(token);
|
|
97
|
+
}
|
|
98
|
+
return { paths: [...paths], droppedTokens: [...droppedTokens] };
|
|
99
|
+
}
|
|
100
|
+
function inferredPathToken(raw, root) {
|
|
101
|
+
const token = raw.replace(/^\.\//u, "").replace(/\.+$/u, "");
|
|
102
|
+
const parents = PARENT_PREFIX_RE.exec(token)?.[0];
|
|
103
|
+
if (parents === void 0) return { kind: "token", token };
|
|
104
|
+
const rest = token.slice(parents.length);
|
|
105
|
+
const segments = rest.split("/");
|
|
106
|
+
if (rest.length === 0 || segments.includes("..") || segments.includes(".")) return { kind: "token", token };
|
|
107
|
+
return existsSync(resolvePathBoundary(root, rest)) ? { kind: "anchored", token, resolved: rest } : { kind: "dropped", token };
|
|
108
|
+
}
|
|
109
|
+
function failMalformedText(text, source) {
|
|
110
|
+
const withoutUrls = text.replace(HTTP_URL_RE, (url) => " ".repeat(url.length));
|
|
111
|
+
const absolute = POSIX_ABSOLUTE_TOKEN_RE.exec(withoutUrls)?.[1];
|
|
112
|
+
POSIX_ABSOLUTE_TOKEN_RE.lastIndex = 0;
|
|
113
|
+
if (absolute !== void 0) {
|
|
114
|
+
throw new DispatchPathScopeInferenceError("legacy_scope_path_absolute", source, absolute, "an absolute path token");
|
|
115
|
+
}
|
|
116
|
+
const windowsAbsolute = WINDOWS_ABSOLUTE_TOKEN_RE.exec(withoutUrls)?.[1];
|
|
117
|
+
WINDOWS_ABSOLUTE_TOKEN_RE.lastIndex = 0;
|
|
118
|
+
if (windowsAbsolute !== void 0) {
|
|
119
|
+
throw new DispatchPathScopeInferenceError(
|
|
120
|
+
"legacy_scope_path_absolute",
|
|
121
|
+
source,
|
|
122
|
+
windowsAbsolute,
|
|
123
|
+
"an absolute path token"
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
for (const pattern of [BACKSLASH_PATH_RE, DOUBLE_SEPARATOR_PATH_RE]) {
|
|
127
|
+
const malformed = pattern.exec(withoutUrls)?.[0];
|
|
128
|
+
pattern.lastIndex = 0;
|
|
129
|
+
if (malformed !== void 0) {
|
|
130
|
+
throw new DispatchPathScopeInferenceError(
|
|
131
|
+
"legacy_scope_path_malformed",
|
|
132
|
+
source,
|
|
133
|
+
malformed,
|
|
134
|
+
"a malformed path token"
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
function strictInferredPaths(text, source, root) {
|
|
140
|
+
failMalformedText(text, source);
|
|
141
|
+
const withoutUrls = text.replace(HTTP_URL_RE, (url) => " ".repeat(url.length));
|
|
142
|
+
const evidence = source === "task" ? { provenance: "inferred", source, confidence: "medium", reason: "task_path_token" } : { provenance: "inferred", source, confidence: "low", reason: "briefing_path_token" };
|
|
143
|
+
const paths = [];
|
|
144
|
+
const parentTokens = [];
|
|
145
|
+
for (const match of withoutUrls.matchAll(DISPATCH_PATH_TOKEN_RE)) {
|
|
146
|
+
const inferred = inferredPathToken(match[0], root);
|
|
147
|
+
if (inferred.kind === "dropped") {
|
|
148
|
+
parentTokens.push({ token: inferred.token, resolved: null, source });
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
if (inferred.kind === "anchored") {
|
|
152
|
+
parentTokens.push({ token: inferred.token, resolved: inferred.resolved, source });
|
|
153
|
+
}
|
|
154
|
+
const token = inferred.kind === "anchored" ? inferred.resolved : inferred.token;
|
|
155
|
+
try {
|
|
156
|
+
paths.push({ path: normalizePathBoundaryEntry(token), evidence });
|
|
157
|
+
} catch (error) {
|
|
158
|
+
const code = error instanceof PathBoundaryError && error.code === "absolute" ? "legacy_scope_path_absolute" : "legacy_scope_path_malformed";
|
|
159
|
+
throw new DispatchPathScopeInferenceError(
|
|
160
|
+
code,
|
|
161
|
+
source,
|
|
162
|
+
token,
|
|
163
|
+
code === "legacy_scope_path_absolute" ? "an absolute path token" : "a malformed path token"
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return { paths, parentTokens };
|
|
168
|
+
}
|
|
169
|
+
function legacyPathScope(req, cwd) {
|
|
170
|
+
const workingEntries = /* @__PURE__ */ new Map();
|
|
171
|
+
const writeEntries = /* @__PURE__ */ new Map();
|
|
172
|
+
const writeEvidence = {
|
|
173
|
+
provenance: "derived",
|
|
174
|
+
source: "writeRoots",
|
|
175
|
+
confidence: "high",
|
|
176
|
+
reason: "legacy_write_roots"
|
|
177
|
+
};
|
|
178
|
+
for (const root of req.writeRoots ?? []) {
|
|
179
|
+
addProvenance(workingEntries, root, writeEvidence);
|
|
180
|
+
addProvenance(writeEntries, asDirectoryPathBoundary(resolvePathBoundary(cwd, root)), writeEvidence);
|
|
181
|
+
}
|
|
182
|
+
const parentTokens = /* @__PURE__ */ new Map();
|
|
183
|
+
const recordParentTokens = (entries) => {
|
|
184
|
+
for (const entry of entries) if (!parentTokens.has(entry.token)) parentTokens.set(entry.token, entry);
|
|
185
|
+
};
|
|
186
|
+
const taskScope = strictInferredPaths(req.task, "task", cwd);
|
|
187
|
+
for (const candidate of taskScope.paths) addProvenance(workingEntries, candidate.path, candidate.evidence);
|
|
188
|
+
recordParentTokens(taskScope.parentTokens);
|
|
189
|
+
if (req.briefing !== void 0) {
|
|
190
|
+
const briefingScope = strictInferredPaths(req.briefing, "briefing", cwd);
|
|
191
|
+
for (const candidate of briefingScope.paths) addProvenance(workingEntries, candidate.path, candidate.evidence);
|
|
192
|
+
recordParentTokens(briefingScope.parentTokens);
|
|
193
|
+
}
|
|
194
|
+
const workingContext = [...workingEntries.values()].map((entry) => ({
|
|
195
|
+
path: entry.path,
|
|
196
|
+
evidence: entry.evidence.map(cloneEvidence)
|
|
197
|
+
}));
|
|
198
|
+
const writeBoundaries = [...writeEntries.values()].map((entry) => ({
|
|
199
|
+
path: entry.path,
|
|
200
|
+
evidence: entry.evidence.map(cloneEvidence)
|
|
201
|
+
}));
|
|
202
|
+
return {
|
|
203
|
+
source: "inferred",
|
|
204
|
+
workingContextPaths: workingContext.map((entry) => entry.path),
|
|
205
|
+
writeBoundaries: writeBoundaries.map((entry) => entry.path),
|
|
206
|
+
inferredOnlyPaths: [],
|
|
207
|
+
parentTokens: [...parentTokens.values()],
|
|
208
|
+
provenance: {
|
|
209
|
+
version: 1,
|
|
210
|
+
mode: "legacy-inferred",
|
|
211
|
+
workingContextPaths: workingContext,
|
|
212
|
+
writeBoundaries
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
function resolveDispatchPathScope(req) {
|
|
217
|
+
const cwd = req.cwd ?? process.cwd();
|
|
218
|
+
if (req.intent === void 0) return legacyPathScope(req, cwd);
|
|
219
|
+
const declaredProvenance = declaredIntentPathProvenance(req.intent);
|
|
220
|
+
const declaredPaths = declaredProvenance.map((entry) => entry.path);
|
|
221
|
+
const inferred = inferredPaths(req, cwd);
|
|
222
|
+
const inferredOnlyPaths = [
|
|
223
|
+
...inferred.paths.filter((candidate) => !pathBoundaryCovers(declaredPaths, candidate)),
|
|
224
|
+
...inferred.droppedTokens
|
|
225
|
+
];
|
|
226
|
+
const writeEvidence = DECLARED_EVIDENCE.writeRoots;
|
|
227
|
+
const writeBoundaries = req.intent.writeRoots.map((root) => ({
|
|
228
|
+
path: resolvePathBoundary(cwd, root),
|
|
229
|
+
evidence: [cloneEvidence(writeEvidence)]
|
|
230
|
+
}));
|
|
231
|
+
return {
|
|
232
|
+
source: "declared",
|
|
233
|
+
workingContextPaths: declaredPaths,
|
|
234
|
+
writeBoundaries: writeBoundaries.map((entry) => entry.path),
|
|
235
|
+
inferredOnlyPaths,
|
|
236
|
+
// Empty on purpose: the declaration is the scope here, so no "../" token
|
|
237
|
+
// changed what the worker sees and there is nothing for the legacy notice
|
|
238
|
+
// to report. A dropped one still reaches the operator through
|
|
239
|
+
// inferredOnlyPaths above.
|
|
240
|
+
parentTokens: [],
|
|
241
|
+
provenance: {
|
|
242
|
+
version: 1,
|
|
243
|
+
mode: "declared",
|
|
244
|
+
workingContextPaths: declaredProvenance,
|
|
245
|
+
writeBoundaries
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
var REPORTABLE_OMITTED_PATH_RE = /\.(?:[cm]?[jt]sx?|json|ya?ml|md|txt|py|go|rs|c|h|cc|cpp|hpp|java|rb|sh|toml|css|html|sql|lock)(?:\/|$)|\/$/u;
|
|
250
|
+
var OMITTED_PATH_REPORT_CAP = 12;
|
|
251
|
+
function reportableOmittedPaths(scope) {
|
|
252
|
+
return scope.inferredOnlyPaths.filter((path2) => REPORTABLE_OMITTED_PATH_RE.test(path2));
|
|
253
|
+
}
|
|
254
|
+
function renderOmittedPaths(paths) {
|
|
255
|
+
if (paths.length <= OMITTED_PATH_REPORT_CAP) return paths.join(", ");
|
|
256
|
+
return `${paths.slice(0, OMITTED_PATH_REPORT_CAP).join(", ")} and ${paths.length - OMITTED_PATH_REPORT_CAP} more`;
|
|
257
|
+
}
|
|
258
|
+
function declaredScopeReplacementDiagnostic(scope) {
|
|
259
|
+
if (scope.source !== "declared") return null;
|
|
260
|
+
const omitted = reportableOmittedPaths(scope);
|
|
261
|
+
if (omitted.length === 0) return null;
|
|
262
|
+
return `typed_scope_replaced_inferred_paths: typed intent omitted prose-inferred paths ${renderOmittedPaths(
|
|
263
|
+
omitted
|
|
264
|
+
)}; those paths did not select project rules or expand worker authority`;
|
|
265
|
+
}
|
|
266
|
+
function declaredScopeReplacementNotice(scope) {
|
|
267
|
+
if (scope.source !== "declared") return null;
|
|
268
|
+
const omittedPaths = reportableOmittedPaths(scope);
|
|
269
|
+
if (omittedPaths.length === 0) return null;
|
|
270
|
+
return {
|
|
271
|
+
code: "typed_scope_replaced_inferred_paths",
|
|
272
|
+
level: "warning",
|
|
273
|
+
omittedPaths,
|
|
274
|
+
message: `[dispatch scope] typed intent replaced prose path inference; omitted paths: ${renderOmittedPaths(
|
|
275
|
+
omittedPaths
|
|
276
|
+
)}. Those paths did not select project rules or expand worker authority.`
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
function renderParentTokens(tokens) {
|
|
280
|
+
return renderOmittedPaths(tokens.map((entry) => `${entry.token} -> ${entry.resolved ?? "dropped"}`));
|
|
281
|
+
}
|
|
282
|
+
function inferredScopeParentTokenDiagnostic(scope) {
|
|
283
|
+
const tokens = scope.parentTokens;
|
|
284
|
+
if (tokens.length === 0) return null;
|
|
285
|
+
return `legacy_scope_inferred: prose inference resolved path tokens carrying a leading '../' run against the dispatch root ${renderParentTokens(
|
|
286
|
+
tokens
|
|
287
|
+
)}; an anchored token selects project rules without expanding worker authority and a dropped one took no part in scope`;
|
|
288
|
+
}
|
|
289
|
+
function inferredScopeParentTokenNotice(scope) {
|
|
290
|
+
const tokens = scope.parentTokens;
|
|
291
|
+
if (tokens.length === 0) return null;
|
|
292
|
+
return {
|
|
293
|
+
code: "legacy_scope_inferred",
|
|
294
|
+
level: "warning",
|
|
295
|
+
// Every entry names the raw prose token, the one spelling both outcomes
|
|
296
|
+
// share; the message carries what each one resolved to.
|
|
297
|
+
paths: tokens.map((entry) => ({
|
|
298
|
+
path: entry.token,
|
|
299
|
+
policy: "working-context",
|
|
300
|
+
provenance: "inferred",
|
|
301
|
+
source: entry.source,
|
|
302
|
+
confidence: "low"
|
|
303
|
+
})),
|
|
304
|
+
message: `[dispatch scope] prose inference resolved path tokens carrying a leading '../' run against the dispatch root: ${renderParentTokens(
|
|
305
|
+
tokens
|
|
306
|
+
)}. An anchored token selects project rules without expanding worker authority; a dropped one took no part in scope.`
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// src/domains/dispatch/intent.ts
|
|
311
|
+
var DISPATCH_INTENT_PATH_LIST_CAP = PATH_BOUNDARY_MAX_ENTRIES;
|
|
312
|
+
var DISPATCH_INTENT_PATH_ENTRY_BYTES_CAP = 512;
|
|
313
|
+
var DISPATCH_INTENT_VERIFICATION_CAP = 8;
|
|
314
|
+
var DISPATCH_INTENT_TIMEOUT_MIN_MS = 1e3;
|
|
315
|
+
var RAW_FIELDS = /* @__PURE__ */ new Set([
|
|
316
|
+
"version",
|
|
317
|
+
"read_roots",
|
|
318
|
+
"write_roots",
|
|
319
|
+
"relevant_paths",
|
|
320
|
+
"expected_outputs",
|
|
321
|
+
"verification"
|
|
322
|
+
]);
|
|
323
|
+
function isRecord(value) {
|
|
324
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
325
|
+
}
|
|
326
|
+
function compareCodepoints(left, right) {
|
|
327
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
328
|
+
}
|
|
329
|
+
function fail(reason, message) {
|
|
330
|
+
return { ok: false, reason, message };
|
|
331
|
+
}
|
|
332
|
+
function checkedPathText(value, field, index) {
|
|
333
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
334
|
+
return fail("intent_path_malformed", `${field}[${index}] must be a non-empty repository-relative POSIX path`);
|
|
335
|
+
}
|
|
336
|
+
const trimmed = value.trim();
|
|
337
|
+
if (Buffer.byteLength(trimmed, "utf8") > DISPATCH_INTENT_PATH_ENTRY_BYTES_CAP) {
|
|
338
|
+
return fail(
|
|
339
|
+
"intent_path_over_cap",
|
|
340
|
+
`${field}[${index}] exceeds the ${DISPATCH_INTENT_PATH_ENTRY_BYTES_CAP}-byte cap`
|
|
341
|
+
);
|
|
342
|
+
}
|
|
343
|
+
return trimmed;
|
|
344
|
+
}
|
|
345
|
+
function normalizeScopePathEntry(value, field, index) {
|
|
346
|
+
const checked = checkedPathText(value, field, index);
|
|
347
|
+
if (typeof checked !== "string") return checked;
|
|
348
|
+
try {
|
|
349
|
+
return normalizePathBoundaryEntry(checked);
|
|
350
|
+
} catch (error) {
|
|
351
|
+
if (error instanceof PathBoundaryError) {
|
|
352
|
+
if (error.code === "absolute") {
|
|
353
|
+
return fail("intent_path_absolute", `${field}[${index}] must be a repository-relative POSIX path`);
|
|
354
|
+
}
|
|
355
|
+
if (error.code === "parent") {
|
|
356
|
+
return fail("intent_path_escapes_root", `${field}[${index}] escapes the repository root`);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
return fail(
|
|
360
|
+
"intent_path_malformed",
|
|
361
|
+
`${field}[${index}] does not follow the repository path boundary grammar: ${error instanceof Error ? error.message : String(error)}`
|
|
362
|
+
);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
function normalizeExpectedOutputEntry(value, field, index) {
|
|
366
|
+
const checked = checkedPathText(value, field, index);
|
|
367
|
+
if (typeof checked !== "string") return checked;
|
|
368
|
+
const trimmed = checked;
|
|
369
|
+
if (trimmed.includes("\\") || path.posix.isAbsolute(trimmed) || path.win32.isAbsolute(trimmed)) {
|
|
370
|
+
return fail("intent_path_absolute", `${field}[${index}] must be a repository-relative POSIX path`);
|
|
371
|
+
}
|
|
372
|
+
const normalized = path.posix.normalize(trimmed.replace(/^\.\//u, "").replace(/\/{2,}/gu, "/"));
|
|
373
|
+
if (normalized === "." || normalized.length === 0) {
|
|
374
|
+
return fail("intent_path_malformed", `${field}[${index}] must not normalize to an empty path`);
|
|
375
|
+
}
|
|
376
|
+
if (normalized === ".." || normalized.startsWith("../") || normalized.split("/").includes("..")) {
|
|
377
|
+
return fail("intent_path_escapes_root", `${field}[${index}] escapes the repository root`);
|
|
378
|
+
}
|
|
379
|
+
return normalized;
|
|
380
|
+
}
|
|
381
|
+
function normalizePathList(value, field, normalizeEntry = normalizeScopePathEntry) {
|
|
382
|
+
if (value === void 0) return [];
|
|
383
|
+
if (!Array.isArray(value)) return fail("intent_path_malformed", `${field} must be an array`);
|
|
384
|
+
if (value.length > DISPATCH_INTENT_PATH_LIST_CAP) {
|
|
385
|
+
return fail("intent_path_over_cap", `${field} exceeds the ${DISPATCH_INTENT_PATH_LIST_CAP}-entry cap`);
|
|
386
|
+
}
|
|
387
|
+
const normalized = [];
|
|
388
|
+
for (const [index, entry] of value.entries()) {
|
|
389
|
+
if (normalizeEntry === normalizeScopePathEntry && typeof entry === "string" && /^\.\/?$/u.test(entry.trim())) {
|
|
390
|
+
continue;
|
|
391
|
+
}
|
|
392
|
+
const result = normalizeEntry(entry, field, index);
|
|
393
|
+
if (typeof result !== "string") return result;
|
|
394
|
+
normalized.push(result);
|
|
395
|
+
}
|
|
396
|
+
return [...new Set(normalized)].sort(compareCodepoints);
|
|
397
|
+
}
|
|
398
|
+
function declaredScopeIntent(input) {
|
|
399
|
+
const readRoots = normalizePathList(input.readRoots, "intent.read_roots");
|
|
400
|
+
if (!Array.isArray(readRoots)) return readRoots;
|
|
401
|
+
const writeRoots = normalizePathList(input.writeRoots, "intent.write_roots");
|
|
402
|
+
if (!Array.isArray(writeRoots)) return writeRoots;
|
|
403
|
+
const relevantPaths = normalizePathList(input.relevantPaths, "intent.relevant_paths");
|
|
404
|
+
if (!Array.isArray(relevantPaths)) return relevantPaths;
|
|
405
|
+
return {
|
|
406
|
+
ok: true,
|
|
407
|
+
intent: {
|
|
408
|
+
version: 2,
|
|
409
|
+
readRoots,
|
|
410
|
+
writeRoots,
|
|
411
|
+
relevantPaths,
|
|
412
|
+
pathProvenance: declaredIntentPathProvenance({ readRoots, writeRoots, relevantPaths }),
|
|
413
|
+
expectedOutputs: [],
|
|
414
|
+
verification: []
|
|
415
|
+
}
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
function isDispatchIntent(value) {
|
|
419
|
+
if (!isRecord(value) || value.version !== 2) return false;
|
|
420
|
+
for (const field of ["readRoots", "writeRoots", "relevantPaths", "expectedOutputs"]) {
|
|
421
|
+
if (!Array.isArray(value[field]) || !value[field].every((entry) => typeof entry === "string")) return false;
|
|
422
|
+
}
|
|
423
|
+
const readRoots = value.readRoots;
|
|
424
|
+
const writeRoots = value.writeRoots;
|
|
425
|
+
const relevantPaths = value.relevantPaths;
|
|
426
|
+
if (!Array.isArray(value.pathProvenance) || JSON.stringify(value.pathProvenance) !== JSON.stringify(
|
|
427
|
+
declaredIntentPathProvenance({
|
|
428
|
+
readRoots,
|
|
429
|
+
writeRoots,
|
|
430
|
+
relevantPaths
|
|
431
|
+
})
|
|
432
|
+
)) {
|
|
433
|
+
return false;
|
|
434
|
+
}
|
|
435
|
+
return Array.isArray(value.verification) && value.verification.every(
|
|
436
|
+
(entry) => isRecord(entry) && typeof entry.check === "string" && entry.check.length > 0 && typeof entry.timeoutMs === "number" && Number.isInteger(entry.timeoutMs) && entry.timeoutMs >= DISPATCH_INTENT_TIMEOUT_MIN_MS
|
|
437
|
+
);
|
|
438
|
+
}
|
|
439
|
+
function narrowDispatchIntentToReadOnly(intent) {
|
|
440
|
+
if (intent.writeRoots.length === 0) return intent;
|
|
441
|
+
const readRoots = [.../* @__PURE__ */ new Set([...intent.readRoots, ...intent.writeRoots])].sort(compareCodepoints);
|
|
442
|
+
return {
|
|
443
|
+
version: 2,
|
|
444
|
+
readRoots,
|
|
445
|
+
writeRoots: [],
|
|
446
|
+
relevantPaths: [...intent.relevantPaths],
|
|
447
|
+
pathProvenance: declaredIntentPathProvenance({ readRoots, writeRoots: [], relevantPaths: intent.relevantPaths }),
|
|
448
|
+
expectedOutputs: [...intent.expectedOutputs],
|
|
449
|
+
verification: intent.verification.map((entry) => ({ ...entry }))
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
function normalizeDispatchIntent(raw, checks) {
|
|
453
|
+
if (!isRecord(raw)) return fail("intent_malformed", "intent must be an object");
|
|
454
|
+
const unknown = Object.keys(raw).filter((key) => !RAW_FIELDS.has(key)).sort(compareCodepoints);
|
|
455
|
+
if (unknown.length > 0) return fail("intent_malformed", `intent contains unknown field '${unknown[0]}'`);
|
|
456
|
+
if (raw.version !== void 0 && raw.version !== 2) {
|
|
457
|
+
return fail(
|
|
458
|
+
"intent_version_unsupported",
|
|
459
|
+
`intent declares version ${JSON.stringify(raw.version)}; this build speaks dispatch intent version 2. A declaration at another version is refused rather than migrated: restate read_roots, write_roots, relevant_paths, expected_outputs, and verification under version 2`
|
|
460
|
+
);
|
|
461
|
+
}
|
|
462
|
+
const readRoots = normalizePathList(raw.read_roots, "intent.read_roots");
|
|
463
|
+
if (!Array.isArray(readRoots)) return readRoots;
|
|
464
|
+
const writeRoots = normalizePathList(raw.write_roots, "intent.write_roots");
|
|
465
|
+
if (!Array.isArray(writeRoots)) return writeRoots;
|
|
466
|
+
const relevantPaths = normalizePathList(raw.relevant_paths, "intent.relevant_paths");
|
|
467
|
+
if (!Array.isArray(relevantPaths)) return relevantPaths;
|
|
468
|
+
const expectedOutputs = normalizeIntentExpectedOutputs(raw.expected_outputs);
|
|
469
|
+
if (!Array.isArray(expectedOutputs)) return expectedOutputs;
|
|
470
|
+
const verification = normalizeIntentVerification(raw.verification, checks);
|
|
471
|
+
if (!Array.isArray(verification)) return verification;
|
|
472
|
+
return {
|
|
473
|
+
ok: true,
|
|
474
|
+
intent: {
|
|
475
|
+
version: 2,
|
|
476
|
+
readRoots,
|
|
477
|
+
writeRoots,
|
|
478
|
+
relevantPaths,
|
|
479
|
+
pathProvenance: declaredIntentPathProvenance({ readRoots, writeRoots, relevantPaths }),
|
|
480
|
+
expectedOutputs,
|
|
481
|
+
verification
|
|
482
|
+
}
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
function normalizeIntentExpectedOutputs(raw) {
|
|
486
|
+
return normalizePathList(raw, "intent.expected_outputs", normalizeExpectedOutputEntry);
|
|
487
|
+
}
|
|
488
|
+
function normalizeIntentVerification(raw, checks) {
|
|
489
|
+
const rawVerification = raw ?? [];
|
|
490
|
+
if (!Array.isArray(rawVerification)) {
|
|
491
|
+
return fail("verification_malformed", "intent.verification must be an array");
|
|
492
|
+
}
|
|
493
|
+
if (rawVerification.length > DISPATCH_INTENT_VERIFICATION_CAP) {
|
|
494
|
+
return fail("verification_over_cap", `intent.verification exceeds the ${DISPATCH_INTENT_VERIFICATION_CAP}-entry cap`);
|
|
495
|
+
}
|
|
496
|
+
const verification = [];
|
|
497
|
+
for (const [index, entry] of rawVerification.entries()) {
|
|
498
|
+
if (!isRecord(entry) || Object.keys(entry).some((key) => key !== "check" && key !== "timeout_ms")) {
|
|
499
|
+
return fail("verification_malformed", `intent.verification[${index}] must contain check and optional timeout_ms`);
|
|
500
|
+
}
|
|
501
|
+
if (typeof entry.check !== "string" || entry.check.trim().length === 0) {
|
|
502
|
+
return fail("verification_malformed", `intent.verification[${index}].check must be a non-empty declared id`);
|
|
503
|
+
}
|
|
504
|
+
const check = entry.check.trim();
|
|
505
|
+
const declared = checks.get(check);
|
|
506
|
+
if (declared === void 0 && check.toLowerCase() === "none") continue;
|
|
507
|
+
if (declared === void 0) {
|
|
508
|
+
return fail(
|
|
509
|
+
"verification_check_undeclared",
|
|
510
|
+
`verification check '${check}' is undeclared: intent.verification takes only check ids that verify() lists (package.json verification scripts or .clio-coder/verifiers.yaml entries), never a shell command; omit verification and run the check yourself after the receipt, or declare the check first`
|
|
511
|
+
);
|
|
512
|
+
}
|
|
513
|
+
if (entry.timeout_ms !== void 0 && (typeof entry.timeout_ms !== "number" || !Number.isInteger(entry.timeout_ms) || entry.timeout_ms <= 0)) {
|
|
514
|
+
return fail("verification_malformed", `intent.verification[${index}].timeout_ms must be a positive integer`);
|
|
515
|
+
}
|
|
516
|
+
const requested = typeof entry.timeout_ms === "number" ? entry.timeout_ms : declared.timeoutMs;
|
|
517
|
+
verification.push({
|
|
518
|
+
check,
|
|
519
|
+
timeoutMs: Math.min(declared.timeoutMs, Math.max(DISPATCH_INTENT_TIMEOUT_MIN_MS, requested))
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
return verification;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
export {
|
|
526
|
+
resolveDispatchPathScope,
|
|
527
|
+
declaredScopeReplacementDiagnostic,
|
|
528
|
+
declaredScopeReplacementNotice,
|
|
529
|
+
inferredScopeParentTokenDiagnostic,
|
|
530
|
+
inferredScopeParentTokenNotice,
|
|
531
|
+
DISPATCH_INTENT_TIMEOUT_MIN_MS,
|
|
532
|
+
declaredScopeIntent,
|
|
533
|
+
isDispatchIntent,
|
|
534
|
+
narrowDispatchIntentToReadOnly,
|
|
535
|
+
normalizeDispatchIntent,
|
|
536
|
+
normalizeIntentExpectedOutputs,
|
|
537
|
+
normalizeIntentVerification
|
|
538
|
+
};
|
|
539
|
+
//# sourceMappingURL=chunk-IRXAATOX.js.map
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { createRequire as __clioCreateRequire } from "node:module"; const require = __clioCreateRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
inspectEvidence
|
|
4
|
+
} from "./chunk-NRO2BJRH.js";
|
|
5
|
+
import {
|
|
6
|
+
TRUST_STATUS_AXES,
|
|
7
|
+
trustVerdict
|
|
8
|
+
} from "./chunk-CUSRQKPU.js";
|
|
9
|
+
import {
|
|
10
|
+
clioDataDir
|
|
11
|
+
} from "./chunk-BYP5D4HI.js";
|
|
12
|
+
import {
|
|
13
|
+
init_esm_shims
|
|
14
|
+
} from "./chunk-3R73A4XB.js";
|
|
15
|
+
|
|
16
|
+
// src/domains/evidence/detail.ts
|
|
17
|
+
init_esm_shims();
|
|
18
|
+
var EVIDENCE_DETAIL_MAX_RUNS = 16;
|
|
19
|
+
async function evidenceDetailSnapshot(evidenceId, now = Date.now, dataDir = clioDataDir()) {
|
|
20
|
+
const inspected = await inspectEvidence(dataDir, evidenceId);
|
|
21
|
+
const all = inspected.trustStatus.runs;
|
|
22
|
+
const window = all.slice(0, EVIDENCE_DETAIL_MAX_RUNS);
|
|
23
|
+
return {
|
|
24
|
+
version: 1,
|
|
25
|
+
generatedAt: new Date(now()).toISOString(),
|
|
26
|
+
evidenceId: inspected.overview.evidenceId,
|
|
27
|
+
sourceKind: inspected.overview.source.kind,
|
|
28
|
+
canonical: inspected.trustStatus.projection === "canonical",
|
|
29
|
+
runs: window.map(
|
|
30
|
+
(run) => ({
|
|
31
|
+
runId: run.runId,
|
|
32
|
+
verdict: trustVerdict(run.status),
|
|
33
|
+
axes: Object.fromEntries(TRUST_STATUS_AXES.map((axis) => [axis, run.status[axis].state]))
|
|
34
|
+
})
|
|
35
|
+
),
|
|
36
|
+
runsTruncated: all.length > window.length
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export {
|
|
41
|
+
EVIDENCE_DETAIL_MAX_RUNS,
|
|
42
|
+
evidenceDetailSnapshot
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=chunk-IXIY2H4R.js.map
|