autokap 1.0.6 → 1.0.8

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 (347) hide show
  1. package/assets/chrome/ios-statusbar-comparison-reference.jpg +0 -0
  2. package/assets/chrome/ios-statusbar-dark-reference.jpg +0 -0
  3. package/assets/chrome/ios-statusbar-light-reference.jpg +0 -0
  4. package/assets/cursors/macos.svg +4 -0
  5. package/assets/cursors/windows.svg +15 -0
  6. package/assets/devices/ipad-pro-11-m4.json +52 -0
  7. package/assets/devices/iphone-16-pro.json +53 -0
  8. package/assets/devices/macbook-air-13.json +45 -0
  9. package/assets/frames/MacBook Air 13.svg +242 -0
  10. package/assets/frames/Status bar - iPhone.png +0 -0
  11. Menu bar- iPad.png +0 -0
  12. package/assets/frames/iPad Pro M4 11_.png +0 -0
  13. package/assets/frames/iPhone 16 Pro.png +0 -0
  14. package/assets/icons/Cellular Connection.svg +3 -0
  15. package/assets/icons/Union.svg +6 -0
  16. package/assets/icons/Wifi.svg +3 -0
  17. package/assets/icons/battery.svg +5 -0
  18. package/assets/icons/battery_charging.svg +8 -0
  19. package/assets/skill/OPCODE-REFERENCE.md +607 -0
  20. package/assets/skill/README.md +39 -0
  21. package/assets/skill/SKILL.md +453 -468
  22. package/assets/skill/STUDIO-SKILL.md +476 -0
  23. package/assets/skill/references/examples.md +104 -0
  24. package/assets/skill/references/interactive-demo.md +225 -0
  25. package/assets/skill/references/mock-data.md +178 -0
  26. package/dist/abort.d.ts +5 -0
  27. package/dist/abort.js +44 -0
  28. package/dist/action-verifier.d.ts +29 -0
  29. package/dist/action-verifier.js +133 -0
  30. package/dist/agent-action-recovery.d.ts +45 -0
  31. package/dist/agent-action-recovery.js +370 -0
  32. package/dist/agent-message-utils.d.ts +21 -0
  33. package/dist/agent-message-utils.js +77 -0
  34. package/dist/agent-url-utils.d.ts +30 -0
  35. package/dist/agent-url-utils.js +138 -0
  36. package/dist/agent.d.ts +226 -0
  37. package/dist/agent.js +6666 -0
  38. package/dist/ak-tree.d.ts +39 -0
  39. package/dist/ak-tree.js +368 -0
  40. package/dist/alt-text.d.ts +26 -0
  41. package/dist/alt-text.js +55 -0
  42. package/dist/auth-capture.d.ts +17 -0
  43. package/dist/auth-capture.js +164 -0
  44. package/dist/benchmark.d.ts +59 -0
  45. package/dist/benchmark.js +135 -0
  46. package/dist/billing-operation-logging.d.ts +38 -0
  47. package/dist/billing-operation-logging.js +248 -0
  48. package/dist/browser-bar.d.ts +48 -0
  49. package/dist/browser-bar.js +284 -0
  50. package/dist/browser-pool.d.ts +7 -0
  51. package/dist/browser-pool.js +15 -5
  52. package/dist/browser-utils.d.ts +31 -0
  53. package/dist/browser-utils.js +97 -0
  54. package/dist/browser.d.ts +76 -1
  55. package/dist/browser.js +1657 -39
  56. package/dist/capture-alt-text.d.ts +12 -0
  57. package/dist/capture-alt-text.js +52 -0
  58. package/dist/capture-encryption.d.ts +10 -0
  59. package/dist/capture-encryption.js +41 -0
  60. package/dist/capture-language-preflight.d.ts +41 -0
  61. package/dist/capture-language-preflight.js +300 -0
  62. package/dist/capture-llm-page-identity.d.ts +15 -0
  63. package/dist/capture-llm-page-identity.js +128 -0
  64. package/dist/capture-model-resolution.d.ts +9 -0
  65. package/dist/capture-model-resolution.js +21 -0
  66. package/dist/capture-page-identity.d.ts +7 -0
  67. package/dist/capture-page-identity.js +352 -0
  68. package/dist/capture-preset-credentials.d.ts +62 -0
  69. package/dist/capture-preset-credentials.js +184 -0
  70. package/dist/capture-request-plan.d.ts +58 -0
  71. package/dist/capture-request-plan.js +264 -0
  72. package/dist/capture-run-optimizer.d.ts +139 -0
  73. package/dist/capture-run-optimizer.js +863 -0
  74. package/dist/capture-selector-memory.d.ts +31 -0
  75. package/dist/capture-selector-memory.js +345 -0
  76. package/dist/capture-session-profile-encryption.d.ts +2 -0
  77. package/dist/capture-session-profile-encryption.js +22 -0
  78. package/dist/capture-step-timeout.d.ts +10 -0
  79. package/dist/capture-step-timeout.js +30 -0
  80. package/dist/capture-strategy.d.ts +36 -0
  81. package/dist/capture-strategy.js +95 -0
  82. package/dist/capture-studio-sync.d.ts +23 -0
  83. package/dist/capture-studio-sync.js +172 -0
  84. package/dist/capture-surface-contract.d.ts +36 -0
  85. package/dist/capture-surface-contract.js +299 -0
  86. package/dist/capture-transition-engine.d.ts +28 -0
  87. package/dist/capture-transition-engine.js +292 -0
  88. package/dist/capture-variant-state.d.ts +56 -0
  89. package/dist/capture-variant-state.js +182 -0
  90. package/dist/capture-verification.d.ts +35 -0
  91. package/dist/capture-verification.js +95 -0
  92. package/dist/capture-viewport-lock.d.ts +48 -0
  93. package/dist/capture-viewport-lock.js +74 -0
  94. package/dist/circuit-breaker.d.ts +42 -0
  95. package/dist/circuit-breaker.js +119 -0
  96. package/dist/cli-config.d.ts +8 -1
  97. package/dist/cli-config.js +62 -6
  98. package/dist/cli-contract.d.ts +15 -0
  99. package/dist/cli-contract.js +167 -0
  100. package/dist/cli-runner-local.d.ts +12 -0
  101. package/dist/cli-runner-local.js +102 -0
  102. package/dist/cli-runner.d.ts +34 -0
  103. package/dist/cli-runner.js +433 -0
  104. package/dist/cli-utils.d.ts +0 -1
  105. package/dist/cli-utils.js +2 -5
  106. package/dist/cli.js +1005 -252
  107. package/dist/clip-orchestrator.d.ts +148 -0
  108. package/dist/clip-orchestrator.js +957 -0
  109. package/dist/clip-postprocess.d.ts +42 -0
  110. package/dist/clip-postprocess.js +201 -0
  111. package/dist/cookie-dismiss.d.ts +2 -0
  112. package/dist/cookie-dismiss.js +48 -13
  113. package/dist/cost-logging.d.ts +35 -0
  114. package/dist/cost-logging.js +242 -0
  115. package/dist/cost-resolution-monitor.d.ts +16 -0
  116. package/dist/cost-resolution-monitor.js +34 -0
  117. package/dist/credential-templates.d.ts +5 -0
  118. package/dist/credential-templates.js +60 -0
  119. package/dist/cursor-overlay-script.d.ts +6 -0
  120. package/dist/cursor-overlay-script.js +169 -0
  121. package/dist/dom-css-purger.d.ts +65 -0
  122. package/dist/dom-css-purger.js +333 -0
  123. package/dist/dom-font-inliner.d.ts +45 -0
  124. package/dist/dom-font-inliner.js +148 -0
  125. package/dist/dom-patch-resolver.d.ts +52 -0
  126. package/dist/dom-patch-resolver.js +242 -0
  127. package/dist/dom-serializer.d.ts +82 -0
  128. package/dist/dom-serializer.js +378 -0
  129. package/dist/element-capture.d.ts +13 -0
  130. package/dist/element-capture.js +522 -0
  131. package/dist/env-validation.d.ts +5 -0
  132. package/dist/env-validation.js +29 -0
  133. package/dist/execution-schema.d.ts +4423 -0
  134. package/dist/execution-schema.js +507 -0
  135. package/dist/execution-types.d.ts +886 -0
  136. package/dist/execution-types.js +65 -0
  137. package/dist/fonts-loader.d.ts +14 -0
  138. package/dist/fonts-loader.js +55 -0
  139. package/dist/hybrid-navigator.d.ts +138 -0
  140. package/dist/hybrid-navigator.js +468 -0
  141. package/dist/index.d.ts +18 -0
  142. package/dist/index.js +17 -0
  143. package/dist/legacy/agent-action-recovery.d.ts +45 -0
  144. package/dist/legacy/agent-action-recovery.js +370 -0
  145. package/dist/legacy/agent-message-utils.d.ts +21 -0
  146. package/dist/legacy/agent-message-utils.js +77 -0
  147. package/dist/legacy/agent-url-utils.d.ts +30 -0
  148. package/dist/legacy/agent-url-utils.js +138 -0
  149. package/dist/legacy/agent.d.ts +226 -0
  150. package/dist/legacy/agent.js +6666 -0
  151. package/dist/legacy/clip-orchestrator.d.ts +148 -0
  152. package/dist/legacy/clip-orchestrator.js +957 -0
  153. package/dist/legacy/credential-templates.d.ts +5 -0
  154. package/dist/legacy/credential-templates.js +60 -0
  155. package/dist/legacy/hybrid-navigator.d.ts +138 -0
  156. package/dist/legacy/hybrid-navigator.js +468 -0
  157. package/dist/legacy/llm-usage.d.ts +17 -0
  158. package/dist/legacy/llm-usage.js +45 -0
  159. package/dist/legacy/prompt-cache.d.ts +10 -0
  160. package/dist/legacy/prompt-cache.js +24 -0
  161. package/dist/legacy/prompts.d.ts +175 -0
  162. package/dist/legacy/prompts.js +1038 -0
  163. package/dist/legacy/tools.d.ts +4 -0
  164. package/dist/legacy/tools.js +216 -0
  165. package/dist/legacy/video-agent.d.ts +143 -0
  166. package/dist/legacy/video-agent.js +4788 -0
  167. package/dist/legacy/video-observation.d.ts +36 -0
  168. package/dist/legacy/video-observation.js +192 -0
  169. package/dist/legacy/video-planner.d.ts +12 -0
  170. package/dist/legacy/video-planner.js +501 -0
  171. package/dist/legacy/video-prompts.d.ts +37 -0
  172. package/dist/legacy/video-prompts.js +569 -0
  173. package/dist/legacy/video-tools.d.ts +3 -0
  174. package/dist/legacy/video-tools.js +59 -0
  175. package/dist/legacy/video-variant-state.d.ts +29 -0
  176. package/dist/legacy/video-variant-state.js +80 -0
  177. package/dist/legacy/vision-model.d.ts +17 -0
  178. package/dist/legacy/vision-model.js +74 -0
  179. package/dist/llm-healer.d.ts +63 -0
  180. package/dist/llm-healer.js +166 -0
  181. package/dist/llm-provider.d.ts +29 -0
  182. package/dist/llm-provider.js +80 -0
  183. package/dist/llm-usage.d.ts +17 -0
  184. package/dist/llm-usage.js +45 -0
  185. package/dist/logger.d.ts +6 -2
  186. package/dist/logger.js +15 -1
  187. package/dist/mockup-html.d.ts +119 -0
  188. package/dist/mockup-html.js +263 -0
  189. package/dist/mockup.d.ts +187 -0
  190. package/dist/mockup.js +869 -0
  191. package/dist/mouse-animation.d.ts +46 -0
  192. package/dist/mouse-animation.js +114 -0
  193. package/dist/opcode-actions.d.ts +42 -0
  194. package/dist/opcode-actions.js +511 -0
  195. package/dist/opcode-runner.d.ts +51 -0
  196. package/dist/opcode-runner.js +770 -0
  197. package/dist/openrouter-client.d.ts +40 -0
  198. package/dist/openrouter-client.js +16 -0
  199. package/dist/overlay-engine.d.ts +24 -0
  200. package/dist/overlay-engine.js +176 -0
  201. package/dist/overlay-utils.d.ts +14 -0
  202. package/dist/overlay-utils.js +13 -0
  203. package/dist/postcondition.d.ts +16 -0
  204. package/dist/postcondition.js +269 -0
  205. package/dist/posthog.d.ts +4 -0
  206. package/dist/posthog.js +26 -0
  207. package/dist/program-patcher.d.ts +25 -0
  208. package/dist/program-patcher.js +44 -0
  209. package/dist/prompt-cache.d.ts +10 -0
  210. package/dist/prompt-cache.js +24 -0
  211. package/dist/prompts.d.ts +175 -0
  212. package/dist/prompts.js +1038 -0
  213. package/dist/provider-config.d.ts +12 -0
  214. package/dist/provider-config.js +15 -0
  215. package/dist/recovery-chain.d.ts +37 -0
  216. package/dist/recovery-chain.js +350 -0
  217. package/dist/remote-browser.d.ts +215 -0
  218. package/dist/remote-browser.js +360 -0
  219. package/dist/safari-browser-bar.d.ts +15 -0
  220. package/dist/safari-browser-bar.js +95 -0
  221. package/dist/safari-toolbar-asset.d.ts +15 -0
  222. package/dist/safari-toolbar-asset.js +12 -0
  223. package/dist/security.d.ts +21 -0
  224. package/dist/security.js +608 -0
  225. package/dist/selector-resolver.d.ts +34 -0
  226. package/dist/selector-resolver.js +181 -0
  227. package/dist/semantic-resolver.d.ts +35 -0
  228. package/dist/semantic-resolver.js +161 -0
  229. package/dist/server-capture-runtime.d.ts +125 -0
  230. package/dist/server-capture-runtime.js +585 -0
  231. package/dist/server-credit-usage.d.ts +12 -0
  232. package/dist/server-credit-usage.js +41 -0
  233. package/dist/server-posthog.d.ts +2 -0
  234. package/dist/server-posthog.js +16 -0
  235. package/dist/server-project-webhooks.d.ts +59 -0
  236. package/dist/server-project-webhooks.js +123 -0
  237. package/dist/server-screenshot-watermark.d.ts +7 -0
  238. package/dist/server-screenshot-watermark.js +60 -0
  239. package/dist/session-profile.d.ts +86 -0
  240. package/dist/session-profile.js +1536 -0
  241. package/dist/sf-pro-fonts.d.ts +4 -0
  242. package/dist/sf-pro-fonts.js +7 -0
  243. package/dist/sf-pro-symbols.d.ts +1 -0
  244. package/dist/sf-pro-symbols.js +55 -0
  245. package/dist/skill-packaging.d.ts +28 -0
  246. package/dist/skill-packaging.js +169 -0
  247. package/dist/smart-wait.d.ts +27 -0
  248. package/dist/smart-wait.js +81 -0
  249. package/dist/status-bar-l10n.d.ts +14 -0
  250. package/dist/status-bar-l10n.js +177 -0
  251. package/dist/status-bar-render.d.ts +20 -0
  252. package/dist/status-bar-render.js +410 -0
  253. package/dist/status-bar.d.ts +53 -0
  254. package/dist/status-bar.js +620 -0
  255. package/dist/svg-browser-bar.d.ts +33 -0
  256. package/dist/svg-browser-bar.js +206 -0
  257. package/dist/svg-status-bar.d.ts +36 -0
  258. package/dist/svg-status-bar.js +597 -0
  259. package/dist/svg-text.d.ts +61 -0
  260. package/dist/svg-text.js +118 -0
  261. package/dist/tools.d.ts +4 -0
  262. package/dist/tools.js +216 -0
  263. package/dist/types.d.ts +240 -5
  264. package/dist/types.js +23 -1
  265. package/dist/v2/action-verifier.d.ts +29 -0
  266. package/dist/v2/action-verifier.js +133 -0
  267. package/dist/v2/alt-text.d.ts +26 -0
  268. package/dist/v2/alt-text.js +55 -0
  269. package/dist/v2/benchmark.d.ts +59 -0
  270. package/dist/v2/benchmark.js +135 -0
  271. package/dist/v2/capture-strategy.d.ts +30 -0
  272. package/dist/v2/capture-strategy.js +67 -0
  273. package/dist/v2/capture-verification.d.ts +35 -0
  274. package/dist/v2/capture-verification.js +95 -0
  275. package/dist/v2/circuit-breaker.d.ts +42 -0
  276. package/dist/v2/circuit-breaker.js +119 -0
  277. package/dist/v2/cli-runner-local.d.ts +11 -0
  278. package/dist/v2/cli-runner-local.js +91 -0
  279. package/dist/v2/cli-runner.d.ts +34 -0
  280. package/dist/v2/cli-runner.js +300 -0
  281. package/dist/v2/compiler-prompts.d.ts +27 -0
  282. package/dist/v2/compiler-prompts.js +123 -0
  283. package/dist/v2/compiler.d.ts +37 -0
  284. package/dist/v2/compiler.js +147 -0
  285. package/dist/v2/explorer.d.ts +41 -0
  286. package/dist/v2/explorer.js +56 -0
  287. package/dist/v2/index.d.ts +37 -0
  288. package/dist/v2/index.js +31 -0
  289. package/dist/v2/llm-healer.d.ts +62 -0
  290. package/dist/v2/llm-healer.js +166 -0
  291. package/dist/v2/llm-provider.d.ts +29 -0
  292. package/dist/v2/llm-provider.js +80 -0
  293. package/dist/v2/opcode-runner.d.ts +47 -0
  294. package/dist/v2/opcode-runner.js +634 -0
  295. package/dist/v2/overlay-engine.d.ts +24 -0
  296. package/dist/v2/overlay-engine.js +150 -0
  297. package/dist/v2/postcondition.d.ts +16 -0
  298. package/dist/v2/postcondition.js +249 -0
  299. package/dist/v2/program-patcher.d.ts +25 -0
  300. package/dist/v2/program-patcher.js +44 -0
  301. package/dist/v2/recovery-chain.d.ts +30 -0
  302. package/dist/v2/recovery-chain.js +368 -0
  303. package/dist/v2/schema.d.ts +2580 -0
  304. package/dist/v2/schema.js +295 -0
  305. package/dist/v2/selector-resolver.d.ts +34 -0
  306. package/dist/v2/selector-resolver.js +181 -0
  307. package/dist/v2/semantic-resolver.d.ts +35 -0
  308. package/dist/v2/semantic-resolver.js +161 -0
  309. package/dist/v2/smart-wait.d.ts +27 -0
  310. package/dist/v2/smart-wait.js +81 -0
  311. package/dist/v2/types.d.ts +444 -0
  312. package/dist/v2/types.js +19 -0
  313. package/dist/v2/web-playwright-local.d.ts +69 -0
  314. package/dist/v2/web-playwright-local.js +392 -0
  315. package/dist/version.d.ts +1 -0
  316. package/dist/version.js +5 -0
  317. package/dist/video-agent.d.ts +143 -0
  318. package/dist/video-agent.js +4788 -0
  319. package/dist/video-observation.d.ts +36 -0
  320. package/dist/video-observation.js +192 -0
  321. package/dist/video-planner.d.ts +12 -0
  322. package/dist/video-planner.js +501 -0
  323. package/dist/video-prompts.d.ts +37 -0
  324. package/dist/video-prompts.js +554 -0
  325. package/dist/video-tools.d.ts +3 -0
  326. package/dist/video-tools.js +59 -0
  327. package/dist/video-variant-state.d.ts +29 -0
  328. package/dist/video-variant-state.js +80 -0
  329. package/dist/vision-model.d.ts +17 -0
  330. package/dist/vision-model.js +74 -0
  331. package/dist/web-playwright-local.d.ts +126 -0
  332. package/dist/web-playwright-local.js +819 -0
  333. package/dist/ws-auth.d.ts +20 -0
  334. package/dist/ws-auth.js +70 -0
  335. package/dist/ws-broadcast.d.ts +34 -0
  336. package/dist/ws-broadcast.js +85 -0
  337. package/dist/ws-connection-limits.d.ts +12 -0
  338. package/dist/ws-connection-limits.js +44 -0
  339. package/dist/ws-handler-utils.d.ts +32 -0
  340. package/dist/ws-handler-utils.js +139 -0
  341. package/dist/ws-handler.d.ts +10 -0
  342. package/dist/ws-handler.js +1793 -0
  343. package/dist/ws-metrics-server.d.ts +9 -0
  344. package/dist/ws-metrics-server.js +31 -0
  345. package/dist/ws-server.d.ts +9 -0
  346. package/dist/ws-server.js +92 -0
  347. package/package.json +142 -71
@@ -0,0 +1,378 @@
1
+ /**
2
+ * DOM Serializer — AUT-121 Interactive Demos
3
+ *
4
+ * Pure functions that take a raw HTML snapshot from Playwright
5
+ * (`document.documentElement.outerHTML`) and produce a sanitized HTML string
6
+ * suitable for client-side replay by the demo player.
7
+ *
8
+ * Phase 1 responsibilities:
9
+ * - Strip every `<script>` element (security + we never replay JS)
10
+ * - Strip every `on*` event handler attribute
11
+ * - Strip cross-origin `<iframe>` elements (XSS surface)
12
+ * - Strip `<link rel="modulepreload">` and `<link rel="preload" as="script">`
13
+ * - Strip framework dev overlays (Next.js, Vite, Astro, Nuxt) — same set as
14
+ * `cookie-dismiss.ts`'s `DEV_TOOL_SELECTORS`, just removed instead of hidden
15
+ * - Collect every asset URL referenced from `<img src|srcset>`,
16
+ * `<source src|srcset>`, `<link rel="stylesheet" href>`. Phase 3 will
17
+ * resolve these via CAS — Phase 1 only records them for telemetry.
18
+ *
19
+ * Out of scope for Phase 1: PurgeCSS, font inlining, CSS `url(...)` extraction,
20
+ * Brotli. Those land in Phase 3.
21
+ */
22
+ import { parse, parseFragment, serialize, defaultTreeAdapter, } from 'parse5';
23
+ /**
24
+ * Selectors of dev tooling overlays we want to strip from captured DOMs.
25
+ * Mirrors the list in `cookie-dismiss.ts`. Each entry is matched as either
26
+ * a tag name (e.g. `nextjs-portal`) or an `#id` selector — anything more
27
+ * complex must be added by hand to {@link matchesDevSelector}.
28
+ */
29
+ const DEV_TOOL_TAGS = new Set([
30
+ 'nextjs-portal',
31
+ 'astro-dev-toolbar',
32
+ 'vite-error-overlay',
33
+ 'vite-plugin-checker-error-overlay',
34
+ 'nuxt-devtools',
35
+ 'nuxt-devtools-frame',
36
+ ]);
37
+ const DEV_TOOL_IDS = new Set([
38
+ '__next-build-watcher',
39
+ 'nuxt-devtools-anchor',
40
+ 'nuxt-devtools-container',
41
+ ]);
42
+ const DEV_TOOL_DATA_ATTRS = new Set([
43
+ 'data-next-badge-root',
44
+ ]);
45
+ /**
46
+ * Rewrite asset URLs (img/source/srcset, link rel=stylesheet) inside an HTML
47
+ * string using a `originalUrl → replacementUrl` map. URLs not in the map are
48
+ * left untouched. Used by Phase 3 to point captured DOMs at CAS-backed
49
+ * permanent URLs after asset extraction.
50
+ */
51
+ export function rewriteAssetUrls(html, replacements) {
52
+ if (replacements.size === 0)
53
+ return html;
54
+ const document = parse(html);
55
+ walk(document, (node) => {
56
+ if (!isElement(node))
57
+ return;
58
+ if (node.tagName === "img" || node.tagName === "source") {
59
+ replaceAttr(node, "src", replacements);
60
+ replaceSrcset(node, replacements);
61
+ }
62
+ else if (node.tagName === "link") {
63
+ const rel = (getAttr(node, "rel") ?? "").toLowerCase();
64
+ if (rel === "stylesheet") {
65
+ replaceAttr(node, "href", replacements);
66
+ }
67
+ }
68
+ });
69
+ return serialize(document);
70
+ }
71
+ function replaceAttr(element, name, replacements) {
72
+ for (const attr of element.attrs) {
73
+ if (attr.name === name) {
74
+ const replacement = replacements.get(attr.value);
75
+ if (replacement)
76
+ attr.value = replacement;
77
+ }
78
+ }
79
+ }
80
+ function replaceSrcset(element, replacements) {
81
+ for (const attr of element.attrs) {
82
+ if (attr.name !== "srcset")
83
+ continue;
84
+ const candidates = attr.value.split(",").map((entry) => entry.trim());
85
+ const next = candidates.map((entry) => {
86
+ const parts = entry.split(/\s+/);
87
+ const url = parts[0];
88
+ const replacement = replacements.get(url);
89
+ if (replacement) {
90
+ parts[0] = replacement;
91
+ return parts.join(" ");
92
+ }
93
+ return entry;
94
+ });
95
+ attr.value = next.join(", ");
96
+ }
97
+ }
98
+ /** Sanitize a raw DOM snapshot and return the cleaned HTML + asset manifest. */
99
+ export function sanitizeDom(raw) {
100
+ const document = parse(raw.html);
101
+ const result = walkAndSanitize(document, raw.baseUrl);
102
+ const html = serialize(document);
103
+ return {
104
+ html,
105
+ assetUrls: result.assetUrls,
106
+ htmlBytes: Buffer.byteLength(html, 'utf8'),
107
+ removed: result.removed,
108
+ neutralized: result.neutralized,
109
+ };
110
+ }
111
+ /**
112
+ * Sanitize a single subtree captured via `CAPTURE_FRAGMENT`. Same passes as
113
+ * {@link sanitizeDom} (strip scripts, on*, dev overlays, third-party iframes,
114
+ * neutralize anchors / forms, collect asset URLs) but operates on a fragment
115
+ * — no `<html>` / `<head>` / `<body>` shell. Phase 5 of AUT-121.
116
+ */
117
+ export function sanitizeFragment(raw) {
118
+ const fragment = parseFragment(raw.html);
119
+ const result = walkAndSanitize(fragment, raw.baseUrl);
120
+ const html = serialize(fragment);
121
+ return {
122
+ html,
123
+ assetUrls: result.assetUrls,
124
+ htmlBytes: Buffer.byteLength(html, 'utf8'),
125
+ removed: result.removed,
126
+ neutralized: result.neutralized,
127
+ };
128
+ }
129
+ function walkAndSanitize(root, baseUrl) {
130
+ const stats = {
131
+ scripts: 0,
132
+ eventHandlers: 0,
133
+ iframes: 0,
134
+ devOverlays: 0,
135
+ preloads: 0,
136
+ };
137
+ const neutralized = {
138
+ links: 0,
139
+ forms: 0,
140
+ };
141
+ const assetUrls = new Set();
142
+ const baseOrigin = safeOrigin(baseUrl);
143
+ walk(root, (node, parent) => {
144
+ if (!isElement(node))
145
+ return;
146
+ // 1. Drop scripts entirely
147
+ if (node.tagName === 'script') {
148
+ removeChild(parent, node);
149
+ stats.scripts += 1;
150
+ return;
151
+ }
152
+ // 2. Drop dev tool overlays entirely
153
+ if (matchesDevSelector(node)) {
154
+ removeChild(parent, node);
155
+ stats.devOverlays += 1;
156
+ return;
157
+ }
158
+ // 3. Drop cross-origin iframes
159
+ if (node.tagName === 'iframe') {
160
+ const src = getAttr(node, 'src');
161
+ if (src && !isSameOriginUrl(src, baseOrigin)) {
162
+ removeChild(parent, node);
163
+ stats.iframes += 1;
164
+ return;
165
+ }
166
+ }
167
+ // 4. Drop preload/modulepreload links pointing to scripts, and manifest links
168
+ if (node.tagName === 'link') {
169
+ const rel = (getAttr(node, 'rel') ?? '').toLowerCase();
170
+ const asAttr = (getAttr(node, 'as') ?? '').toLowerCase();
171
+ if (rel === 'modulepreload' || (rel === 'preload' && (asAttr === 'script' || asAttr === 'font'))) {
172
+ removeChild(parent, node);
173
+ stats.preloads += 1;
174
+ return;
175
+ }
176
+ // Drop manifest links — they reference app-specific JSON that won't
177
+ // exist when the captured HTML is served from the demo player.
178
+ if (rel === 'manifest') {
179
+ removeChild(parent, node);
180
+ stats.preloads += 1;
181
+ return;
182
+ }
183
+ // Stylesheet links contribute to the asset manifest
184
+ if (rel === 'stylesheet') {
185
+ const href = getAttr(node, 'href');
186
+ const absolute = absolutize(href, baseUrl);
187
+ if (absolute)
188
+ assetUrls.add(absolute);
189
+ }
190
+ }
191
+ // 5. Strip every on* attribute (case-insensitive)
192
+ const removed = stripEventHandlers(node);
193
+ stats.eventHandlers += removed;
194
+ // 6. Collect asset URLs from img/source
195
+ if (node.tagName === 'img' || node.tagName === 'source') {
196
+ const src = getAttr(node, 'src');
197
+ const absolute = absolutize(src, baseUrl);
198
+ if (absolute)
199
+ assetUrls.add(absolute);
200
+ const srcset = getAttr(node, 'srcset');
201
+ if (srcset) {
202
+ for (const candidate of parseSrcset(srcset)) {
203
+ const abs = absolutize(candidate, baseUrl);
204
+ if (abs)
205
+ assetUrls.add(abs);
206
+ }
207
+ }
208
+ }
209
+ // 7. Neutralize anchor navigation. We keep the visual styling (cursor,
210
+ // underline, etc.) but rewrite the href to a no-op so the iframe
211
+ // sandbox doesn't try to navigate to a route that doesn't exist.
212
+ // The original target is preserved in `data-ak-original-href` for
213
+ // debugging and possible Phase 5 "open in a new tab" behavior.
214
+ //
215
+ // In-page anchors (`#anything`) are left alone — they let the user
216
+ // scroll to a section within the same captured DOM.
217
+ if (node.tagName === 'a') {
218
+ const originalHref = getAttr(node, 'href');
219
+ if (originalHref !== undefined && !originalHref.startsWith('#')) {
220
+ rewriteAttr(node, 'href', '#');
221
+ setAttrIfMissing(node, 'data-ak-original-href', originalHref);
222
+ neutralized.links += 1;
223
+ }
224
+ // Strip target so even keyboard activation can't open new tabs.
225
+ removeAttr(node, 'target');
226
+ removeAttr(node, 'rel');
227
+ removeAttr(node, 'download');
228
+ }
229
+ // 8. Neutralize form submissions for the same reason.
230
+ if (node.tagName === 'form') {
231
+ const action = getAttr(node, 'action');
232
+ if (action !== undefined) {
233
+ rewriteAttr(node, 'action', '#');
234
+ setAttrIfMissing(node, 'data-ak-original-action', action);
235
+ neutralized.forms += 1;
236
+ }
237
+ removeAttr(node, 'target');
238
+ }
239
+ });
240
+ return {
241
+ assetUrls: Array.from(assetUrls),
242
+ removed: stats,
243
+ neutralized,
244
+ };
245
+ }
246
+ // ── Tree helpers ────────────────────────────────────────────────────
247
+ function isElement(node) {
248
+ return node.tagName !== undefined && node.attrs !== undefined;
249
+ }
250
+ function isParentNode(node) {
251
+ return Array.isArray(node.childNodes);
252
+ }
253
+ /**
254
+ * Depth-first walker. Visits each node BEFORE descending. The callback
255
+ * receives the node and its parent. Removed nodes are not descended into.
256
+ */
257
+ function walk(root, visit) {
258
+ const stack = [
259
+ { node: root, parent: null },
260
+ ];
261
+ while (stack.length > 0) {
262
+ const { node, parent } = stack.pop();
263
+ visit(node, parent);
264
+ // If the node was removed during visit, parentNode is cleared.
265
+ if (!isParentNode(node))
266
+ continue;
267
+ // Snapshot children since visit may mutate the live array on subsequent
268
+ // iterations. Iterate in reverse so popped order matches document order.
269
+ const children = [...node.childNodes];
270
+ for (let i = children.length - 1; i >= 0; i -= 1) {
271
+ stack.push({ node: children[i], parent: node });
272
+ }
273
+ }
274
+ }
275
+ function removeChild(parent, child) {
276
+ if (!parent)
277
+ return;
278
+ defaultTreeAdapter.detachNode(child);
279
+ }
280
+ function getAttr(element, name) {
281
+ for (const attr of element.attrs) {
282
+ if (attr.name === name)
283
+ return attr.value;
284
+ }
285
+ return undefined;
286
+ }
287
+ function rewriteAttr(element, name, value) {
288
+ for (const attr of element.attrs) {
289
+ if (attr.name === name) {
290
+ attr.value = value;
291
+ return;
292
+ }
293
+ }
294
+ element.attrs.push({ name, value });
295
+ }
296
+ function setAttrIfMissing(element, name, value) {
297
+ if (getAttr(element, name) === undefined) {
298
+ element.attrs.push({ name, value });
299
+ }
300
+ }
301
+ function removeAttr(element, name) {
302
+ for (let i = element.attrs.length - 1; i >= 0; i -= 1) {
303
+ if (element.attrs[i].name === name) {
304
+ element.attrs.splice(i, 1);
305
+ }
306
+ }
307
+ }
308
+ function stripEventHandlers(element) {
309
+ let removed = 0;
310
+ for (let i = element.attrs.length - 1; i >= 0; i -= 1) {
311
+ const attr = element.attrs[i];
312
+ if (attr.name.length > 2 && attr.name[0] === 'o' && attr.name[1] === 'n') {
313
+ element.attrs.splice(i, 1);
314
+ removed += 1;
315
+ }
316
+ }
317
+ return removed;
318
+ }
319
+ function matchesDevSelector(element) {
320
+ if (DEV_TOOL_TAGS.has(element.tagName))
321
+ return true;
322
+ const id = getAttr(element, 'id');
323
+ if (id && DEV_TOOL_IDS.has(id))
324
+ return true;
325
+ for (const dataAttr of DEV_TOOL_DATA_ATTRS) {
326
+ if (getAttr(element, dataAttr) !== undefined)
327
+ return true;
328
+ }
329
+ return false;
330
+ }
331
+ // ── URL helpers ─────────────────────────────────────────────────────
332
+ function safeOrigin(url) {
333
+ try {
334
+ return new URL(url).origin;
335
+ }
336
+ catch {
337
+ return null;
338
+ }
339
+ }
340
+ function isSameOriginUrl(value, baseOrigin) {
341
+ if (!baseOrigin)
342
+ return false;
343
+ if (value.startsWith('/') && !value.startsWith('//'))
344
+ return true;
345
+ if (!value.startsWith('http://') && !value.startsWith('https://') && !value.startsWith('//')) {
346
+ // relative URL — same origin
347
+ return true;
348
+ }
349
+ try {
350
+ return new URL(value, baseOrigin).origin === baseOrigin;
351
+ }
352
+ catch {
353
+ return false;
354
+ }
355
+ }
356
+ function absolutize(value, baseUrl) {
357
+ if (!value)
358
+ return null;
359
+ const trimmed = value.trim();
360
+ if (!trimmed)
361
+ return null;
362
+ if (trimmed.startsWith('data:') || trimmed.startsWith('blob:'))
363
+ return null;
364
+ try {
365
+ return new URL(trimmed, baseUrl).toString();
366
+ }
367
+ catch {
368
+ return null;
369
+ }
370
+ }
371
+ function parseSrcset(srcset) {
372
+ // srcset = "url1 1x, url2 2x" or "url1 480w, url2 800w"
373
+ return srcset
374
+ .split(',')
375
+ .map((entry) => entry.trim().split(/\s+/)[0])
376
+ .filter((url) => url.length > 0);
377
+ }
378
+ //# sourceMappingURL=dom-serializer.js.map
@@ -0,0 +1,13 @@
1
+ import { Browser } from './browser.js';
2
+ import type { IsolatedElement, ElementCaptureResult, OutscaleConfig } from './types.js';
3
+ export declare function isLooseElementCaptureRejectionReason(reason: string | null | undefined): boolean;
4
+ export declare function outscaleAddsPadding(outscale: OutscaleConfig | undefined): boolean;
5
+ export declare function buildVerificationOutscale(outscale: OutscaleConfig | undefined): OutscaleConfig;
6
+ interface ElementCaptureOptions {
7
+ abortSignal?: AbortSignal;
8
+ distinctId?: string;
9
+ fallbackModel?: string;
10
+ uploadImage?: (buffer: Buffer, mimeType: 'image/jpeg' | 'image/png') => Promise<string>;
11
+ }
12
+ export declare function captureIsolatedElement(browser: Browser, element: IsolatedElement, apiKey: string, model: string, options?: ElementCaptureOptions): Promise<ElementCaptureResult>;
13
+ export {};