@iowarp/clio-coder 0.3.1 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +233 -373
- package/CONTRIBUTING.md +23 -23
- package/README.md +284 -613
- package/dist/{acp-FPR54DGL.js → acp-P2AQILE2.js} +43 -53
- package/dist/{agents-OGPIHPJH.js → agents-72W3BI7I.js} +43 -26
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-IC3K6NIZ.js → auth-5TWEIYDN.js} +20 -12
- package/dist/chunk-2DJ2KNFG.js +2095 -0
- package/dist/{chunk-IS3ONKU3.js → chunk-2IR2NMPA.js} +6 -4
- package/dist/chunk-2SFS6XQE.js +122 -0
- package/dist/{chunk-PV4JUBVJ.js → chunk-2TLUCQVG.js} +40 -21
- package/dist/chunk-2VTFPG5O.js +48 -0
- package/dist/chunk-4BJ5BYCE.js +61 -0
- package/dist/{chunk-474KN5II.js → chunk-4BPJXDWC.js} +111 -181
- package/dist/chunk-4VP4KH3K.js +962 -0
- package/dist/chunk-4XUGQOHA.js +797 -0
- package/dist/chunk-4ZG3XFUR.js +77 -0
- package/dist/chunk-5B2AEOW5.js +5407 -0
- package/dist/{chunk-K2ITRMHZ.js → chunk-5TSRNF4G.js} +6 -138
- package/dist/{chunk-4QKXUHSR.js → chunk-5UFT4SUX.js} +70 -20
- package/dist/{chunk-OLBBMFRD.js → chunk-5UUP6MWO.js} +24 -62
- package/dist/chunk-65DEGPJ6.js +52 -0
- package/dist/chunk-6EJMN2Y3.js +17 -0
- package/dist/chunk-6N5PTWMY.js +136 -0
- package/dist/chunk-6SGHMWE3.js +277 -0
- package/dist/chunk-6XLNIQDB.js +27 -0
- package/dist/chunk-7CR24IG7.js +242 -0
- package/dist/chunk-7MNJORFF.js +22 -0
- package/dist/{chunk-KY56HMHH.js → chunk-A3CYT5EX.js} +125 -31
- package/dist/chunk-AGYYIBLL.js +1069 -0
- package/dist/{chunk-GB6QRBXN.js → chunk-APJ265NV.js} +54 -1187
- package/dist/{chunk-673JJUWJ.js → chunk-BMEMKKIT.js} +2 -2
- package/dist/chunk-CBCAPZAA.js +229 -0
- package/dist/chunk-CMZWFGD2.js +352 -0
- package/dist/chunk-COU2UHX6.js +400 -0
- package/dist/chunk-DSELYM6W.js +1077 -0
- package/dist/chunk-DUYJ5IO6.js +644 -0
- package/dist/chunk-ECH6PKUQ.js +39 -0
- package/dist/chunk-ED4KHGC3.js +143 -0
- package/dist/chunk-EKMEHE4H.js +340 -0
- package/dist/chunk-FCSXB6T2.js +338 -0
- package/dist/chunk-FJ3H4MN5.js +48 -0
- package/dist/{chunk-RPTR2H26.js → chunk-FNTMWMX5.js} +21 -15
- package/dist/chunk-FQ4SKYE4.js +29 -0
- package/dist/chunk-G4BMMOKF.js +182 -0
- package/dist/{chunk-ZPY3JZ5E.js → chunk-GGXXDWE4.js} +183 -1233
- package/dist/chunk-HC4CLZ2Y.js +68 -0
- package/dist/{chunk-LU4TK2PR.js → chunk-HFSBBKSQ.js} +5 -56
- package/dist/{chunk-PIUMUEMV.js → chunk-HKIYEGME.js} +10 -6
- package/dist/chunk-I4HZDVNP.js +73 -0
- package/dist/chunk-IKCO5N3L.js +162 -0
- package/dist/chunk-IR4CFBFN.js +56 -0
- package/dist/{chunk-R5KLMSBV.js → chunk-J5Q24KAG.js} +2 -2
- package/dist/chunk-J7CWMCQD.js +255 -0
- package/dist/{chunk-K5XEMXTI.js → chunk-JVCV3ICN.js} +1 -1
- package/dist/chunk-KZWTDYJF.js +217 -0
- package/dist/chunk-LBMZMYH2.js +285 -0
- package/dist/{chunk-G34LV2PF.js → chunk-LM5TQCJZ.js} +84 -170
- package/dist/chunk-LW6DSM3M.js +5135 -0
- package/dist/chunk-LWLEKMDQ.js +3482 -0
- package/dist/{chunk-H6F6BYOH.js → chunk-LZSJBIVT.js} +7003 -7434
- package/dist/{chunk-HQQID6OA.js → chunk-M6SHUN7Q.js} +5 -5
- package/dist/{chunk-FST4FYJB.js → chunk-MFFY33HR.js} +99 -140
- package/dist/{chunk-BSU2YIWB.js → chunk-MVVUPGPW.js} +131 -136
- package/dist/chunk-OAO4GE4M.js +619 -0
- package/dist/{chunk-Q3RUPKEJ.js → chunk-OC7FIQPC.js} +58 -189
- package/dist/chunk-OKGUZO2U.js +34 -0
- package/dist/{chunk-GAEBEQVI.js → chunk-OOJYHWRB.js} +32 -346
- package/dist/{chunk-Q5WJOSJ7.js → chunk-OQ33BKR3.js} +2 -1
- package/dist/chunk-OQE5J4C6.js +73 -0
- package/dist/{chunk-KKNLWXI6.js → chunk-ORBHGJC5.js} +8 -8
- package/dist/{chunk-MAR7Y6HW.js → chunk-PAJK6MAQ.js} +23 -16
- package/dist/{chunk-M5T5VO65.js → chunk-PIWWS5BL.js} +837 -635
- package/dist/chunk-POHLU5DW.js +1186 -0
- package/dist/chunk-QKMUKYO7.js +4961 -0
- package/dist/chunk-SRDMMSEP.js +16405 -0
- package/dist/chunk-SST6Z5JA.js +80 -0
- package/dist/chunk-STBPMHSX.js +2456 -0
- package/dist/chunk-T6YILFSB.js +80 -0
- package/dist/chunk-TZK7PACC.js +174 -0
- package/dist/chunk-TZTZS7QK.js +227 -0
- package/dist/{chunk-ASND7OZK.js → chunk-UFIIWP2H.js} +13 -13
- package/dist/chunk-UOV2BYIW.js +107 -0
- package/dist/{chunk-PFEFKVGL.js → chunk-V6RTAOC2.js} +13 -11
- package/dist/chunk-VAKQQHWR.js +434 -0
- package/dist/chunk-VG7TBQIY.js +128 -0
- package/dist/chunk-VJWL6YS5.js +244 -0
- package/dist/{chunk-EYOKLTMF.js → chunk-VPAYEGVX.js} +17 -3
- package/dist/chunk-WEH5XRJQ.js +32 -0
- package/dist/chunk-X4RCMKVQ.js +641 -0
- package/dist/{chunk-TEKV33Q5.js → chunk-X6IAEBZR.js} +65 -33
- package/dist/chunk-XBXAASKX.js +18 -0
- package/dist/chunk-XN3L4EYL.js +46 -0
- package/dist/{chunk-RDLVBZEO.js → chunk-YCWGATWI.js} +6 -4
- package/dist/chunk-YHZX5GEU.js +193 -0
- package/dist/chunk-YXLYO42X.js +91 -0
- package/dist/{chunk-NMOX6HFD.js → chunk-ZDOOVTXZ.js} +29 -77
- package/dist/chunk-ZI647VB5.js +37 -0
- package/dist/{chunk-C4PTHK7P.js → chunk-ZWLZP4ZT.js} +5 -5
- package/dist/chunk-ZWMF7253.js +1882 -0
- package/dist/cli/index.js +62 -54
- package/dist/clio-JOU4FXVA.js +25 -0
- package/dist/code-nav-7AX6FYE6.js +600 -0
- package/dist/codewiki/build-worker.js +66 -0
- package/dist/compile-cache-CVJMMODC.js +18 -0
- package/dist/{components-DMAOEKFB.js → components-KELWS457.js} +11 -6
- package/dist/{config-IRUQ7SE4.js → config-XCDVKR23.js} +92 -55
- package/dist/configure-4GAP54ZW.js +42 -0
- package/dist/{context-5RADCKTR.js → context-4UOGGLQ5.js} +71 -35
- package/dist/context-5VKGUVJJ.js +866 -0
- package/dist/{context-3KWFLHJG.js → context-77FM5DV5.js} +15 -13
- package/dist/{context-clear-7TSNPAAI.js → context-clear-XXJRLCJJ.js} +54 -28
- package/dist/{context-index-W4RLWOQH.js → context-index-BZ4UYMTC.js} +30 -24
- package/dist/dispatch-runner-QPRDDBDX.js +1997 -0
- package/dist/{docs-5AWSPS37.js → docs-2C2LTVT2.js} +23 -10
- package/dist/{doctor-UC5NAJYQ.js → doctor-HR46URBJ.js} +27 -17
- package/dist/{eval-U6TJHRLX.js → eval-XSSNATB4.js} +29 -16
- package/dist/{evidence-YEGUW4L3.js → evidence-6HG2PY2B.js} +46 -26
- package/dist/{evolve-TXARCTPG.js → evolve-K7YU3NCY.js} +45 -25
- package/dist/{extensions-OZFJ3A3G.js → extensions-QVDOHDGJ.js} +16 -7
- package/dist/{fleet-6G3DHNYE.js → fleet-VY3HHKN6.js} +163 -54
- package/dist/{fleet-preflight-DSNT37JK.js → fleet-preflight-DDN536IT.js} +7 -4
- package/dist/{init-KZ5QTF6M.js → init-JYGXI3FK.js} +69 -32
- package/dist/{memory-73ESV5YC.js → memory-WFZMGYHX.js} +48 -27
- package/dist/{models-A4PVNWJK.js → models-I5QWSEOM.js} +39 -25
- package/dist/monitor-GE4ID3IA.js +661 -0
- package/dist/{chunk-FCIH3BIZ.js → orchestrator-EM5MC3HM.js} +15979 -12407
- package/dist/{paths-C4H6IV77.js → paths-UXLN5YYZ.js} +10 -5
- package/dist/{preload-6WVMHX3A.js → preload-P6DGH2PZ.js} +2 -2
- package/dist/{reset-BGW6OGMV.js → reset-L2FQEE3E.js} +16 -10
- package/dist/{run-YTPEYQOH.js → run-ZU3QMZPZ.js} +101 -61
- package/dist/{share-YIFFV4NQ.js → share-S5BZQC5I.js} +15 -8
- package/dist/{skills-2V6RA3OQ.js → skills-X5VXCRNQ.js} +34 -14
- package/dist/{skills-eval-S2TVJO4F.js → skills-eval-WKIHWTHR.js} +70 -34
- package/dist/steer-GGWFUJUD.js +77 -0
- package/dist/{targets-TYXLPB23.js → targets-SNCPI2NR.js} +43 -27
- package/dist/terminal-lease-BNAHVHBS.js +395 -0
- package/dist/{trace-GGOJ6Q6Z.js → trace-PNCASAXC.js} +41 -16
- package/dist/{chunk-N6F52NLF.js → tree-sitter-HGKH6LG4.js} +28 -2306
- package/dist/{uninstall-LLLT4F4W.js → uninstall-FZCQCDKC.js} +10 -5
- package/dist/{upgrade-33G2LMM5.js → upgrade-JQHHPQ4K.js} +45 -25
- package/dist/{usage-ZAFSXKKG.js → usage-OR4O5SMZ.js} +62 -31
- package/dist/verify-375KUB3Y.js +716 -0
- package/dist/web-fetch-2YHJ3KTG.js +638 -0
- package/dist/{wiki-generate-NUQCVOQ3.js → wiki-generate-UEXP2ARI.js} +74 -34
- package/dist/worker/entry.js +221 -36
- package/dist/workspace-G4ZWUIPR.js +22 -0
- package/docs/README.md +22 -17
- package/docs/acp.md +168 -16
- package/docs/alcf-provider.md +1 -1
- package/docs/architecture.md +136 -7
- package/docs/artifact-versions.md +1 -1
- package/docs/built-in-agents.md +1 -1
- package/docs/capacity-and-scheduling.md +1 -1
- package/docs/commands-and-modes.md +114 -71
- package/docs/config-knobs-audit.md +1 -3
- package/docs/configuration-and-targets.md +174 -46
- package/docs/context-engine.md +29 -6
- package/docs/development-pipeline.md +26 -1
- package/docs/dispatch-architecture-rationale.md +1 -1
- package/docs/documentation-coverage.md +2 -2
- package/docs/documentation-guide.md +1 -1
- package/docs/environment-variables.md +13 -5
- package/docs/eval-runner.md +1 -1
- package/docs/evals-internal.md +1 -1
- package/docs/evidence-and-memory.md +6 -2
- package/docs/evolution.md +2 -2
- package/docs/exit-codes-and-output.md +15 -9
- package/docs/extensions-and-sharing.md +9 -9
- package/docs/fleet-dispatch.md +7 -5
- package/docs/git-commit-provenance.md +120 -0
- package/docs/glossary.md +1 -1
- package/docs/installation-and-lifecycle.md +34 -27
- package/docs/middleware-and-components.md +1 -1
- package/docs/model-catalog.md +45 -14
- package/docs/observability.md +8 -5
- package/docs/performance-methodology.md +491 -0
- package/docs/pi-boundary.md +72 -0
- package/docs/proactive-memory.md +3 -3
- package/docs/prompt-envelope-and-tools.md +24 -3
- package/docs/provider-adapter-cookbook.md +57 -4
- package/docs/release-cut-checklist.md +129 -115
- package/docs/safety-model.md +9 -5
- package/docs/scientific-validation.md +3 -3
- package/docs/session-lifecycle.md +55 -12
- package/docs/skills-marketplace.md +12 -8
- package/docs/time-conventions.md +1 -1
- package/docs/tool-usage.md +3 -3
- package/docs/trace-store.md +1 -1
- package/docs/troubleshooting.md +10 -7
- package/docs/tui-design.md +47 -10
- package/docs/worker-dispatch-mechanics.md +1 -1
- package/package.json +19 -22
- package/skills/coding/ast-grep/SKILL.md +136 -0
- package/skills/coding/ast-grep/evals.md +56 -0
- package/skills/coding/ast-grep/references/rule_reference.md +297 -0
- package/skills/coding/coding-standards/SKILL.md +113 -0
- package/skills/coding/coding-standards/evals.md +34 -0
- package/skills/coding/prototype/SKILL.md +86 -0
- package/skills/coding/prototype/evals.md +42 -0
- package/skills/coding/prototype/references/LOGIC.md +67 -0
- package/skills/coding/prototype/references/UI.md +112 -0
- package/skills/coding/tdd/SKILL.md +101 -0
- package/skills/coding/tdd/evals.md +41 -0
- package/skills/coding/tdd/references/mocking.md +59 -0
- package/skills/coding/tdd/references/tests.md +77 -0
- package/skills/context/context-handoff/SKILL.md +126 -0
- package/skills/context/context-handoff/evals.md +57 -0
- package/skills/context/context-handoff/scripts/new-handoff.sh +26 -0
- package/skills/context/context-prime/SKILL.md +95 -0
- package/skills/context/context-prime/evals.md +54 -0
- package/skills/meta/clio-dev/SKILL.md +91 -0
- package/skills/meta/clio-dev/evals.md +45 -0
- package/skills/meta/clio-test/SKILL.md +130 -0
- package/skills/meta/clio-test/evals.md +43 -0
- package/skills/meta/clio-test/references/harness.md +97 -0
- package/skills/meta/clio-test/references/test-map.md +59 -0
- package/skills/meta/credentials/SKILL.md +125 -0
- package/skills/meta/credentials/evals.md +104 -0
- package/skills/meta/find-skills/SKILL.md +72 -0
- package/skills/meta/find-skills/evals.md +47 -0
- package/skills/meta/herdr/SKILL.md +127 -0
- package/skills/meta/herdr/evals.md +38 -0
- package/skills/meta/skill-craft/SKILL.md +102 -0
- package/skills/meta/skill-craft/evals.md +41 -0
- package/skills/planning/architecture/SKILL.md +129 -0
- package/skills/planning/architecture/evals.md +36 -0
- package/skills/planning/backlog/SKILL.md +90 -0
- package/skills/planning/backlog/evals.md +43 -0
- package/skills/planning/prd/SKILL.md +82 -0
- package/skills/planning/prd/evals.md +49 -0
- package/skills/planning/product-intent/SKILL.md +112 -0
- package/skills/planning/product-intent/evals.md +36 -0
- package/skills/planning/tech-spec/SKILL.md +115 -0
- package/skills/planning/tech-spec/evals.md +47 -0
- package/skills/registry.yaml +136 -0
- package/skills/research/arxiv-literature/SKILL.md +104 -0
- package/skills/research/arxiv-literature/evals.md +58 -0
- package/skills/research/experiment-protocol/SKILL.md +122 -0
- package/skills/research/experiment-protocol/evals.md +91 -0
- package/skills/research/scientific-debugging/SKILL.md +119 -0
- package/skills/research/scientific-debugging/evals.md +138 -0
- package/skills/research/scientific-modernization/SKILL.md +138 -0
- package/skills/research/scientific-modernization/evals.md +84 -0
- package/skills/workflow/design-council/SKILL.md +139 -0
- package/skills/workflow/design-council/evals.md +97 -0
- package/skills/workflow/grill-me/SKILL.md +186 -0
- package/skills/workflow/grill-me/evals.md +78 -0
- package/skills/workflow/workflow-distiller/SKILL.md +136 -0
- package/skills/workflow/workflow-distiller/evals.md +107 -0
- package/src/cli/acp.ts +31 -4
- package/src/cli/clio.ts +68 -6
- package/src/cli/config-inspect.ts +28 -22
- package/src/cli/configure.ts +47 -9
- package/src/cli/context-clear.ts +2 -2
- package/src/cli/context-index.ts +21 -23
- package/src/cli/context.ts +13 -8
- package/src/cli/default-target.ts +9 -17
- package/src/cli/docs.ts +11 -5
- package/src/cli/evidence.ts +4 -1
- package/src/cli/extensions.ts +10 -1
- package/src/cli/fleet.ts +47 -6
- package/src/cli/index.ts +55 -26
- package/src/cli/memory.ts +3 -1
- package/src/cli/models.ts +1 -1
- package/src/cli/modes/json-stream.ts +37 -1
- package/src/cli/modes/print.ts +24 -9
- package/src/cli/run.ts +2 -2
- package/src/cli/skills-eval.ts +23 -8
- package/src/cli/skills.ts +19 -4
- package/src/cli/targets.ts +4 -0
- package/src/cli/text-layout.ts +15 -5
- package/src/cli/trace.ts +62 -14
- package/src/cli/upgrade.ts +18 -2
- package/src/cli/usage.ts +10 -3
- package/src/cli/wiki-generate.ts +2 -1
- package/src/core/agent-environment.ts +7 -0
- package/src/core/bash-exec.ts +72 -1
- package/src/core/boot-trace.ts +9 -4
- package/src/core/bus-events.ts +20 -4
- package/src/core/commit-attribution.ts +157 -0
- package/src/core/compile-cache.ts +159 -0
- package/src/core/config.ts +131 -2
- package/src/core/defaults.ts +39 -5
- package/src/core/domain-loader.ts +12 -5
- package/src/core/git-commit-attribution.ts +387 -0
- package/src/core/incomplete-installation.ts +45 -0
- package/src/core/response-schema.ts +1 -1
- package/src/core/safe-exec.ts +13 -1
- package/src/core/settings-layers.ts +155 -21
- package/src/core/skill-activation.ts +1 -1
- package/src/core/startup-timer.ts +3 -3
- package/src/core/state-file-lock.ts +13 -1
- package/src/core/termination.ts +78 -5
- package/src/domains/config/classify.ts +15 -3
- package/src/domains/config/extension.ts +19 -13
- package/src/domains/config/index.ts +10 -0
- package/src/domains/config/keybindings.ts +45 -9
- package/src/domains/context/bootstrap-prompt.ts +1 -1
- package/src/domains/context/bootstrap.ts +111 -18
- package/src/domains/context/clear.ts +16 -11
- package/src/domains/context/clio-md.ts +111 -9
- package/src/domains/context/codewiki/artifact.ts +400 -0
- package/src/domains/context/codewiki/build-worker-protocol.ts +24 -0
- package/src/domains/context/codewiki/build-worker.ts +54 -0
- package/src/domains/context/codewiki/coordinator.ts +182 -0
- package/src/domains/context/codewiki/indexer.ts +59 -144
- package/src/domains/context/codewiki/paths.ts +67 -0
- package/src/domains/context/codewiki/schema.ts +80 -0
- package/src/domains/context/codewiki/tree-sitter.ts +1 -1
- package/src/domains/context/contract.ts +11 -5
- package/src/domains/context/extension.ts +94 -143
- package/src/domains/context/fingerprint.ts +3 -1
- package/src/domains/context/index.ts +12 -22
- package/src/domains/context/project-metadata.ts +19 -0
- package/src/domains/context/prompt-context.ts +9 -10
- package/src/domains/context/refresh.ts +29 -21
- package/src/domains/context/runtime.ts +17 -0
- package/src/domains/context/wiki/generate.ts +39 -34
- package/src/domains/context/wiki/plan.ts +1 -1
- package/src/domains/context/wiki/prompts.ts +21 -8
- package/src/domains/dispatch/code-step.ts +20 -1
- package/src/domains/dispatch/extension.ts +158 -21
- package/src/domains/dispatch/failure-classification.ts +6 -0
- package/src/domains/dispatch/fleet-commit-attribution.ts +56 -0
- package/src/domains/dispatch/orphan-recovery.ts +50 -8
- package/src/domains/dispatch/receipt-integrity.ts +5 -0
- package/src/domains/dispatch/state.ts +31 -6
- package/src/domains/dispatch/transport.ts +2 -1
- package/src/domains/dispatch/types.ts +14 -0
- package/src/domains/dispatch/worker-spawn.ts +21 -2
- package/src/domains/eval/metrics/context.ts +1 -1
- package/src/domains/eval/types.ts +0 -1
- package/src/domains/evidence/build.ts +41 -1
- package/src/domains/lifecycle/migrations/2026-08-18-lmstudio-runtime-id.ts +52 -0
- package/src/domains/lifecycle/migrations/index.ts +24 -4
- package/src/domains/middleware/hooks-io.ts +12 -0
- package/src/domains/middleware/skills-reminder.ts +30 -15
- package/src/domains/prompts/compiler.ts +142 -84
- package/src/domains/prompts/contract.ts +18 -2
- package/src/domains/prompts/extension.ts +39 -7
- package/src/domains/prompts/fragment-loader.ts +0 -1
- package/src/domains/prompts/fragments/identity/clio.md +2 -4
- package/src/domains/prompts/fragments/identity/docs-routing.md +10 -0
- package/src/domains/prompts/fragments/identity/self-awareness.md +1 -45
- package/src/domains/prompts/fragments/operating/contract.md +4 -50
- package/src/domains/prompts/fragments/operating/delegation.md +42 -0
- package/src/domains/prompts/fragments/operating/skills.md +26 -0
- package/src/domains/prompts/fragments/operating/worker.md +16 -0
- package/src/domains/prompts/fragments/safety/auto-edit.md +5 -5
- package/src/domains/prompts/fragments/safety/full-auto.md +3 -3
- package/src/domains/prompts/fragments/safety/read-only.md +4 -4
- package/src/domains/prompts/fragments/safety/suggest.md +2 -2
- package/src/domains/prompts/fragments/wiki/page.md +10 -0
- package/src/domains/prompts/fragments/wiki/plan.md +10 -0
- package/src/domains/prompts/preload.ts +3 -3
- package/src/domains/providers/auth/api-key.ts +1 -1
- package/src/domains/providers/auth/backend-file.ts +20 -10
- package/src/domains/providers/auth/backend-memory.ts +59 -4
- package/src/domains/providers/auth/boot-status.ts +65 -0
- package/src/domains/providers/auth/oauth.ts +2 -1
- package/src/domains/providers/auth/storage.ts +97 -38
- package/src/domains/providers/capabilities.ts +12 -4
- package/src/domains/providers/contract.ts +15 -4
- package/src/domains/providers/extension.ts +18 -6
- package/src/domains/providers/model-runtime-capabilities.ts +15 -4
- package/src/domains/providers/models/local-models/clio-local-coding-targets.yaml +118 -35
- package/src/domains/providers/plugins.ts +5 -3
- package/src/domains/providers/probe/fingerprint.ts +25 -5
- package/src/domains/providers/registry.ts +31 -10
- package/src/domains/providers/runtimes/boot-manifest.ts +55 -0
- package/src/domains/providers/runtimes/builtins.ts +2 -2
- package/src/domains/providers/runtimes/common/lmstudio-http.ts +423 -0
- package/src/domains/providers/runtimes/common/local-synth.ts +6 -7
- package/src/domains/providers/runtimes/local-native/lmstudio.ts +241 -0
- package/src/domains/providers/support.ts +6 -3
- package/src/domains/providers/types/local-model-quirks.ts +7 -9
- package/src/domains/providers/types/runtime-descriptor.ts +12 -1
- package/src/domains/providers/types/target-descriptor.ts +22 -0
- package/src/domains/resources/contract.ts +0 -1
- package/src/domains/resources/extension.ts +1 -3
- package/src/domains/resources/loader.ts +3 -4
- package/src/domains/resources/prompts/loader.ts +16 -2
- package/src/domains/resources/prompts/substitute.ts +1 -65
- package/src/domains/resources/skills/content-hash.ts +2 -0
- package/src/domains/resources/skills/install.ts +17 -0
- package/src/domains/resources/skills/loader.ts +17 -10
- package/src/domains/resources/skills/marketplace.ts +55 -9
- package/src/domains/safety/action-classifier.ts +4 -2
- package/src/domains/safety/audit.ts +8 -2
- package/src/domains/safety/extension.ts +1 -1
- package/src/domains/session/compaction/branch-summary.ts +3 -2
- package/src/domains/session/compaction/cut-point.ts +2 -1
- package/src/domains/session/compaction/tokens.ts +2 -1
- package/src/domains/session/context-ledger.ts +14 -0
- package/src/domains/session/contract.ts +15 -0
- package/src/domains/session/decision-board.ts +190 -0
- package/src/domains/session/entries.ts +66 -3
- package/src/domains/session/extension.ts +93 -12
- package/src/domains/session/retry.ts +10 -18
- package/src/domains/session/session-artifacts.ts +107 -0
- package/src/domains/session/task-board.ts +207 -13
- package/src/domains/session/tree/active-path.ts +44 -5
- package/src/domains/session/tree/fork.ts +26 -27
- package/src/domains/session/tree/preview.ts +2 -2
- package/src/domains/session/workspace/git-probe.ts +17 -11
- package/src/domains/user-tasks/store.ts +297 -0
- package/src/engine/acp/errors.ts +96 -0
- package/src/engine/acp/server.ts +1728 -146
- package/src/engine/acp/transport.ts +135 -14
- package/src/engine/acp/types.ts +26 -0
- package/src/engine/agent.ts +3 -3
- package/src/engine/ai.ts +32 -27
- package/src/engine/alcf-oauth.ts +26 -19
- package/src/engine/api-registry.ts +223 -0
- package/src/engine/apis/index.ts +3 -7
- package/src/engine/apis/llamacpp-residency.ts +49 -9
- package/src/engine/apis/lmstudio-residency.ts +5 -21
- package/src/engine/apis/lmstudio.ts +243 -0
- package/src/engine/apis/ollama-native.ts +24 -3
- package/src/engine/apis/openai-completions.ts +170 -91
- package/src/engine/apis/residency.ts +139 -3
- package/src/engine/apis/types.ts +16 -0
- package/src/engine/env-api-keys.ts +98 -0
- package/src/engine/gemma-channel-filter.ts +223 -0
- package/src/engine/instrumented-tui.ts +192 -0
- package/src/engine/messages.ts +14 -0
- package/src/engine/models.ts +42 -0
- package/src/engine/oauth.ts +16 -12
- package/src/engine/prompt-templates.ts +1 -0
- package/src/engine/provider-payload.ts +16 -59
- package/src/engine/strip-tokenizer-sentinels.ts +1 -1
- package/src/engine/truncate.ts +9 -0
- package/src/engine/tui.ts +17 -9
- package/src/engine/types.ts +3 -6
- package/src/engine/worker-runtime-capabilities.ts +5 -0
- package/src/engine/worker-runtime.ts +1 -1
- package/src/engine/worker-tools.ts +9 -4
- package/src/entry/boot-options.ts +50 -0
- package/src/entry/orchestrator.ts +288 -150
- package/src/interactive/application-controller.ts +89 -2
- package/src/interactive/chat-loop.ts +266 -41
- package/src/interactive/chat-panel.ts +715 -278
- package/src/interactive/chat-renderer.ts +306 -85
- package/src/interactive/clio-editor.ts +3 -8
- package/src/interactive/command-fallbacks.ts +2 -2
- package/src/interactive/context-overlay.ts +27 -1
- package/src/interactive/editor-submit.ts +253 -24
- package/src/interactive/export-html/ansi-to-html.ts +161 -0
- package/src/interactive/export-html/index.ts +51 -0
- package/src/interactive/export-html/template.ts +45 -0
- package/src/interactive/export-html/tool-renderer.ts +54 -0
- package/src/interactive/footer/dashboard.ts +4 -0
- package/src/interactive/footer/notifications.ts +1 -1
- package/src/interactive/footer/widgets.ts +42 -22
- package/src/interactive/footer-panel.ts +8 -3
- package/src/interactive/format-time.ts +14 -2
- package/src/interactive/interactive-application.ts +203 -17
- package/src/interactive/interactive-event-projection.ts +18 -1
- package/src/interactive/interactive-input-runtime.ts +50 -4
- package/src/interactive/interactive-presentation.ts +151 -19
- package/src/interactive/interactive-shell.ts +268 -14
- package/src/interactive/interactive-slash-runtime.ts +184 -117
- package/src/interactive/interactive-tickers.ts +38 -7
- package/src/interactive/keybinding-manager.ts +1 -1
- package/src/interactive/layout.ts +40 -3
- package/src/interactive/overlay-frame.ts +1 -1
- package/src/interactive/overlay-general-openers.ts +58 -1
- package/src/interactive/overlay-key-routing.ts +3 -0
- package/src/interactive/overlay-lifecycle.ts +13 -0
- package/src/interactive/overlay-permission-lifecycle.ts +2 -1
- package/src/interactive/overlay-session-lifecycle.ts +69 -12
- package/src/interactive/overlays/ask-user.ts +146 -24
- package/src/interactive/overlays/decisions.ts +300 -0
- package/src/interactive/overlays/help-reference.ts +15 -10
- package/src/interactive/overlays/model-selector.ts +34 -16
- package/src/interactive/overlays/session-selector.ts +18 -0
- package/src/interactive/overlays/settings.ts +105 -17
- package/src/interactive/overlays/skills-hub.ts +4 -4
- package/src/interactive/overlays/tree-selector.ts +41 -6
- package/src/interactive/render-trace.ts +499 -90
- package/src/interactive/renderers/compaction-summary.ts +2 -2
- package/src/interactive/renderers/diff.ts +115 -104
- package/src/interactive/renderers/mermaid.ts +53 -0
- package/src/interactive/renderers/tool-execution.ts +516 -168
- package/src/interactive/renderers/worker-entry.ts +20 -4
- package/src/interactive/session-switch-settlement.ts +10 -0
- package/src/interactive/slash-autocomplete.ts +6 -114
- package/src/interactive/slash-commands.ts +135 -47
- package/src/interactive/slash-spec.ts +9 -38
- package/src/interactive/status/controller.ts +5 -1
- package/src/interactive/status/index.ts +12 -1
- package/src/interactive/status/reasoning.ts +87 -0
- package/src/interactive/status/summary.ts +13 -2
- package/src/interactive/stdout-backpressure.ts +99 -0
- package/src/interactive/stream-pacer.ts +530 -0
- package/src/interactive/stream-pacing-policy.ts +66 -0
- package/src/interactive/tasks-overlay.ts +368 -14
- package/src/interactive/terminal-lease.ts +485 -0
- package/src/interactive/theme/tokens.ts +1 -1
- package/src/interactive/transcript-detail.ts +120 -0
- package/src/interactive/turn-context.ts +4 -3
- package/src/interactive/turn-persistence.ts +30 -13
- package/src/interactive/turn-queues.ts +12 -0
- package/src/interactive/turn-recovery.ts +25 -8
- package/src/interactive/turn-runtime.ts +79 -12
- package/src/interactive/turn-state.ts +10 -0
- package/src/interactive/view/artifacts.ts +114 -4
- package/src/interactive/view/view-overlay.ts +3 -0
- package/src/interactive/welcome-dashboard.ts +17 -16
- package/src/interactive/worker-receipts.ts +52 -3
- package/src/interactive/worker-stream.ts +5 -1
- package/src/tools/agent-tools.ts +23 -3
- package/src/tools/artifact.ts +2 -2
- package/src/tools/ask-user.ts +23 -13
- package/src/tools/bash.ts +30 -2
- package/src/tools/bootstrap.ts +34 -431
- package/src/tools/builtin-tool-catalog.ts +271 -0
- package/src/tools/codewiki/code-nav-surface.ts +29 -0
- package/src/tools/codewiki/code-nav.ts +8 -22
- package/src/tools/codewiki/shared.ts +41 -38
- package/src/tools/context/docs-engine.ts +14 -3
- package/src/tools/context/index.ts +107 -28
- package/src/tools/context/surface.ts +19 -0
- package/src/tools/core-bootstrap.ts +168 -0
- package/src/tools/credential-present.ts +5 -5
- package/src/tools/dispatch-admission.ts +533 -0
- package/src/tools/dispatch-background.ts +54 -0
- package/src/tools/dispatch-event-text.ts +6 -0
- package/src/tools/dispatch-plan.ts +9 -4
- package/src/tools/dispatch-run-events.ts +238 -0
- package/src/tools/dispatch-runner.ts +2370 -0
- package/src/tools/dispatch-scout-admission.ts +295 -0
- package/src/tools/dispatch-types.ts +77 -0
- package/src/tools/dispatch.ts +67 -3161
- package/src/tools/find.ts +4 -2
- package/src/tools/grep.ts +2 -2
- package/src/tools/lazy-tool.ts +60 -0
- package/src/tools/ledger.ts +3 -3
- package/src/tools/monitor-surface.ts +36 -0
- package/src/tools/monitor.ts +2 -32
- package/src/tools/observers.ts +2 -2
- package/src/tools/presentation.ts +107 -0
- package/src/tools/registry.ts +45 -27
- package/src/tools/safe-exec.ts +2 -2
- package/src/tools/steer-surface.ts +17 -0
- package/src/tools/steer.ts +2 -13
- package/src/tools/tasks.ts +108 -11
- package/src/tools/truncate.ts +25 -184
- package/src/tools/verify/frontend.ts +3 -1
- package/src/tools/verify/index.ts +3 -38
- package/src/tools/verify/surface.ts +46 -0
- package/src/tools/web-fetch-surface.ts +23 -0
- package/src/tools/web-fetch.ts +2 -20
- package/src/tools/write.ts +7 -2
- package/src/worker/entry.ts +39 -2
- package/src/worker/spec-contract.ts +26 -5
- package/dist/chunk-7SS2CTV2.js +0 -61361
- package/dist/chunk-DKGKUHFA.js +0 -924
- package/dist/chunk-GEP36Y4X.js +0 -12796
- package/dist/chunk-XYWBQRDM.js +0 -137
- package/dist/clio-BZVGEUFJ.js +0 -58
- package/dist/configure-S7S6F6CL.js +0 -32
- package/docs/html/agents_blueprint.html +0 -936
- package/docs/html/alcf_blueprint.html +0 -324
- package/docs/html/architecture_blueprint.html +0 -850
- package/docs/html/commands_blueprint.html +0 -939
- package/docs/html/config_knobs_audit_blueprint.html +0 -178
- package/docs/html/configuration_blueprint.html +0 -1080
- package/docs/html/context_blueprint.html +0 -603
- package/docs/html/documentation_blueprint.html +0 -832
- package/docs/html/environment_blueprint.html +0 -404
- package/docs/html/eval_blueprint.html +0 -743
- package/docs/html/evals_internal_blueprint.html +0 -190
- package/docs/html/evolution_blueprint.html +0 -674
- package/docs/html/extensions_blueprint.html +0 -2065
- package/docs/html/fleet_dispatch_blueprint.html +0 -286
- package/docs/html/index.html +0 -919
- package/docs/html/lifecycle_blueprint.html +0 -723
- package/docs/html/memory_blueprint.html +0 -699
- package/docs/html/middleware_blueprint.html +0 -664
- package/docs/html/models_blueprint.html +0 -2366
- package/docs/html/observability_blueprint.html +0 -683
- package/docs/html/provider_adapter_blueprint.html +0 -245
- package/docs/html/safety_blueprint.html +0 -1386
- package/docs/html/shared.css +0 -571
- package/docs/html/shared.js +0 -143
- package/docs/html/skills_blueprint.html +0 -671
- package/docs/html/soak_blueprint.html +0 -182
- package/docs/html/tool_usage_blueprint.html +0 -350
- package/docs/html/tools_blueprint.html +0 -2249
- package/docs/html/trace_blueprint.html +0 -235
- package/docs/html/tui_design_blueprint.html +0 -374
- package/docs/html/validation_blueprint.html +0 -961
- package/docs/html/worker_dispatch_blueprint.html +0 -231
- package/src/core/release.ts +0 -2
- package/src/domains/providers/runtimes/common/lmstudio-logger.ts +0 -32
- package/src/domains/providers/runtimes/local-native/lmstudio-native.ts +0 -491
- package/src/engine/apis/lmstudio-native.ts +0 -1438
- package/src/engine/apis/thinking-replay.ts +0 -11
- package/src/tools/string-enum.ts +0 -15
|
@@ -0,0 +1,1069 @@
|
|
|
1
|
+
import { createRequire as __clioCreateRequire } from "node:module"; const require = __clioCreateRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
ROUTE_POLICY_VERSION,
|
|
4
|
+
isExecutionRole,
|
|
5
|
+
isRouteDecisionAgentSelection,
|
|
6
|
+
isRoutingIntent
|
|
7
|
+
} from "./chunk-GGXXDWE4.js";
|
|
8
|
+
import {
|
|
9
|
+
assertSafeId
|
|
10
|
+
} from "./chunk-R346GLFC.js";
|
|
11
|
+
import {
|
|
12
|
+
require_dist
|
|
13
|
+
} from "./chunk-APJ265NV.js";
|
|
14
|
+
import {
|
|
15
|
+
safeResourceWrite
|
|
16
|
+
} from "./chunk-WEPFGWHJ.js";
|
|
17
|
+
import {
|
|
18
|
+
readClioVersion,
|
|
19
|
+
resolvePackageRoot
|
|
20
|
+
} from "./chunk-IWHMRKLL.js";
|
|
21
|
+
import {
|
|
22
|
+
__toESM,
|
|
23
|
+
init_esm_shims
|
|
24
|
+
} from "./chunk-3R73A4XB.js";
|
|
25
|
+
|
|
26
|
+
// src/domains/dispatch/receipt-integrity.ts
|
|
27
|
+
init_esm_shims();
|
|
28
|
+
import { createHash } from "node:crypto";
|
|
29
|
+
var RUN_RECEIPT_INTEGRITY_VERSION = 15;
|
|
30
|
+
var RUN_RECEIPT_INTEGRITY_ALGORITHM = "sha256";
|
|
31
|
+
function sha256(input) {
|
|
32
|
+
return createHash("sha256").update(input, "utf8").digest("hex");
|
|
33
|
+
}
|
|
34
|
+
function canonicalJson(value) {
|
|
35
|
+
return serializeCanonical(value);
|
|
36
|
+
}
|
|
37
|
+
function serializeCanonical(value) {
|
|
38
|
+
if (value === null) return "null";
|
|
39
|
+
if (typeof value === "number") {
|
|
40
|
+
if (!Number.isFinite(value)) {
|
|
41
|
+
throw new Error(`receipt integrity: non-finite number ${String(value)} is not representable`);
|
|
42
|
+
}
|
|
43
|
+
return JSON.stringify(value);
|
|
44
|
+
}
|
|
45
|
+
if (typeof value === "string" || typeof value === "boolean") return JSON.stringify(value);
|
|
46
|
+
if (typeof value === "bigint") throw new Error("receipt integrity: bigint is not representable");
|
|
47
|
+
if (typeof value === "symbol" || typeof value === "function") {
|
|
48
|
+
throw new Error(`receipt integrity: ${typeof value} is not representable`);
|
|
49
|
+
}
|
|
50
|
+
if (value === void 0) throw new Error("receipt integrity: undefined is not representable at root");
|
|
51
|
+
if (Array.isArray(value)) {
|
|
52
|
+
const parts = [];
|
|
53
|
+
for (let i = 0; i < value.length; i++) {
|
|
54
|
+
if (!(i in value) || value[i] === void 0) {
|
|
55
|
+
parts.push("null");
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
parts.push(serializeCanonical(value[i]));
|
|
59
|
+
}
|
|
60
|
+
return `[${parts.join(",")}]`;
|
|
61
|
+
}
|
|
62
|
+
if (typeof value === "object") {
|
|
63
|
+
const obj = value;
|
|
64
|
+
const keys = Object.keys(obj).sort();
|
|
65
|
+
const parts = [];
|
|
66
|
+
for (const key of keys) {
|
|
67
|
+
const child = obj[key];
|
|
68
|
+
if (child === void 0) continue;
|
|
69
|
+
parts.push(`${JSON.stringify(key)}:${serializeCanonical(child)}`);
|
|
70
|
+
}
|
|
71
|
+
return `{${parts.join(",")}}`;
|
|
72
|
+
}
|
|
73
|
+
throw new Error(`receipt integrity: unsupported value of type ${typeof value}`);
|
|
74
|
+
}
|
|
75
|
+
var RECEIPT_INTEGRITY_FIELD_COVERAGE = {
|
|
76
|
+
runId: true,
|
|
77
|
+
agentId: true,
|
|
78
|
+
executionRole: true,
|
|
79
|
+
agentAudience: true,
|
|
80
|
+
requestOrigin: true,
|
|
81
|
+
task: true,
|
|
82
|
+
targetId: true,
|
|
83
|
+
wireModelId: true,
|
|
84
|
+
runtimeId: true,
|
|
85
|
+
runtimeKind: true,
|
|
86
|
+
startedAt: true,
|
|
87
|
+
endedAt: true,
|
|
88
|
+
outcome: true,
|
|
89
|
+
outcomeDetail: true,
|
|
90
|
+
lineage: true,
|
|
91
|
+
identity: true,
|
|
92
|
+
node: true,
|
|
93
|
+
attestation: true,
|
|
94
|
+
reroutes: true,
|
|
95
|
+
pipeline: true,
|
|
96
|
+
gate: true,
|
|
97
|
+
plan: true,
|
|
98
|
+
personaOverride: true,
|
|
99
|
+
projectContext: true,
|
|
100
|
+
// Always set on receipts written after #104 landed; absent only on older
|
|
101
|
+
// receipts, which digest exactly as they did before these fields existed,
|
|
102
|
+
// so the integrity version stays where it is.
|
|
103
|
+
rulesApplied: true,
|
|
104
|
+
operatorProfileApplied: true,
|
|
105
|
+
exitCode: true,
|
|
106
|
+
failureMessage: true,
|
|
107
|
+
tokenCount: true,
|
|
108
|
+
inputTokenCount: true,
|
|
109
|
+
outputTokenCount: true,
|
|
110
|
+
cacheReadTokenCount: true,
|
|
111
|
+
cacheWriteTokenCount: true,
|
|
112
|
+
reasoningTokenCount: true,
|
|
113
|
+
upstreamResponses: true,
|
|
114
|
+
output: true,
|
|
115
|
+
costUsd: true,
|
|
116
|
+
costProvenance: true,
|
|
117
|
+
compiledPromptHash: true,
|
|
118
|
+
staticCompositionHash: true,
|
|
119
|
+
staticShellHash: true,
|
|
120
|
+
sessionShellHash: true,
|
|
121
|
+
dynamicHash: true,
|
|
122
|
+
promptSignature: true,
|
|
123
|
+
toolSignature: true,
|
|
124
|
+
clioVersion: true,
|
|
125
|
+
piMonoVersion: true,
|
|
126
|
+
platform: true,
|
|
127
|
+
nodeVersion: true,
|
|
128
|
+
toolCalls: true,
|
|
129
|
+
toolStats: true,
|
|
130
|
+
toolActivity: true,
|
|
131
|
+
verification: true,
|
|
132
|
+
routingIntent: true,
|
|
133
|
+
quality: true,
|
|
134
|
+
skillActivations: true,
|
|
135
|
+
autonomyEnforcement: true,
|
|
136
|
+
safety: true,
|
|
137
|
+
reproducibility: true,
|
|
138
|
+
runtimeResolution: true,
|
|
139
|
+
delegation: true,
|
|
140
|
+
findingsSummary: true,
|
|
141
|
+
// Both are optional and absent unless the run produced the condition they
|
|
142
|
+
// name, so a receipt that carries neither digests exactly as it did before
|
|
143
|
+
// they existed and the integrity version stays where it is.
|
|
144
|
+
validationGrounding: true,
|
|
145
|
+
capabilityMismatch: true,
|
|
146
|
+
// Same reasoning: absent unless the run had an agent ledger, so a receipt
|
|
147
|
+
// without one digests byte-identically to one produced before it existed.
|
|
148
|
+
ledgerContribution: true,
|
|
149
|
+
sessionId: true,
|
|
150
|
+
briefing: true,
|
|
151
|
+
outcomeCode: true,
|
|
152
|
+
steering: true,
|
|
153
|
+
routeDecision: true
|
|
154
|
+
};
|
|
155
|
+
var RECEIPT_FIELDS = Object.keys(RECEIPT_INTEGRITY_FIELD_COVERAGE);
|
|
156
|
+
function selectedReceiptFields(receipt, fields) {
|
|
157
|
+
const source = receipt;
|
|
158
|
+
const result = {};
|
|
159
|
+
for (const field of fields) {
|
|
160
|
+
const value = source[field];
|
|
161
|
+
if (value !== void 0) result[field] = value;
|
|
162
|
+
}
|
|
163
|
+
return result;
|
|
164
|
+
}
|
|
165
|
+
function receiptDigestFields(receipt) {
|
|
166
|
+
const result = selectedReceiptFields(receipt, RECEIPT_FIELDS);
|
|
167
|
+
result.briefing = receipt.briefing ?? null;
|
|
168
|
+
result.outcomeCode = receipt.outcomeCode ?? null;
|
|
169
|
+
result.steering = receipt.steering ?? null;
|
|
170
|
+
return result;
|
|
171
|
+
}
|
|
172
|
+
function ledgerDigestFields(envelope) {
|
|
173
|
+
return {
|
|
174
|
+
id: envelope.id,
|
|
175
|
+
agentId: envelope.agentId,
|
|
176
|
+
executionRole: envelope.executionRole,
|
|
177
|
+
task: envelope.task,
|
|
178
|
+
targetId: envelope.targetId,
|
|
179
|
+
wireModelId: envelope.wireModelId,
|
|
180
|
+
runtimeId: envelope.runtimeId,
|
|
181
|
+
runtimeKind: envelope.runtimeKind,
|
|
182
|
+
startedAt: envelope.startedAt,
|
|
183
|
+
endedAt: envelope.endedAt,
|
|
184
|
+
status: envelope.status,
|
|
185
|
+
exitCode: envelope.exitCode,
|
|
186
|
+
sessionId: envelope.sessionId,
|
|
187
|
+
cwd: envelope.cwd,
|
|
188
|
+
tokenCount: envelope.tokenCount,
|
|
189
|
+
cacheReadTokenCount: envelope.cacheReadTokenCount,
|
|
190
|
+
cacheWriteTokenCount: envelope.cacheWriteTokenCount,
|
|
191
|
+
reasoningTokenCount: envelope.reasoningTokenCount,
|
|
192
|
+
staticShellHash: envelope.staticShellHash,
|
|
193
|
+
sessionShellHash: envelope.sessionShellHash,
|
|
194
|
+
dynamicHash: envelope.dynamicHash,
|
|
195
|
+
costUsd: envelope.costUsd,
|
|
196
|
+
agentAudience: envelope.agentAudience ?? null,
|
|
197
|
+
requestOrigin: envelope.requestOrigin ?? null,
|
|
198
|
+
outcome: envelope.outcome ?? null,
|
|
199
|
+
outcomeDetail: envelope.outcomeDetail ?? null,
|
|
200
|
+
lineage: envelope.lineage ?? null,
|
|
201
|
+
identity: envelope.identity ?? null,
|
|
202
|
+
node: envelope.node ?? null,
|
|
203
|
+
reroutes: envelope.reroutes ?? null,
|
|
204
|
+
pipeline: envelope.pipeline ?? null,
|
|
205
|
+
gate: envelope.gate ?? null,
|
|
206
|
+
plan: envelope.plan ?? null,
|
|
207
|
+
personaOverride: envelope.personaOverride ?? null,
|
|
208
|
+
inputTokenCount: envelope.inputTokenCount ?? 0,
|
|
209
|
+
outputTokenCount: envelope.outputTokenCount ?? 0,
|
|
210
|
+
promptSignature: envelope.promptSignature ?? null,
|
|
211
|
+
toolSignature: envelope.toolSignature ?? null,
|
|
212
|
+
briefing: envelope.briefing ?? null,
|
|
213
|
+
outcomeCode: envelope.outcomeCode ?? null,
|
|
214
|
+
steering: envelope.steering ?? null
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
function integrityPayload(receipt, envelope) {
|
|
218
|
+
return {
|
|
219
|
+
contract: "clio.runReceipt.integrity",
|
|
220
|
+
version: RUN_RECEIPT_INTEGRITY_VERSION,
|
|
221
|
+
sources: ["receipt", "run-ledger"],
|
|
222
|
+
receipt: receiptDigestFields(receipt),
|
|
223
|
+
ledger: ledgerDigestFields(envelope)
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
function computeReceiptIntegrity(receipt, envelope) {
|
|
227
|
+
return {
|
|
228
|
+
version: RUN_RECEIPT_INTEGRITY_VERSION,
|
|
229
|
+
algorithm: RUN_RECEIPT_INTEGRITY_ALGORITHM,
|
|
230
|
+
digest: sha256(canonicalJson(integrityPayload(receipt, envelope)))
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
function isReceiptQuality(value) {
|
|
234
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
235
|
+
const quality = value;
|
|
236
|
+
if (quality.version !== 1 || !Array.isArray(quality.typedValidations)) return false;
|
|
237
|
+
if (!quality.typedValidations.every(
|
|
238
|
+
(fact) => fact !== null && typeof fact === "object" && typeof fact.sourceId === "string" && typeof fact.validatorDigest === "string" && /^[0-9a-f]{64}$/.test(String(fact.validatorDigest)) && typeof fact.passed === "boolean"
|
|
239
|
+
))
|
|
240
|
+
return false;
|
|
241
|
+
const schema = quality.responseSchema;
|
|
242
|
+
if (!schema || typeof schema !== "object" || Array.isArray(schema)) return false;
|
|
243
|
+
const responseSchema = schema;
|
|
244
|
+
const resultContract = quality.resultContract;
|
|
245
|
+
const validResultContract = resultContract === null || resultContract !== void 0 && typeof resultContract === "object" && !Array.isArray(resultContract) && typeof resultContract.sourceId === "string" && typeof resultContract.validatorDigest === "string" && /^[0-9a-f]{64}$/.test(String(resultContract.validatorDigest)) && (resultContract.conformance === "pass" || resultContract.conformance === "fail" || resultContract.conformance === "not-reached") && (resultContract.quality === "pass" || resultContract.quality === "fail" || resultContract.quality === "unmeasured");
|
|
246
|
+
return (responseSchema.sourceId === null || typeof responseSchema.sourceId === "string") && (responseSchema.schemaDigest === null || typeof responseSchema.schemaDigest === "string" && /^[0-9a-f]{64}$/.test(responseSchema.schemaDigest)) && typeof responseSchema.runtimeEnforceable === "boolean" && (responseSchema.enforcementPassed === null || typeof responseSchema.enforcementPassed === "boolean") && validResultContract;
|
|
247
|
+
}
|
|
248
|
+
function isCurrentRouteDecision(value) {
|
|
249
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
250
|
+
const decision = value;
|
|
251
|
+
return decision.policyVersion === ROUTE_POLICY_VERSION && (decision.mode === "fixed" || decision.mode === "shadow" || decision.mode === "active") && isRouteDecisionAgentSelection(decision.agentSelection) && typeof decision.decisionHash === "string" && /^[0-9a-f]{64}$/u.test(decision.decisionHash);
|
|
252
|
+
}
|
|
253
|
+
function withReceiptIntegrity(receipt, envelope) {
|
|
254
|
+
if (!isReceiptQuality(receipt.quality)) throw new Error("receipt integrity: required quality block invalid");
|
|
255
|
+
if (!isExecutionRole(receipt.executionRole)) throw new Error("receipt integrity: required execution role invalid");
|
|
256
|
+
if (!isRoutingIntent(receipt.routingIntent)) {
|
|
257
|
+
throw new Error("receipt integrity: required routing intent invalid");
|
|
258
|
+
}
|
|
259
|
+
if (receipt.routeDecision !== void 0 && !isCurrentRouteDecision(receipt.routeDecision)) {
|
|
260
|
+
throw new Error("receipt integrity: route decision is invalid or retired");
|
|
261
|
+
}
|
|
262
|
+
return {
|
|
263
|
+
...receipt,
|
|
264
|
+
routingIntent: receipt.routingIntent,
|
|
265
|
+
integrity: computeReceiptIntegrity(receipt, envelope)
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
function isReceiptIntegrity(value) {
|
|
269
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
270
|
+
const candidate = value;
|
|
271
|
+
return candidate.version === RUN_RECEIPT_INTEGRITY_VERSION && candidate.algorithm === RUN_RECEIPT_INTEGRITY_ALGORITHM && typeof candidate.digest === "string" && /^[0-9a-f]{64}$/.test(candidate.digest);
|
|
272
|
+
}
|
|
273
|
+
function firstLedgerMismatch(receipt, envelope) {
|
|
274
|
+
const sharedFields = [
|
|
275
|
+
["runId", receipt.runId, envelope.id],
|
|
276
|
+
["agentId", receipt.agentId, envelope.agentId],
|
|
277
|
+
["executionRole", receipt.executionRole, envelope.executionRole],
|
|
278
|
+
["agentAudience", receipt.agentAudience, envelope.agentAudience],
|
|
279
|
+
["requestOrigin", receipt.requestOrigin, envelope.requestOrigin],
|
|
280
|
+
["task", receipt.task, envelope.task],
|
|
281
|
+
["targetId", receipt.targetId, envelope.targetId],
|
|
282
|
+
["wireModelId", receipt.wireModelId, envelope.wireModelId],
|
|
283
|
+
["runtimeId", receipt.runtimeId, envelope.runtimeId],
|
|
284
|
+
["runtimeKind", receipt.runtimeKind, envelope.runtimeKind],
|
|
285
|
+
["startedAt", receipt.startedAt, envelope.startedAt],
|
|
286
|
+
["endedAt", receipt.endedAt, envelope.endedAt],
|
|
287
|
+
["exitCode", receipt.exitCode, envelope.exitCode],
|
|
288
|
+
["tokenCount", receipt.tokenCount, envelope.tokenCount],
|
|
289
|
+
["cacheReadTokenCount", receipt.cacheReadTokenCount ?? 0, envelope.cacheReadTokenCount ?? 0],
|
|
290
|
+
["cacheWriteTokenCount", receipt.cacheWriteTokenCount ?? 0, envelope.cacheWriteTokenCount ?? 0],
|
|
291
|
+
["reasoningTokenCount", receipt.reasoningTokenCount ?? 0, envelope.reasoningTokenCount ?? 0],
|
|
292
|
+
["staticShellHash", receipt.staticShellHash ?? null, envelope.staticShellHash ?? null],
|
|
293
|
+
["sessionShellHash", receipt.sessionShellHash ?? null, envelope.sessionShellHash ?? null],
|
|
294
|
+
["dynamicHash", receipt.dynamicHash ?? null, envelope.dynamicHash ?? null],
|
|
295
|
+
["costUsd", receipt.costUsd, envelope.costUsd],
|
|
296
|
+
["sessionId", receipt.sessionId, envelope.sessionId],
|
|
297
|
+
["outcome", receipt.outcome ?? null, envelope.outcome ?? null],
|
|
298
|
+
["outcomeDetail", receipt.outcomeDetail ?? null, envelope.outcomeDetail ?? null],
|
|
299
|
+
["nodeId", receipt.node?.id ?? null, envelope.node?.id ?? null],
|
|
300
|
+
["outcomeCode", receipt.outcomeCode ?? null, envelope.outcomeCode ?? null]
|
|
301
|
+
];
|
|
302
|
+
for (const [field, receiptValue, ledgerValue] of sharedFields) {
|
|
303
|
+
if (!Object.is(receiptValue, ledgerValue)) return field;
|
|
304
|
+
}
|
|
305
|
+
if (canonicalJson(receipt.briefing ?? null) !== canonicalJson(envelope.briefing ?? null)) return "briefing";
|
|
306
|
+
if (canonicalJson(receipt.steering ?? null) !== canonicalJson(envelope.steering ?? null)) return "steering";
|
|
307
|
+
return null;
|
|
308
|
+
}
|
|
309
|
+
function verifyReceiptIntegrity(receipt, envelope) {
|
|
310
|
+
if (!isReceiptQuality(receipt.quality) || !isReceiptIntegrity(receipt.integrity)) {
|
|
311
|
+
return { ok: false, reason: "integrity invalid" };
|
|
312
|
+
}
|
|
313
|
+
if (!isExecutionRole(receipt.executionRole)) return { ok: false, reason: "execution role invalid" };
|
|
314
|
+
if (!isRoutingIntent(receipt.routingIntent)) {
|
|
315
|
+
return { ok: false, reason: "routing intent invalid" };
|
|
316
|
+
}
|
|
317
|
+
if (receipt.routeDecision !== void 0 && !isCurrentRouteDecision(receipt.routeDecision)) {
|
|
318
|
+
return { ok: false, reason: "route decision invalid" };
|
|
319
|
+
}
|
|
320
|
+
const mismatch = firstLedgerMismatch(receipt, envelope);
|
|
321
|
+
if (mismatch) {
|
|
322
|
+
return { ok: false, reason: `ledger mismatch: ${mismatch}` };
|
|
323
|
+
}
|
|
324
|
+
const expected = computeReceiptIntegrity(receipt, envelope);
|
|
325
|
+
if (expected.digest !== receipt.integrity.digest) {
|
|
326
|
+
return { ok: false, reason: "integrity mismatch" };
|
|
327
|
+
}
|
|
328
|
+
return { ok: true };
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// src/domains/eval/harness-metrics.ts
|
|
332
|
+
init_esm_shims();
|
|
333
|
+
var ZERO_EVAL_HARNESS_METRICS = {
|
|
334
|
+
receiptCount: 0,
|
|
335
|
+
toolCalls: 0,
|
|
336
|
+
retries: 0,
|
|
337
|
+
safetyBlocks: 0,
|
|
338
|
+
correctionLatencyMs: 0,
|
|
339
|
+
validationEvidence: 0
|
|
340
|
+
};
|
|
341
|
+
function evalHarnessMetricsFromCommands(commands) {
|
|
342
|
+
return {
|
|
343
|
+
...ZERO_EVAL_HARNESS_METRICS,
|
|
344
|
+
validationEvidence: commands.filter(
|
|
345
|
+
(command) => command.phase === "verifier" && command.exitCode === 0 && !command.timedOut
|
|
346
|
+
).length
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
function sumEvalHarnessMetrics(records) {
|
|
350
|
+
return records.reduce((total, record) => addEvalHarnessMetrics(total, record.harness), {
|
|
351
|
+
...ZERO_EVAL_HARNESS_METRICS
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
function addEvalHarnessMetrics(left, right) {
|
|
355
|
+
return {
|
|
356
|
+
receiptCount: left.receiptCount + right.receiptCount,
|
|
357
|
+
toolCalls: left.toolCalls + right.toolCalls,
|
|
358
|
+
retries: left.retries + right.retries,
|
|
359
|
+
safetyBlocks: left.safetyBlocks + right.safetyBlocks,
|
|
360
|
+
correctionLatencyMs: left.correctionLatencyMs + right.correctionLatencyMs,
|
|
361
|
+
validationEvidence: left.validationEvidence + right.validationEvidence
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// src/domains/eval/store.ts
|
|
366
|
+
init_esm_shims();
|
|
367
|
+
import { createHash as createHash2, randomBytes } from "node:crypto";
|
|
368
|
+
import { readFile } from "node:fs/promises";
|
|
369
|
+
import { join } from "node:path";
|
|
370
|
+
|
|
371
|
+
// src/domains/eval/artifacts/redact.ts
|
|
372
|
+
init_esm_shims();
|
|
373
|
+
var SENSITIVE_KEY = /(?:^|[_-])(api[_-]?key|authorization|cookie|password|secret|token)(?:$|[_-])/i;
|
|
374
|
+
var CREDENTIAL_PATTERNS = [
|
|
375
|
+
[/\b(authorization\s*[:=]\s*)(?:bearer|basic)\s+[A-Za-z0-9._~+/=-]+/gi, "$1[redacted]"],
|
|
376
|
+
[/\b(bearer\s+)[A-Za-z0-9._~+/=-]{12,}/gi, "$1[redacted]"],
|
|
377
|
+
[/\b(sk-[A-Za-z0-9_-]{16,})\b/g, "[redacted]"],
|
|
378
|
+
[/\b(gh[pousr]_[A-Za-z0-9_]{16,})\b/g, "[redacted]"],
|
|
379
|
+
[/\b(AKIA[0-9A-Z]{16})\b/g, "[redacted]"],
|
|
380
|
+
[/\b((?:api[_-]?key|access[_-]?token|refresh[_-]?token|password|secret)\s*[:=]\s*)[^\s"',}]+/gi, "$1[redacted]"]
|
|
381
|
+
];
|
|
382
|
+
function redactArtifactForStorage(value, env = process.env) {
|
|
383
|
+
return redactValue(value, env);
|
|
384
|
+
}
|
|
385
|
+
function redactValue(value, env) {
|
|
386
|
+
if (typeof value === "string") return redactString(value, env);
|
|
387
|
+
if (Array.isArray(value)) return value.map((entry) => redactValue(entry, env));
|
|
388
|
+
if (value !== null && typeof value === "object") {
|
|
389
|
+
const out = {};
|
|
390
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
391
|
+
out[key] = SENSITIVE_KEY.test(key) ? "[redacted]" : redactValue(entry, env);
|
|
392
|
+
}
|
|
393
|
+
return out;
|
|
394
|
+
}
|
|
395
|
+
return value;
|
|
396
|
+
}
|
|
397
|
+
function redactString(value, env) {
|
|
398
|
+
let out = stripHomePrefix(value, env.HOME);
|
|
399
|
+
for (const [pattern, replacement] of CREDENTIAL_PATTERNS) {
|
|
400
|
+
out = out.replace(pattern, replacement);
|
|
401
|
+
}
|
|
402
|
+
return out;
|
|
403
|
+
}
|
|
404
|
+
function stripHomePrefix(value, home) {
|
|
405
|
+
if (home === void 0 || home.length === 0) return value;
|
|
406
|
+
const normalized = home.replace(/\/+$/g, "");
|
|
407
|
+
if (normalized.length === 0) return value;
|
|
408
|
+
return value.split(normalized).join("$HOME");
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
// src/domains/eval/store.ts
|
|
412
|
+
var NODE_SIGNALS = /* @__PURE__ */ new Set([
|
|
413
|
+
"SIGHUP",
|
|
414
|
+
"SIGINT",
|
|
415
|
+
"SIGQUIT",
|
|
416
|
+
"SIGILL",
|
|
417
|
+
"SIGTRAP",
|
|
418
|
+
"SIGABRT",
|
|
419
|
+
"SIGIOT",
|
|
420
|
+
"SIGBUS",
|
|
421
|
+
"SIGFPE",
|
|
422
|
+
"SIGKILL",
|
|
423
|
+
"SIGUSR1",
|
|
424
|
+
"SIGSEGV",
|
|
425
|
+
"SIGUSR2",
|
|
426
|
+
"SIGPIPE",
|
|
427
|
+
"SIGALRM",
|
|
428
|
+
"SIGTERM",
|
|
429
|
+
"SIGCHLD",
|
|
430
|
+
"SIGSTKFLT",
|
|
431
|
+
"SIGCONT",
|
|
432
|
+
"SIGSTOP",
|
|
433
|
+
"SIGTSTP",
|
|
434
|
+
"SIGTTIN",
|
|
435
|
+
"SIGTTOU",
|
|
436
|
+
"SIGURG",
|
|
437
|
+
"SIGXCPU",
|
|
438
|
+
"SIGXFSZ",
|
|
439
|
+
"SIGVTALRM",
|
|
440
|
+
"SIGPROF",
|
|
441
|
+
"SIGWINCH",
|
|
442
|
+
"SIGIO",
|
|
443
|
+
"SIGPOLL",
|
|
444
|
+
"SIGPWR",
|
|
445
|
+
"SIGSYS",
|
|
446
|
+
"SIGUNUSED"
|
|
447
|
+
]);
|
|
448
|
+
function evalRoot(dataDir) {
|
|
449
|
+
return join(dataDir, "evals");
|
|
450
|
+
}
|
|
451
|
+
function evalArtifactPath(dataDir, evalId) {
|
|
452
|
+
assertSafeId(evalId, "eval");
|
|
453
|
+
return join(evalRoot(dataDir), `${evalId}.json`);
|
|
454
|
+
}
|
|
455
|
+
function createEvalId(startedAt, taskFileHash) {
|
|
456
|
+
const stamp = startedAt.toISOString().replace(/[-:.]/g, "");
|
|
457
|
+
return `eval-${stamp}-${taskFileHash.slice(0, 8)}-${randomBytes(6).toString("hex")}`;
|
|
458
|
+
}
|
|
459
|
+
async function writeEvalArtifact(dataDir, artifact) {
|
|
460
|
+
const path = evalArtifactPath(dataDir, artifact.evalId);
|
|
461
|
+
const redacted = redactArtifactForStorage({
|
|
462
|
+
...artifact,
|
|
463
|
+
paths: { ...artifact.paths, artifact: path }
|
|
464
|
+
});
|
|
465
|
+
safeResourceWrite(path, `${JSON.stringify(redacted, null, 2)}
|
|
466
|
+
`, { encoding: "utf8" });
|
|
467
|
+
return path;
|
|
468
|
+
}
|
|
469
|
+
async function loadEvalArtifact(dataDir, evalId) {
|
|
470
|
+
let raw;
|
|
471
|
+
try {
|
|
472
|
+
raw = await readFile(evalArtifactPath(dataDir, evalId), "utf8");
|
|
473
|
+
} catch (error) {
|
|
474
|
+
if (isErrorWithCode(error) && error.code === "ENOENT") throw new Error(`eval artifact not found: ${evalId}`);
|
|
475
|
+
throw error;
|
|
476
|
+
}
|
|
477
|
+
const source = evalArtifactPath(dataDir, evalId);
|
|
478
|
+
const parsed = parseJson(raw, source);
|
|
479
|
+
return parseArtifact(parsed, source);
|
|
480
|
+
}
|
|
481
|
+
function parseArtifact(value, source) {
|
|
482
|
+
if (!isRecord(value)) throw new Error(`${source}: expected object`);
|
|
483
|
+
if (value.version !== 1) throw new Error(`${source}.version: expected 1`);
|
|
484
|
+
const results = readArray(value, source, "results").map(
|
|
485
|
+
(entry, index) => parseRecord(entry, `${source}.results[${index}]`)
|
|
486
|
+
);
|
|
487
|
+
return {
|
|
488
|
+
version: 1,
|
|
489
|
+
evalId: readString(value, source, "evalId"),
|
|
490
|
+
taskFile: readString(value, source, "taskFile"),
|
|
491
|
+
taskFileHash: readString(value, source, "taskFileHash"),
|
|
492
|
+
clio: parseClioProvenance(readRequiredArtifactField(value, source, "clio"), `${source}.clio`),
|
|
493
|
+
environment: parseEnvironmentProvenance(
|
|
494
|
+
readRequiredArtifactField(value, source, "environment"),
|
|
495
|
+
`${source}.environment`
|
|
496
|
+
),
|
|
497
|
+
target: readOptionalNullableString(value, source, "target"),
|
|
498
|
+
model: readOptionalNullableString(value, source, "model"),
|
|
499
|
+
thinking: readOptionalNullableString(value, source, "thinking"),
|
|
500
|
+
paths: parseArtifactPaths(readRequiredArtifactField(value, source, "paths"), `${source}.paths`),
|
|
501
|
+
repeat: readNumber(value, source, "repeat"),
|
|
502
|
+
startedAt: readString(value, source, "startedAt"),
|
|
503
|
+
endedAt: readString(value, source, "endedAt"),
|
|
504
|
+
summary: parseSummary(value.summary, `${source}.summary`),
|
|
505
|
+
results
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
function parseSummary(value, source) {
|
|
509
|
+
if (!isRecord(value)) throw new Error(`${source}: expected object`);
|
|
510
|
+
return {
|
|
511
|
+
runs: readNumber(value, source, "runs"),
|
|
512
|
+
passed: readNumber(value, source, "passed"),
|
|
513
|
+
failed: readNumber(value, source, "failed"),
|
|
514
|
+
passRate: readNumber(value, source, "passRate"),
|
|
515
|
+
tokens: readNumber(value, source, "tokens"),
|
|
516
|
+
costUsd: readNumber(value, source, "costUsd"),
|
|
517
|
+
wallTimeMs: readNumber(value, source, "wallTimeMs"),
|
|
518
|
+
harness: value.harness === void 0 ? { ...ZERO_EVAL_HARNESS_METRICS } : parseHarnessMetrics(value.harness, `${source}.harness`),
|
|
519
|
+
failureClasses: readArray(value, source, "failureClasses").map(
|
|
520
|
+
(entry, index) => parseFailureClassCount(entry, `${source}.failureClasses[${index}]`)
|
|
521
|
+
)
|
|
522
|
+
};
|
|
523
|
+
}
|
|
524
|
+
function parseRecord(value, source) {
|
|
525
|
+
if (!isRecord(value)) throw new Error(`${source}: expected object`);
|
|
526
|
+
const failureClass = readOptionalFailureClass(value, source, "failureClass");
|
|
527
|
+
const commands = readArray(value, source, "commands").map(
|
|
528
|
+
(entry, index) => parseCommand(entry, `${source}.commands[${index}]`)
|
|
529
|
+
);
|
|
530
|
+
const record = {
|
|
531
|
+
taskId: readString(value, source, "taskId"),
|
|
532
|
+
runId: readString(value, source, "runId"),
|
|
533
|
+
repeatIndex: readNumber(value, source, "repeatIndex"),
|
|
534
|
+
cwd: readString(value, source, "cwd"),
|
|
535
|
+
prompt: readString(value, source, "prompt"),
|
|
536
|
+
tags: readStringArray(value, source, "tags"),
|
|
537
|
+
pass: readBoolean(value, source, "pass"),
|
|
538
|
+
exitCode: readNumber(value, source, "exitCode"),
|
|
539
|
+
tokens: readNumber(value, source, "tokens"),
|
|
540
|
+
costUsd: readNumber(value, source, "costUsd"),
|
|
541
|
+
wallTimeMs: readNumber(value, source, "wallTimeMs"),
|
|
542
|
+
harness: value.harness === void 0 ? evalHarnessMetricsFromCommands(commands) : parseHarnessMetrics(value.harness, `${source}.harness`),
|
|
543
|
+
commands
|
|
544
|
+
};
|
|
545
|
+
if (failureClass !== void 0) record.failureClass = failureClass;
|
|
546
|
+
const receiptPath = readOptionalString(value, source, "receiptPath");
|
|
547
|
+
if (receiptPath !== void 0) record.receiptPath = receiptPath;
|
|
548
|
+
const evidenceId = readOptionalString(value, source, "evidenceId");
|
|
549
|
+
if (evidenceId !== void 0) record.evidenceId = evidenceId;
|
|
550
|
+
const paths = value.paths === void 0 ? void 0 : parseRunPaths(value.paths, `${source}.paths`);
|
|
551
|
+
if (paths !== void 0) record.paths = paths;
|
|
552
|
+
return record;
|
|
553
|
+
}
|
|
554
|
+
function parseClioProvenance(value, source) {
|
|
555
|
+
if (!isRecord(value)) throw new Error(`${source}: expected object`);
|
|
556
|
+
return {
|
|
557
|
+
version: readString(value, source, "version"),
|
|
558
|
+
commit: readNullableString(value, source, "commit"),
|
|
559
|
+
entry: readString(value, source, "entry")
|
|
560
|
+
};
|
|
561
|
+
}
|
|
562
|
+
function parseEnvironmentProvenance(value, source) {
|
|
563
|
+
if (!isRecord(value)) throw new Error(`${source}: expected object`);
|
|
564
|
+
return {
|
|
565
|
+
platform: readString(value, source, "platform"),
|
|
566
|
+
node: readString(value, source, "node")
|
|
567
|
+
};
|
|
568
|
+
}
|
|
569
|
+
function parseArtifactPaths(value, source) {
|
|
570
|
+
if (!isRecord(value)) throw new Error(`${source}: expected object`);
|
|
571
|
+
const out = {
|
|
572
|
+
taskFile: readString(value, source, "taskFile"),
|
|
573
|
+
receipts: readStringArray(value, source, "receipts"),
|
|
574
|
+
sessionLedgers: readStringArray(value, source, "sessionLedgers")
|
|
575
|
+
};
|
|
576
|
+
const artifact = readOptionalString(value, source, "artifact");
|
|
577
|
+
if (artifact !== void 0) out.artifact = artifact;
|
|
578
|
+
const evidence = readOptionalString(value, source, "evidence");
|
|
579
|
+
if (evidence !== void 0) out.evidence = evidence;
|
|
580
|
+
return out;
|
|
581
|
+
}
|
|
582
|
+
function parseRunPaths(value, source) {
|
|
583
|
+
if (!isRecord(value)) throw new Error(`${source}: expected object`);
|
|
584
|
+
const out = {};
|
|
585
|
+
const receipt = readOptionalString(value, source, "receipt");
|
|
586
|
+
if (receipt !== void 0) out.receipt = receipt;
|
|
587
|
+
const sessionLedger = readOptionalString(value, source, "sessionLedger");
|
|
588
|
+
if (sessionLedger !== void 0) out.sessionLedger = sessionLedger;
|
|
589
|
+
const evidence = readOptionalString(value, source, "evidence");
|
|
590
|
+
if (evidence !== void 0) out.evidence = evidence;
|
|
591
|
+
return out;
|
|
592
|
+
}
|
|
593
|
+
function readRequiredArtifactField(record, source, field) {
|
|
594
|
+
const value = record[field];
|
|
595
|
+
if (value === void 0) {
|
|
596
|
+
throw new Error(
|
|
597
|
+
`eval artifact has an invalid schema: missing required field '${field}' in ${source}. Re-run the evaluation suite to generate a complete artifact.`
|
|
598
|
+
);
|
|
599
|
+
}
|
|
600
|
+
return value;
|
|
601
|
+
}
|
|
602
|
+
function parseHarnessMetrics(value, source) {
|
|
603
|
+
if (!isRecord(value)) throw new Error(`${source}: expected object`);
|
|
604
|
+
return {
|
|
605
|
+
receiptCount: readNumber(value, source, "receiptCount"),
|
|
606
|
+
toolCalls: readNumber(value, source, "toolCalls"),
|
|
607
|
+
retries: readNumber(value, source, "retries"),
|
|
608
|
+
safetyBlocks: readNumber(value, source, "safetyBlocks"),
|
|
609
|
+
correctionLatencyMs: readNumber(value, source, "correctionLatencyMs"),
|
|
610
|
+
validationEvidence: readNumber(value, source, "validationEvidence")
|
|
611
|
+
};
|
|
612
|
+
}
|
|
613
|
+
function parseCommand(value, source) {
|
|
614
|
+
if (!isRecord(value)) throw new Error(`${source}: expected object`);
|
|
615
|
+
const phase = readString(value, source, "phase");
|
|
616
|
+
if (phase !== "setup" && phase !== "verifier") throw new Error(`${source}.phase: expected setup or verifier`);
|
|
617
|
+
return {
|
|
618
|
+
phase,
|
|
619
|
+
index: readNumber(value, source, "index"),
|
|
620
|
+
command: readString(value, source, "command"),
|
|
621
|
+
exitCode: readNumber(value, source, "exitCode"),
|
|
622
|
+
signal: readSignal(value.signal, `${source}.signal`),
|
|
623
|
+
timedOut: readBoolean(value, source, "timedOut"),
|
|
624
|
+
wallTimeMs: readNumber(value, source, "wallTimeMs"),
|
|
625
|
+
stdout: readStringAllowEmpty(value, source, "stdout"),
|
|
626
|
+
stderr: readStringAllowEmpty(value, source, "stderr")
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
function readSignal(value, source) {
|
|
630
|
+
if (value === null) return null;
|
|
631
|
+
if (typeof value === "string" && NODE_SIGNALS.has(value)) return value;
|
|
632
|
+
throw new Error(`${source}: expected signal or null`);
|
|
633
|
+
}
|
|
634
|
+
function parseFailureClassCount(value, source) {
|
|
635
|
+
if (!isRecord(value)) throw new Error(`${source}: expected object`);
|
|
636
|
+
return {
|
|
637
|
+
failureClass: readFailureClass(value, source, "failureClass"),
|
|
638
|
+
count: readNumber(value, source, "count")
|
|
639
|
+
};
|
|
640
|
+
}
|
|
641
|
+
function readFailureClass(record, source, field) {
|
|
642
|
+
const value = record[field];
|
|
643
|
+
if (value === "setup_failed" || value === "verifier_failed" || value === "timeout" || value === "cwd_missing" || value === "command_error") {
|
|
644
|
+
return value;
|
|
645
|
+
}
|
|
646
|
+
throw new Error(`${source}.${field}: expected failure class`);
|
|
647
|
+
}
|
|
648
|
+
function readOptionalFailureClass(record, source, field) {
|
|
649
|
+
if (record[field] === void 0) return void 0;
|
|
650
|
+
return readFailureClass(record, source, field);
|
|
651
|
+
}
|
|
652
|
+
function readString(record, source, field) {
|
|
653
|
+
const value = record[field];
|
|
654
|
+
if (typeof value !== "string" || value.length === 0) throw new Error(`${source}.${field}: expected string`);
|
|
655
|
+
return value;
|
|
656
|
+
}
|
|
657
|
+
function readStringAllowEmpty(record, source, field) {
|
|
658
|
+
const value = record[field];
|
|
659
|
+
if (typeof value !== "string") throw new Error(`${source}.${field}: expected string`);
|
|
660
|
+
return value;
|
|
661
|
+
}
|
|
662
|
+
function readOptionalString(record, source, field) {
|
|
663
|
+
const value = record[field];
|
|
664
|
+
if (value === void 0) return void 0;
|
|
665
|
+
if (typeof value !== "string" || value.length === 0) throw new Error(`${source}.${field}: expected string`);
|
|
666
|
+
return value;
|
|
667
|
+
}
|
|
668
|
+
function readNullableString(record, source, field) {
|
|
669
|
+
const value = record[field];
|
|
670
|
+
if (value === null) return null;
|
|
671
|
+
if (typeof value !== "string" || value.length === 0) throw new Error(`${source}.${field}: expected string or null`);
|
|
672
|
+
return value;
|
|
673
|
+
}
|
|
674
|
+
function readOptionalNullableString(record, source, field) {
|
|
675
|
+
const value = record[field];
|
|
676
|
+
if (value === void 0 || value === null) return null;
|
|
677
|
+
if (typeof value !== "string" || value.length === 0) throw new Error(`${source}.${field}: expected string or null`);
|
|
678
|
+
return value;
|
|
679
|
+
}
|
|
680
|
+
function readStringArray(record, source, field) {
|
|
681
|
+
const value = readArray(record, source, field);
|
|
682
|
+
const out = [];
|
|
683
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
684
|
+
const entry = value[index];
|
|
685
|
+
if (typeof entry !== "string") throw new Error(`${source}.${field}[${index}]: expected string`);
|
|
686
|
+
out.push(entry);
|
|
687
|
+
}
|
|
688
|
+
return out;
|
|
689
|
+
}
|
|
690
|
+
function readNumber(record, source, field) {
|
|
691
|
+
const value = record[field];
|
|
692
|
+
if (typeof value !== "number" || !Number.isFinite(value)) throw new Error(`${source}.${field}: expected number`);
|
|
693
|
+
return value;
|
|
694
|
+
}
|
|
695
|
+
function readBoolean(record, source, field) {
|
|
696
|
+
const value = record[field];
|
|
697
|
+
if (typeof value !== "boolean") throw new Error(`${source}.${field}: expected boolean`);
|
|
698
|
+
return value;
|
|
699
|
+
}
|
|
700
|
+
function readArray(record, source, field) {
|
|
701
|
+
const value = record[field];
|
|
702
|
+
if (!Array.isArray(value)) throw new Error(`${source}.${field}: expected array`);
|
|
703
|
+
return value;
|
|
704
|
+
}
|
|
705
|
+
function parseJson(raw, source) {
|
|
706
|
+
try {
|
|
707
|
+
return JSON.parse(raw);
|
|
708
|
+
} catch (error) {
|
|
709
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
710
|
+
throw new Error(`${source}: invalid JSON: ${message}`);
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
function isRecord(value) {
|
|
714
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
715
|
+
}
|
|
716
|
+
function isErrorWithCode(error) {
|
|
717
|
+
return error instanceof Error && "code" in error && typeof error.code === "string";
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
// src/domains/eval/artifacts/store.ts
|
|
721
|
+
init_esm_shims();
|
|
722
|
+
import { readFile as readFile2 } from "node:fs/promises";
|
|
723
|
+
import { join as join2 } from "node:path";
|
|
724
|
+
function evalArtifactPathV4(dataDir, evalId) {
|
|
725
|
+
assertSafeId(evalId, "eval");
|
|
726
|
+
return join2(evalRoot(dataDir), `${evalId}.json`);
|
|
727
|
+
}
|
|
728
|
+
async function writeEvalArtifactV4(dataDir, artifact, out) {
|
|
729
|
+
const path = out === void 0 ? evalArtifactPathV4(dataDir, artifact.evalId) : out.endsWith(".json") ? out : join2(out, `${artifact.evalId}.json`);
|
|
730
|
+
safeResourceWrite(path, `${JSON.stringify(redactArtifactForStorage(artifact), null, 2)}
|
|
731
|
+
`, { encoding: "utf8" });
|
|
732
|
+
return path;
|
|
733
|
+
}
|
|
734
|
+
async function loadEvalArtifactV4(dataDir, evalId) {
|
|
735
|
+
let raw;
|
|
736
|
+
try {
|
|
737
|
+
raw = await readFile2(evalArtifactPathV4(dataDir, evalId), "utf8");
|
|
738
|
+
} catch (error) {
|
|
739
|
+
if (error.code === "ENOENT") throw new Error(`eval artifact not found: ${evalId}`);
|
|
740
|
+
throw error;
|
|
741
|
+
}
|
|
742
|
+
return parseEvalArtifactV4(JSON.parse(raw), evalId);
|
|
743
|
+
}
|
|
744
|
+
function parseEvalArtifactV4(value, source) {
|
|
745
|
+
if (!isRecord2(value)) throw new Error(`${source}: expected object`);
|
|
746
|
+
if (value.version !== 4) throw new Error(`${source}.version: expected current version 4`);
|
|
747
|
+
const summary = asRecord(value.summary, `${source}.summary`);
|
|
748
|
+
const matrix = asRecord(value.matrix, `${source}.matrix`);
|
|
749
|
+
const suite = asRecord(value.suite, `${source}.suite`);
|
|
750
|
+
return {
|
|
751
|
+
version: 4,
|
|
752
|
+
evalId: readString2(value, source, "evalId"),
|
|
753
|
+
suite: { id: readString2(suite, `${source}.suite`, "id"), hash: readString2(suite, `${source}.suite`, "hash") },
|
|
754
|
+
clio: {
|
|
755
|
+
version: readString2(asRecord(value.clio, `${source}.clio`), `${source}.clio`, "version"),
|
|
756
|
+
commit: readNullableString2(asRecord(value.clio, `${source}.clio`), `${source}.clio`, "commit"),
|
|
757
|
+
entry: readString2(asRecord(value.clio, `${source}.clio`), `${source}.clio`, "entry")
|
|
758
|
+
},
|
|
759
|
+
environment: {
|
|
760
|
+
platform: readString2(asRecord(value.environment, `${source}.environment`), `${source}.environment`, "platform"),
|
|
761
|
+
node: readString2(asRecord(value.environment, `${source}.environment`), `${source}.environment`, "node")
|
|
762
|
+
},
|
|
763
|
+
matrix: {
|
|
764
|
+
target: readString2(matrix, `${source}.matrix`, "target"),
|
|
765
|
+
model: readNullableString2(matrix, `${source}.matrix`, "model"),
|
|
766
|
+
thinking: readNullableString2(matrix, `${source}.matrix`, "thinking")
|
|
767
|
+
},
|
|
768
|
+
summary: {
|
|
769
|
+
runs: readNumber2(summary, `${source}.summary`, "runs"),
|
|
770
|
+
passed: readNumber2(summary, `${source}.summary`, "passed"),
|
|
771
|
+
failed: readNumber2(summary, `${source}.summary`, "failed"),
|
|
772
|
+
passRate: readNumber2(summary, `${source}.summary`, "passRate"),
|
|
773
|
+
tokens: parseTokenAccounting(summary.tokens, `${source}.summary.tokens`),
|
|
774
|
+
wallTimeMs: readNumber2(summary, `${source}.summary`, "wallTimeMs")
|
|
775
|
+
},
|
|
776
|
+
results: readArray2(value, source, "results").map((entry, index) => parseResult(entry, `${source}.results[${index}]`))
|
|
777
|
+
};
|
|
778
|
+
}
|
|
779
|
+
function parseTokenAccounting(value, source) {
|
|
780
|
+
const record = asRecord(value, source);
|
|
781
|
+
const measured = readBoolean2(record, source, "measured");
|
|
782
|
+
const runs = readNumber2(record, source, "runs");
|
|
783
|
+
const measuredRuns = readNumber2(record, source, "measuredRuns");
|
|
784
|
+
const countFields = ["input", "output", "total", "cacheRead", "cacheWrite"];
|
|
785
|
+
if (!measured) {
|
|
786
|
+
if (measuredRuns !== 0) throw new Error(`${source}.measuredRuns: expected 0 when unmeasured`);
|
|
787
|
+
const present = countFields.filter((field) => field in record);
|
|
788
|
+
if (present.length > 0) throw new Error(`${source}: unmeasured accounting carries no counts (${present.join(", ")})`);
|
|
789
|
+
return { measured: false, runs, measuredRuns: 0 };
|
|
790
|
+
}
|
|
791
|
+
if (measuredRuns <= 0) throw new Error(`${source}.measuredRuns: expected a positive count when measured`);
|
|
792
|
+
return {
|
|
793
|
+
measured: true,
|
|
794
|
+
runs,
|
|
795
|
+
measuredRuns,
|
|
796
|
+
input: readNumber2(record, source, "input"),
|
|
797
|
+
output: readNumber2(record, source, "output"),
|
|
798
|
+
total: readNumber2(record, source, "total"),
|
|
799
|
+
cacheRead: readNumber2(record, source, "cacheRead"),
|
|
800
|
+
cacheWrite: readNumber2(record, source, "cacheWrite")
|
|
801
|
+
};
|
|
802
|
+
}
|
|
803
|
+
function parseResult(value, source) {
|
|
804
|
+
const record = asRecord(value, source);
|
|
805
|
+
const target = asRecord(record.target, `${source}.target`);
|
|
806
|
+
return {
|
|
807
|
+
assignmentId: readNullableString2(record, source, "assignmentId"),
|
|
808
|
+
terminalReceiptDigest: readNullableDigest(record, source, "terminalReceiptDigest"),
|
|
809
|
+
taskId: readString2(record, source, "taskId"),
|
|
810
|
+
repeatIndex: readNumber2(record, source, "repeatIndex"),
|
|
811
|
+
target: {
|
|
812
|
+
id: readString2(target, `${source}.target`, "id"),
|
|
813
|
+
model: readNullableString2(target, `${source}.target`, "model"),
|
|
814
|
+
thinking: readNullableString2(target, `${source}.target`, "thinking")
|
|
815
|
+
},
|
|
816
|
+
pass: readBoolean2(record, source, "pass"),
|
|
817
|
+
failureClass: readNullableString2(record, source, "failureClass"),
|
|
818
|
+
metrics: asRecord(record.metrics, `${source}.metrics`),
|
|
819
|
+
artifacts: asRecord(record.artifacts, `${source}.artifacts`)
|
|
820
|
+
};
|
|
821
|
+
}
|
|
822
|
+
function asRecord(value, source) {
|
|
823
|
+
if (isRecord2(value)) return value;
|
|
824
|
+
throw new Error(`${source}: expected object`);
|
|
825
|
+
}
|
|
826
|
+
function isRecord2(value) {
|
|
827
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
828
|
+
}
|
|
829
|
+
function readString2(record, source, field) {
|
|
830
|
+
const value = record[field];
|
|
831
|
+
if (typeof value !== "string" || value.length === 0) throw new Error(`${source}.${field}: expected string`);
|
|
832
|
+
return value;
|
|
833
|
+
}
|
|
834
|
+
function readNullableString2(record, source, field) {
|
|
835
|
+
const value = record[field];
|
|
836
|
+
if (value === null) return null;
|
|
837
|
+
if (typeof value !== "string" || value.length === 0) throw new Error(`${source}.${field}: expected string or null`);
|
|
838
|
+
return value;
|
|
839
|
+
}
|
|
840
|
+
function readNullableDigest(record, source, field) {
|
|
841
|
+
const value = readNullableString2(record, source, field);
|
|
842
|
+
if (value !== null && !/^[0-9a-f]{64}$/u.test(value))
|
|
843
|
+
throw new Error(`${source}.${field}: expected sha256 digest or null`);
|
|
844
|
+
return value;
|
|
845
|
+
}
|
|
846
|
+
function readNumber2(record, source, field) {
|
|
847
|
+
const value = record[field];
|
|
848
|
+
if (typeof value !== "number" || !Number.isFinite(value)) throw new Error(`${source}.${field}: expected number`);
|
|
849
|
+
return value;
|
|
850
|
+
}
|
|
851
|
+
function readBoolean2(record, source, field) {
|
|
852
|
+
const value = record[field];
|
|
853
|
+
if (typeof value !== "boolean") throw new Error(`${source}.${field}: expected boolean`);
|
|
854
|
+
return value;
|
|
855
|
+
}
|
|
856
|
+
function readArray2(record, source, field) {
|
|
857
|
+
const value = record[field];
|
|
858
|
+
if (!Array.isArray(value)) throw new Error(`${source}.${field}: expected array`);
|
|
859
|
+
return value;
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
// src/domains/eval/provenance.ts
|
|
863
|
+
init_esm_shims();
|
|
864
|
+
import { spawnSync } from "node:child_process";
|
|
865
|
+
function evalClioProvenance(options = {}) {
|
|
866
|
+
return {
|
|
867
|
+
version: readClioVersion(),
|
|
868
|
+
commit: options.commit === void 0 ? currentClioCommit() : options.commit,
|
|
869
|
+
entry: options.entry ?? process.argv[1] ?? "unknown"
|
|
870
|
+
};
|
|
871
|
+
}
|
|
872
|
+
function evalEnvironmentProvenance() {
|
|
873
|
+
return {
|
|
874
|
+
platform: `${process.platform}-${process.arch}`,
|
|
875
|
+
node: process.version
|
|
876
|
+
};
|
|
877
|
+
}
|
|
878
|
+
function currentClioCommit() {
|
|
879
|
+
const result = spawnSync("git", ["rev-parse", "HEAD"], {
|
|
880
|
+
cwd: resolvePackageRoot(),
|
|
881
|
+
encoding: "utf8",
|
|
882
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
883
|
+
timeout: 1e3
|
|
884
|
+
});
|
|
885
|
+
if (result.status !== 0 || typeof result.stdout !== "string") return null;
|
|
886
|
+
const value = result.stdout.trim();
|
|
887
|
+
return value.length > 0 ? value : null;
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
// src/domains/eval/task-file.ts
|
|
891
|
+
init_esm_shims();
|
|
892
|
+
var import_yaml = __toESM(require_dist(), 1);
|
|
893
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
894
|
+
import { readFile as readFile3 } from "node:fs/promises";
|
|
895
|
+
import { dirname, isAbsolute, relative, resolve } from "node:path";
|
|
896
|
+
|
|
897
|
+
// src/domains/eval/types.ts
|
|
898
|
+
init_esm_shims();
|
|
899
|
+
var EVAL_TASK_FILE_VERSION = 1;
|
|
900
|
+
|
|
901
|
+
// src/domains/eval/task-file.ts
|
|
902
|
+
var TASK_KEYS = /* @__PURE__ */ new Set(["id", "prompt", "cwd", "setup", "verifier", "timeoutMs", "tags"]);
|
|
903
|
+
async function loadEvalTaskFile(path) {
|
|
904
|
+
const resolved = resolve(path);
|
|
905
|
+
const raw = await readFile3(resolved, "utf8");
|
|
906
|
+
const result = parseEvalTaskFileYaml(raw);
|
|
907
|
+
if (!result.valid) {
|
|
908
|
+
throw new EvalTaskFileError(result.issues);
|
|
909
|
+
}
|
|
910
|
+
const baseDir = dirname(resolved);
|
|
911
|
+
const cwdIssues = validateTaskCwds(result.taskFile.tasks, baseDir);
|
|
912
|
+
if (cwdIssues.length > 0) throw new EvalTaskFileError(cwdIssues);
|
|
913
|
+
return {
|
|
914
|
+
path: resolved,
|
|
915
|
+
baseDir,
|
|
916
|
+
contentHash: sha256Hex(raw),
|
|
917
|
+
taskFile: result.taskFile
|
|
918
|
+
};
|
|
919
|
+
}
|
|
920
|
+
function parseEvalTaskFileYaml(raw) {
|
|
921
|
+
let parsed;
|
|
922
|
+
try {
|
|
923
|
+
parsed = (0, import_yaml.parse)(raw);
|
|
924
|
+
} catch (error) {
|
|
925
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
926
|
+
return { valid: false, issues: [{ path: "$", message: `invalid YAML: ${message}` }] };
|
|
927
|
+
}
|
|
928
|
+
return validateEvalTaskFile(parsed);
|
|
929
|
+
}
|
|
930
|
+
function validateEvalTaskFile(value) {
|
|
931
|
+
const issues = [];
|
|
932
|
+
if (!isRecord3(value)) {
|
|
933
|
+
return { valid: false, issues: [{ path: "$", message: "expected object" }] };
|
|
934
|
+
}
|
|
935
|
+
if (value.version !== EVAL_TASK_FILE_VERSION) {
|
|
936
|
+
issues.push({ path: "$.version", message: "expected version 1" });
|
|
937
|
+
}
|
|
938
|
+
if (!Array.isArray(value.tasks)) {
|
|
939
|
+
issues.push({ path: "$.tasks", message: "expected non-empty array" });
|
|
940
|
+
return { valid: false, issues };
|
|
941
|
+
}
|
|
942
|
+
if (value.tasks.length === 0) {
|
|
943
|
+
issues.push({ path: "$.tasks", message: "expected non-empty array" });
|
|
944
|
+
}
|
|
945
|
+
const tasks = [];
|
|
946
|
+
const seenIds = /* @__PURE__ */ new Set();
|
|
947
|
+
for (let index = 0; index < value.tasks.length; index += 1) {
|
|
948
|
+
const task = parseTask(value.tasks[index], `$.tasks[${index}]`, issues);
|
|
949
|
+
if (task === null) continue;
|
|
950
|
+
if (seenIds.has(task.id)) {
|
|
951
|
+
issues.push({ path: `$.tasks[${index}].id`, message: `duplicate task id: ${task.id}` });
|
|
952
|
+
}
|
|
953
|
+
seenIds.add(task.id);
|
|
954
|
+
tasks.push(task);
|
|
955
|
+
}
|
|
956
|
+
if (issues.length > 0) return { valid: false, issues };
|
|
957
|
+
return { valid: true, taskFile: { version: 1, tasks } };
|
|
958
|
+
}
|
|
959
|
+
var EvalTaskFileError = class extends Error {
|
|
960
|
+
issues;
|
|
961
|
+
constructor(issues) {
|
|
962
|
+
super(`eval task file invalid (${issues.length} ${issues.length === 1 ? "issue" : "issues"})`);
|
|
963
|
+
this.name = "EvalTaskFileError";
|
|
964
|
+
this.issues = [...issues];
|
|
965
|
+
}
|
|
966
|
+
};
|
|
967
|
+
function parseTask(value, path, issues) {
|
|
968
|
+
if (!isRecord3(value)) {
|
|
969
|
+
issues.push({ path, message: "expected object" });
|
|
970
|
+
return null;
|
|
971
|
+
}
|
|
972
|
+
for (const key of Object.keys(value).sort((a, b) => a.localeCompare(b))) {
|
|
973
|
+
if (!TASK_KEYS.has(key)) issues.push({ path: `${path}.${key}`, message: "unknown field" });
|
|
974
|
+
}
|
|
975
|
+
const id = readNonEmptyString(value, path, "id", issues);
|
|
976
|
+
if (id !== null && !/^[A-Za-z0-9._-]+$/.test(id)) {
|
|
977
|
+
issues.push({ path: `${path}.id`, message: "expected id with letters, numbers, dots, underscores, or hyphens" });
|
|
978
|
+
}
|
|
979
|
+
const prompt = readNonEmptyString(value, path, "prompt", issues);
|
|
980
|
+
const cwd = readNonEmptyString(value, path, "cwd", issues);
|
|
981
|
+
if (cwd !== null && isAbsolute(cwd)) {
|
|
982
|
+
issues.push({ path: `${path}.cwd`, message: "expected repo-local relative path" });
|
|
983
|
+
}
|
|
984
|
+
const setup = readStringArray2(value, path, "setup", issues, true);
|
|
985
|
+
const verifier = readStringArray2(value, path, "verifier", issues, false);
|
|
986
|
+
if (verifier !== null && verifier.length === 0) {
|
|
987
|
+
issues.push({ path: `${path}.verifier`, message: "expected at least one command" });
|
|
988
|
+
}
|
|
989
|
+
const timeoutMs = readPositiveInteger(value, path, "timeoutMs", issues);
|
|
990
|
+
const tags = readStringArray2(value, path, "tags", issues, true);
|
|
991
|
+
if (id === null || prompt === null || cwd === null || setup === null || verifier === null || timeoutMs === null) {
|
|
992
|
+
return null;
|
|
993
|
+
}
|
|
994
|
+
return { id, prompt, cwd, setup, verifier, timeoutMs, tags: tags ?? [] };
|
|
995
|
+
}
|
|
996
|
+
function validateTaskCwds(tasks, baseDir) {
|
|
997
|
+
const issues = [];
|
|
998
|
+
for (let index = 0; index < tasks.length; index += 1) {
|
|
999
|
+
const task = tasks[index];
|
|
1000
|
+
if (task === void 0) continue;
|
|
1001
|
+
const resolved = resolve(baseDir, task.cwd);
|
|
1002
|
+
const rel = relative(baseDir, resolved);
|
|
1003
|
+
if (rel === "" || !rel.startsWith("..") && !isAbsolute(rel)) continue;
|
|
1004
|
+
issues.push({ path: `$.tasks[${index}].cwd`, message: "cwd must stay within the task file directory" });
|
|
1005
|
+
}
|
|
1006
|
+
return issues;
|
|
1007
|
+
}
|
|
1008
|
+
function readNonEmptyString(record, path, field, issues) {
|
|
1009
|
+
const value = record[field];
|
|
1010
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
1011
|
+
issues.push({ path: `${path}.${field}`, message: "expected non-empty string" });
|
|
1012
|
+
return null;
|
|
1013
|
+
}
|
|
1014
|
+
return value;
|
|
1015
|
+
}
|
|
1016
|
+
function readStringArray2(record, path, field, issues, allowMissing) {
|
|
1017
|
+
const value = record[field];
|
|
1018
|
+
if (value === void 0 && allowMissing) return [];
|
|
1019
|
+
if (!Array.isArray(value)) {
|
|
1020
|
+
issues.push({ path: `${path}.${field}`, message: "expected string array" });
|
|
1021
|
+
return null;
|
|
1022
|
+
}
|
|
1023
|
+
const out = [];
|
|
1024
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
1025
|
+
const entry = value[index];
|
|
1026
|
+
if (typeof entry !== "string" || entry.trim().length === 0) {
|
|
1027
|
+
issues.push({ path: `${path}.${field}[${index}]`, message: "expected non-empty string" });
|
|
1028
|
+
continue;
|
|
1029
|
+
}
|
|
1030
|
+
out.push(entry);
|
|
1031
|
+
}
|
|
1032
|
+
return out;
|
|
1033
|
+
}
|
|
1034
|
+
function readPositiveInteger(record, path, field, issues) {
|
|
1035
|
+
const value = record[field];
|
|
1036
|
+
if (typeof value !== "number" || !Number.isInteger(value) || value <= 0) {
|
|
1037
|
+
issues.push({ path: `${path}.${field}`, message: "expected positive integer" });
|
|
1038
|
+
return null;
|
|
1039
|
+
}
|
|
1040
|
+
return value;
|
|
1041
|
+
}
|
|
1042
|
+
function isRecord3(value) {
|
|
1043
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1044
|
+
}
|
|
1045
|
+
function sha256Hex(content) {
|
|
1046
|
+
return createHash3("sha256").update(content, "utf8").digest("hex");
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
export {
|
|
1050
|
+
RUN_RECEIPT_INTEGRITY_VERSION,
|
|
1051
|
+
RUN_RECEIPT_INTEGRITY_ALGORITHM,
|
|
1052
|
+
withReceiptIntegrity,
|
|
1053
|
+
isReceiptIntegrity,
|
|
1054
|
+
verifyReceiptIntegrity,
|
|
1055
|
+
redactArtifactForStorage,
|
|
1056
|
+
ZERO_EVAL_HARNESS_METRICS,
|
|
1057
|
+
sumEvalHarnessMetrics,
|
|
1058
|
+
createEvalId,
|
|
1059
|
+
writeEvalArtifact,
|
|
1060
|
+
loadEvalArtifact,
|
|
1061
|
+
writeEvalArtifactV4,
|
|
1062
|
+
loadEvalArtifactV4,
|
|
1063
|
+
parseEvalArtifactV4,
|
|
1064
|
+
evalClioProvenance,
|
|
1065
|
+
evalEnvironmentProvenance,
|
|
1066
|
+
loadEvalTaskFile,
|
|
1067
|
+
EvalTaskFileError
|
|
1068
|
+
};
|
|
1069
|
+
//# sourceMappingURL=chunk-AGYYIBLL.js.map
|