@tangle-network/browser-agent-driver 0.21.0 → 0.23.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 (58) hide show
  1. package/dist/brain/index.d.ts +21 -0
  2. package/dist/brain/index.d.ts.map +1 -1
  3. package/dist/brain/index.js +462 -34
  4. package/dist/brain/index.js.map +1 -1
  5. package/dist/browser-launch.d.ts +2 -0
  6. package/dist/browser-launch.d.ts.map +1 -1
  7. package/dist/browser-launch.js +12 -5
  8. package/dist/browser-launch.js.map +1 -1
  9. package/dist/captcha.d.ts +0 -7
  10. package/dist/captcha.d.ts.map +1 -1
  11. package/dist/captcha.js +113 -4
  12. package/dist/captcha.js.map +1 -1
  13. package/dist/cli.js +69 -13
  14. package/dist/cli.js.map +1 -1
  15. package/dist/config.d.ts +9 -0
  16. package/dist/config.d.ts.map +1 -1
  17. package/dist/config.js +2 -0
  18. package/dist/config.js.map +1 -1
  19. package/dist/drivers/cursor-overlay.d.ts +1 -1
  20. package/dist/drivers/cursor-overlay.d.ts.map +1 -1
  21. package/dist/drivers/cursor-overlay.js +21 -9
  22. package/dist/drivers/cursor-overlay.js.map +1 -1
  23. package/dist/drivers/extract-with-index.d.ts +45 -0
  24. package/dist/drivers/extract-with-index.d.ts.map +1 -0
  25. package/dist/drivers/extract-with-index.js +141 -0
  26. package/dist/drivers/extract-with-index.js.map +1 -0
  27. package/dist/drivers/playwright.d.ts +7 -0
  28. package/dist/drivers/playwright.d.ts.map +1 -1
  29. package/dist/drivers/playwright.js +232 -1
  30. package/dist/drivers/playwright.js.map +1 -1
  31. package/dist/drivers/som-overlay.d.ts +36 -0
  32. package/dist/drivers/som-overlay.d.ts.map +1 -0
  33. package/dist/drivers/som-overlay.js +109 -0
  34. package/dist/drivers/som-overlay.js.map +1 -0
  35. package/dist/drivers/types.d.ts +2 -0
  36. package/dist/drivers/types.d.ts.map +1 -1
  37. package/dist/recovery.d.ts.map +1 -1
  38. package/dist/recovery.js +2 -0
  39. package/dist/recovery.js.map +1 -1
  40. package/dist/run-state.d.ts +27 -1
  41. package/dist/run-state.d.ts.map +1 -1
  42. package/dist/run-state.js +40 -1
  43. package/dist/run-state.js.map +1 -1
  44. package/dist/runner/runner.d.ts +21 -0
  45. package/dist/runner/runner.d.ts.map +1 -1
  46. package/dist/runner/runner.js +282 -14
  47. package/dist/runner/runner.js.map +1 -1
  48. package/dist/supervisor/critic.d.ts.map +1 -1
  49. package/dist/supervisor/critic.js +1 -0
  50. package/dist/supervisor/critic.js.map +1 -1
  51. package/dist/supervisor/policy.js +10 -0
  52. package/dist/supervisor/policy.js.map +1 -1
  53. package/dist/test-runner.d.ts.map +1 -1
  54. package/dist/test-runner.js +8 -3
  55. package/dist/test-runner.js.map +1 -1
  56. package/dist/types.d.ts +70 -1
  57. package/dist/types.d.ts.map +1 -1
  58. package/package.json +3 -1
@@ -17,5 +17,5 @@
17
17
  * The init script that runs in every page. Returned as a string so it can be
18
18
  * passed to `page.addInitScript`. Pure DOM/CSS — no dependencies.
19
19
  */
20
- export declare const CURSOR_OVERLAY_INIT_SCRIPT = "\n(() => {\n if (window.__bad_overlay_installed) return;\n window.__bad_overlay_installed = true;\n\n const NS = 'http://www.w3.org/2000/svg';\n const Z = 2147483647; // max i32\n\n // \u2500\u2500 Root container (absolute, ignores pointer events) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const root = document.createElement('div');\n root.id = '__bad_overlay_root';\n Object.assign(root.style, {\n position: 'fixed',\n inset: '0',\n width: '100vw',\n height: '100vh',\n pointerEvents: 'none',\n zIndex: String(Z),\n });\n\n // \u2500\u2500 Cursor sprite (SVG arrow) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const cursor = document.createElementNS(NS, 'svg');\n cursor.setAttribute('width', '24');\n cursor.setAttribute('height', '24');\n cursor.setAttribute('viewBox', '0 0 24 24');\n cursor.setAttribute('fill', 'none');\n Object.assign(cursor.style, {\n position: 'fixed',\n left: '0',\n top: '0',\n transform: 'translate(-100px, -100px)',\n transition: 'transform 220ms cubic-bezier(0.22, 1, 0.36, 1)',\n pointerEvents: 'none',\n filter: 'drop-shadow(0 1px 2px rgba(0,0,0,0.4))',\n });\n cursor.innerHTML = `\n <path d=\"M3 2 L21 12 L13 14 L9 22 Z\" fill=\"#ffffff\" stroke=\"#0b1220\" stroke-width=\"1.5\" stroke-linejoin=\"round\"/>\n `;\n\n // \u2500\u2500 Pulse ring (animated on click) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const ring = document.createElement('div');\n Object.assign(ring.style, {\n position: 'fixed',\n left: '0',\n top: '0',\n width: '0',\n height: '0',\n borderRadius: '9999px',\n border: '3px solid rgba(79, 70, 229, 0.95)',\n transform: 'translate(-100px, -100px)',\n pointerEvents: 'none',\n opacity: '0',\n transition: 'all 500ms ease-out',\n });\n\n // \u2500\u2500 Highlight box (drawn around the target element) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const box = document.createElement('div');\n box.id = '__bad_overlay_box';\n Object.assign(box.style, {\n position: 'fixed',\n left: '0',\n top: '0',\n width: '0',\n height: '0',\n border: '2px solid rgba(34, 197, 94, 0.95)',\n borderRadius: '6px',\n background: 'rgba(34, 197, 94, 0.08)',\n boxShadow: '0 0 0 4px rgba(34, 197, 94, 0.18)',\n transform: 'translate(-100px, -100px)',\n pointerEvents: 'none',\n transition: 'all 180ms ease-out',\n opacity: '0',\n });\n\n // \u2500\u2500 Action label (shows \"click\" / \"type\" / etc next to cursor) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const label = document.createElement('div');\n Object.assign(label.style, {\n position: 'fixed',\n left: '0',\n top: '0',\n padding: '4px 10px',\n background: 'rgba(11, 18, 32, 0.92)',\n color: '#ffffff',\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n fontSize: '12px',\n fontWeight: '600',\n borderRadius: '6px',\n transform: 'translate(-200px, -200px)',\n pointerEvents: 'none',\n opacity: '0',\n transition: 'all 220ms cubic-bezier(0.22, 1, 0.36, 1)',\n boxShadow: '0 4px 12px rgba(0,0,0,0.3)',\n whiteSpace: 'nowrap',\n });\n\n // Append to documentElement (not body) so the overlay is not affected by\n // body's stacking context \u2014 many modern sites apply transform/will-change\n // to body which would clip a max-z-index child appended to body.\n // Bound the retry loop so a body-less doc (XML, PDF viewer, chrome://)\n // doesn't spin requestAnimationFrame forever.\n let attachAttempts = 0;\n function attach() {\n const host = document.documentElement || document.body;\n if (!host) {\n if (++attachAttempts > 60) return; // ~1 second of attempts\n requestAnimationFrame(attach);\n return;\n }\n host.appendChild(root);\n root.appendChild(box);\n root.appendChild(ring);\n root.appendChild(cursor);\n root.appendChild(label);\n }\n attach();\n\n // \u2500\u2500 Public API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n window.__bad_overlay = {\n /**\n * Highlight a target element by CSS selector. Returns the rect or null.\n * Used when the caller has a stable CSS selector.\n */\n highlight(selector) {\n try {\n const el = typeof selector === 'string'\n ? document.querySelector(selector)\n : null;\n if (!el) return null;\n const rect = el.getBoundingClientRect();\n if (rect.width === 0 || rect.height === 0) return null;\n Object.assign(box.style, {\n width: rect.width + 'px',\n height: rect.height + 'px',\n transform: `translate(${rect.left}px, ${rect.top}px)`,\n opacity: '1',\n });\n return { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2, width: rect.width, height: rect.height };\n } catch { return null; }\n },\n\n /**\n * Highlight an arbitrary rect at given page coordinates. Used when the\n * caller already computed the rect via Playwright's boundingBox (i.e.,\n * the @ref selector isn't a real CSS selector).\n */\n highlightRect(x, y, width, height) {\n try {\n Object.assign(box.style, {\n width: width + 'px',\n height: height + 'px',\n transform: `translate(${x}px, ${y}px)`,\n opacity: '1',\n });\n } catch { /* never let cosmetic overlay break a run */ }\n },\n\n /**\n * Move the cursor to (x, y) and show a label.\n */\n moveTo(x, y, labelText) {\n cursor.style.transform = `translate(${x - 4}px, ${y - 4}px)`;\n if (labelText) {\n label.textContent = labelText;\n Object.assign(label.style, {\n transform: `translate(${x + 16}px, ${y + 16}px)`,\n opacity: '1',\n });\n }\n },\n\n /**\n * Pulse a click ring at (x, y).\n */\n pulseClick(x, y) {\n // reset\n Object.assign(ring.style, {\n width: '0',\n height: '0',\n transform: `translate(${x}px, ${y}px)`,\n opacity: '1',\n });\n // expand\n requestAnimationFrame(() => {\n Object.assign(ring.style, {\n width: '60px',\n height: '60px',\n transform: `translate(${x - 30}px, ${y - 30}px)`,\n opacity: '0',\n });\n });\n },\n\n /**\n * Hide all overlay elements.\n */\n hide() {\n box.style.opacity = '0';\n label.style.opacity = '0';\n ring.style.opacity = '0';\n },\n\n /**\n * Hide just the highlight box (cursor + label stay).\n */\n clearHighlight() {\n box.style.opacity = '0';\n },\n };\n})();\n";
20
+ export declare const CURSOR_OVERLAY_INIT_SCRIPT = "\n(() => {\n if (window.__bad_overlay_installed) return;\n window.__bad_overlay_installed = true;\n\n const NS = 'http://www.w3.org/2000/svg';\n const Z = 2147483647; // max i32\n\n // \u2500\u2500 Root container (absolute, ignores pointer events) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const root = document.createElement('div');\n root.id = '__bad_overlay_root';\n Object.assign(root.style, {\n position: 'fixed',\n inset: '0',\n width: '100vw',\n height: '100vh',\n pointerEvents: 'none',\n zIndex: String(Z),\n });\n\n // \u2500\u2500 Cursor sprite (SVG arrow) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // \u2500\u2500 Idle bounce keyframes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const style = document.createElement('style');\n style.textContent = `\n @keyframes __bad_cursor_bob {\n 0%, 100% { margin-top: 0px; }\n 50% { margin-top: -3px; }\n }\n `;\n (document.head || document.documentElement).appendChild(style);\n\n const cursor = document.createElementNS(NS, 'svg');\n cursor.setAttribute('width', '24');\n cursor.setAttribute('height', '24');\n cursor.setAttribute('viewBox', '0 0 24 24');\n cursor.setAttribute('fill', 'none');\n Object.assign(cursor.style, {\n position: 'fixed',\n left: '0',\n top: '0',\n transform: 'translate(-100px, -100px)',\n transition: 'transform 400ms cubic-bezier(0.34, 1.56, 0.64, 1)',\n pointerEvents: 'none',\n filter: 'drop-shadow(0 2px 4px rgba(0,0,0,0.5))',\n animation: '__bad_cursor_bob 1.8s ease-in-out infinite',\n });\n cursor.innerHTML = `\n <path d=\"M3 2 L21 12 L13 14 L9 22 Z\" fill=\"#ffffff\" stroke=\"#0b1220\" stroke-width=\"1.5\" stroke-linejoin=\"round\"/>\n `;\n\n // \u2500\u2500 Pulse ring (animated on click) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const ring = document.createElement('div');\n Object.assign(ring.style, {\n position: 'fixed',\n left: '0',\n top: '0',\n width: '0',\n height: '0',\n borderRadius: '9999px',\n border: '3px solid rgba(79, 70, 229, 0.95)',\n transform: 'translate(-100px, -100px)',\n pointerEvents: 'none',\n opacity: '0',\n transition: 'all 500ms ease-out',\n });\n\n // \u2500\u2500 Highlight box (drawn around the target element) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const box = document.createElement('div');\n box.id = '__bad_overlay_box';\n Object.assign(box.style, {\n position: 'fixed',\n left: '0',\n top: '0',\n width: '0',\n height: '0',\n border: '2px solid rgba(34, 197, 94, 0.95)',\n borderRadius: '6px',\n background: 'rgba(34, 197, 94, 0.08)',\n boxShadow: '0 0 0 4px rgba(34, 197, 94, 0.18)',\n transform: 'translate(-100px, -100px)',\n pointerEvents: 'none',\n transition: 'all 350ms cubic-bezier(0.34, 1.56, 0.64, 1)',\n opacity: '0',\n });\n\n // \u2500\u2500 Action label (shows \"click\" / \"type\" / etc next to cursor) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const label = document.createElement('div');\n Object.assign(label.style, {\n position: 'fixed',\n left: '0',\n top: '0',\n padding: '5px 12px',\n background: 'rgba(11, 18, 32, 0.95)',\n color: '#ffffff',\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n fontSize: '13px',\n fontWeight: '600',\n letterSpacing: '0.01em',\n borderRadius: '8px',\n transform: 'translate(-200px, -200px)',\n pointerEvents: 'none',\n opacity: '0',\n transition: 'transform 400ms cubic-bezier(0.34, 1.56, 0.64, 1), opacity 200ms ease',\n boxShadow: '0 4px 16px rgba(0,0,0,0.35)',\n whiteSpace: 'nowrap',\n });\n\n // Append to documentElement (not body) so the overlay is not affected by\n // body's stacking context \u2014 many modern sites apply transform/will-change\n // to body which would clip a max-z-index child appended to body.\n // Bound the retry loop so a body-less doc (XML, PDF viewer, chrome://)\n // doesn't spin requestAnimationFrame forever.\n let attachAttempts = 0;\n function attach() {\n const host = document.documentElement || document.body;\n if (!host) {\n if (++attachAttempts > 60) return; // ~1 second of attempts\n requestAnimationFrame(attach);\n return;\n }\n host.appendChild(root);\n root.appendChild(box);\n root.appendChild(ring);\n root.appendChild(cursor);\n root.appendChild(label);\n }\n attach();\n\n // \u2500\u2500 Public API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n window.__bad_overlay = {\n /**\n * Highlight a target element by CSS selector. Returns the rect or null.\n * Used when the caller has a stable CSS selector.\n */\n highlight(selector) {\n try {\n const el = typeof selector === 'string'\n ? document.querySelector(selector)\n : null;\n if (!el) return null;\n const rect = el.getBoundingClientRect();\n if (rect.width === 0 || rect.height === 0) return null;\n Object.assign(box.style, {\n width: rect.width + 'px',\n height: rect.height + 'px',\n transform: `translate(${rect.left}px, ${rect.top}px)`,\n opacity: '1',\n });\n return { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2, width: rect.width, height: rect.height };\n } catch { return null; }\n },\n\n /**\n * Highlight an arbitrary rect at given page coordinates. Used when the\n * caller already computed the rect via Playwright's boundingBox (i.e.,\n * the @ref selector isn't a real CSS selector).\n */\n highlightRect(x, y, width, height) {\n try {\n Object.assign(box.style, {\n width: width + 'px',\n height: height + 'px',\n transform: `translate(${x}px, ${y}px)`,\n opacity: '1',\n });\n } catch { /* never let cosmetic overlay break a run */ }\n },\n\n /**\n * Move the cursor to (x, y) and show a label.\n */\n moveTo(x, y, labelText) {\n cursor.style.transform = `translate(${x - 4}px, ${y - 4}px)`;\n if (labelText) {\n label.textContent = labelText;\n Object.assign(label.style, {\n transform: `translate(${x + 16}px, ${y + 16}px)`,\n opacity: '1',\n });\n }\n },\n\n /**\n * Pulse a click ring at (x, y).\n */\n pulseClick(x, y) {\n // reset\n Object.assign(ring.style, {\n width: '0',\n height: '0',\n transform: `translate(${x}px, ${y}px)`,\n opacity: '1',\n });\n // expand\n requestAnimationFrame(() => {\n Object.assign(ring.style, {\n width: '60px',\n height: '60px',\n transform: `translate(${x - 30}px, ${y - 30}px)`,\n opacity: '0',\n });\n });\n },\n\n /**\n * Hide all overlay elements.\n */\n hide() {\n box.style.opacity = '0';\n label.style.opacity = '0';\n ring.style.opacity = '0';\n },\n\n /**\n * Hide just the highlight box (cursor + label stay).\n */\n clearHighlight() {\n box.style.opacity = '0';\n },\n };\n})();\n";
21
21
  //# sourceMappingURL=cursor-overlay.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cursor-overlay.d.ts","sourceRoot":"","sources":["../../src/drivers/cursor-overlay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;GAGG;AACH,eAAO,MAAM,0BAA0B,01OAiNtC,CAAA"}
1
+ {"version":3,"file":"cursor-overlay.d.ts","sourceRoot":"","sources":["../../src/drivers/cursor-overlay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;GAGG;AACH,eAAO,MAAM,0BAA0B,4hQA6NtC,CAAA"}
@@ -38,6 +38,16 @@ export const CURSOR_OVERLAY_INIT_SCRIPT = `
38
38
  });
39
39
 
40
40
  // ── Cursor sprite (SVG arrow) ──────────────────────────────────────────
41
+ // ── Idle bounce keyframes ──────────────────────────────────────────
42
+ const style = document.createElement('style');
43
+ style.textContent = \`
44
+ @keyframes __bad_cursor_bob {
45
+ 0%, 100% { margin-top: 0px; }
46
+ 50% { margin-top: -3px; }
47
+ }
48
+ \`;
49
+ (document.head || document.documentElement).appendChild(style);
50
+
41
51
  const cursor = document.createElementNS(NS, 'svg');
42
52
  cursor.setAttribute('width', '24');
43
53
  cursor.setAttribute('height', '24');
@@ -48,9 +58,10 @@ export const CURSOR_OVERLAY_INIT_SCRIPT = `
48
58
  left: '0',
49
59
  top: '0',
50
60
  transform: 'translate(-100px, -100px)',
51
- transition: 'transform 220ms cubic-bezier(0.22, 1, 0.36, 1)',
61
+ transition: 'transform 400ms cubic-bezier(0.34, 1.56, 0.64, 1)',
52
62
  pointerEvents: 'none',
53
- filter: 'drop-shadow(0 1px 2px rgba(0,0,0,0.4))',
63
+ filter: 'drop-shadow(0 2px 4px rgba(0,0,0,0.5))',
64
+ animation: '__bad_cursor_bob 1.8s ease-in-out infinite',
54
65
  });
55
66
  cursor.innerHTML = \`
56
67
  <path d="M3 2 L21 12 L13 14 L9 22 Z" fill="#ffffff" stroke="#0b1220" stroke-width="1.5" stroke-linejoin="round"/>
@@ -87,7 +98,7 @@ export const CURSOR_OVERLAY_INIT_SCRIPT = `
87
98
  boxShadow: '0 0 0 4px rgba(34, 197, 94, 0.18)',
88
99
  transform: 'translate(-100px, -100px)',
89
100
  pointerEvents: 'none',
90
- transition: 'all 180ms ease-out',
101
+ transition: 'all 350ms cubic-bezier(0.34, 1.56, 0.64, 1)',
91
102
  opacity: '0',
92
103
  });
93
104
 
@@ -97,18 +108,19 @@ export const CURSOR_OVERLAY_INIT_SCRIPT = `
97
108
  position: 'fixed',
98
109
  left: '0',
99
110
  top: '0',
100
- padding: '4px 10px',
101
- background: 'rgba(11, 18, 32, 0.92)',
111
+ padding: '5px 12px',
112
+ background: 'rgba(11, 18, 32, 0.95)',
102
113
  color: '#ffffff',
103
114
  fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
104
- fontSize: '12px',
115
+ fontSize: '13px',
105
116
  fontWeight: '600',
106
- borderRadius: '6px',
117
+ letterSpacing: '0.01em',
118
+ borderRadius: '8px',
107
119
  transform: 'translate(-200px, -200px)',
108
120
  pointerEvents: 'none',
109
121
  opacity: '0',
110
- transition: 'all 220ms cubic-bezier(0.22, 1, 0.36, 1)',
111
- boxShadow: '0 4px 12px rgba(0,0,0,0.3)',
122
+ transition: 'transform 400ms cubic-bezier(0.34, 1.56, 0.64, 1), opacity 200ms ease',
123
+ boxShadow: '0 4px 16px rgba(0,0,0,0.35)',
112
124
  whiteSpace: 'nowrap',
113
125
  });
114
126
 
@@ -1 +1 @@
1
- {"version":3,"file":"cursor-overlay.js","sourceRoot":"","sources":["../../src/drivers/cursor-overlay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiNzC,CAAA"}
1
+ {"version":3,"file":"cursor-overlay.js","sourceRoot":"","sources":["../../src/drivers/cursor-overlay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6NzC,CAAA"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Gen 10 — extractWithIndex implementation.
3
+ *
4
+ * Runs in page context via page.evaluate() and returns a numbered list of
5
+ * every visible element matching `query`, each with its tag, textContent,
6
+ * key attributes, and a stable selector. The agent picks elements by index
7
+ * in the next turn.
8
+ *
9
+ * Why this is the Gen 10 capability fix: rather than asking the LLM to
10
+ * write a precise CSS selector that returns exactly one element (the
11
+ * approach that fails on real-web pages where data lives in obscurely-classed
12
+ * wrapper divs or `<dl>/<dt>/<dd>` blocks), the LLM emits a wide query and
13
+ * READS the actual text content of every match. Pick-by-content beats
14
+ * pick-by-selector on every failing task in the Gen 8 gauntlet.
15
+ */
16
+ import type { Page } from 'playwright';
17
+ export interface ExtractMatch {
18
+ /** Position in the result list (0-based) */
19
+ index: number;
20
+ /** Element tag name (lowercase) */
21
+ tag: string;
22
+ /** Visible text content, trimmed and length-capped */
23
+ text: string;
24
+ /** Key attributes that help uniquely identify the element */
25
+ attributes: Record<string, string>;
26
+ /** A stable CSS selector the agent can use in a follow-up action */
27
+ selector: string;
28
+ }
29
+ /**
30
+ * Execute the extractWithIndex action in page context. The function passed
31
+ * to page.evaluate runs in the browser; it must be self-contained (no
32
+ * closures over Node-side variables).
33
+ */
34
+ export declare function runExtractWithIndex(page: Page, query: string, contains?: string): Promise<ExtractMatch[]>;
35
+ /**
36
+ * Format extract matches as a compact, LLM-readable list. The format is
37
+ * line-per-match with index, tag, attributes, then text on the next line.
38
+ *
39
+ * [0] p {class: "downloads"}
40
+ * Weekly downloads: 26,543,821
41
+ * [1] dd
42
+ * Returns a new array formed by applying...
43
+ */
44
+ export declare function formatExtractWithIndexResult(matches: ExtractMatch[], query: string, contains?: string): string;
45
+ //# sourceMappingURL=extract-with-index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract-with-index.d.ts","sourceRoot":"","sources":["../../src/drivers/extract-with-index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,WAAW,YAAY;IAC3B,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,mCAAmC;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,oEAAoE;IACpE,QAAQ,EAAE,MAAM,CAAC;CAClB;AAOD;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,YAAY,EAAE,CAAC,CAsFzB;AAED;;;;;;;;GAQG;AACH,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,YAAY,EAAE,EACvB,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,CAmBR"}
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Gen 10 — extractWithIndex implementation.
3
+ *
4
+ * Runs in page context via page.evaluate() and returns a numbered list of
5
+ * every visible element matching `query`, each with its tag, textContent,
6
+ * key attributes, and a stable selector. The agent picks elements by index
7
+ * in the next turn.
8
+ *
9
+ * Why this is the Gen 10 capability fix: rather than asking the LLM to
10
+ * write a precise CSS selector that returns exactly one element (the
11
+ * approach that fails on real-web pages where data lives in obscurely-classed
12
+ * wrapper divs or `<dl>/<dt>/<dd>` blocks), the LLM emits a wide query and
13
+ * READS the actual text content of every match. Pick-by-content beats
14
+ * pick-by-selector on every failing task in the Gen 8 gauntlet.
15
+ */
16
+ /** Hard cap on matches returned per call. Prevents 800-element pages from blowing the response. */
17
+ const MAX_MATCHES = 80;
18
+ /** Per-element textContent cap. */
19
+ const TEXT_CAP = 200;
20
+ /**
21
+ * Execute the extractWithIndex action in page context. The function passed
22
+ * to page.evaluate runs in the browser; it must be self-contained (no
23
+ * closures over Node-side variables).
24
+ */
25
+ export async function runExtractWithIndex(page, query, contains) {
26
+ return await page.evaluate(({ query, contains, max, textCap }) => {
27
+ // Browser-side helpers (must be self-contained)
28
+ const isVisible = (el) => {
29
+ if (!(el instanceof HTMLElement))
30
+ return true;
31
+ const style = window.getComputedStyle(el);
32
+ if (style.display === 'none' || style.visibility === 'hidden' || style.opacity === '0')
33
+ return false;
34
+ const rect = el.getBoundingClientRect();
35
+ return rect.width > 0 && rect.height > 0;
36
+ };
37
+ const cssEscape = (s) => (window.CSS && typeof window.CSS.escape === 'function')
38
+ ? window.CSS.escape(s)
39
+ : s.replace(/[^\w-]/g, (c) => `\\${c}`);
40
+ // Build a selector that uniquely targets the element. Preference order:
41
+ // [data-testid="x"] > [id="x"] > [aria-label="x"] > tag.cls.cls > nth-of-type
42
+ const buildSelector = (el) => {
43
+ const tag = el.tagName.toLowerCase();
44
+ const testid = el.getAttribute('data-testid');
45
+ if (testid)
46
+ return `[data-testid="${testid}"]`;
47
+ const id = el.getAttribute('id');
48
+ if (id && /^[a-zA-Z][\w-]*$/.test(id))
49
+ return `#${id}`;
50
+ const aria = el.getAttribute('aria-label');
51
+ if (aria && aria.length < 60)
52
+ return `${tag}[aria-label="${aria.replace(/"/g, '\\"')}"]`;
53
+ // Class-based fallback (cap at 3 stable-looking classes)
54
+ const classes = (el.className && typeof el.className === 'string')
55
+ ? el.className.split(/\s+/).filter((c) => c.length > 0 && c.length < 40 && /^[a-zA-Z_-][\w-]*$/.test(c) && !/^\d/.test(c)).slice(0, 3)
56
+ : [];
57
+ if (classes.length > 0)
58
+ return `${tag}.${classes.map(cssEscape).join('.')}`;
59
+ // Last resort: tag + nth-of-type position relative to parent
60
+ const parent = el.parentElement;
61
+ if (!parent)
62
+ return tag;
63
+ const siblings = Array.from(parent.children).filter((c) => c.tagName === el.tagName);
64
+ const idx = siblings.indexOf(el) + 1;
65
+ return `${tag}:nth-of-type(${idx})`;
66
+ };
67
+ // Collect interesting attributes for each match (helps the LLM
68
+ // disambiguate without bloating the response)
69
+ const attrsForMatch = (el) => {
70
+ const attrs = {};
71
+ const interesting = ['id', 'data-testid', 'aria-label', 'role', 'href', 'name', 'type', 'value'];
72
+ for (const name of interesting) {
73
+ const v = el.getAttribute(name);
74
+ if (v != null && v.length > 0 && v.length < 200)
75
+ attrs[name] = v;
76
+ }
77
+ return attrs;
78
+ };
79
+ let elements;
80
+ try {
81
+ elements = Array.from(document.querySelectorAll(query));
82
+ }
83
+ catch {
84
+ // Invalid selector — return empty so the runner can report the error cleanly.
85
+ return [];
86
+ }
87
+ const filterText = contains ? contains.toLowerCase() : '';
88
+ const matches = [];
89
+ for (const el of elements) {
90
+ if (!isVisible(el))
91
+ continue;
92
+ const rawText = (el.textContent || '').trim().replace(/\s+/g, ' ');
93
+ if (filterText && !rawText.toLowerCase().includes(filterText))
94
+ continue;
95
+ const text = rawText.length > textCap ? rawText.slice(0, textCap) + '…' : rawText;
96
+ // Skip empty text matches unless the element has interesting attributes
97
+ if (!text && Object.keys(attrsForMatch(el)).length === 0)
98
+ continue;
99
+ matches.push({
100
+ index: matches.length,
101
+ tag: el.tagName.toLowerCase(),
102
+ text,
103
+ attributes: attrsForMatch(el),
104
+ selector: buildSelector(el),
105
+ });
106
+ if (matches.length >= max)
107
+ break;
108
+ }
109
+ return matches;
110
+ }, { query, contains: contains ?? '', max: MAX_MATCHES, textCap: TEXT_CAP });
111
+ }
112
+ /**
113
+ * Format extract matches as a compact, LLM-readable list. The format is
114
+ * line-per-match with index, tag, attributes, then text on the next line.
115
+ *
116
+ * [0] p {class: "downloads"}
117
+ * Weekly downloads: 26,543,821
118
+ * [1] dd
119
+ * Returns a new array formed by applying...
120
+ */
121
+ export function formatExtractWithIndexResult(matches, query, contains) {
122
+ if (matches.length === 0) {
123
+ return `(no matches for query "${query}"${contains ? ` containing "${contains}"` : ''})`;
124
+ }
125
+ const lines = [];
126
+ for (const m of matches) {
127
+ const attrPairs = Object.entries(m.attributes)
128
+ .map(([k, v]) => `${k}="${v.length > 60 ? v.slice(0, 60) + '…' : v}"`)
129
+ .join(' ');
130
+ const attrPart = attrPairs ? ` ${attrPairs}` : '';
131
+ lines.push(`[${m.index}] <${m.tag}>${attrPart} selector: ${m.selector}`);
132
+ if (m.text) {
133
+ lines.push(` text: ${m.text}`);
134
+ }
135
+ }
136
+ if (matches.length === MAX_MATCHES) {
137
+ lines.push(`(capped at ${MAX_MATCHES} matches — narrow your query or use a 'contains' filter to see more)`);
138
+ }
139
+ return lines.join('\n');
140
+ }
141
+ //# sourceMappingURL=extract-with-index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract-with-index.js","sourceRoot":"","sources":["../../src/drivers/extract-with-index.ts"],"names":[],"mappings":"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"}
@@ -70,6 +70,8 @@ export declare class PlaywrightDriver implements Driver {
70
70
  * the init script. Undefined if showCursor is off.
71
71
  */
72
72
  private cursorInstallPromise?;
73
+ /** Gen 23: SoM element map from last observe — used to resolve clickLabel/typeLabel */
74
+ private somElements;
73
75
  constructor(page: Page, options?: PlaywrightDriverOptions);
74
76
  /**
75
77
  * Inject the cursor overlay init script into the current page and into the
@@ -85,6 +87,11 @@ export declare class PlaywrightDriver implements Driver {
85
87
  * overlay via its public `highlightRect` / `moveTo` / `pulseClick` API.
86
88
  */
87
89
  private animateCursorToSelector;
90
+ /**
91
+ * Animate cursor to raw (x, y) coordinates — for clickAt/typeAt actions.
92
+ * Same visual effect as animateCursorToSelector but without needing a locator.
93
+ */
94
+ private animateCursorToCoord;
88
95
  /** Get phase-level timing from the last observe() call */
89
96
  getLastTiming(): ObserveTiming | undefined;
90
97
  getPage(): Page;
@@ -1 +1 @@
1
- {"version":3,"file":"playwright.d.ts","sourceRoot":"","sources":["../../src/drivers/playwright.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAc,MAAM,YAAY,CAAC;AACnD,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAChF,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAWrD,iDAAiD;AACjD,MAAM,WAAW,aAAa;IAC5B,iCAAiC;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,aAAa,EAAE,MAAM,CAAC;IACtB,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,YAAY,EAAE,MAAM,CAAC;IACrB,qCAAqC;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,qCAAqC;IACrC,YAAY,EAAE,MAAM,CAAC;IACrB,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,uBAAuB;IACtC,2BAA2B;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,6CAA6C;IAC7C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,qEAAqE;IACrE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,sEAAsE;IACtE,cAAc,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;IAC7C,6EAA6E;IAC7E,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;;;;;;OAUG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,qBAAa,gBAAiB,YAAW,MAAM;IAc3C,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,OAAO;IAdjB,OAAO,CAAC,QAAQ,CAA4B;IAC5C,OAAO,CAAC,UAAU,CAA2B;IAC7C,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,UAAU,CAA4B;IAC9C,OAAO,CAAC,YAAY,CAAK;IACzB;;;;OAIG;IACH,OAAO,CAAC,oBAAoB,CAAC,CAAgB;gBAGnC,IAAI,EAAE,IAAI,EACV,OAAO,GAAE,uBAA4B;IAU/C;;;OAGG;YACW,oBAAoB;IAWlC;;;;;;;OAOG;YACW,uBAAuB;IA4CrC,0DAA0D;IAC1D,aAAa,IAAI,aAAa,GAAG,SAAS;IAI1C,OAAO,IAAI,IAAI;IAIf,MAAM,IAAI,MAAM;IAIV,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;YAS1D,SAAS;IAWvB;;;OAGG;IACG,qBAAqB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;IAuC5E;;;OAGG;YACW,gBAAgB;IAcxB,OAAO,IAAI,OAAO,CAAC,SAAS,CAAC;IAmDnC;;OAEG;YACW,UAAU;IA4DxB;;OAEG;YACW,iBAAiB;IAwCzB,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAI7B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAO5B;;;OAGG;YACW,mBAAmB;YAUnB,aAAa;IAUrB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;CA2PrD"}
1
+ {"version":3,"file":"playwright.d.ts","sourceRoot":"","sources":["../../src/drivers/playwright.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAc,MAAM,YAAY,CAAC;AACnD,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAChF,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAyFrD,iDAAiD;AACjD,MAAM,WAAW,aAAa;IAC5B,iCAAiC;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,aAAa,EAAE,MAAM,CAAC;IACtB,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,YAAY,EAAE,MAAM,CAAC;IACrB,qCAAqC;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,qCAAqC;IACrC,YAAY,EAAE,MAAM,CAAC;IACrB,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,uBAAuB;IACtC,2BAA2B;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,6CAA6C;IAC7C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,qEAAqE;IACrE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,sEAAsE;IACtE,cAAc,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;IAC7C,6EAA6E;IAC7E,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;;;;;;OAUG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,qBAAa,gBAAiB,YAAW,MAAM;IAgB3C,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,OAAO;IAhBjB,OAAO,CAAC,QAAQ,CAA4B;IAC5C,OAAO,CAAC,UAAU,CAA2B;IAC7C,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,UAAU,CAA4B;IAC9C,OAAO,CAAC,YAAY,CAAK;IACzB;;;;OAIG;IACH,OAAO,CAAC,oBAAoB,CAAC,CAAgB;IAC7C,uFAAuF;IACvF,OAAO,CAAC,WAAW,CAAoB;gBAG7B,IAAI,EAAE,IAAI,EACV,OAAO,GAAE,uBAA4B;IAU/C;;;OAGG;YACW,oBAAoB;IAWlC;;;;;;;OAOG;YACW,uBAAuB;IA4CrC;;;OAGG;YACW,oBAAoB;IAqBlC,0DAA0D;IAC1D,aAAa,IAAI,aAAa,GAAG,SAAS;IAI1C,OAAO,IAAI,IAAI;IAIf,MAAM,IAAI,MAAM;IAIV,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;YAS1D,SAAS;IAWvB;;;OAGG;IACG,qBAAqB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;IAuC5E;;;OAGG;YACW,gBAAgB;IAcxB,OAAO,IAAI,OAAO,CAAC,SAAS,CAAC;IAmDnC;;OAEG;YACW,UAAU;IA4ExB;;OAEG;YACW,iBAAiB;IAwCzB,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAI7B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAO5B;;;OAGG;YACW,mBAAmB;YAUnB,aAAa;IAUrB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;CAoXrD"}