@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.
Files changed (489) 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/browser-launch.d.ts +6 -0
  77. package/dist/browser-launch.d.ts.map +1 -1
  78. package/dist/browser-launch.js +3 -0
  79. package/dist/browser-launch.js.map +1 -1
  80. package/dist/cli/args.d.ts +141 -0
  81. package/dist/cli/args.d.ts.map +1 -0
  82. package/dist/cli/args.js +167 -0
  83. package/dist/cli/args.js.map +1 -0
  84. package/dist/cli/benchmark-sync.d.ts +9 -0
  85. package/dist/cli/benchmark-sync.d.ts.map +1 -0
  86. package/dist/cli/benchmark-sync.js +43 -0
  87. package/dist/cli/benchmark-sync.js.map +1 -0
  88. package/dist/cli/build-config.d.ts +11 -0
  89. package/dist/cli/build-config.d.ts.map +1 -0
  90. package/dist/cli/build-config.js +355 -0
  91. package/dist/cli/build-config.js.map +1 -0
  92. package/dist/cli/commands/auth.d.ts +3 -0
  93. package/dist/cli/commands/auth.d.ts.map +1 -0
  94. package/dist/cli/commands/auth.js +36 -0
  95. package/dist/cli/commands/auth.js.map +1 -0
  96. package/dist/cli/commands/chrome-debug.d.ts +7 -0
  97. package/dist/cli/commands/chrome-debug.d.ts.map +1 -0
  98. package/dist/cli/commands/chrome-debug.js +11 -0
  99. package/dist/cli/commands/chrome-debug.js.map +1 -0
  100. package/dist/cli/commands/design-audit.d.ts +3 -0
  101. package/dist/cli/commands/design-audit.d.ts.map +1 -0
  102. package/dist/cli/commands/design-audit.js +68 -0
  103. package/dist/cli/commands/design-audit.js.map +1 -0
  104. package/dist/cli/commands/preview.d.ts +14 -0
  105. package/dist/cli/commands/preview.d.ts.map +1 -0
  106. package/dist/cli/commands/preview.js +31 -0
  107. package/dist/cli/commands/preview.js.map +1 -0
  108. package/dist/cli/commands/run.d.ts +3 -0
  109. package/dist/cli/commands/run.d.ts.map +1 -0
  110. package/dist/cli/commands/run.js +740 -0
  111. package/dist/cli/commands/run.js.map +1 -0
  112. package/dist/cli/commands/runs.d.ts +8 -0
  113. package/dist/cli/commands/runs.d.ts.map +1 -0
  114. package/dist/cli/commands/runs.js +35 -0
  115. package/dist/cli/commands/runs.js.map +1 -0
  116. package/dist/cli/commands/share.d.ts +10 -0
  117. package/dist/cli/commands/share.d.ts.map +1 -0
  118. package/dist/cli/commands/share.js +32 -0
  119. package/dist/cli/commands/share.js.map +1 -0
  120. package/dist/cli/commands/showcase.d.ts +17 -0
  121. package/dist/cli/commands/showcase.d.ts.map +1 -0
  122. package/dist/cli/commands/showcase.js +20 -0
  123. package/dist/cli/commands/showcase.js.map +1 -0
  124. package/dist/cli/commands/snapshot.d.ts +12 -0
  125. package/dist/cli/commands/snapshot.d.ts.map +1 -0
  126. package/dist/cli/commands/snapshot.js +24 -0
  127. package/dist/cli/commands/snapshot.js.map +1 -0
  128. package/dist/cli/commands/view.d.ts +7 -0
  129. package/dist/cli/commands/view.d.ts.map +1 -0
  130. package/dist/cli/commands/view.js +23 -0
  131. package/dist/cli/commands/view.js.map +1 -0
  132. package/dist/cli/constants.d.ts +6 -0
  133. package/dist/cli/constants.d.ts.map +1 -0
  134. package/dist/cli/constants.js +3 -0
  135. package/dist/cli/constants.js.map +1 -0
  136. package/dist/cli/version.d.ts +7 -0
  137. package/dist/cli/version.d.ts.map +1 -0
  138. package/dist/cli/version.js +16 -0
  139. package/dist/cli/version.js.map +1 -0
  140. package/dist/cli-design-audit.d.ts +44 -36
  141. package/dist/cli-design-audit.d.ts.map +1 -1
  142. package/dist/cli-design-audit.js +137 -1646
  143. package/dist/cli-design-audit.js.map +1 -1
  144. package/dist/cli-jobs.js +2 -1
  145. package/dist/cli-jobs.js.map +1 -1
  146. package/dist/cli.js +66 -1697
  147. package/dist/cli.js.map +1 -1
  148. package/dist/config.d.ts +12 -0
  149. package/dist/config.d.ts.map +1 -1
  150. package/dist/config.js +20 -2
  151. package/dist/config.js.map +1 -1
  152. package/dist/design/audit/evolve/agent.d.ts +23 -0
  153. package/dist/design/audit/evolve/agent.d.ts.map +1 -0
  154. package/dist/design/audit/evolve/agent.js +273 -0
  155. package/dist/design/audit/evolve/agent.js.map +1 -0
  156. package/dist/design/audit/evolve/css.d.ts +10 -0
  157. package/dist/design/audit/evolve/css.d.ts.map +1 -0
  158. package/dist/design/audit/evolve/css.js +206 -0
  159. package/dist/design/audit/evolve/css.js.map +1 -0
  160. package/dist/design/audit/evolve/index.d.ts +13 -0
  161. package/dist/design/audit/evolve/index.d.ts.map +1 -0
  162. package/dist/design/audit/evolve/index.js +12 -0
  163. package/dist/design/audit/evolve/index.js.map +1 -0
  164. package/dist/design/audit/evolve/report.d.ts +3 -0
  165. package/dist/design/audit/evolve/report.d.ts.map +1 -0
  166. package/dist/design/audit/evolve/report.js +45 -0
  167. package/dist/design/audit/evolve/report.js.map +1 -0
  168. package/dist/design/audit/evolve/types.d.ts +14 -0
  169. package/dist/design/audit/evolve/types.d.ts.map +1 -0
  170. package/dist/design/audit/evolve/types.js +2 -0
  171. package/dist/design/audit/evolve/types.js.map +1 -0
  172. package/dist/design/audit/pipeline.d.ts +12 -0
  173. package/dist/design/audit/pipeline.d.ts.map +1 -1
  174. package/dist/design/audit/pipeline.js +43 -27
  175. package/dist/design/audit/pipeline.js.map +1 -1
  176. package/dist/design/audit/reference/artifact/build.d.ts +33 -0
  177. package/dist/design/audit/reference/artifact/build.d.ts.map +1 -0
  178. package/dist/design/audit/reference/artifact/build.js +64 -0
  179. package/dist/design/audit/reference/artifact/build.js.map +1 -0
  180. package/dist/design/audit/reference/artifact/render.d.ts +39 -0
  181. package/dist/design/audit/reference/artifact/render.d.ts.map +1 -0
  182. package/dist/design/audit/reference/artifact/render.js +213 -0
  183. package/dist/design/audit/reference/artifact/render.js.map +1 -0
  184. package/dist/design/audit/reference/artifact/text.d.ts +11 -0
  185. package/dist/design/audit/reference/artifact/text.d.ts.map +1 -0
  186. package/dist/design/audit/reference/artifact/text.js +20 -0
  187. package/dist/design/audit/reference/artifact/text.js.map +1 -0
  188. package/dist/design/audit/reference/artifact/to-findings.d.ts +57 -0
  189. package/dist/design/audit/reference/artifact/to-findings.d.ts.map +1 -0
  190. package/dist/design/audit/reference/artifact/to-findings.js +314 -0
  191. package/dist/design/audit/reference/artifact/to-findings.js.map +1 -0
  192. package/dist/design/audit/reference/config.d.ts +50 -0
  193. package/dist/design/audit/reference/config.d.ts.map +1 -0
  194. package/dist/design/audit/reference/config.js +108 -0
  195. package/dist/design/audit/reference/config.js.map +1 -0
  196. package/dist/design/audit/reference/contracts.d.ts +1030 -0
  197. package/dist/design/audit/reference/contracts.d.ts.map +1 -0
  198. package/dist/design/audit/reference/contracts.js +28 -0
  199. package/dist/design/audit/reference/contracts.js.map +1 -0
  200. package/dist/design/audit/reference/corpus/build.d.ts +115 -0
  201. package/dist/design/audit/reference/corpus/build.d.ts.map +1 -0
  202. package/dist/design/audit/reference/corpus/build.js +152 -0
  203. package/dist/design/audit/reference/corpus/build.js.map +1 -0
  204. package/dist/design/audit/reference/corpus/schema.d.ts +33 -0
  205. package/dist/design/audit/reference/corpus/schema.d.ts.map +1 -0
  206. package/dist/design/audit/reference/corpus/schema.js +249 -0
  207. package/dist/design/audit/reference/corpus/schema.js.map +1 -0
  208. package/dist/design/audit/reference/corpus/store.d.ts +26 -0
  209. package/dist/design/audit/reference/corpus/store.d.ts.map +1 -0
  210. package/dist/design/audit/reference/corpus/store.js +104 -0
  211. package/dist/design/audit/reference/corpus/store.js.map +1 -0
  212. package/dist/design/audit/reference/dna/delta.d.ts +21 -0
  213. package/dist/design/audit/reference/dna/delta.d.ts.map +1 -0
  214. package/dist/design/audit/reference/dna/delta.js +126 -0
  215. package/dist/design/audit/reference/dna/delta.js.map +1 -0
  216. package/dist/design/audit/reference/dna/derive.d.ts +31 -0
  217. package/dist/design/audit/reference/dna/derive.d.ts.map +1 -0
  218. package/dist/design/audit/reference/dna/derive.js +381 -0
  219. package/dist/design/audit/reference/dna/derive.js.map +1 -0
  220. package/dist/design/audit/reference/dna/descriptor.d.ts +36 -0
  221. package/dist/design/audit/reference/dna/descriptor.d.ts.map +1 -0
  222. package/dist/design/audit/reference/dna/descriptor.js +209 -0
  223. package/dist/design/audit/reference/dna/descriptor.js.map +1 -0
  224. package/dist/design/audit/reference/dna/page-adapter.d.ts +17 -0
  225. package/dist/design/audit/reference/dna/page-adapter.d.ts.map +1 -0
  226. package/dist/design/audit/reference/dna/page-adapter.js +35 -0
  227. package/dist/design/audit/reference/dna/page-adapter.js.map +1 -0
  228. package/dist/design/audit/reference/dna/scroll-capture.d.ts +93 -0
  229. package/dist/design/audit/reference/dna/scroll-capture.d.ts.map +1 -0
  230. package/dist/design/audit/reference/dna/scroll-capture.js +374 -0
  231. package/dist/design/audit/reference/dna/scroll-capture.js.map +1 -0
  232. package/dist/design/audit/reference/engine/budget.d.ts +63 -0
  233. package/dist/design/audit/reference/engine/budget.d.ts.map +1 -0
  234. package/dist/design/audit/reference/engine/budget.js +110 -0
  235. package/dist/design/audit/reference/engine/budget.js.map +1 -0
  236. package/dist/design/audit/reference/engine/core.d.ts +32 -0
  237. package/dist/design/audit/reference/engine/core.d.ts.map +1 -0
  238. package/dist/design/audit/reference/engine/core.js +261 -0
  239. package/dist/design/audit/reference/engine/core.js.map +1 -0
  240. package/dist/design/audit/reference/engine/guard.d.ts +43 -0
  241. package/dist/design/audit/reference/engine/guard.d.ts.map +1 -0
  242. package/dist/design/audit/reference/engine/guard.js +43 -0
  243. package/dist/design/audit/reference/engine/guard.js.map +1 -0
  244. package/dist/design/audit/reference/engine/score-core.d.ts +48 -0
  245. package/dist/design/audit/reference/engine/score-core.d.ts.map +1 -0
  246. package/dist/design/audit/reference/engine/score-core.js +134 -0
  247. package/dist/design/audit/reference/engine/score-core.js.map +1 -0
  248. package/dist/design/audit/reference/engine/wiring.d.ts +35 -0
  249. package/dist/design/audit/reference/engine/wiring.d.ts.map +1 -0
  250. package/dist/design/audit/reference/engine/wiring.js +80 -0
  251. package/dist/design/audit/reference/engine/wiring.js.map +1 -0
  252. package/dist/design/audit/reference/eval/taste-core.d.ts +77 -0
  253. package/dist/design/audit/reference/eval/taste-core.d.ts.map +1 -0
  254. package/dist/design/audit/reference/eval/taste-core.js +95 -0
  255. package/dist/design/audit/reference/eval/taste-core.js.map +1 -0
  256. package/dist/design/audit/reference/generate/generator.d.ts +49 -0
  257. package/dist/design/audit/reference/generate/generator.d.ts.map +1 -0
  258. package/dist/design/audit/reference/generate/generator.js +100 -0
  259. package/dist/design/audit/reference/generate/generator.js.map +1 -0
  260. package/dist/design/audit/reference/generate/parse.d.ts +28 -0
  261. package/dist/design/audit/reference/generate/parse.d.ts.map +1 -0
  262. package/dist/design/audit/reference/generate/parse.js +220 -0
  263. package/dist/design/audit/reference/generate/parse.js.map +1 -0
  264. package/dist/design/audit/reference/generate/prompt.d.ts +36 -0
  265. package/dist/design/audit/reference/generate/prompt.d.ts.map +1 -0
  266. package/dist/design/audit/reference/generate/prompt.js +172 -0
  267. package/dist/design/audit/reference/generate/prompt.js.map +1 -0
  268. package/dist/design/audit/reference/index.d.ts +26 -0
  269. package/dist/design/audit/reference/index.d.ts.map +1 -0
  270. package/dist/design/audit/reference/index.js +31 -0
  271. package/dist/design/audit/reference/index.js.map +1 -0
  272. package/dist/design/audit/reference/judge/image-clamp.d.ts +34 -0
  273. package/dist/design/audit/reference/judge/image-clamp.d.ts.map +1 -0
  274. package/dist/design/audit/reference/judge/image-clamp.js +88 -0
  275. package/dist/design/audit/reference/judge/image-clamp.js.map +1 -0
  276. package/dist/design/audit/reference/judge/pairwise.d.ts +34 -0
  277. package/dist/design/audit/reference/judge/pairwise.d.ts.map +1 -0
  278. package/dist/design/audit/reference/judge/pairwise.js +105 -0
  279. package/dist/design/audit/reference/judge/pairwise.js.map +1 -0
  280. package/dist/design/audit/reference/judge/parse.d.ts +31 -0
  281. package/dist/design/audit/reference/judge/parse.d.ts.map +1 -0
  282. package/dist/design/audit/reference/judge/parse.js +113 -0
  283. package/dist/design/audit/reference/judge/parse.js.map +1 -0
  284. package/dist/design/audit/reference/judge/prompt.d.ts +38 -0
  285. package/dist/design/audit/reference/judge/prompt.d.ts.map +1 -0
  286. package/dist/design/audit/reference/judge/prompt.js +123 -0
  287. package/dist/design/audit/reference/judge/prompt.js.map +1 -0
  288. package/dist/design/audit/reference/judge/quality.d.ts +28 -0
  289. package/dist/design/audit/reference/judge/quality.d.ts.map +1 -0
  290. package/dist/design/audit/reference/judge/quality.js +62 -0
  291. package/dist/design/audit/reference/judge/quality.js.map +1 -0
  292. package/dist/design/audit/reference/judge/rank.d.ts +41 -0
  293. package/dist/design/audit/reference/judge/rank.d.ts.map +1 -0
  294. package/dist/design/audit/reference/judge/rank.js +196 -0
  295. package/dist/design/audit/reference/judge/rank.js.map +1 -0
  296. package/dist/design/audit/reference/judge/text-judge.d.ts +31 -0
  297. package/dist/design/audit/reference/judge/text-judge.d.ts.map +1 -0
  298. package/dist/design/audit/reference/judge/text-judge.js +43 -0
  299. package/dist/design/audit/reference/judge/text-judge.js.map +1 -0
  300. package/dist/design/audit/reference/judge/vision-judge.d.ts +59 -0
  301. package/dist/design/audit/reference/judge/vision-judge.d.ts.map +1 -0
  302. package/dist/design/audit/reference/judge/vision-judge.js +150 -0
  303. package/dist/design/audit/reference/judge/vision-judge.js.map +1 -0
  304. package/dist/design/audit/reference/judge/vision-model.d.ts +65 -0
  305. package/dist/design/audit/reference/judge/vision-model.d.ts.map +1 -0
  306. package/dist/design/audit/reference/judge/vision-model.js +110 -0
  307. package/dist/design/audit/reference/judge/vision-model.js.map +1 -0
  308. package/dist/design/audit/reference/pipeline/evaluate-reference.d.ts +68 -0
  309. package/dist/design/audit/reference/pipeline/evaluate-reference.d.ts.map +1 -0
  310. package/dist/design/audit/reference/pipeline/evaluate-reference.js +52 -0
  311. package/dist/design/audit/reference/pipeline/evaluate-reference.js.map +1 -0
  312. package/dist/design/audit/reference/reference-context.d.ts +31 -0
  313. package/dist/design/audit/reference/reference-context.d.ts.map +1 -0
  314. package/dist/design/audit/reference/reference-context.js +73 -0
  315. package/dist/design/audit/reference/reference-context.js.map +1 -0
  316. package/dist/design/audit/reference/retrieval/embedding-hash.d.ts +30 -0
  317. package/dist/design/audit/reference/retrieval/embedding-hash.d.ts.map +1 -0
  318. package/dist/design/audit/reference/retrieval/embedding-hash.js +87 -0
  319. package/dist/design/audit/reference/retrieval/embedding-hash.js.map +1 -0
  320. package/dist/design/audit/reference/retrieval/embedding-openai.d.ts +38 -0
  321. package/dist/design/audit/reference/retrieval/embedding-openai.d.ts.map +1 -0
  322. package/dist/design/audit/reference/retrieval/embedding-openai.js +73 -0
  323. package/dist/design/audit/reference/retrieval/embedding-openai.js.map +1 -0
  324. package/dist/design/audit/reference/retrieval/matcher.d.ts +34 -0
  325. package/dist/design/audit/reference/retrieval/matcher.d.ts.map +1 -0
  326. package/dist/design/audit/reference/retrieval/matcher.js +107 -0
  327. package/dist/design/audit/reference/retrieval/matcher.js.map +1 -0
  328. package/dist/design/audit/reference/run.d.ts +59 -0
  329. package/dist/design/audit/reference/run.d.ts.map +1 -0
  330. package/dist/design/audit/reference/run.js +99 -0
  331. package/dist/design/audit/reference/run.js.map +1 -0
  332. package/dist/design/audit/report.d.ts +35 -0
  333. package/dist/design/audit/report.d.ts.map +1 -0
  334. package/dist/design/audit/report.js +195 -0
  335. package/dist/design/audit/report.js.map +1 -0
  336. package/dist/design/audit/tokens/extract.d.ts +71 -0
  337. package/dist/design/audit/tokens/extract.d.ts.map +1 -0
  338. package/dist/design/audit/tokens/extract.js +1034 -0
  339. package/dist/design/audit/tokens/extract.js.map +1 -0
  340. package/dist/design/audit/types.d.ts +8 -0
  341. package/dist/design/audit/types.d.ts.map +1 -1
  342. package/dist/design/compare.d.ts.map +1 -1
  343. package/dist/design/compare.js +2 -6
  344. package/dist/design/compare.js.map +1 -1
  345. package/dist/design/cookie-consent.d.ts +3 -0
  346. package/dist/design/cookie-consent.d.ts.map +1 -0
  347. package/dist/design/cookie-consent.js +26 -0
  348. package/dist/design/cookie-consent.js.map +1 -0
  349. package/dist/design/viewports.d.ts +18 -0
  350. package/dist/design/viewports.d.ts.map +1 -0
  351. package/dist/design/viewports.js +10 -0
  352. package/dist/design/viewports.js.map +1 -0
  353. package/dist/index.d.ts +2 -2
  354. package/dist/index.d.ts.map +1 -1
  355. package/dist/index.js +1 -1
  356. package/dist/index.js.map +1 -1
  357. package/dist/memory/store.d.ts +19 -1
  358. package/dist/memory/store.d.ts.map +1 -1
  359. package/dist/memory/store.js +47 -0
  360. package/dist/memory/store.js.map +1 -1
  361. package/dist/provider-defaults.d.ts +18 -0
  362. package/dist/provider-defaults.d.ts.map +1 -1
  363. package/dist/provider-defaults.js +33 -0
  364. package/dist/provider-defaults.js.map +1 -1
  365. package/dist/runner/allowed-domains.d.ts +11 -0
  366. package/dist/runner/allowed-domains.d.ts.map +1 -0
  367. package/dist/runner/allowed-domains.js +14 -0
  368. package/dist/runner/allowed-domains.js.map +1 -0
  369. package/dist/runner/batch-fill.d.ts +28 -0
  370. package/dist/runner/batch-fill.d.ts.map +1 -0
  371. package/dist/runner/batch-fill.js +80 -0
  372. package/dist/runner/batch-fill.js.map +1 -0
  373. package/dist/runner/completion-policy.d.ts +26 -0
  374. package/dist/runner/completion-policy.d.ts.map +1 -0
  375. package/dist/runner/completion-policy.js +76 -0
  376. package/dist/runner/completion-policy.js.map +1 -0
  377. package/dist/runner/constants.d.ts +14 -0
  378. package/dist/runner/constants.d.ts.map +1 -0
  379. package/dist/runner/constants.js +23 -0
  380. package/dist/runner/constants.js.map +1 -0
  381. package/dist/runner/decision-screenshot.d.ts +24 -0
  382. package/dist/runner/decision-screenshot.d.ts.map +1 -0
  383. package/dist/runner/decision-screenshot.js +23 -0
  384. package/dist/runner/decision-screenshot.js.map +1 -0
  385. package/dist/runner/domain-boundary.d.ts +36 -0
  386. package/dist/runner/domain-boundary.d.ts.map +1 -0
  387. package/dist/runner/domain-boundary.js +81 -0
  388. package/dist/runner/domain-boundary.js.map +1 -0
  389. package/dist/runner/effect-verify.d.ts +28 -0
  390. package/dist/runner/effect-verify.d.ts.map +1 -0
  391. package/dist/runner/effect-verify.js +42 -0
  392. package/dist/runner/effect-verify.js.map +1 -0
  393. package/dist/runner/execute-plan.d.ts +58 -0
  394. package/dist/runner/execute-plan.d.ts.map +1 -0
  395. package/dist/runner/execute-plan.js +426 -0
  396. package/dist/runner/execute-plan.js.map +1 -0
  397. package/dist/runner/max-turns-extension.d.ts +19 -0
  398. package/dist/runner/max-turns-extension.d.ts.map +1 -0
  399. package/dist/runner/max-turns-extension.js +25 -0
  400. package/dist/runner/max-turns-extension.js.map +1 -0
  401. package/dist/runner/micro-plan.d.ts +11 -0
  402. package/dist/runner/micro-plan.d.ts.map +1 -0
  403. package/dist/runner/micro-plan.js +29 -0
  404. package/dist/runner/micro-plan.js.map +1 -0
  405. package/dist/runner/prompt-snippets.d.ts +5 -0
  406. package/dist/runner/prompt-snippets.d.ts.map +1 -0
  407. package/dist/runner/prompt-snippets.js +13 -0
  408. package/dist/runner/prompt-snippets.js.map +1 -0
  409. package/dist/runner/replay/contracts.d.ts +300 -0
  410. package/dist/runner/replay/contracts.d.ts.map +1 -0
  411. package/dist/runner/replay/contracts.js +42 -0
  412. package/dist/runner/replay/contracts.js.map +1 -0
  413. package/dist/runner/replay/controller.d.ts +27 -0
  414. package/dist/runner/replay/controller.d.ts.map +1 -0
  415. package/dist/runner/replay/controller.js +197 -0
  416. package/dist/runner/replay/controller.js.map +1 -0
  417. package/dist/runner/replay/guard.d.ts +28 -0
  418. package/dist/runner/replay/guard.d.ts.map +1 -0
  419. package/dist/runner/replay/guard.js +100 -0
  420. package/dist/runner/replay/guard.js.map +1 -0
  421. package/dist/runner/runner.d.ts +44 -51
  422. package/dist/runner/runner.d.ts.map +1 -1
  423. package/dist/runner/runner.js +155 -851
  424. package/dist/runner/runner.js.map +1 -1
  425. package/dist/runner/scout-feedback.d.ts +51 -0
  426. package/dist/runner/scout-feedback.d.ts.map +1 -0
  427. package/dist/runner/scout-feedback.js +149 -0
  428. package/dist/runner/scout-feedback.js.map +1 -0
  429. package/dist/skills/macro-loader.d.ts +1 -1
  430. package/dist/test-runner.d.ts.map +1 -1
  431. package/dist/test-runner.js +27 -1
  432. package/dist/test-runner.js.map +1 -1
  433. package/dist/types/actions.d.ts +241 -0
  434. package/dist/types/actions.d.ts.map +1 -0
  435. package/dist/types/actions.js +5 -0
  436. package/dist/types/actions.js.map +1 -0
  437. package/dist/types/config.d.ts +211 -0
  438. package/dist/types/config.d.ts.map +1 -0
  439. package/dist/types/config.js +2 -0
  440. package/dist/types/config.js.map +1 -0
  441. package/dist/types/design-audit.d.ts +92 -0
  442. package/dist/types/design-audit.d.ts.map +1 -0
  443. package/dist/types/design-audit.js +5 -0
  444. package/dist/types/design-audit.js.map +1 -0
  445. package/dist/types/design-tokens.d.ts +138 -0
  446. package/dist/types/design-tokens.d.ts.map +1 -0
  447. package/dist/types/design-tokens.js +5 -0
  448. package/dist/types/design-tokens.js.map +1 -0
  449. package/dist/types/page.d.ts +16 -0
  450. package/dist/types/page.d.ts.map +1 -0
  451. package/dist/types/page.js +2 -0
  452. package/dist/types/page.js.map +1 -0
  453. package/dist/types/plan.d.ts +50 -0
  454. package/dist/types/plan.d.ts.map +1 -0
  455. package/dist/types/plan.js +2 -0
  456. package/dist/types/plan.js.map +1 -0
  457. package/dist/types/preview.d.ts +9 -0
  458. package/dist/types/preview.d.ts.map +1 -0
  459. package/dist/types/preview.js +5 -0
  460. package/dist/types/preview.js.map +1 -0
  461. package/dist/types/result.d.ts +62 -0
  462. package/dist/types/result.d.ts.map +1 -0
  463. package/dist/types/result.js +2 -0
  464. package/dist/types/result.js.map +1 -0
  465. package/dist/types/scenario.d.ts +20 -0
  466. package/dist/types/scenario.d.ts.map +1 -0
  467. package/dist/types/scenario.js +5 -0
  468. package/dist/types/scenario.js.map +1 -0
  469. package/dist/types/test-runner.d.ts +145 -0
  470. package/dist/types/test-runner.d.ts.map +1 -0
  471. package/dist/types/test-runner.js +10 -0
  472. package/dist/types/test-runner.js.map +1 -0
  473. package/dist/types/trajectory.d.ts +38 -0
  474. package/dist/types/trajectory.d.ts.map +1 -0
  475. package/dist/types/trajectory.js +2 -0
  476. package/dist/types/trajectory.js.map +1 -0
  477. package/dist/types/turn.d.ts +50 -0
  478. package/dist/types/turn.d.ts.map +1 -0
  479. package/dist/types/turn.js +2 -0
  480. package/dist/types/turn.js.map +1 -0
  481. package/dist/types.d.ts +16 -1017
  482. package/dist/types.d.ts.map +1 -1
  483. package/dist/types.js +15 -8
  484. package/dist/types.js.map +1 -1
  485. package/dist/wallet/rpc-interception.d.ts +15 -0
  486. package/dist/wallet/rpc-interception.d.ts.map +1 -0
  487. package/dist/wallet/rpc-interception.js +95 -0
  488. package/dist/wallet/rpc-interception.js.map +1 -0
  489. package/package.json +23 -5
@@ -0,0 +1,740 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import { toAgentConfig } from '../../config.js';
4
+ import { buildBrowserLaunchPlan } from '../../browser-launch.js';
5
+ import { runWalletPreflight, startWalletAutoApprover } from '../../wallet/automation.js';
6
+ import { isPersonaId, listPersonaIds, withPersonaDirective } from '../../personas.js';
7
+ import { resolveProviderApiKey, resolveProviderModelName, resolveDefaultProvider } from '../../provider-defaults.js';
8
+ import { CliRenderer, cliError, cliWarn, cliLog } from '../../cli-ui.js';
9
+ import { ProjectStore } from '../../memory/project-store.js';
10
+ import { RunRegistry } from '../../memory/run-registry.js';
11
+ import { applyStorageStateToPersistentContext } from '../../browser/storage-state.js';
12
+ import { STEALTH_INIT_SCRIPT } from '../../browser/stealth-init-script.js';
13
+ import { installWalletRpcInterception } from '../../wallet/rpc-interception.js';
14
+ import { buildDriverConfig } from '../build-config.js';
15
+ import { readCliVersion } from '../version.js';
16
+ import { syncLocalBenchmarkRun } from '../benchmark-sync.js';
17
+ export async function runRunCommand(values) {
18
+ // Validate inputs
19
+ if (!values.goal && !values.cases && !values['cases-json'] && !values['resume-run'] && !values['fork-run']) {
20
+ cliError('provide --goal "..." --url "..." for a single task, --cases ./cases.json (or --cases-json \'[...]\') for a suite, or --resume-run / --fork-run <runId>.');
21
+ process.exit(1);
22
+ }
23
+ // Load config file, overlay CLI flags, apply presets.
24
+ const driverConfig = await buildDriverConfig(values);
25
+ const mode = values.mode;
26
+ const launchPlan = buildBrowserLaunchPlan(driverConfig);
27
+ const quiet = values.quiet;
28
+ for (const warning of launchPlan.warnings) {
29
+ if (!quiet) {
30
+ cliWarn(warning);
31
+ }
32
+ }
33
+ if (launchPlan.errors.length > 0) {
34
+ for (const error of launchPlan.errors) {
35
+ cliError(error);
36
+ }
37
+ process.exit(1);
38
+ }
39
+ // Dynamic imports keep startup fast. Prefer patchright for lower browser
40
+ // automation fingerprinting, falling back to regular Playwright.
41
+ const isStealthProfile = launchPlan.profile.includes('stealth');
42
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
43
+ let browserLib;
44
+ try {
45
+ browserLib = await import('patchright');
46
+ }
47
+ catch {
48
+ browserLib = await import('playwright');
49
+ }
50
+ const { chromium, firefox, webkit } = browserLib;
51
+ const { PlaywrightDriver } = await import('../../drivers/playwright.js');
52
+ const { TestRunner } = await import('../../test-runner.js');
53
+ const { FilesystemSink } = await import('../../artifacts/filesystem-sink.js');
54
+ const { loadExtensions } = await import('../../extensions/loader.js');
55
+ const { TurnEventBus } = await import('../../runner/events.js');
56
+ // Optional live event bus + SSE viewer. Constructed only when `--live` is
57
+ // passed; otherwise the runner uses an internal no-op bus and pays nothing.
58
+ // The bus is shared across the entire suite so a single SSE connection
59
+ // observes all turns of all test cases. When `--stream <url>` is passed
60
+ // the bus is always created so the webhook streamer can subscribe.
61
+ const liveEnabled = values.live === true;
62
+ const streamUrl = typeof values.stream === 'string' && values.stream.length > 0 ? values.stream : undefined;
63
+ const needsBus = liveEnabled || !!streamUrl;
64
+ const liveBus = needsBus ? new TurnEventBus() : undefined;
65
+ const liveCancelController = liveEnabled ? new AbortController() : undefined;
66
+ let liveViewHandle;
67
+ if (liveEnabled && liveBus) {
68
+ const { runLiveView } = await import('../../cli-view-live.js');
69
+ liveViewHandle = await runLiveView({
70
+ bus: liveBus,
71
+ ...(liveCancelController ? { cancelController: liveCancelController } : {}),
72
+ port: values.port ? parseInt(values.port, 10) : undefined,
73
+ noOpen: values['no-open'] === true,
74
+ });
75
+ }
76
+ // Webhook streamer. When `--stream <url>` is passed, subscribe
77
+ // to the bus and POST every event to <url> as it fires. Auth via
78
+ // `--stream-token` or $BAD_STREAM_TOKEN. Non-fatal on failure — the
79
+ // canonical record is always events.jsonl on disk.
80
+ let webhookStreamer;
81
+ if (streamUrl && liveBus) {
82
+ const { WebhookStreamer } = await import('../../runner/stream-webhook.js');
83
+ const token = values['stream-token'] || process.env.BAD_STREAM_TOKEN;
84
+ const streamId = `stream_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
85
+ webhookStreamer = new WebhookStreamer({
86
+ url: streamUrl,
87
+ authToken: token,
88
+ streamId,
89
+ onError: (err, dropped) => {
90
+ if (!values.json)
91
+ cliWarn(`stream: ${err.message} (dropped ${dropped} event${dropped === 1 ? '' : 's'})`);
92
+ },
93
+ }).attach(liveBus);
94
+ if (!values.json)
95
+ cliLog('stream', `POST → ${streamUrl} (id ${streamId})`);
96
+ }
97
+ // Interrupt controller. `--interrupt` enables keyboard pause/
98
+ // resume/abort during a run. No-op in non-TTY (CI, piped output).
99
+ let interruptController;
100
+ let detachInterrupt;
101
+ if (values.interrupt === true && process.stdin.isTTY) {
102
+ const { InterruptController } = await import('../../runner/interrupt-controller.js');
103
+ interruptController = new InterruptController({
104
+ onStatus: (msg) => { if (!values.json)
105
+ cliLog('interrupt', msg); },
106
+ });
107
+ detachInterrupt = interruptController.attach();
108
+ }
109
+ // Auto-discover bad.config.{ts,mjs,js,...} from cwd plus any explicit
110
+ // --extension paths. Failures are reported but never fatal: a broken user
111
+ // config should warn, not abort the run.
112
+ const explicitExtPaths = (values.extension ?? []);
113
+ const explicitExtArr = Array.isArray(explicitExtPaths)
114
+ ? explicitExtPaths
115
+ : explicitExtPaths
116
+ ? [explicitExtPaths]
117
+ : [];
118
+ // Domain skills: markdown-based per-host rule libraries under
119
+ // skills/domain/<host>/SKILL.md. They plumb into the same BadExtension
120
+ // pipeline as user `bad.config.mjs` files via addRulesForDomain, so the
121
+ // existing setExtensionRules injection at brain/index.ts:899 picks them up
122
+ // with no second injection site. Gated by BAD_DOMAIN_SKILLS_DISABLED=1.
123
+ const domainSkillsDisabled = process.env.BAD_DOMAIN_SKILLS_DISABLED === '1';
124
+ let domainSkillExtension;
125
+ let domainSkillsLoadedCount = 0;
126
+ if (!domainSkillsDisabled) {
127
+ const { loadDomainSkills, buildDomainSkillExtension } = await import('../../skills/domain-loader.js');
128
+ const domainLoad = await loadDomainSkills();
129
+ if (domainLoad.skills.length > 0) {
130
+ domainSkillExtension = buildDomainSkillExtension(domainLoad.skills);
131
+ domainSkillsLoadedCount = domainLoad.skills.length;
132
+ }
133
+ if (domainLoad.errors.length > 0 && !values.json) {
134
+ for (const err of domainLoad.errors) {
135
+ cliWarn(`domain-skill load failed: ${err.path} — ${err.error}`);
136
+ }
137
+ }
138
+ }
139
+ const extensionLoad = await loadExtensions({ explicitPaths: explicitExtArr });
140
+ if (extensionLoad.loadedFrom.length > 0 && !values.json) {
141
+ cliLog('extensions', `loaded ${extensionLoad.loadedFrom.length}: ${extensionLoad.loadedFrom.join(', ')}`);
142
+ }
143
+ if (extensionLoad.errors.length > 0 && !values.json) {
144
+ for (const err of extensionLoad.errors) {
145
+ cliWarn(`extension load failed: ${err.path} — ${err.error}`);
146
+ }
147
+ }
148
+ if (domainSkillExtension && domainSkillsLoadedCount > 0) {
149
+ // Re-resolve the bundle with the domain-skill synthetic extension
150
+ // merged in. Resolving twice is cheap (the list is short) and keeps
151
+ // domainSkillExtension from having to plumb through a separate wire.
152
+ const { resolveExtensions } = await import('../../extensions/types.js');
153
+ const combined = resolveExtensions([...extensionLoad.resolved.extensions, domainSkillExtension]);
154
+ extensionLoad.resolved = combined;
155
+ if (!values.json)
156
+ cliLog('skills', `domain: ${domainSkillsLoadedCount} loaded`);
157
+ }
158
+ // Macros. Loaded alongside domain skills; gated by BAD_MACROS_DISABLED=1.
159
+ // The registry is passed to PlaywrightDriver and its promptBlock to BrowserAgent.
160
+ const macrosDisabled = process.env.BAD_MACROS_DISABLED === '1';
161
+ let macroRegistry;
162
+ if (!macrosDisabled) {
163
+ const { loadMacros, buildMacroRegistry } = await import('../../skills/macro-loader.js');
164
+ const macroLoad = await loadMacros();
165
+ if (macroLoad.errors.length > 0 && !values.json) {
166
+ for (const err of macroLoad.errors) {
167
+ cliWarn(`macro load failed: ${err.path} — ${err.error}`);
168
+ }
169
+ }
170
+ if (macroLoad.macros.length > 0) {
171
+ macroRegistry = buildMacroRegistry(macroLoad.macros);
172
+ if (!values.json)
173
+ cliLog('skills', `macros: ${macroLoad.macros.length} loaded`);
174
+ }
175
+ }
176
+ const concurrency = launchPlan.concurrency;
177
+ const maxTurns = driverConfig.maxTurns ?? 30;
178
+ const screenshotInterval = driverConfig.screenshotInterval ?? 5;
179
+ const timeoutMs = driverConfig.timeoutMs ?? 600_000;
180
+ const browserName = driverConfig.browser ?? 'chromium';
181
+ const debug = values.debug;
182
+ const sinkDir = driverConfig.outputDir ?? './agent-results';
183
+ const resolvedProvider = driverConfig.provider || resolveDefaultProvider();
184
+ const resolvedApiKey = resolveProviderApiKey(resolvedProvider, driverConfig.apiKey);
185
+ const resolvedModel = resolveProviderModelName(resolvedProvider, driverConfig.model, {
186
+ sandboxBackendType: resolvedProvider === 'sandbox-backend' ? driverConfig.sandboxBackendType : undefined,
187
+ });
188
+ const resolvedNavProvider = driverConfig.navProvider || resolvedProvider;
189
+ const resolvedNavModel = driverConfig.navModel
190
+ ? resolveProviderModelName(resolvedNavProvider, driverConfig.navModel, {
191
+ sandboxBackendType: resolvedNavProvider === 'sandbox-backend' ? driverConfig.sandboxBackendType : undefined,
192
+ })
193
+ : undefined;
194
+ const resolvedSupervisorProvider = driverConfig.supervisor?.provider || resolvedProvider;
195
+ const resolvedSupervisorModel = resolveProviderModelName(resolvedSupervisorProvider, driverConfig.supervisor?.model || resolvedModel, {
196
+ sandboxBackendType: resolvedSupervisorProvider === 'sandbox-backend' ? driverConfig.sandboxBackendType : undefined,
197
+ });
198
+ const config = {
199
+ ...toAgentConfig(driverConfig),
200
+ model: resolvedModel,
201
+ ...(resolvedNavModel ? { navModel: resolvedNavModel } : {}),
202
+ apiKey: resolvedApiKey,
203
+ baseUrl: driverConfig.baseUrl || process.env.LLM_BASE_URL,
204
+ supervisor: driverConfig.supervisor
205
+ ? {
206
+ ...driverConfig.supervisor,
207
+ provider: resolvedSupervisorProvider,
208
+ model: resolvedSupervisorModel,
209
+ }
210
+ : undefined,
211
+ debug,
212
+ walletMode: Boolean(driverConfig.wallet?.enabled),
213
+ walletAddress: driverConfig.wallet?.address,
214
+ };
215
+ // Create project store for memory + run registry
216
+ const memoryEnabled = driverConfig.memory?.enabled === true;
217
+ const projectStore = memoryEnabled
218
+ ? new ProjectStore(driverConfig.memory?.dir)
219
+ : undefined;
220
+ const runRegistry = projectStore
221
+ ? new RunRegistry(projectStore.getRoot())
222
+ : undefined;
223
+ // Build test cases
224
+ let cases;
225
+ if (values['resume-run'] || values['fork-run']) {
226
+ // Resume or fork from a previous run
227
+ if (!runRegistry) {
228
+ cliError('--resume-run and --fork-run require memory to be enabled');
229
+ process.exit(1);
230
+ }
231
+ const isResume = Boolean(values['resume-run']);
232
+ const sourceRunId = (values['resume-run'] || values['fork-run']);
233
+ const scenario = isResume
234
+ ? runRegistry.buildResumeScenario(sourceRunId, values.goal)
235
+ : runRegistry.buildForkScenario(sourceRunId, values.goal || '');
236
+ if (!scenario) {
237
+ cliError(`run "${sourceRunId}" not found in registry`);
238
+ process.exit(1);
239
+ }
240
+ if (!isResume && !values.goal) {
241
+ cliError('--fork-run requires --goal');
242
+ process.exit(1);
243
+ }
244
+ cases = [{
245
+ id: `${isResume ? 'resume' : 'fork'}-${sourceRunId.slice(0, 20)}`,
246
+ name: scenario.goal.slice(0, 60),
247
+ startUrl: values.url || scenario.startUrl,
248
+ goal: scenario.goal,
249
+ allowedDomains: parseAllowedDomains(values['allowed-domains']),
250
+ maxTurns,
251
+ timeoutMs,
252
+ priority: 0,
253
+ sessionId: scenario.sessionId,
254
+ parentRunId: scenario.parentRunId,
255
+ }];
256
+ }
257
+ else if (values['cases-json'] || values.cases) {
258
+ const raw = values['cases-json'] || fs.readFileSync(path.resolve(values.cases), 'utf-8');
259
+ const parsed = JSON.parse(raw);
260
+ const rawCases = Array.isArray(parsed) ? parsed : [parsed];
261
+ // Ensure required fields — spread raw case first so explicit fields become defaults
262
+ cases = rawCases.map((c, i) => ({
263
+ id: c.id || `case-${i}`,
264
+ name: c.name || c.goal?.slice(0, 60) || `Case ${i}`,
265
+ startUrl: c.startUrl || c.url || values.url || '',
266
+ goal: c.goal || '',
267
+ allowedDomains: Array.isArray(c.allowedDomains)
268
+ ? c.allowedDomains.filter((domain) => typeof domain === 'string' && domain.length > 0)
269
+ : parseAllowedDomains(values['allowed-domains']),
270
+ maxTurns: c.maxTurns || maxTurns,
271
+ timeoutMs: c.timeoutMs || timeoutMs,
272
+ priority: c.priority ?? i,
273
+ }));
274
+ }
275
+ else {
276
+ cases = [{
277
+ id: 'cli-task',
278
+ name: values.goal.slice(0, 60),
279
+ startUrl: values.url || '',
280
+ goal: values.goal,
281
+ allowedDomains: parseAllowedDomains(values['allowed-domains']),
282
+ maxTurns,
283
+ timeoutMs,
284
+ priority: 0,
285
+ sessionId: values['session-id'],
286
+ }];
287
+ }
288
+ // Apply --session-id to all cases from file too
289
+ if (values['session-id'] && cases.length > 0 && cases[0].id !== 'cli-task') {
290
+ const sid = values['session-id'];
291
+ cases = cases.map(c => ({ ...c, sessionId: c.sessionId || sid }));
292
+ }
293
+ const persona = values.persona;
294
+ if (persona) {
295
+ if (!isPersonaId(persona)) {
296
+ cliError(`unknown persona "${persona}". Valid personas: ${listPersonaIds().join(', ')}`);
297
+ process.exit(1);
298
+ }
299
+ cases = cases.map((c) => ({
300
+ ...c,
301
+ goal: withPersonaDirective({
302
+ persona,
303
+ goal: c.goal,
304
+ startUrl: c.startUrl,
305
+ }),
306
+ }));
307
+ }
308
+ const renderer = (!quiet && !values.json) ? new CliRenderer({ debug }) : null;
309
+ if (renderer) {
310
+ const version = readCliVersion();
311
+ renderer.banner({
312
+ version,
313
+ provider: config.provider || resolveDefaultProvider(),
314
+ model: config.model,
315
+ browser: browserName,
316
+ testCount: cases.length,
317
+ concurrency,
318
+ mode: mode || undefined,
319
+ profile: driverConfig.profile,
320
+ adaptiveRouting: config.adaptiveModelRouting ? {
321
+ navProvider: config.navProvider || config.provider || resolveDefaultProvider(),
322
+ navModel: config.navModel || 'gpt-4.1-mini',
323
+ } : undefined,
324
+ outputDir: sinkDir,
325
+ });
326
+ }
327
+ // Set up artifact sink
328
+ const sink = new FilesystemSink(path.resolve(sinkDir));
329
+ const videoDir = path.join(sinkDir, '_videos');
330
+ const viewport = launchPlan.viewport;
331
+ const storageStatePath = driverConfig.storageState
332
+ ? path.resolve(driverConfig.storageState)
333
+ : undefined;
334
+ if (storageStatePath && !fs.existsSync(storageStatePath)) {
335
+ cliError(`storage state file not found: ${storageStatePath}`);
336
+ process.exit(1);
337
+ }
338
+ if (launchPlan.persistentContext && !launchPlan.cdpUrl && browserName !== 'chromium') {
339
+ const feature = launchPlan.walletMode ? 'Wallet mode' : '--profile-dir';
340
+ throw new Error(`${feature} requires Chromium. Set --browser chromium.`);
341
+ }
342
+ // Ensure clean exit on interrupt
343
+ process.on('SIGINT', () => { renderer?.destroy(); process.exit(130); });
344
+ process.on('SIGTERM', () => { renderer?.destroy(); process.exit(143); });
345
+ renderer?.launchStart(browserName);
346
+ // Set up browser
347
+ let browser;
348
+ let persistentContext;
349
+ let stopWalletAutoApprover;
350
+ const launchDiagnostics = {};
351
+ // CDP connection — attach to an existing browser (Atlas, Chrome, Brave, etc.)
352
+ let cdpUrl = launchPlan.cdpUrl || process.env.BROWSER_ENDPOINT;
353
+ let cdpConnected = false;
354
+ if (cdpUrl) {
355
+ // Auto-discover WebSocket URL from HTTP endpoint
356
+ if (cdpUrl.startsWith('http://') || cdpUrl.startsWith('https://')) {
357
+ try {
358
+ const versionUrl = cdpUrl.replace(/\/$/, '') + '/json/version';
359
+ const res = await fetch(versionUrl);
360
+ const info = await res.json();
361
+ if (info.webSocketDebuggerUrl) {
362
+ if (info.Browser && !quiet)
363
+ cliLog('cdp', `connected to ${info.Browser}`);
364
+ cdpUrl = info.webSocketDebuggerUrl;
365
+ }
366
+ }
367
+ catch {
368
+ // Fall through — try the URL as-is
369
+ }
370
+ }
371
+ const cdpStartedAt = Date.now();
372
+ if (cdpUrl.includes('/devtools/') || browserName === 'chromium') {
373
+ browser = await chromium.connectOverCDP(cdpUrl);
374
+ }
375
+ else {
376
+ const browserType = browserName === 'firefox' ? firefox : browserName === 'webkit' ? webkit : chromium;
377
+ browser = await browserType.connect(cdpUrl);
378
+ }
379
+ launchDiagnostics.browserLaunchMs = Date.now() - cdpStartedAt;
380
+ launchDiagnostics.cdpUrl = cdpUrl;
381
+ cdpConnected = true;
382
+ }
383
+ else if (launchPlan.persistentContext) {
384
+ for (const extensionPath of launchPlan.extensionPaths) {
385
+ if (!fs.existsSync(extensionPath)) {
386
+ throw new Error(`Wallet extension path does not exist: ${extensionPath}`);
387
+ }
388
+ }
389
+ const userDataDir = launchPlan.userDataDir ?? path.resolve(launchPlan.walletMode ? '.agent-wallet-profile' : '.agent-profile');
390
+ fs.mkdirSync(userDataDir, { recursive: true });
391
+ const persistentLaunchStartedAt = Date.now();
392
+ persistentContext = await chromium.launchPersistentContext(userDataDir, {
393
+ // An explicit Chromium binary (e.g. the sandbox's Nix Chromium via
394
+ // BAD_CHROMIUM_EXECUTABLE_PATH) overrides the Playwright-managed channel;
395
+ // Playwright ignores `channel` when `executablePath` is set.
396
+ ...(launchPlan.executablePath
397
+ ? { executablePath: launchPlan.executablePath }
398
+ : { channel: isStealthProfile ? 'chrome' : 'chromium' }),
399
+ headless: launchPlan.headless,
400
+ args: launchPlan.browserArgs,
401
+ viewport,
402
+ recordVideo: { dir: videoDir, size: viewport },
403
+ ...(launchPlan.proxyServer
404
+ ? { proxy: { server: launchPlan.proxyServer, ...(launchPlan.proxyBypass ? { bypass: launchPlan.proxyBypass } : {}) } }
405
+ : {}),
406
+ ...(launchPlan.ignoreHTTPSErrors ? { ignoreHTTPSErrors: true } : {}),
407
+ });
408
+ launchDiagnostics.browserLaunchMs = Date.now() - persistentLaunchStartedAt;
409
+ await applyStorageStateToPersistentContext(persistentContext, storageStatePath);
410
+ if (launchPlan.walletMode) {
411
+ const walletConfig = driverConfig.wallet ?? {};
412
+ // Intercept page-level JSON-RPC so dApps see wallet balances from the
413
+ // local Anvil fork. Only forward user-specific calls (eth_getBalance
414
+ // for the wallet, eth_call with wallet address in calldata). Pool data
415
+ // and protocol calls go to real endpoints for reliability.
416
+ const walletRpcUrl = walletConfig.preflight?.chain?.rpcUrl;
417
+ if (walletRpcUrl) {
418
+ await installWalletRpcInterception(persistentContext, {
419
+ rpcUrl: walletRpcUrl,
420
+ walletAddress: walletConfig.address,
421
+ });
422
+ }
423
+ const shouldAutoApprove = walletConfig.autoApprove ?? true;
424
+ if (shouldAutoApprove) {
425
+ stopWalletAutoApprover = await startWalletAutoApprover(persistentContext, {
426
+ password: walletConfig.password,
427
+ tickMs: walletConfig.tickMs,
428
+ actionSelectors: walletConfig.actionSelectors,
429
+ });
430
+ }
431
+ const preflightEnabled = walletConfig.preflight?.enabled ?? true;
432
+ const preflightSeedUrls = walletConfig.preflight?.seedUrls && walletConfig.preflight.seedUrls.length > 0
433
+ ? walletConfig.preflight.seedUrls
434
+ : [...new Set(cases.map((testCase) => testCase.startUrl).filter(Boolean))];
435
+ if (preflightEnabled && preflightSeedUrls.length > 0) {
436
+ const preflight = await runWalletPreflight(persistentContext, {
437
+ seedUrls: preflightSeedUrls,
438
+ password: walletConfig.password,
439
+ actionSelectors: walletConfig.actionSelectors,
440
+ promptPaths: walletConfig.promptPaths,
441
+ connectSelectors: walletConfig.connectSelectors,
442
+ connectorSelectors: walletConfig.connectorSelectors,
443
+ requestAccounts: walletConfig.preflight?.requestAccounts,
444
+ accountsTimeoutMs: walletConfig.preflight?.accountsTimeoutMs,
445
+ maxChainSwitchAttempts: walletConfig.preflight?.maxChainSwitchAttempts,
446
+ chain: walletConfig.preflight?.chain,
447
+ log: quiet ? undefined : (message) => cliLog('wallet', message),
448
+ });
449
+ if (!preflight.ok) {
450
+ const failed = preflight.results.find((resultEntry) => !resultEntry.ready);
451
+ const details = failed?.details ?? 'unknown reason';
452
+ throw new Error(`Wallet preflight failed for ${preflight.failedUrl ?? 'unknown origin'} (${details})`);
453
+ }
454
+ }
455
+ }
456
+ }
457
+ else {
458
+ const browserType = browserName === 'firefox'
459
+ ? firefox
460
+ : browserName === 'webkit'
461
+ ? webkit
462
+ : chromium;
463
+ const browserLaunchStartedAt = Date.now();
464
+ browser = await browserType.launch({
465
+ headless: launchPlan.headless,
466
+ ...(browserName === 'chromium' ? { args: launchPlan.browserArgs } : {}),
467
+ // An explicit Chromium binary (the sandbox's Nix Chromium via
468
+ // BAD_CHROMIUM_EXECUTABLE_PATH) takes precedence over the stealth
469
+ // system-Chrome channel; Playwright ignores `channel` alongside
470
+ // `executablePath`. Otherwise use system Chrome for stealth profiles only —
471
+ // real TLS/JA3 fingerprint fixes anti-bot blocking, but system Chrome
472
+ // renders differently than bundled Chromium on some sites (Allrecipes click
473
+ // timeouts, Amazon layout shifts), so only enable when evasion is needed.
474
+ ...(browserName === 'chromium' && launchPlan.executablePath
475
+ ? { executablePath: launchPlan.executablePath }
476
+ : isStealthProfile && browserName === 'chromium'
477
+ ? { channel: 'chrome' }
478
+ : {}),
479
+ // Residential/SOCKS5/HTTP proxy — routes all traffic through the proxy
480
+ ...(launchPlan.proxyServer
481
+ ? { proxy: { server: launchPlan.proxyServer, ...(launchPlan.proxyBypass ? { bypass: launchPlan.proxyBypass } : {}) } }
482
+ : {}),
483
+ });
484
+ launchDiagnostics.browserLaunchMs = Date.now() - browserLaunchStartedAt;
485
+ }
486
+ // Headless Chromium sends "HeadlessChrome/..." in the default User-Agent.
487
+ // CDNs like Akamai reject this with ERR_HTTP2_PROTOCOL_ERROR before any JS
488
+ // stealth patches can run. Build a clean UA from the browser version.
489
+ const headlessUserAgent = launchPlan.headless && browser
490
+ ? (() => {
491
+ const ver = browser.version();
492
+ const plat = process.platform;
493
+ const platformToken = plat === 'win32'
494
+ ? 'Windows NT 10.0; Win64; x64'
495
+ : plat === 'linux'
496
+ ? 'X11; Linux x86_64'
497
+ : 'Macintosh; Intel Mac OS X 10_15_7';
498
+ return `Mozilla/5.0 (${platformToken}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${ver} Safari/537.36`;
499
+ })()
500
+ : undefined;
501
+ const driverFactory = async () => {
502
+ const contextStartedAt = Date.now();
503
+ // CDP: reuse the browser's default context (preserves user cookies/sessions).
504
+ // Persistent context: use the already-opened persistent context.
505
+ // Default: create a fresh isolated context.
506
+ let context;
507
+ if (cdpConnected) {
508
+ // Reuse the user's existing browser context — cookies, localStorage, extensions intact
509
+ const contexts = browser.contexts();
510
+ // A freshly-created CDP context still honors egress; the reused contexts[0] is the user's own
511
+ // browser context (see the --cdp-url egress warning in buildBrowserLaunchPlan), left untouched.
512
+ context = contexts[0] ?? await browser.newContext({
513
+ viewport,
514
+ ...(launchPlan.ignoreHTTPSErrors ? { ignoreHTTPSErrors: true } : {}),
515
+ });
516
+ }
517
+ else if (persistentContext) {
518
+ context = persistentContext;
519
+ }
520
+ else {
521
+ context = await browser.newContext({
522
+ viewport,
523
+ recordVideo: { dir: videoDir, size: viewport },
524
+ storageState: storageStatePath,
525
+ locale: 'en-US',
526
+ timezoneId: 'America/New_York',
527
+ ...(headlessUserAgent ? { userAgent: headlessUserAgent } : {}),
528
+ // Accept the managed egress proxy's MITM cert (its CA isn't in Chromium's trust store).
529
+ ...(launchPlan.ignoreHTTPSErrors ? { ignoreHTTPSErrors: true } : {}),
530
+ extraHTTPHeaders: {
531
+ 'Accept-Language': 'en-US,en;q=0.9',
532
+ },
533
+ });
534
+ }
535
+ // Stealth patches: only for Playwright-controlled contexts (not real user browsers)
536
+ if (!cdpConnected) {
537
+ await context.addInitScript(STEALTH_INIT_SCRIPT);
538
+ }
539
+ const contextCreateMs = Date.now() - contextStartedAt;
540
+ const pageStartedAt = Date.now();
541
+ const page = await context.newPage();
542
+ const pageCreateMs = Date.now() - pageStartedAt;
543
+ // Cap per-action timeout so one stuck click can't consume the whole case budget.
544
+ // Default 30s is fine for long runs; for short cases (120s) use at most 15s.
545
+ const actionTimeout = Math.min(30_000, Math.max(5_000, Math.floor(timeoutMs / 8)));
546
+ const driver = new PlaywrightDriver(page, {
547
+ captureScreenshots: config.vision,
548
+ screenshotQuality: 50,
549
+ disableCdp: driverConfig.disableCdp,
550
+ timeout: actionTimeout,
551
+ visionStrategy: config.visionStrategy,
552
+ screenshotInterval,
553
+ showCursor: values['show-cursor'],
554
+ ...(macroRegistry ? { macros: macroRegistry } : {}),
555
+ });
556
+ // Apply resource blocking if configured
557
+ const resourceBlockingStartedAt = Date.now();
558
+ if (driverConfig.resourceBlocking) {
559
+ await driver.setupResourceBlocking(driverConfig.resourceBlocking);
560
+ }
561
+ const resourceBlockingSetupMs = driverConfig.resourceBlocking
562
+ ? Date.now() - resourceBlockingStartedAt
563
+ : 0;
564
+ const diagnostics = {
565
+ browserName,
566
+ headless: launchPlan.headless,
567
+ walletMode: launchPlan.walletMode,
568
+ browserLaunchMs: Number(launchDiagnostics.browserLaunchMs ?? 0),
569
+ contextCreateMs,
570
+ pageCreateMs,
571
+ resourceBlockingSetupMs,
572
+ storageStateApplied: Boolean(storageStatePath) && !cdpConnected,
573
+ persistentContext: Boolean(persistentContext),
574
+ cdpConnected,
575
+ };
576
+ // Wrap in a Driver that properly tears down context on close
577
+ const wrappedDriver = {
578
+ observe: () => driver.observe(),
579
+ execute: (action) => driver.execute(action),
580
+ getPage: () => driver.getPage?.(),
581
+ screenshot: () => driver.screenshot(),
582
+ getDiagnostics: () => diagnostics,
583
+ async close() {
584
+ await driver.close().catch(() => { });
585
+ await page.close().catch(() => { });
586
+ if (!persistentContext && !cdpConnected) {
587
+ await context.close().catch(() => { });
588
+ }
589
+ },
590
+ };
591
+ return wrappedDriver;
592
+ };
593
+ // Create a single driver for sequential mode
594
+ let singleDriver;
595
+ if (concurrency <= 1) {
596
+ singleDriver = await driverFactory();
597
+ }
598
+ renderer?.launchDone();
599
+ const runner = new TestRunner({
600
+ config,
601
+ defaultTimeoutMs: timeoutMs,
602
+ driver: singleDriver,
603
+ driverFactory: concurrency > 1 ? driverFactory : undefined,
604
+ enableMemory: memoryEnabled,
605
+ trajectoryStorePath: driverConfig.memory?.dir,
606
+ projectStore,
607
+ concurrency,
608
+ screenshotInterval,
609
+ artifactSink: sink,
610
+ extensions: extensionLoad.resolved,
611
+ ...(macroRegistry ? { macroPromptBlock: macroRegistry.promptBlock } : {}),
612
+ ...(liveBus ? { eventBus: liveBus } : {}),
613
+ ...(interruptController
614
+ ? { beforeTurn: async () => { await interruptController.waitIfPaused(); } }
615
+ : {}),
616
+ onProgress: (event) => {
617
+ if (values.json) {
618
+ console.log(JSON.stringify(event));
619
+ return;
620
+ }
621
+ if (!renderer)
622
+ return;
623
+ switch (event.type) {
624
+ case 'suite:start':
625
+ renderer.suiteStart(event.totalTests);
626
+ break;
627
+ case 'test:start':
628
+ renderer.testStart(event.testId, event.testName);
629
+ break;
630
+ case 'test:turn':
631
+ renderer.testTurn(event.testId, event.turn, event.action, event.durationMs, event.modelUsed);
632
+ break;
633
+ case 'test:complete':
634
+ renderer.testComplete(event.testId, event.passed, event.verdict, event.turnsUsed, event.durationMs, event.estimatedCostUsd);
635
+ break;
636
+ case 'suite:complete':
637
+ renderer.suiteComplete(event.passed, event.failed, event.skipped, event.totalMs, event.totalCostUsd, event.manifestUri);
638
+ break;
639
+ }
640
+ },
641
+ });
642
+ let result;
643
+ let runError;
644
+ try {
645
+ // Wire interrupt controller. Pressing `q` aborts via the suite-level signal.
646
+ const interruptSignal = interruptController
647
+ ? (() => {
648
+ const ac = new AbortController();
649
+ interruptController.on('abort', () => ac.abort('interrupted by user'));
650
+ if (interruptController.isAborted)
651
+ ac.abort('interrupted by user');
652
+ return ac.signal;
653
+ })()
654
+ : undefined;
655
+ // If --live already provided a signal, merge both. Prefer the user
656
+ // interrupt signal so `q` wins even when --live is set.
657
+ const mergedSignal = interruptSignal ?? liveCancelController?.signal;
658
+ result = await runner.runSuite(cases, mergedSignal ? { signal: mergedSignal } : undefined);
659
+ // Write reports for each configured format
660
+ const { generateReport } = await import('../../test-report.js');
661
+ const reporters = driverConfig.reporters ?? ['json'];
662
+ const reportDir = path.resolve(sinkDir);
663
+ fs.mkdirSync(reportDir, { recursive: true });
664
+ const formatMeta = {
665
+ json: { ext: 'json', contentType: 'application/json' },
666
+ markdown: { ext: 'md', contentType: 'text/markdown' },
667
+ html: { ext: 'html', contentType: 'text/html' },
668
+ junit: { ext: 'xml', contentType: 'application/xml' },
669
+ };
670
+ for (const format of reporters) {
671
+ const meta = formatMeta[format];
672
+ if (!meta)
673
+ continue;
674
+ try {
675
+ const report = generateReport(result, { format, includeTurns: format === 'markdown' });
676
+ const reportPath = path.join(reportDir, `report.${meta.ext}`);
677
+ fs.writeFileSync(reportPath, report);
678
+ renderer?.report(reportPath);
679
+ }
680
+ catch {
681
+ // Report generation is best-effort
682
+ }
683
+ }
684
+ // Also write report to stdout if JSON mode
685
+ if (values.json && !quiet) {
686
+ console.log(JSON.stringify(result, null, 2));
687
+ }
688
+ }
689
+ catch (err) {
690
+ runError = err;
691
+ }
692
+ finally {
693
+ renderer?.destroy();
694
+ // Detach interrupt controller first so stdin leaves raw mode before
695
+ // shutdown logs are written.
696
+ if (detachInterrupt)
697
+ detachInterrupt();
698
+ // Flush and close the stream webhook so the final events (run-completed,
699
+ // suite-complete) reach the endpoint before the CLI exits.
700
+ if (webhookStreamer)
701
+ await webhookStreamer.close().catch(() => { });
702
+ await singleDriver?.close?.().catch(() => { });
703
+ stopWalletAutoApprover?.();
704
+ await persistentContext?.close().catch(() => { });
705
+ await browser?.close().catch(() => { });
706
+ }
707
+ if (runError) {
708
+ if (liveViewHandle) {
709
+ await liveViewHandle.close().catch(() => { });
710
+ }
711
+ throw runError;
712
+ }
713
+ const runLabel = values.cases
714
+ ? `${path.basename(values.cases)} · cli run`
715
+ : `${(values.goal || values['resume-run'] || values['fork-run'] || 'run').slice(0, 80)} · cli run`;
716
+ await syncLocalBenchmarkRun(path.resolve(sinkDir), runLabel);
717
+ // In --live mode, the user usually wants to scrub the final state in the
718
+ // viewer after the run finishes. Hold the process open until SIGINT and
719
+ // shut down the live server cleanly when the user hits Ctrl+C.
720
+ if (liveViewHandle) {
721
+ cliLog('live', `run complete — viewer at ${liveViewHandle.url} (Ctrl+C to exit)`);
722
+ await new Promise((resolve) => {
723
+ const onSigint = () => {
724
+ liveViewHandle.close().finally(() => resolve());
725
+ };
726
+ process.once('SIGINT', onSigint);
727
+ });
728
+ }
729
+ process.exit((result?.summary.failed ?? 1) > 0 ? 1 : 0);
730
+ }
731
+ function parseAllowedDomains(value) {
732
+ if (!value)
733
+ return undefined;
734
+ const domains = value
735
+ .split(',')
736
+ .map((entry) => entry.trim().toLowerCase())
737
+ .filter(Boolean);
738
+ return domains.length > 0 ? [...new Set(domains)] : undefined;
739
+ }
740
+ //# sourceMappingURL=run.js.map