@tangle-network/browser-agent-driver 0.33.3 → 0.34.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.
Files changed (485) hide show
  1. package/README.md +42 -1
  2. package/discovery/llms.txt +27 -0
  3. package/discovery/tangle-agent.json +36 -0
  4. package/dist/brain/action-parse.d.ts +16 -0
  5. package/dist/brain/action-parse.d.ts.map +1 -0
  6. package/dist/brain/action-parse.js +191 -0
  7. package/dist/brain/action-parse.js.map +1 -0
  8. package/dist/brain/decide.d.ts +58 -0
  9. package/dist/brain/decide.d.ts.map +1 -0
  10. package/dist/brain/decide.js +418 -0
  11. package/dist/brain/decide.js.map +1 -0
  12. package/dist/brain/history-compact.d.ts +19 -0
  13. package/dist/brain/history-compact.d.ts.map +1 -0
  14. package/dist/brain/history-compact.js +153 -0
  15. package/dist/brain/history-compact.js.map +1 -0
  16. package/dist/brain/index.d.ts +78 -152
  17. package/dist/brain/index.d.ts.map +1 -1
  18. package/dist/brain/index.js +62 -2268
  19. package/dist/brain/index.js.map +1 -1
  20. package/dist/brain/model-client.d.ts +101 -0
  21. package/dist/brain/model-client.d.ts.map +1 -0
  22. package/dist/brain/model-client.js +391 -0
  23. package/dist/brain/model-client.js.map +1 -0
  24. package/dist/brain/plan.d.ts +57 -0
  25. package/dist/brain/plan.d.ts.map +1 -0
  26. package/dist/brain/plan.js +194 -0
  27. package/dist/brain/plan.js.map +1 -0
  28. package/dist/brain/prompts.d.ts +37 -0
  29. package/dist/brain/prompts.d.ts.map +1 -0
  30. package/dist/brain/prompts.js +455 -0
  31. package/dist/brain/prompts.js.map +1 -0
  32. package/dist/brain/provider-fetch.d.ts +26 -0
  33. package/dist/brain/provider-fetch.d.ts.map +1 -0
  34. package/dist/brain/provider-fetch.js +45 -0
  35. package/dist/brain/provider-fetch.js.map +1 -0
  36. package/dist/brain/snapshot-budget.d.ts +20 -0
  37. package/dist/brain/snapshot-budget.d.ts.map +1 -0
  38. package/dist/brain/snapshot-budget.js +202 -0
  39. package/dist/brain/snapshot-budget.js.map +1 -0
  40. package/dist/brain/system-prompt.d.ts +67 -0
  41. package/dist/brain/system-prompt.d.ts.map +1 -0
  42. package/dist/brain/system-prompt.js +128 -0
  43. package/dist/brain/system-prompt.js.map +1 -0
  44. package/dist/brain/tasks/design-audit.d.ts +33 -0
  45. package/dist/brain/tasks/design-audit.d.ts.map +1 -0
  46. package/dist/brain/tasks/design-audit.js +100 -0
  47. package/dist/brain/tasks/design-audit.js.map +1 -0
  48. package/dist/brain/tasks/evaluate.d.ts +25 -0
  49. package/dist/brain/tasks/evaluate.d.ts.map +1 -0
  50. package/dist/brain/tasks/evaluate.js +55 -0
  51. package/dist/brain/tasks/evaluate.js.map +1 -0
  52. package/dist/brain/tasks/goal-verification.d.ts +32 -0
  53. package/dist/brain/tasks/goal-verification.d.ts.map +1 -0
  54. package/dist/brain/tasks/goal-verification.js +68 -0
  55. package/dist/brain/tasks/goal-verification.js.map +1 -0
  56. package/dist/brain/tasks/knowledge.d.ts +26 -0
  57. package/dist/brain/tasks/knowledge.d.ts.map +1 -0
  58. package/dist/brain/tasks/knowledge.js +56 -0
  59. package/dist/brain/tasks/knowledge.js.map +1 -0
  60. package/dist/brain/tasks/link-scout.d.ts +37 -0
  61. package/dist/brain/tasks/link-scout.d.ts.map +1 -0
  62. package/dist/brain/tasks/link-scout.js +69 -0
  63. package/dist/brain/tasks/link-scout.js.map +1 -0
  64. package/dist/brain/types.d.ts +55 -0
  65. package/dist/brain/types.d.ts.map +1 -0
  66. package/dist/brain/types.js +7 -0
  67. package/dist/brain/types.js.map +1 -0
  68. package/dist/browser/stealth-init-script.d.ts +9 -0
  69. package/dist/browser/stealth-init-script.d.ts.map +1 -0
  70. package/dist/browser/stealth-init-script.js +128 -0
  71. package/dist/browser/stealth-init-script.js.map +1 -0
  72. package/dist/browser/storage-state.d.ts +29 -0
  73. package/dist/browser/storage-state.d.ts.map +1 -0
  74. package/dist/browser/storage-state.js +47 -0
  75. package/dist/browser/storage-state.js.map +1 -0
  76. package/dist/cli/args.d.ts +141 -0
  77. package/dist/cli/args.d.ts.map +1 -0
  78. package/dist/cli/args.js +167 -0
  79. package/dist/cli/args.js.map +1 -0
  80. package/dist/cli/benchmark-sync.d.ts +9 -0
  81. package/dist/cli/benchmark-sync.d.ts.map +1 -0
  82. package/dist/cli/benchmark-sync.js +43 -0
  83. package/dist/cli/benchmark-sync.js.map +1 -0
  84. package/dist/cli/build-config.d.ts +11 -0
  85. package/dist/cli/build-config.d.ts.map +1 -0
  86. package/dist/cli/build-config.js +355 -0
  87. package/dist/cli/build-config.js.map +1 -0
  88. package/dist/cli/commands/auth.d.ts +3 -0
  89. package/dist/cli/commands/auth.d.ts.map +1 -0
  90. package/dist/cli/commands/auth.js +36 -0
  91. package/dist/cli/commands/auth.js.map +1 -0
  92. package/dist/cli/commands/chrome-debug.d.ts +7 -0
  93. package/dist/cli/commands/chrome-debug.d.ts.map +1 -0
  94. package/dist/cli/commands/chrome-debug.js +11 -0
  95. package/dist/cli/commands/chrome-debug.js.map +1 -0
  96. package/dist/cli/commands/design-audit.d.ts +3 -0
  97. package/dist/cli/commands/design-audit.d.ts.map +1 -0
  98. package/dist/cli/commands/design-audit.js +68 -0
  99. package/dist/cli/commands/design-audit.js.map +1 -0
  100. package/dist/cli/commands/preview.d.ts +14 -0
  101. package/dist/cli/commands/preview.d.ts.map +1 -0
  102. package/dist/cli/commands/preview.js +31 -0
  103. package/dist/cli/commands/preview.js.map +1 -0
  104. package/dist/cli/commands/run.d.ts +3 -0
  105. package/dist/cli/commands/run.d.ts.map +1 -0
  106. package/dist/cli/commands/run.js +728 -0
  107. package/dist/cli/commands/run.js.map +1 -0
  108. package/dist/cli/commands/runs.d.ts +8 -0
  109. package/dist/cli/commands/runs.d.ts.map +1 -0
  110. package/dist/cli/commands/runs.js +35 -0
  111. package/dist/cli/commands/runs.js.map +1 -0
  112. package/dist/cli/commands/share.d.ts +10 -0
  113. package/dist/cli/commands/share.d.ts.map +1 -0
  114. package/dist/cli/commands/share.js +32 -0
  115. package/dist/cli/commands/share.js.map +1 -0
  116. package/dist/cli/commands/showcase.d.ts +17 -0
  117. package/dist/cli/commands/showcase.d.ts.map +1 -0
  118. package/dist/cli/commands/showcase.js +20 -0
  119. package/dist/cli/commands/showcase.js.map +1 -0
  120. package/dist/cli/commands/snapshot.d.ts +12 -0
  121. package/dist/cli/commands/snapshot.d.ts.map +1 -0
  122. package/dist/cli/commands/snapshot.js +24 -0
  123. package/dist/cli/commands/snapshot.js.map +1 -0
  124. package/dist/cli/commands/view.d.ts +7 -0
  125. package/dist/cli/commands/view.d.ts.map +1 -0
  126. package/dist/cli/commands/view.js +23 -0
  127. package/dist/cli/commands/view.js.map +1 -0
  128. package/dist/cli/constants.d.ts +6 -0
  129. package/dist/cli/constants.d.ts.map +1 -0
  130. package/dist/cli/constants.js +3 -0
  131. package/dist/cli/constants.js.map +1 -0
  132. package/dist/cli/version.d.ts +7 -0
  133. package/dist/cli/version.d.ts.map +1 -0
  134. package/dist/cli/version.js +16 -0
  135. package/dist/cli/version.js.map +1 -0
  136. package/dist/cli-design-audit.d.ts +44 -36
  137. package/dist/cli-design-audit.d.ts.map +1 -1
  138. package/dist/cli-design-audit.js +137 -1646
  139. package/dist/cli-design-audit.js.map +1 -1
  140. package/dist/cli-jobs.js +2 -1
  141. package/dist/cli-jobs.js.map +1 -1
  142. package/dist/cli.js +66 -1697
  143. package/dist/cli.js.map +1 -1
  144. package/dist/config.d.ts +5 -0
  145. package/dist/config.d.ts.map +1 -1
  146. package/dist/config.js +8 -0
  147. package/dist/config.js.map +1 -1
  148. package/dist/design/audit/evolve/agent.d.ts +23 -0
  149. package/dist/design/audit/evolve/agent.d.ts.map +1 -0
  150. package/dist/design/audit/evolve/agent.js +272 -0
  151. package/dist/design/audit/evolve/agent.js.map +1 -0
  152. package/dist/design/audit/evolve/css.d.ts +10 -0
  153. package/dist/design/audit/evolve/css.d.ts.map +1 -0
  154. package/dist/design/audit/evolve/css.js +206 -0
  155. package/dist/design/audit/evolve/css.js.map +1 -0
  156. package/dist/design/audit/evolve/index.d.ts +13 -0
  157. package/dist/design/audit/evolve/index.d.ts.map +1 -0
  158. package/dist/design/audit/evolve/index.js +12 -0
  159. package/dist/design/audit/evolve/index.js.map +1 -0
  160. package/dist/design/audit/evolve/report.d.ts +3 -0
  161. package/dist/design/audit/evolve/report.d.ts.map +1 -0
  162. package/dist/design/audit/evolve/report.js +45 -0
  163. package/dist/design/audit/evolve/report.js.map +1 -0
  164. package/dist/design/audit/evolve/types.d.ts +14 -0
  165. package/dist/design/audit/evolve/types.d.ts.map +1 -0
  166. package/dist/design/audit/evolve/types.js +2 -0
  167. package/dist/design/audit/evolve/types.js.map +1 -0
  168. package/dist/design/audit/pipeline.d.ts +12 -0
  169. package/dist/design/audit/pipeline.d.ts.map +1 -1
  170. package/dist/design/audit/pipeline.js +43 -27
  171. package/dist/design/audit/pipeline.js.map +1 -1
  172. package/dist/design/audit/reference/artifact/build.d.ts +33 -0
  173. package/dist/design/audit/reference/artifact/build.d.ts.map +1 -0
  174. package/dist/design/audit/reference/artifact/build.js +64 -0
  175. package/dist/design/audit/reference/artifact/build.js.map +1 -0
  176. package/dist/design/audit/reference/artifact/render.d.ts +39 -0
  177. package/dist/design/audit/reference/artifact/render.d.ts.map +1 -0
  178. package/dist/design/audit/reference/artifact/render.js +213 -0
  179. package/dist/design/audit/reference/artifact/render.js.map +1 -0
  180. package/dist/design/audit/reference/artifact/text.d.ts +11 -0
  181. package/dist/design/audit/reference/artifact/text.d.ts.map +1 -0
  182. package/dist/design/audit/reference/artifact/text.js +20 -0
  183. package/dist/design/audit/reference/artifact/text.js.map +1 -0
  184. package/dist/design/audit/reference/artifact/to-findings.d.ts +57 -0
  185. package/dist/design/audit/reference/artifact/to-findings.d.ts.map +1 -0
  186. package/dist/design/audit/reference/artifact/to-findings.js +314 -0
  187. package/dist/design/audit/reference/artifact/to-findings.js.map +1 -0
  188. package/dist/design/audit/reference/config.d.ts +50 -0
  189. package/dist/design/audit/reference/config.d.ts.map +1 -0
  190. package/dist/design/audit/reference/config.js +108 -0
  191. package/dist/design/audit/reference/config.js.map +1 -0
  192. package/dist/design/audit/reference/contracts.d.ts +1030 -0
  193. package/dist/design/audit/reference/contracts.d.ts.map +1 -0
  194. package/dist/design/audit/reference/contracts.js +28 -0
  195. package/dist/design/audit/reference/contracts.js.map +1 -0
  196. package/dist/design/audit/reference/corpus/build.d.ts +115 -0
  197. package/dist/design/audit/reference/corpus/build.d.ts.map +1 -0
  198. package/dist/design/audit/reference/corpus/build.js +152 -0
  199. package/dist/design/audit/reference/corpus/build.js.map +1 -0
  200. package/dist/design/audit/reference/corpus/schema.d.ts +33 -0
  201. package/dist/design/audit/reference/corpus/schema.d.ts.map +1 -0
  202. package/dist/design/audit/reference/corpus/schema.js +249 -0
  203. package/dist/design/audit/reference/corpus/schema.js.map +1 -0
  204. package/dist/design/audit/reference/corpus/store.d.ts +26 -0
  205. package/dist/design/audit/reference/corpus/store.d.ts.map +1 -0
  206. package/dist/design/audit/reference/corpus/store.js +104 -0
  207. package/dist/design/audit/reference/corpus/store.js.map +1 -0
  208. package/dist/design/audit/reference/dna/delta.d.ts +21 -0
  209. package/dist/design/audit/reference/dna/delta.d.ts.map +1 -0
  210. package/dist/design/audit/reference/dna/delta.js +126 -0
  211. package/dist/design/audit/reference/dna/delta.js.map +1 -0
  212. package/dist/design/audit/reference/dna/derive.d.ts +31 -0
  213. package/dist/design/audit/reference/dna/derive.d.ts.map +1 -0
  214. package/dist/design/audit/reference/dna/derive.js +381 -0
  215. package/dist/design/audit/reference/dna/derive.js.map +1 -0
  216. package/dist/design/audit/reference/dna/descriptor.d.ts +36 -0
  217. package/dist/design/audit/reference/dna/descriptor.d.ts.map +1 -0
  218. package/dist/design/audit/reference/dna/descriptor.js +209 -0
  219. package/dist/design/audit/reference/dna/descriptor.js.map +1 -0
  220. package/dist/design/audit/reference/dna/page-adapter.d.ts +17 -0
  221. package/dist/design/audit/reference/dna/page-adapter.d.ts.map +1 -0
  222. package/dist/design/audit/reference/dna/page-adapter.js +35 -0
  223. package/dist/design/audit/reference/dna/page-adapter.js.map +1 -0
  224. package/dist/design/audit/reference/dna/scroll-capture.d.ts +93 -0
  225. package/dist/design/audit/reference/dna/scroll-capture.d.ts.map +1 -0
  226. package/dist/design/audit/reference/dna/scroll-capture.js +374 -0
  227. package/dist/design/audit/reference/dna/scroll-capture.js.map +1 -0
  228. package/dist/design/audit/reference/engine/budget.d.ts +63 -0
  229. package/dist/design/audit/reference/engine/budget.d.ts.map +1 -0
  230. package/dist/design/audit/reference/engine/budget.js +110 -0
  231. package/dist/design/audit/reference/engine/budget.js.map +1 -0
  232. package/dist/design/audit/reference/engine/core.d.ts +32 -0
  233. package/dist/design/audit/reference/engine/core.d.ts.map +1 -0
  234. package/dist/design/audit/reference/engine/core.js +261 -0
  235. package/dist/design/audit/reference/engine/core.js.map +1 -0
  236. package/dist/design/audit/reference/engine/guard.d.ts +43 -0
  237. package/dist/design/audit/reference/engine/guard.d.ts.map +1 -0
  238. package/dist/design/audit/reference/engine/guard.js +43 -0
  239. package/dist/design/audit/reference/engine/guard.js.map +1 -0
  240. package/dist/design/audit/reference/engine/score-core.d.ts +48 -0
  241. package/dist/design/audit/reference/engine/score-core.d.ts.map +1 -0
  242. package/dist/design/audit/reference/engine/score-core.js +134 -0
  243. package/dist/design/audit/reference/engine/score-core.js.map +1 -0
  244. package/dist/design/audit/reference/engine/wiring.d.ts +35 -0
  245. package/dist/design/audit/reference/engine/wiring.d.ts.map +1 -0
  246. package/dist/design/audit/reference/engine/wiring.js +80 -0
  247. package/dist/design/audit/reference/engine/wiring.js.map +1 -0
  248. package/dist/design/audit/reference/eval/taste-core.d.ts +77 -0
  249. package/dist/design/audit/reference/eval/taste-core.d.ts.map +1 -0
  250. package/dist/design/audit/reference/eval/taste-core.js +95 -0
  251. package/dist/design/audit/reference/eval/taste-core.js.map +1 -0
  252. package/dist/design/audit/reference/generate/generator.d.ts +49 -0
  253. package/dist/design/audit/reference/generate/generator.d.ts.map +1 -0
  254. package/dist/design/audit/reference/generate/generator.js +94 -0
  255. package/dist/design/audit/reference/generate/generator.js.map +1 -0
  256. package/dist/design/audit/reference/generate/parse.d.ts +28 -0
  257. package/dist/design/audit/reference/generate/parse.d.ts.map +1 -0
  258. package/dist/design/audit/reference/generate/parse.js +180 -0
  259. package/dist/design/audit/reference/generate/parse.js.map +1 -0
  260. package/dist/design/audit/reference/generate/prompt.d.ts +36 -0
  261. package/dist/design/audit/reference/generate/prompt.d.ts.map +1 -0
  262. package/dist/design/audit/reference/generate/prompt.js +124 -0
  263. package/dist/design/audit/reference/generate/prompt.js.map +1 -0
  264. package/dist/design/audit/reference/index.d.ts +26 -0
  265. package/dist/design/audit/reference/index.d.ts.map +1 -0
  266. package/dist/design/audit/reference/index.js +31 -0
  267. package/dist/design/audit/reference/index.js.map +1 -0
  268. package/dist/design/audit/reference/judge/image-clamp.d.ts +34 -0
  269. package/dist/design/audit/reference/judge/image-clamp.d.ts.map +1 -0
  270. package/dist/design/audit/reference/judge/image-clamp.js +88 -0
  271. package/dist/design/audit/reference/judge/image-clamp.js.map +1 -0
  272. package/dist/design/audit/reference/judge/pairwise.d.ts +34 -0
  273. package/dist/design/audit/reference/judge/pairwise.d.ts.map +1 -0
  274. package/dist/design/audit/reference/judge/pairwise.js +105 -0
  275. package/dist/design/audit/reference/judge/pairwise.js.map +1 -0
  276. package/dist/design/audit/reference/judge/parse.d.ts +31 -0
  277. package/dist/design/audit/reference/judge/parse.d.ts.map +1 -0
  278. package/dist/design/audit/reference/judge/parse.js +113 -0
  279. package/dist/design/audit/reference/judge/parse.js.map +1 -0
  280. package/dist/design/audit/reference/judge/prompt.d.ts +38 -0
  281. package/dist/design/audit/reference/judge/prompt.d.ts.map +1 -0
  282. package/dist/design/audit/reference/judge/prompt.js +111 -0
  283. package/dist/design/audit/reference/judge/prompt.js.map +1 -0
  284. package/dist/design/audit/reference/judge/quality.d.ts +28 -0
  285. package/dist/design/audit/reference/judge/quality.d.ts.map +1 -0
  286. package/dist/design/audit/reference/judge/quality.js +62 -0
  287. package/dist/design/audit/reference/judge/quality.js.map +1 -0
  288. package/dist/design/audit/reference/judge/rank.d.ts +41 -0
  289. package/dist/design/audit/reference/judge/rank.d.ts.map +1 -0
  290. package/dist/design/audit/reference/judge/rank.js +196 -0
  291. package/dist/design/audit/reference/judge/rank.js.map +1 -0
  292. package/dist/design/audit/reference/judge/text-judge.d.ts +31 -0
  293. package/dist/design/audit/reference/judge/text-judge.d.ts.map +1 -0
  294. package/dist/design/audit/reference/judge/text-judge.js +43 -0
  295. package/dist/design/audit/reference/judge/text-judge.js.map +1 -0
  296. package/dist/design/audit/reference/judge/vision-judge.d.ts +59 -0
  297. package/dist/design/audit/reference/judge/vision-judge.d.ts.map +1 -0
  298. package/dist/design/audit/reference/judge/vision-judge.js +150 -0
  299. package/dist/design/audit/reference/judge/vision-judge.js.map +1 -0
  300. package/dist/design/audit/reference/judge/vision-model.d.ts +65 -0
  301. package/dist/design/audit/reference/judge/vision-model.d.ts.map +1 -0
  302. package/dist/design/audit/reference/judge/vision-model.js +110 -0
  303. package/dist/design/audit/reference/judge/vision-model.js.map +1 -0
  304. package/dist/design/audit/reference/pipeline/evaluate-reference.d.ts +68 -0
  305. package/dist/design/audit/reference/pipeline/evaluate-reference.d.ts.map +1 -0
  306. package/dist/design/audit/reference/pipeline/evaluate-reference.js +52 -0
  307. package/dist/design/audit/reference/pipeline/evaluate-reference.js.map +1 -0
  308. package/dist/design/audit/reference/reference-context.d.ts +31 -0
  309. package/dist/design/audit/reference/reference-context.d.ts.map +1 -0
  310. package/dist/design/audit/reference/reference-context.js +73 -0
  311. package/dist/design/audit/reference/reference-context.js.map +1 -0
  312. package/dist/design/audit/reference/retrieval/embedding-hash.d.ts +30 -0
  313. package/dist/design/audit/reference/retrieval/embedding-hash.d.ts.map +1 -0
  314. package/dist/design/audit/reference/retrieval/embedding-hash.js +87 -0
  315. package/dist/design/audit/reference/retrieval/embedding-hash.js.map +1 -0
  316. package/dist/design/audit/reference/retrieval/embedding-openai.d.ts +38 -0
  317. package/dist/design/audit/reference/retrieval/embedding-openai.d.ts.map +1 -0
  318. package/dist/design/audit/reference/retrieval/embedding-openai.js +73 -0
  319. package/dist/design/audit/reference/retrieval/embedding-openai.js.map +1 -0
  320. package/dist/design/audit/reference/retrieval/matcher.d.ts +34 -0
  321. package/dist/design/audit/reference/retrieval/matcher.d.ts.map +1 -0
  322. package/dist/design/audit/reference/retrieval/matcher.js +107 -0
  323. package/dist/design/audit/reference/retrieval/matcher.js.map +1 -0
  324. package/dist/design/audit/reference/run.d.ts +59 -0
  325. package/dist/design/audit/reference/run.d.ts.map +1 -0
  326. package/dist/design/audit/reference/run.js +99 -0
  327. package/dist/design/audit/reference/run.js.map +1 -0
  328. package/dist/design/audit/report.d.ts +35 -0
  329. package/dist/design/audit/report.d.ts.map +1 -0
  330. package/dist/design/audit/report.js +195 -0
  331. package/dist/design/audit/report.js.map +1 -0
  332. package/dist/design/audit/tokens/extract.d.ts +71 -0
  333. package/dist/design/audit/tokens/extract.d.ts.map +1 -0
  334. package/dist/design/audit/tokens/extract.js +1034 -0
  335. package/dist/design/audit/tokens/extract.js.map +1 -0
  336. package/dist/design/audit/types.d.ts +8 -0
  337. package/dist/design/audit/types.d.ts.map +1 -1
  338. package/dist/design/compare.d.ts.map +1 -1
  339. package/dist/design/compare.js +2 -6
  340. package/dist/design/compare.js.map +1 -1
  341. package/dist/design/cookie-consent.d.ts +3 -0
  342. package/dist/design/cookie-consent.d.ts.map +1 -0
  343. package/dist/design/cookie-consent.js +26 -0
  344. package/dist/design/cookie-consent.js.map +1 -0
  345. package/dist/design/viewports.d.ts +18 -0
  346. package/dist/design/viewports.d.ts.map +1 -0
  347. package/dist/design/viewports.js +10 -0
  348. package/dist/design/viewports.js.map +1 -0
  349. package/dist/index.d.ts +2 -2
  350. package/dist/index.d.ts.map +1 -1
  351. package/dist/index.js +1 -1
  352. package/dist/index.js.map +1 -1
  353. package/dist/memory/store.d.ts +19 -1
  354. package/dist/memory/store.d.ts.map +1 -1
  355. package/dist/memory/store.js +47 -0
  356. package/dist/memory/store.js.map +1 -1
  357. package/dist/provider-defaults.d.ts +18 -0
  358. package/dist/provider-defaults.d.ts.map +1 -1
  359. package/dist/provider-defaults.js +33 -0
  360. package/dist/provider-defaults.js.map +1 -1
  361. package/dist/runner/allowed-domains.d.ts +11 -0
  362. package/dist/runner/allowed-domains.d.ts.map +1 -0
  363. package/dist/runner/allowed-domains.js +14 -0
  364. package/dist/runner/allowed-domains.js.map +1 -0
  365. package/dist/runner/batch-fill.d.ts +28 -0
  366. package/dist/runner/batch-fill.d.ts.map +1 -0
  367. package/dist/runner/batch-fill.js +80 -0
  368. package/dist/runner/batch-fill.js.map +1 -0
  369. package/dist/runner/completion-policy.d.ts +26 -0
  370. package/dist/runner/completion-policy.d.ts.map +1 -0
  371. package/dist/runner/completion-policy.js +76 -0
  372. package/dist/runner/completion-policy.js.map +1 -0
  373. package/dist/runner/constants.d.ts +14 -0
  374. package/dist/runner/constants.d.ts.map +1 -0
  375. package/dist/runner/constants.js +23 -0
  376. package/dist/runner/constants.js.map +1 -0
  377. package/dist/runner/decision-screenshot.d.ts +24 -0
  378. package/dist/runner/decision-screenshot.d.ts.map +1 -0
  379. package/dist/runner/decision-screenshot.js +23 -0
  380. package/dist/runner/decision-screenshot.js.map +1 -0
  381. package/dist/runner/domain-boundary.d.ts +36 -0
  382. package/dist/runner/domain-boundary.d.ts.map +1 -0
  383. package/dist/runner/domain-boundary.js +81 -0
  384. package/dist/runner/domain-boundary.js.map +1 -0
  385. package/dist/runner/effect-verify.d.ts +28 -0
  386. package/dist/runner/effect-verify.d.ts.map +1 -0
  387. package/dist/runner/effect-verify.js +42 -0
  388. package/dist/runner/effect-verify.js.map +1 -0
  389. package/dist/runner/execute-plan.d.ts +58 -0
  390. package/dist/runner/execute-plan.d.ts.map +1 -0
  391. package/dist/runner/execute-plan.js +426 -0
  392. package/dist/runner/execute-plan.js.map +1 -0
  393. package/dist/runner/max-turns-extension.d.ts +19 -0
  394. package/dist/runner/max-turns-extension.d.ts.map +1 -0
  395. package/dist/runner/max-turns-extension.js +25 -0
  396. package/dist/runner/max-turns-extension.js.map +1 -0
  397. package/dist/runner/micro-plan.d.ts +11 -0
  398. package/dist/runner/micro-plan.d.ts.map +1 -0
  399. package/dist/runner/micro-plan.js +29 -0
  400. package/dist/runner/micro-plan.js.map +1 -0
  401. package/dist/runner/prompt-snippets.d.ts +5 -0
  402. package/dist/runner/prompt-snippets.d.ts.map +1 -0
  403. package/dist/runner/prompt-snippets.js +13 -0
  404. package/dist/runner/prompt-snippets.js.map +1 -0
  405. package/dist/runner/replay/contracts.d.ts +300 -0
  406. package/dist/runner/replay/contracts.d.ts.map +1 -0
  407. package/dist/runner/replay/contracts.js +42 -0
  408. package/dist/runner/replay/contracts.js.map +1 -0
  409. package/dist/runner/replay/controller.d.ts +27 -0
  410. package/dist/runner/replay/controller.d.ts.map +1 -0
  411. package/dist/runner/replay/controller.js +197 -0
  412. package/dist/runner/replay/controller.js.map +1 -0
  413. package/dist/runner/replay/guard.d.ts +28 -0
  414. package/dist/runner/replay/guard.d.ts.map +1 -0
  415. package/dist/runner/replay/guard.js +100 -0
  416. package/dist/runner/replay/guard.js.map +1 -0
  417. package/dist/runner/runner.d.ts +44 -51
  418. package/dist/runner/runner.d.ts.map +1 -1
  419. package/dist/runner/runner.js +155 -851
  420. package/dist/runner/runner.js.map +1 -1
  421. package/dist/runner/scout-feedback.d.ts +51 -0
  422. package/dist/runner/scout-feedback.d.ts.map +1 -0
  423. package/dist/runner/scout-feedback.js +149 -0
  424. package/dist/runner/scout-feedback.js.map +1 -0
  425. package/dist/skills/macro-loader.d.ts +1 -1
  426. package/dist/test-runner.d.ts.map +1 -1
  427. package/dist/test-runner.js +25 -0
  428. package/dist/test-runner.js.map +1 -1
  429. package/dist/types/actions.d.ts +241 -0
  430. package/dist/types/actions.d.ts.map +1 -0
  431. package/dist/types/actions.js +5 -0
  432. package/dist/types/actions.js.map +1 -0
  433. package/dist/types/config.d.ts +211 -0
  434. package/dist/types/config.d.ts.map +1 -0
  435. package/dist/types/config.js +2 -0
  436. package/dist/types/config.js.map +1 -0
  437. package/dist/types/design-audit.d.ts +92 -0
  438. package/dist/types/design-audit.d.ts.map +1 -0
  439. package/dist/types/design-audit.js +5 -0
  440. package/dist/types/design-audit.js.map +1 -0
  441. package/dist/types/design-tokens.d.ts +138 -0
  442. package/dist/types/design-tokens.d.ts.map +1 -0
  443. package/dist/types/design-tokens.js +5 -0
  444. package/dist/types/design-tokens.js.map +1 -0
  445. package/dist/types/page.d.ts +16 -0
  446. package/dist/types/page.d.ts.map +1 -0
  447. package/dist/types/page.js +2 -0
  448. package/dist/types/page.js.map +1 -0
  449. package/dist/types/plan.d.ts +50 -0
  450. package/dist/types/plan.d.ts.map +1 -0
  451. package/dist/types/plan.js +2 -0
  452. package/dist/types/plan.js.map +1 -0
  453. package/dist/types/preview.d.ts +9 -0
  454. package/dist/types/preview.d.ts.map +1 -0
  455. package/dist/types/preview.js +5 -0
  456. package/dist/types/preview.js.map +1 -0
  457. package/dist/types/result.d.ts +62 -0
  458. package/dist/types/result.d.ts.map +1 -0
  459. package/dist/types/result.js +2 -0
  460. package/dist/types/result.js.map +1 -0
  461. package/dist/types/scenario.d.ts +20 -0
  462. package/dist/types/scenario.d.ts.map +1 -0
  463. package/dist/types/scenario.js +5 -0
  464. package/dist/types/scenario.js.map +1 -0
  465. package/dist/types/test-runner.d.ts +145 -0
  466. package/dist/types/test-runner.d.ts.map +1 -0
  467. package/dist/types/test-runner.js +10 -0
  468. package/dist/types/test-runner.js.map +1 -0
  469. package/dist/types/trajectory.d.ts +38 -0
  470. package/dist/types/trajectory.d.ts.map +1 -0
  471. package/dist/types/trajectory.js +2 -0
  472. package/dist/types/trajectory.js.map +1 -0
  473. package/dist/types/turn.d.ts +50 -0
  474. package/dist/types/turn.d.ts.map +1 -0
  475. package/dist/types/turn.js +2 -0
  476. package/dist/types/turn.js.map +1 -0
  477. package/dist/types.d.ts +16 -1017
  478. package/dist/types.d.ts.map +1 -1
  479. package/dist/types.js +15 -8
  480. package/dist/types.js.map +1 -1
  481. package/dist/wallet/rpc-interception.d.ts +15 -0
  482. package/dist/wallet/rpc-interception.d.ts.map +1 -0
  483. package/dist/wallet/rpc-interception.js +95 -0
  484. package/dist/wallet/rpc-interception.js.map +1 -0
  485. package/package.json +6 -2
@@ -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