@tangle-network/browser-agent-driver 0.33.3 → 0.35.0
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/README.md +42 -1
- package/discovery/llms.txt +27 -0
- package/discovery/tangle-agent.json +36 -0
- package/dist/brain/action-parse.d.ts +16 -0
- package/dist/brain/action-parse.d.ts.map +1 -0
- package/dist/brain/action-parse.js +191 -0
- package/dist/brain/action-parse.js.map +1 -0
- package/dist/brain/decide.d.ts +58 -0
- package/dist/brain/decide.d.ts.map +1 -0
- package/dist/brain/decide.js +418 -0
- package/dist/brain/decide.js.map +1 -0
- package/dist/brain/history-compact.d.ts +19 -0
- package/dist/brain/history-compact.d.ts.map +1 -0
- package/dist/brain/history-compact.js +153 -0
- package/dist/brain/history-compact.js.map +1 -0
- package/dist/brain/index.d.ts +78 -152
- package/dist/brain/index.d.ts.map +1 -1
- package/dist/brain/index.js +62 -2268
- package/dist/brain/index.js.map +1 -1
- package/dist/brain/model-client.d.ts +101 -0
- package/dist/brain/model-client.d.ts.map +1 -0
- package/dist/brain/model-client.js +391 -0
- package/dist/brain/model-client.js.map +1 -0
- package/dist/brain/plan.d.ts +57 -0
- package/dist/brain/plan.d.ts.map +1 -0
- package/dist/brain/plan.js +194 -0
- package/dist/brain/plan.js.map +1 -0
- package/dist/brain/prompts.d.ts +37 -0
- package/dist/brain/prompts.d.ts.map +1 -0
- package/dist/brain/prompts.js +455 -0
- package/dist/brain/prompts.js.map +1 -0
- package/dist/brain/provider-fetch.d.ts +26 -0
- package/dist/brain/provider-fetch.d.ts.map +1 -0
- package/dist/brain/provider-fetch.js +45 -0
- package/dist/brain/provider-fetch.js.map +1 -0
- package/dist/brain/snapshot-budget.d.ts +20 -0
- package/dist/brain/snapshot-budget.d.ts.map +1 -0
- package/dist/brain/snapshot-budget.js +202 -0
- package/dist/brain/snapshot-budget.js.map +1 -0
- package/dist/brain/system-prompt.d.ts +67 -0
- package/dist/brain/system-prompt.d.ts.map +1 -0
- package/dist/brain/system-prompt.js +128 -0
- package/dist/brain/system-prompt.js.map +1 -0
- package/dist/brain/tasks/design-audit.d.ts +33 -0
- package/dist/brain/tasks/design-audit.d.ts.map +1 -0
- package/dist/brain/tasks/design-audit.js +100 -0
- package/dist/brain/tasks/design-audit.js.map +1 -0
- package/dist/brain/tasks/evaluate.d.ts +25 -0
- package/dist/brain/tasks/evaluate.d.ts.map +1 -0
- package/dist/brain/tasks/evaluate.js +55 -0
- package/dist/brain/tasks/evaluate.js.map +1 -0
- package/dist/brain/tasks/goal-verification.d.ts +32 -0
- package/dist/brain/tasks/goal-verification.d.ts.map +1 -0
- package/dist/brain/tasks/goal-verification.js +68 -0
- package/dist/brain/tasks/goal-verification.js.map +1 -0
- package/dist/brain/tasks/knowledge.d.ts +26 -0
- package/dist/brain/tasks/knowledge.d.ts.map +1 -0
- package/dist/brain/tasks/knowledge.js +56 -0
- package/dist/brain/tasks/knowledge.js.map +1 -0
- package/dist/brain/tasks/link-scout.d.ts +37 -0
- package/dist/brain/tasks/link-scout.d.ts.map +1 -0
- package/dist/brain/tasks/link-scout.js +69 -0
- package/dist/brain/tasks/link-scout.js.map +1 -0
- package/dist/brain/types.d.ts +55 -0
- package/dist/brain/types.d.ts.map +1 -0
- package/dist/brain/types.js +7 -0
- package/dist/brain/types.js.map +1 -0
- package/dist/browser/stealth-init-script.d.ts +9 -0
- package/dist/browser/stealth-init-script.d.ts.map +1 -0
- package/dist/browser/stealth-init-script.js +128 -0
- package/dist/browser/stealth-init-script.js.map +1 -0
- package/dist/browser/storage-state.d.ts +29 -0
- package/dist/browser/storage-state.d.ts.map +1 -0
- package/dist/browser/storage-state.js +47 -0
- package/dist/browser/storage-state.js.map +1 -0
- package/dist/browser-launch.d.ts +6 -0
- package/dist/browser-launch.d.ts.map +1 -1
- package/dist/browser-launch.js +3 -0
- package/dist/browser-launch.js.map +1 -1
- package/dist/cli/args.d.ts +141 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/args.js +167 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/benchmark-sync.d.ts +9 -0
- package/dist/cli/benchmark-sync.d.ts.map +1 -0
- package/dist/cli/benchmark-sync.js +43 -0
- package/dist/cli/benchmark-sync.js.map +1 -0
- package/dist/cli/build-config.d.ts +11 -0
- package/dist/cli/build-config.d.ts.map +1 -0
- package/dist/cli/build-config.js +355 -0
- package/dist/cli/build-config.js.map +1 -0
- package/dist/cli/commands/auth.d.ts +3 -0
- package/dist/cli/commands/auth.d.ts.map +1 -0
- package/dist/cli/commands/auth.js +36 -0
- package/dist/cli/commands/auth.js.map +1 -0
- package/dist/cli/commands/chrome-debug.d.ts +7 -0
- package/dist/cli/commands/chrome-debug.d.ts.map +1 -0
- package/dist/cli/commands/chrome-debug.js +11 -0
- package/dist/cli/commands/chrome-debug.js.map +1 -0
- package/dist/cli/commands/design-audit.d.ts +3 -0
- package/dist/cli/commands/design-audit.d.ts.map +1 -0
- package/dist/cli/commands/design-audit.js +68 -0
- package/dist/cli/commands/design-audit.js.map +1 -0
- package/dist/cli/commands/preview.d.ts +14 -0
- package/dist/cli/commands/preview.d.ts.map +1 -0
- package/dist/cli/commands/preview.js +31 -0
- package/dist/cli/commands/preview.js.map +1 -0
- package/dist/cli/commands/run.d.ts +3 -0
- package/dist/cli/commands/run.d.ts.map +1 -0
- package/dist/cli/commands/run.js +740 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/commands/runs.d.ts +8 -0
- package/dist/cli/commands/runs.d.ts.map +1 -0
- package/dist/cli/commands/runs.js +35 -0
- package/dist/cli/commands/runs.js.map +1 -0
- package/dist/cli/commands/share.d.ts +10 -0
- package/dist/cli/commands/share.d.ts.map +1 -0
- package/dist/cli/commands/share.js +32 -0
- package/dist/cli/commands/share.js.map +1 -0
- package/dist/cli/commands/showcase.d.ts +17 -0
- package/dist/cli/commands/showcase.d.ts.map +1 -0
- package/dist/cli/commands/showcase.js +20 -0
- package/dist/cli/commands/showcase.js.map +1 -0
- package/dist/cli/commands/snapshot.d.ts +12 -0
- package/dist/cli/commands/snapshot.d.ts.map +1 -0
- package/dist/cli/commands/snapshot.js +24 -0
- package/dist/cli/commands/snapshot.js.map +1 -0
- package/dist/cli/commands/view.d.ts +7 -0
- package/dist/cli/commands/view.d.ts.map +1 -0
- package/dist/cli/commands/view.js +23 -0
- package/dist/cli/commands/view.js.map +1 -0
- package/dist/cli/constants.d.ts +6 -0
- package/dist/cli/constants.d.ts.map +1 -0
- package/dist/cli/constants.js +3 -0
- package/dist/cli/constants.js.map +1 -0
- package/dist/cli/version.d.ts +7 -0
- package/dist/cli/version.d.ts.map +1 -0
- package/dist/cli/version.js +16 -0
- package/dist/cli/version.js.map +1 -0
- package/dist/cli-design-audit.d.ts +44 -36
- package/dist/cli-design-audit.d.ts.map +1 -1
- package/dist/cli-design-audit.js +137 -1646
- package/dist/cli-design-audit.js.map +1 -1
- package/dist/cli-jobs.js +2 -1
- package/dist/cli-jobs.js.map +1 -1
- package/dist/cli.js +66 -1697
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +12 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +20 -2
- package/dist/config.js.map +1 -1
- package/dist/design/audit/evolve/agent.d.ts +23 -0
- package/dist/design/audit/evolve/agent.d.ts.map +1 -0
- package/dist/design/audit/evolve/agent.js +273 -0
- package/dist/design/audit/evolve/agent.js.map +1 -0
- package/dist/design/audit/evolve/css.d.ts +10 -0
- package/dist/design/audit/evolve/css.d.ts.map +1 -0
- package/dist/design/audit/evolve/css.js +206 -0
- package/dist/design/audit/evolve/css.js.map +1 -0
- package/dist/design/audit/evolve/index.d.ts +13 -0
- package/dist/design/audit/evolve/index.d.ts.map +1 -0
- package/dist/design/audit/evolve/index.js +12 -0
- package/dist/design/audit/evolve/index.js.map +1 -0
- package/dist/design/audit/evolve/report.d.ts +3 -0
- package/dist/design/audit/evolve/report.d.ts.map +1 -0
- package/dist/design/audit/evolve/report.js +45 -0
- package/dist/design/audit/evolve/report.js.map +1 -0
- package/dist/design/audit/evolve/types.d.ts +14 -0
- package/dist/design/audit/evolve/types.d.ts.map +1 -0
- package/dist/design/audit/evolve/types.js +2 -0
- package/dist/design/audit/evolve/types.js.map +1 -0
- package/dist/design/audit/pipeline.d.ts +12 -0
- package/dist/design/audit/pipeline.d.ts.map +1 -1
- package/dist/design/audit/pipeline.js +43 -27
- package/dist/design/audit/pipeline.js.map +1 -1
- package/dist/design/audit/reference/artifact/build.d.ts +33 -0
- package/dist/design/audit/reference/artifact/build.d.ts.map +1 -0
- package/dist/design/audit/reference/artifact/build.js +64 -0
- package/dist/design/audit/reference/artifact/build.js.map +1 -0
- package/dist/design/audit/reference/artifact/render.d.ts +39 -0
- package/dist/design/audit/reference/artifact/render.d.ts.map +1 -0
- package/dist/design/audit/reference/artifact/render.js +213 -0
- package/dist/design/audit/reference/artifact/render.js.map +1 -0
- package/dist/design/audit/reference/artifact/text.d.ts +11 -0
- package/dist/design/audit/reference/artifact/text.d.ts.map +1 -0
- package/dist/design/audit/reference/artifact/text.js +20 -0
- package/dist/design/audit/reference/artifact/text.js.map +1 -0
- package/dist/design/audit/reference/artifact/to-findings.d.ts +57 -0
- package/dist/design/audit/reference/artifact/to-findings.d.ts.map +1 -0
- package/dist/design/audit/reference/artifact/to-findings.js +314 -0
- package/dist/design/audit/reference/artifact/to-findings.js.map +1 -0
- package/dist/design/audit/reference/config.d.ts +50 -0
- package/dist/design/audit/reference/config.d.ts.map +1 -0
- package/dist/design/audit/reference/config.js +108 -0
- package/dist/design/audit/reference/config.js.map +1 -0
- package/dist/design/audit/reference/contracts.d.ts +1030 -0
- package/dist/design/audit/reference/contracts.d.ts.map +1 -0
- package/dist/design/audit/reference/contracts.js +28 -0
- package/dist/design/audit/reference/contracts.js.map +1 -0
- package/dist/design/audit/reference/corpus/build.d.ts +115 -0
- package/dist/design/audit/reference/corpus/build.d.ts.map +1 -0
- package/dist/design/audit/reference/corpus/build.js +152 -0
- package/dist/design/audit/reference/corpus/build.js.map +1 -0
- package/dist/design/audit/reference/corpus/schema.d.ts +33 -0
- package/dist/design/audit/reference/corpus/schema.d.ts.map +1 -0
- package/dist/design/audit/reference/corpus/schema.js +249 -0
- package/dist/design/audit/reference/corpus/schema.js.map +1 -0
- package/dist/design/audit/reference/corpus/store.d.ts +26 -0
- package/dist/design/audit/reference/corpus/store.d.ts.map +1 -0
- package/dist/design/audit/reference/corpus/store.js +104 -0
- package/dist/design/audit/reference/corpus/store.js.map +1 -0
- package/dist/design/audit/reference/dna/delta.d.ts +21 -0
- package/dist/design/audit/reference/dna/delta.d.ts.map +1 -0
- package/dist/design/audit/reference/dna/delta.js +126 -0
- package/dist/design/audit/reference/dna/delta.js.map +1 -0
- package/dist/design/audit/reference/dna/derive.d.ts +31 -0
- package/dist/design/audit/reference/dna/derive.d.ts.map +1 -0
- package/dist/design/audit/reference/dna/derive.js +381 -0
- package/dist/design/audit/reference/dna/derive.js.map +1 -0
- package/dist/design/audit/reference/dna/descriptor.d.ts +36 -0
- package/dist/design/audit/reference/dna/descriptor.d.ts.map +1 -0
- package/dist/design/audit/reference/dna/descriptor.js +209 -0
- package/dist/design/audit/reference/dna/descriptor.js.map +1 -0
- package/dist/design/audit/reference/dna/page-adapter.d.ts +17 -0
- package/dist/design/audit/reference/dna/page-adapter.d.ts.map +1 -0
- package/dist/design/audit/reference/dna/page-adapter.js +35 -0
- package/dist/design/audit/reference/dna/page-adapter.js.map +1 -0
- package/dist/design/audit/reference/dna/scroll-capture.d.ts +93 -0
- package/dist/design/audit/reference/dna/scroll-capture.d.ts.map +1 -0
- package/dist/design/audit/reference/dna/scroll-capture.js +374 -0
- package/dist/design/audit/reference/dna/scroll-capture.js.map +1 -0
- package/dist/design/audit/reference/engine/budget.d.ts +63 -0
- package/dist/design/audit/reference/engine/budget.d.ts.map +1 -0
- package/dist/design/audit/reference/engine/budget.js +110 -0
- package/dist/design/audit/reference/engine/budget.js.map +1 -0
- package/dist/design/audit/reference/engine/core.d.ts +32 -0
- package/dist/design/audit/reference/engine/core.d.ts.map +1 -0
- package/dist/design/audit/reference/engine/core.js +261 -0
- package/dist/design/audit/reference/engine/core.js.map +1 -0
- package/dist/design/audit/reference/engine/guard.d.ts +43 -0
- package/dist/design/audit/reference/engine/guard.d.ts.map +1 -0
- package/dist/design/audit/reference/engine/guard.js +43 -0
- package/dist/design/audit/reference/engine/guard.js.map +1 -0
- package/dist/design/audit/reference/engine/score-core.d.ts +48 -0
- package/dist/design/audit/reference/engine/score-core.d.ts.map +1 -0
- package/dist/design/audit/reference/engine/score-core.js +134 -0
- package/dist/design/audit/reference/engine/score-core.js.map +1 -0
- package/dist/design/audit/reference/engine/wiring.d.ts +35 -0
- package/dist/design/audit/reference/engine/wiring.d.ts.map +1 -0
- package/dist/design/audit/reference/engine/wiring.js +80 -0
- package/dist/design/audit/reference/engine/wiring.js.map +1 -0
- package/dist/design/audit/reference/eval/taste-core.d.ts +77 -0
- package/dist/design/audit/reference/eval/taste-core.d.ts.map +1 -0
- package/dist/design/audit/reference/eval/taste-core.js +95 -0
- package/dist/design/audit/reference/eval/taste-core.js.map +1 -0
- package/dist/design/audit/reference/generate/generator.d.ts +49 -0
- package/dist/design/audit/reference/generate/generator.d.ts.map +1 -0
- package/dist/design/audit/reference/generate/generator.js +100 -0
- package/dist/design/audit/reference/generate/generator.js.map +1 -0
- package/dist/design/audit/reference/generate/parse.d.ts +28 -0
- package/dist/design/audit/reference/generate/parse.d.ts.map +1 -0
- package/dist/design/audit/reference/generate/parse.js +220 -0
- package/dist/design/audit/reference/generate/parse.js.map +1 -0
- package/dist/design/audit/reference/generate/prompt.d.ts +36 -0
- package/dist/design/audit/reference/generate/prompt.d.ts.map +1 -0
- package/dist/design/audit/reference/generate/prompt.js +172 -0
- package/dist/design/audit/reference/generate/prompt.js.map +1 -0
- package/dist/design/audit/reference/index.d.ts +26 -0
- package/dist/design/audit/reference/index.d.ts.map +1 -0
- package/dist/design/audit/reference/index.js +31 -0
- package/dist/design/audit/reference/index.js.map +1 -0
- package/dist/design/audit/reference/judge/image-clamp.d.ts +34 -0
- package/dist/design/audit/reference/judge/image-clamp.d.ts.map +1 -0
- package/dist/design/audit/reference/judge/image-clamp.js +88 -0
- package/dist/design/audit/reference/judge/image-clamp.js.map +1 -0
- package/dist/design/audit/reference/judge/pairwise.d.ts +34 -0
- package/dist/design/audit/reference/judge/pairwise.d.ts.map +1 -0
- package/dist/design/audit/reference/judge/pairwise.js +105 -0
- package/dist/design/audit/reference/judge/pairwise.js.map +1 -0
- package/dist/design/audit/reference/judge/parse.d.ts +31 -0
- package/dist/design/audit/reference/judge/parse.d.ts.map +1 -0
- package/dist/design/audit/reference/judge/parse.js +113 -0
- package/dist/design/audit/reference/judge/parse.js.map +1 -0
- package/dist/design/audit/reference/judge/prompt.d.ts +38 -0
- package/dist/design/audit/reference/judge/prompt.d.ts.map +1 -0
- package/dist/design/audit/reference/judge/prompt.js +123 -0
- package/dist/design/audit/reference/judge/prompt.js.map +1 -0
- package/dist/design/audit/reference/judge/quality.d.ts +28 -0
- package/dist/design/audit/reference/judge/quality.d.ts.map +1 -0
- package/dist/design/audit/reference/judge/quality.js +62 -0
- package/dist/design/audit/reference/judge/quality.js.map +1 -0
- package/dist/design/audit/reference/judge/rank.d.ts +41 -0
- package/dist/design/audit/reference/judge/rank.d.ts.map +1 -0
- package/dist/design/audit/reference/judge/rank.js +196 -0
- package/dist/design/audit/reference/judge/rank.js.map +1 -0
- package/dist/design/audit/reference/judge/text-judge.d.ts +31 -0
- package/dist/design/audit/reference/judge/text-judge.d.ts.map +1 -0
- package/dist/design/audit/reference/judge/text-judge.js +43 -0
- package/dist/design/audit/reference/judge/text-judge.js.map +1 -0
- package/dist/design/audit/reference/judge/vision-judge.d.ts +59 -0
- package/dist/design/audit/reference/judge/vision-judge.d.ts.map +1 -0
- package/dist/design/audit/reference/judge/vision-judge.js +150 -0
- package/dist/design/audit/reference/judge/vision-judge.js.map +1 -0
- package/dist/design/audit/reference/judge/vision-model.d.ts +65 -0
- package/dist/design/audit/reference/judge/vision-model.d.ts.map +1 -0
- package/dist/design/audit/reference/judge/vision-model.js +110 -0
- package/dist/design/audit/reference/judge/vision-model.js.map +1 -0
- package/dist/design/audit/reference/pipeline/evaluate-reference.d.ts +68 -0
- package/dist/design/audit/reference/pipeline/evaluate-reference.d.ts.map +1 -0
- package/dist/design/audit/reference/pipeline/evaluate-reference.js +52 -0
- package/dist/design/audit/reference/pipeline/evaluate-reference.js.map +1 -0
- package/dist/design/audit/reference/reference-context.d.ts +31 -0
- package/dist/design/audit/reference/reference-context.d.ts.map +1 -0
- package/dist/design/audit/reference/reference-context.js +73 -0
- package/dist/design/audit/reference/reference-context.js.map +1 -0
- package/dist/design/audit/reference/retrieval/embedding-hash.d.ts +30 -0
- package/dist/design/audit/reference/retrieval/embedding-hash.d.ts.map +1 -0
- package/dist/design/audit/reference/retrieval/embedding-hash.js +87 -0
- package/dist/design/audit/reference/retrieval/embedding-hash.js.map +1 -0
- package/dist/design/audit/reference/retrieval/embedding-openai.d.ts +38 -0
- package/dist/design/audit/reference/retrieval/embedding-openai.d.ts.map +1 -0
- package/dist/design/audit/reference/retrieval/embedding-openai.js +73 -0
- package/dist/design/audit/reference/retrieval/embedding-openai.js.map +1 -0
- package/dist/design/audit/reference/retrieval/matcher.d.ts +34 -0
- package/dist/design/audit/reference/retrieval/matcher.d.ts.map +1 -0
- package/dist/design/audit/reference/retrieval/matcher.js +107 -0
- package/dist/design/audit/reference/retrieval/matcher.js.map +1 -0
- package/dist/design/audit/reference/run.d.ts +59 -0
- package/dist/design/audit/reference/run.d.ts.map +1 -0
- package/dist/design/audit/reference/run.js +99 -0
- package/dist/design/audit/reference/run.js.map +1 -0
- package/dist/design/audit/report.d.ts +35 -0
- package/dist/design/audit/report.d.ts.map +1 -0
- package/dist/design/audit/report.js +195 -0
- package/dist/design/audit/report.js.map +1 -0
- package/dist/design/audit/tokens/extract.d.ts +71 -0
- package/dist/design/audit/tokens/extract.d.ts.map +1 -0
- package/dist/design/audit/tokens/extract.js +1034 -0
- package/dist/design/audit/tokens/extract.js.map +1 -0
- package/dist/design/audit/types.d.ts +8 -0
- package/dist/design/audit/types.d.ts.map +1 -1
- package/dist/design/compare.d.ts.map +1 -1
- package/dist/design/compare.js +2 -6
- package/dist/design/compare.js.map +1 -1
- package/dist/design/cookie-consent.d.ts +3 -0
- package/dist/design/cookie-consent.d.ts.map +1 -0
- package/dist/design/cookie-consent.js +26 -0
- package/dist/design/cookie-consent.js.map +1 -0
- package/dist/design/viewports.d.ts +18 -0
- package/dist/design/viewports.d.ts.map +1 -0
- package/dist/design/viewports.js +10 -0
- package/dist/design/viewports.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/memory/store.d.ts +19 -1
- package/dist/memory/store.d.ts.map +1 -1
- package/dist/memory/store.js +47 -0
- package/dist/memory/store.js.map +1 -1
- package/dist/provider-defaults.d.ts +18 -0
- package/dist/provider-defaults.d.ts.map +1 -1
- package/dist/provider-defaults.js +33 -0
- package/dist/provider-defaults.js.map +1 -1
- package/dist/runner/allowed-domains.d.ts +11 -0
- package/dist/runner/allowed-domains.d.ts.map +1 -0
- package/dist/runner/allowed-domains.js +14 -0
- package/dist/runner/allowed-domains.js.map +1 -0
- package/dist/runner/batch-fill.d.ts +28 -0
- package/dist/runner/batch-fill.d.ts.map +1 -0
- package/dist/runner/batch-fill.js +80 -0
- package/dist/runner/batch-fill.js.map +1 -0
- package/dist/runner/completion-policy.d.ts +26 -0
- package/dist/runner/completion-policy.d.ts.map +1 -0
- package/dist/runner/completion-policy.js +76 -0
- package/dist/runner/completion-policy.js.map +1 -0
- package/dist/runner/constants.d.ts +14 -0
- package/dist/runner/constants.d.ts.map +1 -0
- package/dist/runner/constants.js +23 -0
- package/dist/runner/constants.js.map +1 -0
- package/dist/runner/decision-screenshot.d.ts +24 -0
- package/dist/runner/decision-screenshot.d.ts.map +1 -0
- package/dist/runner/decision-screenshot.js +23 -0
- package/dist/runner/decision-screenshot.js.map +1 -0
- package/dist/runner/domain-boundary.d.ts +36 -0
- package/dist/runner/domain-boundary.d.ts.map +1 -0
- package/dist/runner/domain-boundary.js +81 -0
- package/dist/runner/domain-boundary.js.map +1 -0
- package/dist/runner/effect-verify.d.ts +28 -0
- package/dist/runner/effect-verify.d.ts.map +1 -0
- package/dist/runner/effect-verify.js +42 -0
- package/dist/runner/effect-verify.js.map +1 -0
- package/dist/runner/execute-plan.d.ts +58 -0
- package/dist/runner/execute-plan.d.ts.map +1 -0
- package/dist/runner/execute-plan.js +426 -0
- package/dist/runner/execute-plan.js.map +1 -0
- package/dist/runner/max-turns-extension.d.ts +19 -0
- package/dist/runner/max-turns-extension.d.ts.map +1 -0
- package/dist/runner/max-turns-extension.js +25 -0
- package/dist/runner/max-turns-extension.js.map +1 -0
- package/dist/runner/micro-plan.d.ts +11 -0
- package/dist/runner/micro-plan.d.ts.map +1 -0
- package/dist/runner/micro-plan.js +29 -0
- package/dist/runner/micro-plan.js.map +1 -0
- package/dist/runner/prompt-snippets.d.ts +5 -0
- package/dist/runner/prompt-snippets.d.ts.map +1 -0
- package/dist/runner/prompt-snippets.js +13 -0
- package/dist/runner/prompt-snippets.js.map +1 -0
- package/dist/runner/replay/contracts.d.ts +300 -0
- package/dist/runner/replay/contracts.d.ts.map +1 -0
- package/dist/runner/replay/contracts.js +42 -0
- package/dist/runner/replay/contracts.js.map +1 -0
- package/dist/runner/replay/controller.d.ts +27 -0
- package/dist/runner/replay/controller.d.ts.map +1 -0
- package/dist/runner/replay/controller.js +197 -0
- package/dist/runner/replay/controller.js.map +1 -0
- package/dist/runner/replay/guard.d.ts +28 -0
- package/dist/runner/replay/guard.d.ts.map +1 -0
- package/dist/runner/replay/guard.js +100 -0
- package/dist/runner/replay/guard.js.map +1 -0
- package/dist/runner/runner.d.ts +44 -51
- package/dist/runner/runner.d.ts.map +1 -1
- package/dist/runner/runner.js +155 -851
- package/dist/runner/runner.js.map +1 -1
- package/dist/runner/scout-feedback.d.ts +51 -0
- package/dist/runner/scout-feedback.d.ts.map +1 -0
- package/dist/runner/scout-feedback.js +149 -0
- package/dist/runner/scout-feedback.js.map +1 -0
- package/dist/skills/macro-loader.d.ts +1 -1
- package/dist/test-runner.d.ts.map +1 -1
- package/dist/test-runner.js +27 -1
- package/dist/test-runner.js.map +1 -1
- package/dist/types/actions.d.ts +241 -0
- package/dist/types/actions.d.ts.map +1 -0
- package/dist/types/actions.js +5 -0
- package/dist/types/actions.js.map +1 -0
- package/dist/types/config.d.ts +211 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +2 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/design-audit.d.ts +92 -0
- package/dist/types/design-audit.d.ts.map +1 -0
- package/dist/types/design-audit.js +5 -0
- package/dist/types/design-audit.js.map +1 -0
- package/dist/types/design-tokens.d.ts +138 -0
- package/dist/types/design-tokens.d.ts.map +1 -0
- package/dist/types/design-tokens.js +5 -0
- package/dist/types/design-tokens.js.map +1 -0
- package/dist/types/page.d.ts +16 -0
- package/dist/types/page.d.ts.map +1 -0
- package/dist/types/page.js +2 -0
- package/dist/types/page.js.map +1 -0
- package/dist/types/plan.d.ts +50 -0
- package/dist/types/plan.d.ts.map +1 -0
- package/dist/types/plan.js +2 -0
- package/dist/types/plan.js.map +1 -0
- package/dist/types/preview.d.ts +9 -0
- package/dist/types/preview.d.ts.map +1 -0
- package/dist/types/preview.js +5 -0
- package/dist/types/preview.js.map +1 -0
- package/dist/types/result.d.ts +62 -0
- package/dist/types/result.d.ts.map +1 -0
- package/dist/types/result.js +2 -0
- package/dist/types/result.js.map +1 -0
- package/dist/types/scenario.d.ts +20 -0
- package/dist/types/scenario.d.ts.map +1 -0
- package/dist/types/scenario.js +5 -0
- package/dist/types/scenario.js.map +1 -0
- package/dist/types/test-runner.d.ts +145 -0
- package/dist/types/test-runner.d.ts.map +1 -0
- package/dist/types/test-runner.js +10 -0
- package/dist/types/test-runner.js.map +1 -0
- package/dist/types/trajectory.d.ts +38 -0
- package/dist/types/trajectory.d.ts.map +1 -0
- package/dist/types/trajectory.js +2 -0
- package/dist/types/trajectory.js.map +1 -0
- package/dist/types/turn.d.ts +50 -0
- package/dist/types/turn.d.ts.map +1 -0
- package/dist/types/turn.js +2 -0
- package/dist/types/turn.js.map +1 -0
- package/dist/types.d.ts +16 -1017
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +15 -8
- package/dist/types.js.map +1 -1
- package/dist/wallet/rpc-interception.d.ts +15 -0
- package/dist/wallet/rpc-interception.d.ts.map +1 -0
- package/dist/wallet/rpc-interception.js +95 -0
- package/dist/wallet/rpc-interception.js.map +1 -0
- package/package.json +23 -5
|
@@ -0,0 +1,1030 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reference-Grounded Art Director — shared contracts.
|
|
3
|
+
*
|
|
4
|
+
* This is the SINGLE source of truth for every type and module-boundary
|
|
5
|
+
* interface the reference engine passes between stages. It holds ZERO runtime
|
|
6
|
+
* logic, ZERO constants, and ZERO default values — only `type`/`interface`
|
|
7
|
+
* declarations and re-exports. Keeping it logic-free is what prevents it from
|
|
8
|
+
* becoming a god module that every core imports for behaviour rather than shape.
|
|
9
|
+
*
|
|
10
|
+
* Design rules encoded here:
|
|
11
|
+
* - Every cross-stage hop is typed by a record in this file, so no module
|
|
12
|
+
* reaches into another's internals.
|
|
13
|
+
* - Every IO / LLM / browser boundary is expressed as a NARROW, single-purpose
|
|
14
|
+
* interface (DesignDnaExtractor, CorpusReader, CorpusWriter, ExemplarMatcher,
|
|
15
|
+
* EmbeddingProvider, RedesignGenerator, TasteJudge, DirectionRanker). Cores
|
|
16
|
+
* and the orchestrator depend on these interfaces, never on concrete
|
|
17
|
+
* adapters. There is deliberately NO single "God" interface — each boundary
|
|
18
|
+
* is its own contract, and read/write surfaces are split (CorpusReader vs
|
|
19
|
+
* CorpusWriter) so the runtime audit path can never reach authoring mutators.
|
|
20
|
+
* - The engine emits the EXISTING audit contracts (DesignFinding,
|
|
21
|
+
* PageAuditResult, …) verbatim by re-exporting them, never redefining them,
|
|
22
|
+
* so the closed enums stay authoritative and stages 7-9 of the v1 pipeline
|
|
23
|
+
* keep working unchanged.
|
|
24
|
+
*
|
|
25
|
+
* Units are noted inline (px, ms, 0-1 ratios) so downstream math is unambiguous.
|
|
26
|
+
*/
|
|
27
|
+
import type { DesignTokens, DesignFinding, DesignSystemScore } from '../../../types.js';
|
|
28
|
+
import type { PageClassification, PageType, MeasurementBundle } from '../types.js';
|
|
29
|
+
import type { Dimension, DimensionScore } from '../score-types.js';
|
|
30
|
+
import type { SupportedProvider } from '../../../provider-defaults.js';
|
|
31
|
+
export type { DesignTokens, ColorToken, ViewportTokens, TypeScaleEntry, FontFamily, DesignFinding, DesignSystemScore, } from '../../../types.js';
|
|
32
|
+
export type { PageClassification, PageType, MeasurementBundle, PageAuditResult, } from '../types.js';
|
|
33
|
+
export type { Dimension, DimensionScore } from '../score-types.js';
|
|
34
|
+
/**
|
|
35
|
+
* Visual density of a layout, derived from whitespace ratio + component counts.
|
|
36
|
+
* Shared by SpacingRhythm and LayoutGrammar so density is computed once.
|
|
37
|
+
*/
|
|
38
|
+
export type Density = 'sparse' | 'balanced' | 'dense';
|
|
39
|
+
/**
|
|
40
|
+
* One semantic step in a page's type scale.
|
|
41
|
+
*/
|
|
42
|
+
export interface TypeStepDNA {
|
|
43
|
+
/** Rendered font size in CSS px. */
|
|
44
|
+
fontSizePx: number;
|
|
45
|
+
/** Numeric font weight (100-900). */
|
|
46
|
+
weight: number;
|
|
47
|
+
/** Unitless line-height (e.g. 1.5), or the px line-height ÷ fontSizePx. */
|
|
48
|
+
lineHeight: number;
|
|
49
|
+
/** Font family this step renders in. */
|
|
50
|
+
family: string;
|
|
51
|
+
/** Semantic role inferred from size/usage. */
|
|
52
|
+
role: 'display' | 'heading' | 'body' | 'caption' | 'label';
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* A font family and the role(s) it plays in the design.
|
|
56
|
+
*/
|
|
57
|
+
export interface FontRoleDNA {
|
|
58
|
+
family: string;
|
|
59
|
+
/** Coarse role classification carried through from DesignTokens.typography. */
|
|
60
|
+
role: 'heading' | 'body' | 'mono' | 'display';
|
|
61
|
+
/** Numeric weights observed for this family. */
|
|
62
|
+
weights: number[];
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* The normalised type system: an ordered scale plus the modular ratio between
|
|
66
|
+
* adjacent steps (if one is detectable).
|
|
67
|
+
*/
|
|
68
|
+
export interface TypeScaleDNA {
|
|
69
|
+
/** Steps sorted ascending by fontSizePx. */
|
|
70
|
+
steps: TypeStepDNA[];
|
|
71
|
+
/** Geometric ratio between adjacent steps (e.g. 1.25), or undefined if irregular. */
|
|
72
|
+
ratio?: number;
|
|
73
|
+
/** Families and their roles. */
|
|
74
|
+
families: FontRoleDNA[];
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Semantic color role. Mirrors ColorToken.cluster so role mapping is a 1:1
|
|
78
|
+
* carry-through from the already-clustered tokens, never a re-clustering.
|
|
79
|
+
*/
|
|
80
|
+
export type ColorRole = 'primary' | 'secondary' | 'accent' | 'neutral' | 'background' | 'border';
|
|
81
|
+
/**
|
|
82
|
+
* The normalised color system: hex values grouped by semantic role.
|
|
83
|
+
*/
|
|
84
|
+
export interface ColorSystemDNA {
|
|
85
|
+
/** Hex strings per role; a role may carry several shades. */
|
|
86
|
+
roles: Record<ColorRole, string[]>;
|
|
87
|
+
/**
|
|
88
|
+
* Minimum AA contrast ratio observed on body text, when measurements are
|
|
89
|
+
* available. Lets the judge reason about legibility without re-measuring.
|
|
90
|
+
*/
|
|
91
|
+
contrastFloor?: number;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* The spacing rhythm: a base grid unit and the discrete spacing scale.
|
|
95
|
+
*/
|
|
96
|
+
export interface SpacingRhythm {
|
|
97
|
+
/** Detected base grid unit in px (4/5/6/8/10), or undefined if no clear grid. */
|
|
98
|
+
baseUnit?: number;
|
|
99
|
+
/** Distinct spacing values in px, sorted ascending. */
|
|
100
|
+
steps: number[];
|
|
101
|
+
/** Visual density of spacing. */
|
|
102
|
+
density: Density;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* The corner-radius scale, in px, sorted ascending.
|
|
106
|
+
*/
|
|
107
|
+
export interface RadiiScale {
|
|
108
|
+
steps: number[];
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* One bucket of scroll-triggered reveals: how many distinct elements animated
|
|
112
|
+
* IN on scroll, and the kinds of reveal observed. Shared by the raw live-page
|
|
113
|
+
* capture and the normalised DNA so the two stay in lock-step.
|
|
114
|
+
*/
|
|
115
|
+
export interface ScrollRevealSummary {
|
|
116
|
+
/** Number of elements observed animating IN as they entered the viewport. */
|
|
117
|
+
count: number;
|
|
118
|
+
/**
|
|
119
|
+
* Free-form labels for the kinds of reveal observed (e.g. 'fade', 'slide-up',
|
|
120
|
+
* 'scale-in', 'mask'). Not a closed enum — novel reveal styles get a novel
|
|
121
|
+
* label rather than a forced bucket. Empty when reveals were counted but not
|
|
122
|
+
* classified.
|
|
123
|
+
*/
|
|
124
|
+
kinds: string[];
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Scroll-driven motion OBSERVED by replaying a top→bottom stepped scroll on the
|
|
128
|
+
* LIVE page (the opt-in `captureScrollMotion` pass). It answers "what actually
|
|
129
|
+
* animates on scroll" — which a static token rip cannot: a static rip can tell a
|
|
130
|
+
* page loads GSAP/Lenis, but not WHAT those libraries drive as you scroll.
|
|
131
|
+
*
|
|
132
|
+
* HONEST SIGNAL. Every field here is a measurement, not a guess. The whole
|
|
133
|
+
* record is OPTIONAL on {@link MotionDNA} and is present ONLY when the scroll
|
|
134
|
+
* pass actually ran AND observed motion. Absent (`undefined`) means "NOT
|
|
135
|
+
* captured", never "no scroll motion" — do not read a missing record as a
|
|
136
|
+
* static page. A captured-but-quiet page is reported as `scrollDriven: false`,
|
|
137
|
+
* which is distinct from the record being absent.
|
|
138
|
+
*/
|
|
139
|
+
export interface ScrollMotionDNA {
|
|
140
|
+
/**
|
|
141
|
+
* Long-scroll storytelling signal: `document.scrollHeight / viewportHeight`,
|
|
142
|
+
* a unitless ratio. ~1 = a single viewport; e.g. 4.2 means the page is 4.2
|
|
143
|
+
* viewports tall. Higher ratios read as long-form scroll narratives.
|
|
144
|
+
*/
|
|
145
|
+
pageHeightRatio: number;
|
|
146
|
+
/** Elements that animated IN on scroll, with a count and their kinds. */
|
|
147
|
+
reveals: ScrollRevealSummary;
|
|
148
|
+
/**
|
|
149
|
+
* Count of `position: sticky` / pinned elements that stayed fixed in the
|
|
150
|
+
* viewport while their section scrolled past. Integer ≥ 0.
|
|
151
|
+
*/
|
|
152
|
+
stickyCount: number;
|
|
153
|
+
/**
|
|
154
|
+
* Parallax strength as a 0–1 score. NORMALISATION (identical to
|
|
155
|
+
* {@link RawScrollCapture.parallax}, carried through unchanged by the fold):
|
|
156
|
+
* for each non-pinned layer let `rate = viewportTranslate / scrollDelta` (1 =
|
|
157
|
+
* rigid with content, 0 = fixed). A genuine parallax layer sits in the slow
|
|
158
|
+
* band `0.15 < rate < 0.85` or moves faster than content `rate > 1.15`; its
|
|
159
|
+
* score is `clamp01(|rate − 1|)` (reverse/over-fast layers clamp to 1). The
|
|
160
|
+
* field is the MAX such score over all layers. `0` = no parallax observed
|
|
161
|
+
* (doubles as the boolean "no parallax"); higher = stronger layered depth.
|
|
162
|
+
*/
|
|
163
|
+
parallax: number;
|
|
164
|
+
/**
|
|
165
|
+
* Rollup verdict: does the page read as a motion-rich scroll experience?
|
|
166
|
+
* Derived (in the PURE fold, never here) from the reveals / sticky / parallax
|
|
167
|
+
* / ratio evidence above. `false` is a real observation ("scrolled, saw
|
|
168
|
+
* little motion"), distinct from the whole record being absent.
|
|
169
|
+
*/
|
|
170
|
+
scrollDriven: boolean;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Motion signature: durations, easings, and any detected animation libraries —
|
|
174
|
+
* all derived from a STATIC token rip.
|
|
175
|
+
*
|
|
176
|
+
* `scroll` is the one LIVE-observed extension. It is OPTIONAL and present ONLY
|
|
177
|
+
* when the opt-in `captureScrollMotion` extraction pass ran on the live page AND
|
|
178
|
+
* saw motion (default OFF, so existing rips/exemplars/tests with no scroll data
|
|
179
|
+
* stay valid). When absent, nothing was captured — never read its absence as
|
|
180
|
+
* "no scroll motion".
|
|
181
|
+
*/
|
|
182
|
+
export interface MotionDNA {
|
|
183
|
+
/** Transition/animation durations in ms. */
|
|
184
|
+
durationsMs: number[];
|
|
185
|
+
/** CSS easing functions / named curves observed. */
|
|
186
|
+
easings: string[];
|
|
187
|
+
/** Detected animation libraries (gsap, framer-motion, lottie, …). */
|
|
188
|
+
libraries: string[];
|
|
189
|
+
/**
|
|
190
|
+
* Scroll-driven motion observed on the live page. Present only when the
|
|
191
|
+
* opt-in `captureScrollMotion` pass ran AND observed motion; otherwise
|
|
192
|
+
* `undefined` (not captured). See {@link ScrollMotionDNA}.
|
|
193
|
+
*/
|
|
194
|
+
scroll?: ScrollMotionDNA;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Layout grammar: the macro structure of the page.
|
|
198
|
+
*/
|
|
199
|
+
export interface LayoutGrammar {
|
|
200
|
+
/** Dominant column count of the primary content grid, if detectable. */
|
|
201
|
+
columns?: number;
|
|
202
|
+
/** Base grid unit in px (carried from ViewportTokens.gridBaseUnit). */
|
|
203
|
+
gridBaseUnit?: number;
|
|
204
|
+
/** Fraction of viewport that is whitespace, 0-1. */
|
|
205
|
+
whitespaceRatio?: number;
|
|
206
|
+
/** Visual density of the layout. */
|
|
207
|
+
density: Density;
|
|
208
|
+
/**
|
|
209
|
+
* Free-form structural archetype label (e.g. "hero+feature-grid",
|
|
210
|
+
* "split-screen", "data-table-shell"). A hint for retrieval/generation, not a
|
|
211
|
+
* closed enum — novel layouts get a novel label rather than a forced bucket.
|
|
212
|
+
*/
|
|
213
|
+
archetype: string;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Component pattern counts — how many distinct button/input/card/nav patterns
|
|
217
|
+
* the page uses. High counts signal an inconsistent system.
|
|
218
|
+
*/
|
|
219
|
+
export interface ComponentPatternDNA {
|
|
220
|
+
buttons: number;
|
|
221
|
+
inputs: number;
|
|
222
|
+
cards: number;
|
|
223
|
+
nav: number;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* The full structured identity of one page or exemplar. Produced purely from a
|
|
227
|
+
* DesignTokens record (+ optional MeasurementBundle) — no browser, no LLM.
|
|
228
|
+
*/
|
|
229
|
+
export interface DesignDNA {
|
|
230
|
+
url: string;
|
|
231
|
+
/** ISO timestamp of capture. */
|
|
232
|
+
capturedAt: string;
|
|
233
|
+
type: TypeScaleDNA;
|
|
234
|
+
color: ColorSystemDNA;
|
|
235
|
+
spacing: SpacingRhythm;
|
|
236
|
+
radii: RadiiScale;
|
|
237
|
+
motion: MotionDNA;
|
|
238
|
+
layout: LayoutGrammar;
|
|
239
|
+
components: ComponentPatternDNA;
|
|
240
|
+
/**
|
|
241
|
+
* Deterministic measurement signals folded in when available. Absent =
|
|
242
|
+
* "no signal" (never treat as "passed").
|
|
243
|
+
*/
|
|
244
|
+
signals?: {
|
|
245
|
+
/** AA contrast pass rate, 0-1. */
|
|
246
|
+
contrastAaPassRate?: number;
|
|
247
|
+
/** Count of critical/serious a11y violations. */
|
|
248
|
+
a11yBlockingCount?: number;
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Structural delta between two DNAs (audited page vs winner, or page vs
|
|
253
|
+
* reference). Computed PURELY over DesignDNA fields — it does NOT diff raw
|
|
254
|
+
* DesignTokens (a different altitude). Used to ground judge feedback and to
|
|
255
|
+
* mint "gap" findings.
|
|
256
|
+
*/
|
|
257
|
+
export interface DnaDelta {
|
|
258
|
+
/** Color roles added/removed/changed between the two systems. */
|
|
259
|
+
color: {
|
|
260
|
+
added: string[];
|
|
261
|
+
removed: string[];
|
|
262
|
+
changed: string[];
|
|
263
|
+
};
|
|
264
|
+
/** Type-scale changes (steps added/removed, ratio shift). */
|
|
265
|
+
type: {
|
|
266
|
+
stepsAdded: number;
|
|
267
|
+
stepsRemoved: number;
|
|
268
|
+
ratioDelta?: number;
|
|
269
|
+
};
|
|
270
|
+
/** Spacing rhythm changes. */
|
|
271
|
+
spacing: {
|
|
272
|
+
baseUnitFrom?: number;
|
|
273
|
+
baseUnitTo?: number;
|
|
274
|
+
densityChanged: boolean;
|
|
275
|
+
};
|
|
276
|
+
/** Component pattern count deltas. */
|
|
277
|
+
components: {
|
|
278
|
+
buttons: number;
|
|
279
|
+
inputs: number;
|
|
280
|
+
cards: number;
|
|
281
|
+
nav: number;
|
|
282
|
+
};
|
|
283
|
+
/** Human-readable one-line summary of the most salient differences. */
|
|
284
|
+
summary: string;
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Options for turning a live URL (or a ripped local copy) into a DnaCapture.
|
|
288
|
+
*/
|
|
289
|
+
export interface ExtractPageDnaOptions {
|
|
290
|
+
/** Live URL or `file://` path to a ripped index.html. */
|
|
291
|
+
url: string;
|
|
292
|
+
headless?: boolean;
|
|
293
|
+
/** Where downloaded assets / screenshots land. */
|
|
294
|
+
outputDir?: string;
|
|
295
|
+
/**
|
|
296
|
+
* Deterministic measurements already gathered for this page, folded into the
|
|
297
|
+
* DNA signals. Optional so the corpus-authoring path (no audit measurements)
|
|
298
|
+
* still works.
|
|
299
|
+
*/
|
|
300
|
+
measurements?: MeasurementBundle;
|
|
301
|
+
/**
|
|
302
|
+
* Opt in to the live scroll-motion capture pass (default OFF). When set, the
|
|
303
|
+
* extractor replays a stepped top→bottom scroll on the page and folds the
|
|
304
|
+
* result into `DesignDNA.motion.scroll`. Off by default because it adds page
|
|
305
|
+
* time and is only meaningful for live audits / corpus authoring — a static
|
|
306
|
+
* rip never observes scroll motion.
|
|
307
|
+
*/
|
|
308
|
+
captureScrollMotion?: boolean;
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* The output of a page→DNA extraction: the DNA plus the raw tokens and
|
|
312
|
+
* screenshots it derived from (kept so callers that need token-altitude data —
|
|
313
|
+
* e.g. an optional rendered before/after — don't re-extract).
|
|
314
|
+
*/
|
|
315
|
+
export interface DnaCapture {
|
|
316
|
+
dna: DesignDNA;
|
|
317
|
+
tokens: DesignTokens;
|
|
318
|
+
/** Per-viewport screenshot file paths, keyed by viewport name. */
|
|
319
|
+
screenshotPaths: Record<string, string>;
|
|
320
|
+
outputDir: string;
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* IO boundary: turn a URL into a DnaCapture. The shipped adapter reuses
|
|
324
|
+
* `extractDesignTokens` then the pure `toDesignDNA`; tests inject a fake.
|
|
325
|
+
*/
|
|
326
|
+
export interface DesignDnaExtractor {
|
|
327
|
+
extract(opts: ExtractPageDnaOptions): Promise<DnaCapture>;
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* The minimal live-page surface the scroll-capture pass drives: the ability to
|
|
331
|
+
* run an async function in page context (where it can `scrollTo`, await
|
|
332
|
+
* `requestAnimationFrame`, and read `getBoundingClientRect` /
|
|
333
|
+
* `getComputedStyle` across scroll steps). Modelled structurally — a Playwright
|
|
334
|
+
* `Page` satisfies it — so these pure contracts stay browser-free and the seam
|
|
335
|
+
* is fakeable in unit tests.
|
|
336
|
+
*/
|
|
337
|
+
export interface ScrollCapturePage {
|
|
338
|
+
evaluate<R>(pageFunction: () => R | Promise<R>): Promise<R>;
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Tunables for one scroll-capture pass. All optional; the implementation picks
|
|
342
|
+
* honest defaults. These affect capture FIDELITY only, never WHETHER the pass
|
|
343
|
+
* runs — that is the separate, opt-in `captureScrollMotion` extraction flag.
|
|
344
|
+
*/
|
|
345
|
+
export interface ScrollCaptureOptions {
|
|
346
|
+
/** Number of discrete top→bottom scroll stops to sample. */
|
|
347
|
+
steps?: number;
|
|
348
|
+
/** Milliseconds to let motion settle after each scroll stop before sampling. */
|
|
349
|
+
settleMs?: number;
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* The RAW signal a single live-page scroll pass returns, BEFORE the pure fold
|
|
353
|
+
* normalises it into {@link ScrollMotionDNA}. It reports only directly-measured
|
|
354
|
+
* quantities (heights in CSS px, observed counts/scores) and leaves the derived
|
|
355
|
+
* `pageHeightRatio` and the `scrollDriven` rollup to `deriveMotion`, keeping the
|
|
356
|
+
* browser layer free of judgement.
|
|
357
|
+
*
|
|
358
|
+
* The capturer returns `undefined` (not a zeroed record) when the pass could not
|
|
359
|
+
* observe anything — e.g. a non-scrolling page — so absence stays honest.
|
|
360
|
+
*/
|
|
361
|
+
export interface RawScrollCapture {
|
|
362
|
+
/** Full document scroll height in CSS px (`document.scrollingElement.scrollHeight`). */
|
|
363
|
+
scrollHeightPx: number;
|
|
364
|
+
/** Viewport height in CSS px at capture time (`window.innerHeight`). */
|
|
365
|
+
viewportHeightPx: number;
|
|
366
|
+
/** Number of top→bottom scroll stops actually sampled. */
|
|
367
|
+
steps: number;
|
|
368
|
+
/** Elements observed animating IN as they entered the viewport. */
|
|
369
|
+
reveals: ScrollRevealSummary;
|
|
370
|
+
/** Count of `position: sticky` / pinned elements that stayed fixed while their section scrolled. */
|
|
371
|
+
stickyCount: number;
|
|
372
|
+
/**
|
|
373
|
+
* Parallax strength as a 0–1 score. For each non-pinned layer let
|
|
374
|
+
* `rate = viewportTranslate / scrollDelta` (1 = rigid with content, 0 =
|
|
375
|
+
* fixed). A parallax layer sits in the slow band `0.15 < rate < 0.85` or moves
|
|
376
|
+
* faster than content `rate > 1.15`; its score is `clamp01(|rate − 1|)`. This
|
|
377
|
+
* field is the MAX such score over all layers (`0` = none observed). Carried
|
|
378
|
+
* into `ScrollMotionDNA.parallax` by the fold unchanged.
|
|
379
|
+
*/
|
|
380
|
+
parallax: number;
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* The narrow capture seam: given an already-open, settled live page, run the
|
|
384
|
+
* stepped top→bottom scroll pass and return a {@link RawScrollCapture}, or
|
|
385
|
+
* `undefined` when nothing was observed. The shipped implementation lives in the
|
|
386
|
+
* browser layer (`design/audit/tokens/extract.ts`); tests inject a fake. Pure consumers
|
|
387
|
+
* (`toDesignDNA` / `deriveMotion`) never touch this — they receive the already
|
|
388
|
+
* folded result, so the DNA core stays browser-free and deterministic.
|
|
389
|
+
*/
|
|
390
|
+
export interface ScrollCapturer {
|
|
391
|
+
capture(page: ScrollCapturePage, opts?: ScrollCaptureOptions): Promise<RawScrollCapture | undefined>;
|
|
392
|
+
}
|
|
393
|
+
/** A fixed-length numeric embedding of a DNA's aesthetic descriptor. */
|
|
394
|
+
export type AestheticVector = number[];
|
|
395
|
+
/** Where an exemplar came from. Open string so new sources need no code change. */
|
|
396
|
+
export type ExemplarSource = 'variant' | 'mobbin' | 'awwwards' | 'rip' | 'manual' | (string & {});
|
|
397
|
+
/**
|
|
398
|
+
* One world-class reference page in the corpus. The corpus is the data-driven
|
|
399
|
+
* replacement for the scattered if/else domain tables: adding coverage is a new
|
|
400
|
+
* Exemplar row, not a new code branch.
|
|
401
|
+
*/
|
|
402
|
+
export interface Exemplar {
|
|
403
|
+
/** Stable id (slug of source+url). */
|
|
404
|
+
id: string;
|
|
405
|
+
source: ExemplarSource;
|
|
406
|
+
url: string;
|
|
407
|
+
/** Page archetype — the hard retrieval filter. */
|
|
408
|
+
pageType: PageType;
|
|
409
|
+
/** Job-to-be-done this page serves (e.g. "convert a visitor to signup"). */
|
|
410
|
+
jobToBeDone: string;
|
|
411
|
+
dna: DesignDNA;
|
|
412
|
+
/** On-disk screenshot path (per the rip.ts manifest layout). */
|
|
413
|
+
screenshotPath: string;
|
|
414
|
+
/** Precomputed aesthetic embedding for retrieval. */
|
|
415
|
+
aestheticVector: AestheticVector;
|
|
416
|
+
/**
|
|
417
|
+
* Elo/Bradley-Terry taste rating, seeded at corpus-build time and updated by
|
|
418
|
+
* pairwise human/judge votes. Used as a retrieval tie-break and a taste prior.
|
|
419
|
+
*/
|
|
420
|
+
eloRating: number;
|
|
421
|
+
}
|
|
422
|
+
/**
|
|
423
|
+
* A retrieval query. The aesthetic embedding is computed ONCE by the
|
|
424
|
+
* orchestrator and passed in here — the matcher is pure and never recomputes an
|
|
425
|
+
* embedding, eliminating the "two sources of the same vector" drift.
|
|
426
|
+
*/
|
|
427
|
+
export interface CorpusQuery {
|
|
428
|
+
/** Hard filter: only same-type exemplars are candidates. */
|
|
429
|
+
pageType: PageType;
|
|
430
|
+
/** Soft signal: token-overlap against Exemplar.jobToBeDone (low default weight). */
|
|
431
|
+
jobToBeDone: string;
|
|
432
|
+
/** Authoritative aesthetic embedding of the page-under-audit's DNA. */
|
|
433
|
+
aestheticVector: AestheticVector;
|
|
434
|
+
/** Optional deterministic structural feature vector for a secondary signal. */
|
|
435
|
+
structuralVector?: number[];
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Relative blend weights for the matcher's score. Aesthetic + pageType dominate;
|
|
439
|
+
* the free-form job signal is intentionally low because classification.intent is
|
|
440
|
+
* noisy and is fabricated on `--profile` runs.
|
|
441
|
+
*/
|
|
442
|
+
export interface RetrieveWeights {
|
|
443
|
+
aesthetic: number;
|
|
444
|
+
structural: number;
|
|
445
|
+
job: number;
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* One ranked retrieval hit.
|
|
449
|
+
*/
|
|
450
|
+
export interface RetrievalResult {
|
|
451
|
+
exemplar: Exemplar;
|
|
452
|
+
/** Blended similarity score, 0-1 (higher = closer). */
|
|
453
|
+
score: number;
|
|
454
|
+
/** Human-readable reasons the exemplar matched (for the artifact/provenance). */
|
|
455
|
+
reasons: string[];
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* Pure k-nearest retrieval boundary. THE de-hardcoding core: a novel page type
|
|
459
|
+
* still resolves to its nearest aesthetic/job neighbour instead of falling
|
|
460
|
+
* through an if/else table. Implemented by a pure function — no IO, no LLM.
|
|
461
|
+
*/
|
|
462
|
+
export interface ExemplarMatcher {
|
|
463
|
+
retrieve(query: CorpusQuery, corpus: Exemplar[], weights?: RetrieveWeights): RetrievalResult[];
|
|
464
|
+
}
|
|
465
|
+
/**
|
|
466
|
+
* READ side of the corpus disk boundary. This is ALL the runtime audit path
|
|
467
|
+
* (engine/core, retrieval/matcher) ever needs — load the corpus once, resolve a
|
|
468
|
+
* screenshot path, look one row up. Fails closed (missing dir → empty corpus /
|
|
469
|
+
* null get), never fabricates an exemplar. The core depends on this narrow read
|
|
470
|
+
* interface so it cannot reach the authoring mutators it never invokes.
|
|
471
|
+
*/
|
|
472
|
+
export interface CorpusReader {
|
|
473
|
+
/** Load all exemplars from the manifest. */
|
|
474
|
+
load(): Promise<Exemplar[]>;
|
|
475
|
+
/** Look up one exemplar by id, or null if absent. */
|
|
476
|
+
get(id: string): Promise<Exemplar | null>;
|
|
477
|
+
/** Resolve an exemplar's screenshot to an absolute path. */
|
|
478
|
+
resolveScreenshot(exemplar: Exemplar): string;
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* WRITE side of the corpus disk boundary. Used ONLY by the offline authoring
|
|
482
|
+
* path (corpus/build) — never by the audit hot path. Kept separate from
|
|
483
|
+
* CorpusReader so a runtime module that holds a reader cannot mutate the corpus.
|
|
484
|
+
*/
|
|
485
|
+
export interface CorpusWriter {
|
|
486
|
+
/** Insert or replace an exemplar (corpus authoring). */
|
|
487
|
+
upsert(exemplar: Exemplar): Promise<void>;
|
|
488
|
+
/** Persist a screenshot for an exemplar; returns its on-disk path. */
|
|
489
|
+
saveScreenshot(id: string, png: Buffer): Promise<string>;
|
|
490
|
+
}
|
|
491
|
+
/**
|
|
492
|
+
* The full disk boundary for the exemplar corpus (JSONL records + sidecar
|
|
493
|
+
* screenshots). The ONLY module that touches the corpus directory. Concrete
|
|
494
|
+
* `createFileCorpusStore` implements both halves; corpus/build consumes the full
|
|
495
|
+
* surface, while engine/core/matcher accept only `CorpusReader`.
|
|
496
|
+
*/
|
|
497
|
+
export interface CorpusStore extends CorpusReader, CorpusWriter {
|
|
498
|
+
}
|
|
499
|
+
/**
|
|
500
|
+
* The aesthetic-embedding boundary. The deterministic hash implementation is the
|
|
501
|
+
* offline/test default (so retrieval works with zero provider and unit tests
|
|
502
|
+
* never hit the network); a real provider is swapped in when an API key exists.
|
|
503
|
+
*/
|
|
504
|
+
export interface EmbeddingProvider {
|
|
505
|
+
/** Stable id of the backing model ('hash-v1', 'openai:text-embedding-3-small', …). */
|
|
506
|
+
readonly id: string;
|
|
507
|
+
/** Embed N descriptor strings → N fixed-length vectors. */
|
|
508
|
+
embed(texts: string[]): Promise<AestheticVector[]>;
|
|
509
|
+
}
|
|
510
|
+
/** How an operator-supplied `--reference` was interpreted. */
|
|
511
|
+
export type ReferenceKind = 'url' | 'rip' | 'tokens' | 'exemplar';
|
|
512
|
+
/**
|
|
513
|
+
* A reference resolved ONCE before the page/rep loops and reused for every page
|
|
514
|
+
* and repetition, so reference-grounded runs stay within the ±0.5 reproducibility
|
|
515
|
+
* gate. When set, this single target stands in for (or augments) corpus
|
|
516
|
+
* retrieval.
|
|
517
|
+
*/
|
|
518
|
+
export interface ReferenceContext {
|
|
519
|
+
kind: ReferenceKind;
|
|
520
|
+
dna: DesignDNA;
|
|
521
|
+
/** Optional screenshot for a future vision judge. */
|
|
522
|
+
screenshotPath?: string;
|
|
523
|
+
/** Budget-bounded prompt-ready summary of the reference DNA. */
|
|
524
|
+
summary: string;
|
|
525
|
+
}
|
|
526
|
+
/**
|
|
527
|
+
* Everything the generator needs about the page-under-audit (not the exemplars,
|
|
528
|
+
* which are passed alongside as RetrievalResult[]).
|
|
529
|
+
*/
|
|
530
|
+
export interface GenerationContext {
|
|
531
|
+
url: string;
|
|
532
|
+
classification: PageClassification;
|
|
533
|
+
dna: DesignDNA;
|
|
534
|
+
measurements?: MeasurementBundle;
|
|
535
|
+
/** Optional composed-rubric body injected as scoring criteria. */
|
|
536
|
+
rubricBody?: string;
|
|
537
|
+
}
|
|
538
|
+
/** A proposed type system for a redesign direction. */
|
|
539
|
+
export interface TypeSystemSpec {
|
|
540
|
+
families: string[];
|
|
541
|
+
/** Target scale in px. */
|
|
542
|
+
scalePx: number[];
|
|
543
|
+
/** Target modular ratio. */
|
|
544
|
+
ratio: number;
|
|
545
|
+
rationale: string;
|
|
546
|
+
}
|
|
547
|
+
/** A proposed color system for a redesign direction. */
|
|
548
|
+
export interface ColorSystemSpec {
|
|
549
|
+
primary: string;
|
|
550
|
+
accent?: string;
|
|
551
|
+
neutrals: string[];
|
|
552
|
+
background: string;
|
|
553
|
+
rationale: string;
|
|
554
|
+
}
|
|
555
|
+
/** A proposed motion spec for a redesign direction. */
|
|
556
|
+
export interface MotionSpec {
|
|
557
|
+
durationsMs: number[];
|
|
558
|
+
easings: string[];
|
|
559
|
+
/** Where motion is applied and why (e.g. "stagger hero cards on enter"). */
|
|
560
|
+
cues: string[];
|
|
561
|
+
}
|
|
562
|
+
/** A single revised copy element. */
|
|
563
|
+
export interface CopyRevision {
|
|
564
|
+
/** CSS selector or semantic location of the copy. */
|
|
565
|
+
location: string;
|
|
566
|
+
before?: string;
|
|
567
|
+
after: string;
|
|
568
|
+
}
|
|
569
|
+
/**
|
|
570
|
+
* A NAMED redesign direction — the core generative artifact. Grounded in
|
|
571
|
+
* concrete world-class exemplars by id so the judge can give reference-specific
|
|
572
|
+
* feedback and the loop compresses to 1-2 shots.
|
|
573
|
+
*/
|
|
574
|
+
export interface RedesignDirection {
|
|
575
|
+
id: string;
|
|
576
|
+
/** Evocative name (e.g. "Editorial Calm", "Dense Control Room"). */
|
|
577
|
+
name: string;
|
|
578
|
+
/** Why this direction fits the page's job-to-be-done. */
|
|
579
|
+
rationale: string;
|
|
580
|
+
/** ASCII / box-drawing layout diagram of the proposed structure. */
|
|
581
|
+
asciiLayout: string;
|
|
582
|
+
typeSystem: TypeSystemSpec;
|
|
583
|
+
colorSystem: ColorSystemSpec;
|
|
584
|
+
motionSpec: MotionSpec;
|
|
585
|
+
/** Ordered information hierarchy, most prominent first. */
|
|
586
|
+
hierarchy: string[];
|
|
587
|
+
/** Revised copy for key surfaces. */
|
|
588
|
+
copy: CopyRevision[];
|
|
589
|
+
/** Exemplar ids this direction is grounded in (⊆ retrieved ids). */
|
|
590
|
+
groundedInExemplarIds: string[];
|
|
591
|
+
}
|
|
592
|
+
/** A typed parse failure — never a fabricated direction. */
|
|
593
|
+
export interface DirectionParseError {
|
|
594
|
+
ok: false;
|
|
595
|
+
reason: string;
|
|
596
|
+
}
|
|
597
|
+
/** Result of parsing one model response into a direction. */
|
|
598
|
+
export type DirectionParseResult = {
|
|
599
|
+
ok: true;
|
|
600
|
+
direction: RedesignDirection;
|
|
601
|
+
} | DirectionParseError;
|
|
602
|
+
/**
|
|
603
|
+
* The output of one generation pass: the accepted directions plus the TOTAL
|
|
604
|
+
* generation tokens consumed across every model call the pass made — INCLUDING
|
|
605
|
+
* calls whose response failed to parse, which still cost tokens. Surfacing the
|
|
606
|
+
* sum here is what lets the engine report a COMPLETE `tokensUsed` (generation +
|
|
607
|
+
* judging) instead of a judge-only undercount.
|
|
608
|
+
*/
|
|
609
|
+
export interface GenerationResult {
|
|
610
|
+
/** Accepted directions in stable slot order (a dropped call leaves no entry). */
|
|
611
|
+
directions: RedesignDirection[];
|
|
612
|
+
/** Sum of `tokensUsed` over every generation model call this pass made. */
|
|
613
|
+
tokensUsed: number;
|
|
614
|
+
}
|
|
615
|
+
/**
|
|
616
|
+
* LLM boundary: turn page context + retrieved exemplars into 2-3 grounded
|
|
617
|
+
* directions. The shipped adapter fans out one cheap `brain.complete` call per
|
|
618
|
+
* exemplar concurrently; tests inject a fake returning canned JSON. Returns the
|
|
619
|
+
* directions alongside the summed generation tokens (see {@link GenerationResult})
|
|
620
|
+
* so the engine's cost accounting covers generation, not only judging.
|
|
621
|
+
*/
|
|
622
|
+
export interface RedesignGenerator {
|
|
623
|
+
generate(ctx: GenerationContext, exemplars: RetrievalResult[], opts?: {
|
|
624
|
+
count?: number;
|
|
625
|
+
onDirection?: (d: RedesignDirection) => void;
|
|
626
|
+
}): Promise<GenerationResult>;
|
|
627
|
+
}
|
|
628
|
+
/**
|
|
629
|
+
* One side of a comparison. Carries the summaries the judge reasons over and an
|
|
630
|
+
* optional screenshot path.
|
|
631
|
+
*
|
|
632
|
+
* `screenshotPath` is the image source for the vision judge: page subjects and
|
|
633
|
+
* corpus exemplars carry an on-disk screenshot, so a vision `TasteJudge` compares
|
|
634
|
+
* them visually. Unrendered `RedesignDirection` specs have no screenshot and omit
|
|
635
|
+
* it, which is why direction ranking stays text-only. The default text judge
|
|
636
|
+
* ignores this field on every subject, so its presence never changes text
|
|
637
|
+
* scoring — adding/threading it is byte-neutral for `judge: 'text'`.
|
|
638
|
+
*/
|
|
639
|
+
export interface JudgeSubject {
|
|
640
|
+
id: string;
|
|
641
|
+
/** Budget-bounded DNA summary. */
|
|
642
|
+
dnaSummary: string;
|
|
643
|
+
/** Direction summary, when comparing generated directions. */
|
|
644
|
+
directionSummary?: string;
|
|
645
|
+
/**
|
|
646
|
+
* Adapter-readable path to this subject's screenshot (absolute, or resolved by
|
|
647
|
+
* the wiring root). Present for pages/exemplars; absent for unrendered
|
|
648
|
+
* directions. Read only by a vision judge; the text judge never touches it.
|
|
649
|
+
*/
|
|
650
|
+
screenshotPath?: string;
|
|
651
|
+
}
|
|
652
|
+
/**
|
|
653
|
+
* Input to a single judge comparison in a single slot order. The pure debias
|
|
654
|
+
* core calls the judge twice (A/B then B/A) and reconciles.
|
|
655
|
+
*/
|
|
656
|
+
export interface JudgePairInput {
|
|
657
|
+
a: JudgeSubject;
|
|
658
|
+
b: JudgeSubject;
|
|
659
|
+
/** The named reference both sides are judged against. */
|
|
660
|
+
reference?: ReferenceContext;
|
|
661
|
+
rubricBody?: string;
|
|
662
|
+
/**
|
|
663
|
+
* Scopes this comparison to ONE product-quality dimension. Set only by the
|
|
664
|
+
* absolute quality leg, which issues one dimension-scoped comparison per
|
|
665
|
+
* `Dimension` so `QualityAssessment.dimensionWinRates` is judged per-dimension
|
|
666
|
+
* (never one overall number stamped across dims). Absent ⇒ holistic comparison
|
|
667
|
+
* (the relative direction-ranking leg). The judge prompt narrows its rubric to
|
|
668
|
+
* this dimension when present.
|
|
669
|
+
*/
|
|
670
|
+
dimension?: Dimension;
|
|
671
|
+
}
|
|
672
|
+
/**
|
|
673
|
+
* The raw, slot-relative verdict from ONE judge call (before debiasing). `A`/`B`
|
|
674
|
+
* refer to presentation slots, not stable ids — reconciliation maps them back.
|
|
675
|
+
*/
|
|
676
|
+
export interface RawVerdict {
|
|
677
|
+
winnerSlot: 'A' | 'B' | 'tie';
|
|
678
|
+
/** Judge confidence 0-1. */
|
|
679
|
+
confidence: number;
|
|
680
|
+
/** Reference-specific reasons. */
|
|
681
|
+
reasons: string[];
|
|
682
|
+
/**
|
|
683
|
+
* Echoes `JudgePairInput.dimension` when the comparison was dimension-scoped,
|
|
684
|
+
* so the quality leg can bucket each verdict into the right per-dimension
|
|
685
|
+
* win-rate. Absent on holistic (direction-ranking) comparisons.
|
|
686
|
+
*/
|
|
687
|
+
dimension?: Dimension;
|
|
688
|
+
tokensUsed?: number;
|
|
689
|
+
}
|
|
690
|
+
/**
|
|
691
|
+
* A position-debiased pairwise verdict keyed by stable direction ids. Produced
|
|
692
|
+
* by reconciling the two slot orders; disagreement collapses to a tie so the
|
|
693
|
+
* verdict measures taste, not slot bias.
|
|
694
|
+
*/
|
|
695
|
+
export interface TasteVerdict {
|
|
696
|
+
aId: string;
|
|
697
|
+
bId: string;
|
|
698
|
+
/** Stable winner id, or 'tie'. */
|
|
699
|
+
winner: string | 'tie';
|
|
700
|
+
/** Strength of preference 0-1 (averaged across the two orders). */
|
|
701
|
+
margin: number;
|
|
702
|
+
reasons: string[];
|
|
703
|
+
}
|
|
704
|
+
/**
|
|
705
|
+
* The Bradley-Terry / Elo rollup of many pairwise verdicts into a single ranking.
|
|
706
|
+
*/
|
|
707
|
+
export interface RankResult {
|
|
708
|
+
/** Direction ids best→worst. */
|
|
709
|
+
order: string[];
|
|
710
|
+
/** The winning direction id. */
|
|
711
|
+
winnerId: string;
|
|
712
|
+
/** Bradley-Terry strengths per id (sum-normalised). */
|
|
713
|
+
bradleyTerry: Record<string, number>;
|
|
714
|
+
/** Elo ratings per id. */
|
|
715
|
+
elo: Record<string, number>;
|
|
716
|
+
}
|
|
717
|
+
/**
|
|
718
|
+
* Pure rollup boundary. Implemented by a pure function (no LLM, no IO); modelled
|
|
719
|
+
* as an interface only so callers depend on the contract, not the solver.
|
|
720
|
+
*/
|
|
721
|
+
export interface DirectionRanker {
|
|
722
|
+
rank(ids: string[], verdicts: TasteVerdict[]): RankResult;
|
|
723
|
+
}
|
|
724
|
+
/**
|
|
725
|
+
* The single LLM/vision comparison boundary. NARROW by design: one comparison,
|
|
726
|
+
* one slot order, returns a RawVerdict. All debiasing/aggregation lives in pure
|
|
727
|
+
* cores around it. The shipped default is text-only over `brain.complete`; a
|
|
728
|
+
* vision judge is a future drop-in implementing the same interface (it must NOT
|
|
729
|
+
* be faked by overloading `brain.auditDesign`).
|
|
730
|
+
*/
|
|
731
|
+
export interface TasteJudge {
|
|
732
|
+
readonly id: string;
|
|
733
|
+
compare(input: JudgePairInput): Promise<RawVerdict>;
|
|
734
|
+
}
|
|
735
|
+
/**
|
|
736
|
+
* A provider-agnostic handle to one model: the `{ provider, model }` pair the
|
|
737
|
+
* vision-judge ensemble keys on. Provider-agnostic by construction — `provider`
|
|
738
|
+
* reuses `SupportedProvider`, so any vision-capable backend the Brain provider
|
|
739
|
+
* layer already resolves (openai/gpt-5.4, anthropic/claude-opus-4-8, google
|
|
740
|
+
* gemini, claude-code, …) is a legal target and selection goes through the
|
|
741
|
+
* existing abstraction, never a bespoke per-provider path. `provider` is optional:
|
|
742
|
+
* when omitted the wiring root fills it from the ambient default. A list of one
|
|
743
|
+
* ref ⇒ a single judge; a list of many ⇒ an ensemble (see `visionModels`).
|
|
744
|
+
*/
|
|
745
|
+
export interface ModelRef {
|
|
746
|
+
provider?: SupportedProvider;
|
|
747
|
+
model: string;
|
|
748
|
+
}
|
|
749
|
+
/**
|
|
750
|
+
* One image handed to a vision judge for a single comparison — each comparison
|
|
751
|
+
* side contributes one. Two interchangeable forms, exactly one set:
|
|
752
|
+
* - `{ screenshotPath }`: an on-disk image the adapter reads (the common case —
|
|
753
|
+
* `JudgeSubject.screenshotPath` for pages/exemplars; PNG or JPEG, mediaType
|
|
754
|
+
* inferred from the file extension);
|
|
755
|
+
* - `{ base64, mediaType }`: already-encoded image bytes, for an in-memory
|
|
756
|
+
* screenshot that was never written to disk.
|
|
757
|
+
* The disjoint required keys make the two mutually exclusive at the type level.
|
|
758
|
+
*/
|
|
759
|
+
export type VisionImageRef = {
|
|
760
|
+
screenshotPath: string;
|
|
761
|
+
} | {
|
|
762
|
+
base64: string;
|
|
763
|
+
mediaType: string;
|
|
764
|
+
};
|
|
765
|
+
/**
|
|
766
|
+
* The narrow vision-capable model seam — the visual analogue of the text judge's
|
|
767
|
+
* `JudgeModel`. ONE instance is bound to ONE resolved `ModelRef` (its `id` is that
|
|
768
|
+
* ref rendered as `provider:model`, e.g. `'openai:gpt-5.4'`), so an ensemble is
|
|
769
|
+
* simply a LIST of these seams. `completeVision` is a single multimodal
|
|
770
|
+
* round-trip: a system prompt + a user prompt + one-or-more `VisionImageRef`s
|
|
771
|
+
* (the compared subjects' screenshots) → raw model text, which the judge parses
|
|
772
|
+
* with the same `parseRawVerdict` the text judge uses.
|
|
773
|
+
*
|
|
774
|
+
* The wiring root binds ONE Brain per `ModelRef` and wraps it in a thin
|
|
775
|
+
* Brain-backed adapter (`createBrainVisionModel`) that supplies the
|
|
776
|
+
* `provider:model` id, reads each `VisionImageRef` off disk, and routes the
|
|
777
|
+
* encoded images through Brain's multimodal round-trip — a SIBLING of
|
|
778
|
+
* `brain.complete`, NOT an overload of `brain.auditDesign` (the page-audit seam
|
|
779
|
+
* stays off-limits to taste comparison by contract). Unit tests inject
|
|
780
|
+
* deterministic stubs with no live model.
|
|
781
|
+
*
|
|
782
|
+
* Ensemble aggregation (how a LIST of these seams collapses to ONE `RawVerdict`
|
|
783
|
+
* per `compare`, on a single slot order — position-swap is the outer debias
|
|
784
|
+
* core's job and is never re-done here):
|
|
785
|
+
* - each model casts ONE vote ∈ {A, B, tie}; a genuine `tie` vote is a real
|
|
786
|
+
* verdict, tallied in its own bucket;
|
|
787
|
+
* - a model that yields NO usable verdict — its call throws, or the response
|
|
788
|
+
* carries no parseable winner token — is DROPPED: excluded from BOTH the tally
|
|
789
|
+
* and the denominator (never silently recounted as a tie). If EVERY model is
|
|
790
|
+
* dropped, `compare` throws — an empty ensemble result is an explicit error,
|
|
791
|
+
* never a fabricated tie (and an empty model list is rejected at construction);
|
|
792
|
+
* - `winnerSlot` = the bucket (A, B, OR tie) holding the STRICT maximum count;
|
|
793
|
+
* `confidence` = that bucket's votes ÷ surviving votes (the honest agreement
|
|
794
|
+
* fraction, never a constant). When ≥2 buckets share the top count the
|
|
795
|
+
* ensemble is undecided ⇒ `winnerSlot: 'tie'`, `confidence: 0`;
|
|
796
|
+
* - `tokensUsed` = the sum over every model call that reported a count;
|
|
797
|
+
* `dimension` echoes `JudgePairInput.dimension` when the comparison was scoped.
|
|
798
|
+
*/
|
|
799
|
+
export interface VisionJudgeModel {
|
|
800
|
+
/** The bound `ModelRef` rendered as `provider:model`. */
|
|
801
|
+
readonly id: string;
|
|
802
|
+
completeVision(system: string, user: string, images: VisionImageRef[], options?: {
|
|
803
|
+
maxOutputTokens?: number;
|
|
804
|
+
}): Promise<{
|
|
805
|
+
text: string;
|
|
806
|
+
tokensUsed?: number;
|
|
807
|
+
}>;
|
|
808
|
+
}
|
|
809
|
+
/** A recorded human pairwise preference, for judge calibration. */
|
|
810
|
+
export interface HumanVote {
|
|
811
|
+
aId: string;
|
|
812
|
+
bId: string;
|
|
813
|
+
winner: string | 'tie';
|
|
814
|
+
}
|
|
815
|
+
/** Judge-vs-human agreement over a vote set. */
|
|
816
|
+
export interface CalibrationResult {
|
|
817
|
+
/** Fraction of comparisons where judge and human agree, 0-1 (ties excluded). */
|
|
818
|
+
agreement: number;
|
|
819
|
+
/** Number of comparisons scored. */
|
|
820
|
+
n: number;
|
|
821
|
+
}
|
|
822
|
+
/**
|
|
823
|
+
* The ABSOLUTE quality assessment of the page-under-audit, produced by judging
|
|
824
|
+
* the current page against the retrieved world-class exemplars (position-swapped
|
|
825
|
+
* pairwise → win-rate). This — NOT the relative direction ranking — is the
|
|
826
|
+
* single, honest scoring authority: it feeds the 0-10 headline score, the
|
|
827
|
+
* per-`Dimension` `precomputedScores` (skipping stage-8's LLM call), and the
|
|
828
|
+
* overall-derived 8-dim DesignSystemScore.
|
|
829
|
+
*/
|
|
830
|
+
export interface QualityAssessment {
|
|
831
|
+
/** Win-rate of the current page vs exemplars, 0-1 (0.5 ≈ on par). */
|
|
832
|
+
overallWinRate: number;
|
|
833
|
+
/**
|
|
834
|
+
* Per-product-dimension win-rates, keyed by the 5-dim `Dimension` taxonomy.
|
|
835
|
+
* Each entry is the win-rate of a dimension-scoped comparison set (the quality
|
|
836
|
+
* leg issues one `JudgePairInput.dimension` per `Dimension`). Present ⇒ the
|
|
837
|
+
* dims are genuinely judge-resolved; `score-core.toDimensionScores` maps them
|
|
838
|
+
* into the rich `Record<Dimension, DimensionScore>` that stage 8 consumes.
|
|
839
|
+
* Omitted ⇒ no per-dim signal was gathered (single-leg budget); callers must
|
|
840
|
+
* NOT fabricate per-dim scores from `overallWinRate`.
|
|
841
|
+
*/
|
|
842
|
+
dimensionWinRates?: Partial<Record<Dimension, number>>;
|
|
843
|
+
/** How many pairwise comparisons backed this assessment. */
|
|
844
|
+
comparisons: number;
|
|
845
|
+
}
|
|
846
|
+
/**
|
|
847
|
+
* The rich, first-class output of the engine. This is NOT a throwaway side file:
|
|
848
|
+
* it is returned by the library entry (`runReferenceRedesign`) and written to
|
|
849
|
+
* disk, and is the artifact the taste eval consumes.
|
|
850
|
+
*/
|
|
851
|
+
export interface RedesignArtifact {
|
|
852
|
+
url: string;
|
|
853
|
+
/** Directions ordered by ranking (winner first). */
|
|
854
|
+
directions: RedesignDirection[];
|
|
855
|
+
ranking: RankResult;
|
|
856
|
+
/** Provenance: which exemplars grounded the generation. */
|
|
857
|
+
retrieval: RetrievalResult[];
|
|
858
|
+
verdicts: TasteVerdict[];
|
|
859
|
+
/** Id of the operator-supplied reference, when one was used. */
|
|
860
|
+
referenceId?: string;
|
|
861
|
+
tokensUsed: number;
|
|
862
|
+
}
|
|
863
|
+
/**
|
|
864
|
+
* The full result of one engine run, shared by BOTH entrypoints. The pure core
|
|
865
|
+
* returns this; `run.ts` surfaces `.artifact`, `pipeline/evaluate-reference.ts`
|
|
866
|
+
* maps it onto a PageAuditResult. Single core, two return-shapings — no
|
|
867
|
+
* duplicated orchestration.
|
|
868
|
+
*/
|
|
869
|
+
export interface RedesignRunResult {
|
|
870
|
+
artifact: RedesignArtifact;
|
|
871
|
+
/** Absolute quality assessment of the current page. */
|
|
872
|
+
quality: QualityAssessment;
|
|
873
|
+
/** Derived 0-10 headline score. */
|
|
874
|
+
headlineScore: number;
|
|
875
|
+
/**
|
|
876
|
+
* The stage-8 `precomputedScores` hook: the 5-dim product-quality scores in the
|
|
877
|
+
* exact `Record<Dimension, DimensionScore>` shape `buildAuditResult` consumes,
|
|
878
|
+
* so passing this skips its second multidim LLM call. Built by
|
|
879
|
+
* `score-core.toDimensionScores` from `quality.dimensionWinRates` (each dim's
|
|
880
|
+
* win-rate → score, with range/confidence reflecting comparison count).
|
|
881
|
+
*/
|
|
882
|
+
dimensionScores: Record<Dimension, DimensionScore>;
|
|
883
|
+
/**
|
|
884
|
+
* The flat 8-dim design-system score for `PageAuditResult.designSystemScore`
|
|
885
|
+
* (back-compat surface). HONESTLY a coarse projection of `overallWinRate` —
|
|
886
|
+
* the judge resolves the 5 product `Dimension`s, not these 8 design-system
|
|
887
|
+
* axes — so it is NOT a second per-dimension scoring authority.
|
|
888
|
+
*/
|
|
889
|
+
designSystemScore: DesignSystemScore;
|
|
890
|
+
/** Findings projected from the winner + measurement ground truth. */
|
|
891
|
+
findings: DesignFinding[];
|
|
892
|
+
classification: PageClassification;
|
|
893
|
+
measurements: MeasurementBundle;
|
|
894
|
+
tokensUsed: number;
|
|
895
|
+
}
|
|
896
|
+
/** Pipeline evaluation mode. Absent/`'v1'` ⇒ byte-identical legacy behaviour. */
|
|
897
|
+
export type EvalMode = 'v1' | 'reference-grounded';
|
|
898
|
+
/**
|
|
899
|
+
* Cost ceiling for one engine run. Pairwise judging multiplies LLM calls, so
|
|
900
|
+
* every leg is explicitly capped and the orchestrator runs independent calls
|
|
901
|
+
* concurrently up to `concurrency`.
|
|
902
|
+
*/
|
|
903
|
+
export interface EngineBudget {
|
|
904
|
+
/** Max generation calls (≈ direction count). */
|
|
905
|
+
maxGenerationCalls: number;
|
|
906
|
+
/** Max judge calls across quality + direction legs. */
|
|
907
|
+
maxJudgeCalls: number;
|
|
908
|
+
/** Repetitions per pairwise comparison (each rep = both slot orders). */
|
|
909
|
+
judgeReps: number;
|
|
910
|
+
/** Max concurrent in-flight LLM calls. */
|
|
911
|
+
concurrency: number;
|
|
912
|
+
/**
|
|
913
|
+
* When true, screen directions at 1 rep then validate only the top-2 at full
|
|
914
|
+
* reps (the two-stage screen/validate pattern) to contain cost.
|
|
915
|
+
*/
|
|
916
|
+
screenThenValidate: boolean;
|
|
917
|
+
}
|
|
918
|
+
/**
|
|
919
|
+
* Resolved configuration for the reference-grounded engine. Lives on
|
|
920
|
+
* AuditOnePageOptions as a sibling of `overrides` — NOT inside AuditOverrides
|
|
921
|
+
* (a static prompt-knob bag) and NOT on DriverConfig (which the audit path
|
|
922
|
+
* bypasses).
|
|
923
|
+
*/
|
|
924
|
+
export interface ReferenceGroundedConfig {
|
|
925
|
+
/** Directory of the exemplar corpus. */
|
|
926
|
+
corpusDir: string;
|
|
927
|
+
/** Where the rich artifact is written. */
|
|
928
|
+
artifactDir?: string;
|
|
929
|
+
/** Number of exemplars to retrieve. */
|
|
930
|
+
k: number;
|
|
931
|
+
/** Number of redesign directions to generate (2-3). */
|
|
932
|
+
directionCount: number;
|
|
933
|
+
/**
|
|
934
|
+
* Judge backend. `'text'` (default) judges from DNA/direction summaries via
|
|
935
|
+
* `brain.complete`. `'vision'` selects the screenshot-grounded ensemble judge
|
|
936
|
+
* built from `visionModels`; it scores the subjects that HAVE a screenshot —
|
|
937
|
+
* the audited page and the corpus exemplars (the quality leg) — and falls back
|
|
938
|
+
* to the text judge for screenshot-less subjects, so the unrendered
|
|
939
|
+
* direction-ranking leg stays text-only either way.
|
|
940
|
+
*/
|
|
941
|
+
judge: 'text' | 'vision';
|
|
942
|
+
/**
|
|
943
|
+
* The vision-judge ensemble: the list of `{ provider, model }` refs run when
|
|
944
|
+
* `judge: 'vision'` (ignored when `judge: 'text'`). ONE ref ⇒ a single judge;
|
|
945
|
+
* MANY ⇒ an ensemble that, for each comparison, runs every model in parallel
|
|
946
|
+
* on the SAME slot order, then aggregates across models — see
|
|
947
|
+
* {@link VisionJudgeModel} for the EXACT tally/drop/confidence rules (majority
|
|
948
|
+
* bucket wins, agreement fraction → confidence, a split → tie, a no-verdict
|
|
949
|
+
* model is dropped, an all-dropped result throws). Position-swap (A-vs-B and
|
|
950
|
+
* B-vs-A, to cancel order bias) is supplied by the surrounding pure debias core
|
|
951
|
+
* that calls the judge twice, so the ensemble layer varies MODELS only and
|
|
952
|
+
* never re-swaps order. Provider-agnostic: each ref resolves through the Brain
|
|
953
|
+
* provider abstraction, so a mixed openai+anthropic+google ensemble is legal —
|
|
954
|
+
* though `provider` admits non-vision backends too (`cli-bridge`,
|
|
955
|
+
* `sandbox-backend`, …): vision-capability is a RUNTIME precondition the wiring
|
|
956
|
+
* assumes, not something the type guarantees.
|
|
957
|
+
*/
|
|
958
|
+
visionModels?: ModelRef[];
|
|
959
|
+
/** Embedding backend; falls back to 'deterministic' when no key is present. */
|
|
960
|
+
embedder: 'deterministic' | 'provider';
|
|
961
|
+
budget: EngineBudget;
|
|
962
|
+
/** Operator-supplied reference, resolved once. */
|
|
963
|
+
reference?: ReferenceContext;
|
|
964
|
+
/** Model id override for generation/judging. */
|
|
965
|
+
model?: string;
|
|
966
|
+
}
|
|
967
|
+
/**
|
|
968
|
+
* The injected dependency bundle for the shared core. The core depends ONLY on
|
|
969
|
+
* these narrow interfaces; concrete adapters are wired at the composition roots
|
|
970
|
+
* (`run.ts`, `pipeline/evaluate-reference.ts`) and passed in — so the core never
|
|
971
|
+
* imports a concrete IO/LLM module and stays a pure sequencer.
|
|
972
|
+
*/
|
|
973
|
+
export interface ReferenceEngineDeps {
|
|
974
|
+
extractor: DesignDnaExtractor;
|
|
975
|
+
/**
|
|
976
|
+
* READ-ONLY corpus access. The core never authors the corpus, so it depends on
|
|
977
|
+
* `CorpusReader`, not the full `CorpusStore` — the authoring mutators
|
|
978
|
+
* (upsert/saveScreenshot) are unreachable from the audit path by construction.
|
|
979
|
+
*/
|
|
980
|
+
store: CorpusReader;
|
|
981
|
+
embedder: EmbeddingProvider;
|
|
982
|
+
matcher: ExemplarMatcher;
|
|
983
|
+
generator: RedesignGenerator;
|
|
984
|
+
judge: TasteJudge;
|
|
985
|
+
ranker: DirectionRanker;
|
|
986
|
+
}
|
|
987
|
+
/**
|
|
988
|
+
* Per-page input to the shared core. The exemplar `corpus` is loaded ONCE per
|
|
989
|
+
* run by the L4 entrypoint (a single `deps.store.load()` before the page/rep
|
|
990
|
+
* loops) and threaded in here — mirroring the acquire-once `ReferenceContext` —
|
|
991
|
+
* so a multi-page / multi-rep run never re-reads, re-parses, and re-validates
|
|
992
|
+
* the full corpus from disk. The core retrieves against this in-memory array and
|
|
993
|
+
* does NOT call `store.load()` itself.
|
|
994
|
+
*/
|
|
995
|
+
export interface RedesignCoreInput {
|
|
996
|
+
url: string;
|
|
997
|
+
classification: PageClassification;
|
|
998
|
+
measurements: MeasurementBundle;
|
|
999
|
+
screenshotPath?: string;
|
|
1000
|
+
/** The full exemplar corpus, loaded once per run and reused across pages/reps. */
|
|
1001
|
+
corpus: Exemplar[];
|
|
1002
|
+
config: ReferenceGroundedConfig;
|
|
1003
|
+
}
|
|
1004
|
+
/** A corpus-vs-corpus taste pair: a known-stronger vs known-weaker exemplar. */
|
|
1005
|
+
export interface TastePair {
|
|
1006
|
+
strongId: string;
|
|
1007
|
+
weakId: string;
|
|
1008
|
+
}
|
|
1009
|
+
/** Corpus-order agreement over a set of taste pairs. */
|
|
1010
|
+
export interface TasteAgreementResult {
|
|
1011
|
+
/** Fraction of pairs where the judge preferred the stronger member, 0-1. */
|
|
1012
|
+
agreementRate: number;
|
|
1013
|
+
/** Number of non-tie comparisons. */
|
|
1014
|
+
n: number;
|
|
1015
|
+
}
|
|
1016
|
+
/**
|
|
1017
|
+
* Bench metric shape for the taste eval. Mirrors the existing `patchMetrics`
|
|
1018
|
+
* branch pattern: an optional sibling field on a TrialResult that remaps the
|
|
1019
|
+
* ObjectiveVector axes (recall ← winsVsReference, precision ← corpusOrderAgreement)
|
|
1020
|
+
* with ZERO change to the 5-axis vector schema.
|
|
1021
|
+
*/
|
|
1022
|
+
export interface TasteMetrics {
|
|
1023
|
+
/** Generated-vs-reference wins. */
|
|
1024
|
+
winsVsReference: number;
|
|
1025
|
+
/** Total comparisons backing winsVsReference. */
|
|
1026
|
+
comparisons: number;
|
|
1027
|
+
/** Corpus-order agreement rate, when computed. */
|
|
1028
|
+
corpusOrderAgreement?: number;
|
|
1029
|
+
}
|
|
1030
|
+
//# sourceMappingURL=contracts.d.ts.map
|