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,181 @@
1
+ /**
2
+ * Capture Agent — Selector Resolver
3
+ *
4
+ * Progressive selector resolution for opcodes that target elements:
5
+ * 1. Primary selector from compiled program
6
+ * 2. AKTree fingerprint match
7
+ * 3. Selector memory candidates (from Supabase)
8
+ * 4. Fuzzy text match on AKTree nodes
9
+ */
10
+ /**
11
+ * Resolves a selector by trying multiple strategies in order.
12
+ * Returns the first working selector, or null if nothing matches.
13
+ */
14
+ export async function resolveSelector(adapter, options) {
15
+ const tree = await adapter.getAKTree();
16
+ // 1. Try primary selector
17
+ if (await selectorExists(adapter, options.primary)) {
18
+ return { selector: options.primary, strategy: 'primary', confidence: 'high' };
19
+ }
20
+ // 2. Try alternate selectors
21
+ if (options.alternates) {
22
+ for (const alt of options.alternates) {
23
+ if (await selectorExists(adapter, alt)) {
24
+ return { selector: alt, strategy: 'alternate', confidence: 'high' };
25
+ }
26
+ }
27
+ }
28
+ // 3. Try fingerprint match in AKTree
29
+ if (options.fingerprint) {
30
+ const match = findNodeByFingerprint(tree, options.fingerprint);
31
+ if (match) {
32
+ return { selector: match, strategy: 'fingerprint', confidence: 'medium' };
33
+ }
34
+ }
35
+ // 4. Try selector memory
36
+ if (options.selectorMemory && options.stepSignature) {
37
+ const candidates = options.selectorMemory[options.stepSignature];
38
+ if (candidates) {
39
+ for (const candidate of candidates) {
40
+ if (await selectorExists(adapter, candidate)) {
41
+ return { selector: candidate, strategy: 'memory', confidence: 'medium' };
42
+ }
43
+ }
44
+ }
45
+ }
46
+ // 5. Try fuzzy text match
47
+ if (options.description) {
48
+ const match = findNodeByFuzzyText(tree, options.description);
49
+ if (match) {
50
+ return { selector: match, strategy: 'fuzzy_text', confidence: 'low' };
51
+ }
52
+ }
53
+ return null;
54
+ }
55
+ // ── Helpers ─────────────────────────────────────────────────────────
56
+ async function selectorExists(adapter, selector) {
57
+ try {
58
+ const found = await adapter.waitFor({
59
+ selector,
60
+ state: 'attached',
61
+ timeoutMs: 2000,
62
+ });
63
+ return found;
64
+ }
65
+ catch {
66
+ return false;
67
+ }
68
+ }
69
+ /**
70
+ * Finds an AKTree node whose sourceRef/attributes match a fingerprint string.
71
+ * Returns a CSS selector that can be used to interact with the element.
72
+ */
73
+ function findNodeByFingerprint(tree, fingerprint) {
74
+ const parts = fingerprint.split(':');
75
+ // Fingerprint format: "type:label:context" e.g. "button:submit:login-form"
76
+ const [expectedType, expectedLabel, expectedContext] = parts;
77
+ let bestMatch = null;
78
+ let bestScore = 0;
79
+ function walk(node) {
80
+ if (!node.visible || !node.interactive) {
81
+ node.children.forEach(walk);
82
+ return;
83
+ }
84
+ let score = 0;
85
+ // Match type
86
+ if (expectedType && node.type === expectedType)
87
+ score += 3;
88
+ // Match label (fuzzy)
89
+ if (expectedLabel) {
90
+ const nodeLabelLower = node.label.toLowerCase();
91
+ const expectedLabelLower = expectedLabel.toLowerCase();
92
+ if (nodeLabelLower === expectedLabelLower)
93
+ score += 5;
94
+ else if (nodeLabelLower.includes(expectedLabelLower))
95
+ score += 3;
96
+ else if (expectedLabelLower.includes(nodeLabelLower))
97
+ score += 1;
98
+ }
99
+ // Match context (check sourceRef)
100
+ if (expectedContext && node.sourceRef.toLowerCase().includes(expectedContext.toLowerCase())) {
101
+ score += 2;
102
+ }
103
+ if (score > bestScore) {
104
+ bestScore = score;
105
+ bestMatch = node;
106
+ }
107
+ node.children.forEach(walk);
108
+ }
109
+ walk(tree.root);
110
+ if (bestMatch && bestScore >= 4) {
111
+ return buildSelectorFromNode(bestMatch);
112
+ }
113
+ return null;
114
+ }
115
+ /**
116
+ * Finds a visible interactive node by fuzzy text matching against the description.
117
+ */
118
+ function findNodeByFuzzyText(tree, description) {
119
+ const descTokens = tokenize(description);
120
+ if (descTokens.length === 0)
121
+ return null;
122
+ let bestMatch = null;
123
+ let bestOverlap = 0;
124
+ function walk(node) {
125
+ if (!node.visible || !node.interactive) {
126
+ node.children.forEach(walk);
127
+ return;
128
+ }
129
+ const nodeTokens = tokenize(node.label);
130
+ const overlap = countOverlap(descTokens, nodeTokens);
131
+ if (overlap > bestOverlap) {
132
+ bestOverlap = overlap;
133
+ bestMatch = node;
134
+ }
135
+ node.children.forEach(walk);
136
+ }
137
+ walk(tree.root);
138
+ // Require at least 2 token overlap or >50% match
139
+ if (bestMatch && (bestOverlap >= 2 || bestOverlap / descTokens.length > 0.5)) {
140
+ return buildSelectorFromNode(bestMatch);
141
+ }
142
+ return null;
143
+ }
144
+ function buildSelectorFromNode(node) {
145
+ // Try to build the most specific selector from node attributes
146
+ const ref = node.sourceRef;
147
+ // Extract data-testid
148
+ const testIdMatch = ref.match(/data-testid="([^"]+)"/);
149
+ if (testIdMatch)
150
+ return `[data-testid="${testIdMatch[1]}"]`;
151
+ // Extract id
152
+ const idMatch = ref.match(/ id="([^"]+)"/);
153
+ if (idMatch)
154
+ return `#${idMatch[1]}`;
155
+ // Extract tag + role + text
156
+ const tagMatch = ref.match(/^<(\w+)/);
157
+ const tag = tagMatch?.[1] ?? '*';
158
+ const role = node.attributes['role'];
159
+ if (role) {
160
+ return `${tag}[role="${role}"]`;
161
+ }
162
+ // Fallback: use AKNode id as a CSS selector via data attribute
163
+ if (node.id) {
164
+ return `[data-ak-id="${node.id}"]`;
165
+ }
166
+ return `${tag}:has-text("${escapeText(node.label.slice(0, 50))}")`;
167
+ }
168
+ function tokenize(text) {
169
+ return text
170
+ .toLowerCase()
171
+ .split(/[^a-z0-9]+/)
172
+ .filter(t => t.length >= 2);
173
+ }
174
+ function countOverlap(a, b) {
175
+ const setB = new Set(b);
176
+ return a.filter(t => setB.has(t)).length;
177
+ }
178
+ function escapeText(text) {
179
+ return text.replace(/"/g, '\\"').replace(/\n/g, ' ');
180
+ }
181
+ //# sourceMappingURL=selector-resolver.js.map
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Capture Agent — Semantic Target Resolver
3
+ *
4
+ * Resolves a SemanticTarget to a concrete Playwright locator.
5
+ * This is the core mechanism that allows opcodes to work WITHOUT CSS selectors.
6
+ *
7
+ * Resolution cascade:
8
+ * 1. CSS selector (if provided, fast path)
9
+ * 2. Playwright semantic locators (getByRole, getByText, getByLabel, getByPlaceholder)
10
+ * 3. Selector alternates
11
+ * 4. Composite: role + name + near (for disambiguation)
12
+ *
13
+ * All resolution happens via Playwright's built-in locator API — no AKTree needed.
14
+ */
15
+ import type { Page, Locator } from 'playwright';
16
+ import type { SemanticTarget } from './execution-types.js';
17
+ export interface ResolvedTarget {
18
+ locator: Locator;
19
+ method: 'selector' | 'role' | 'text' | 'label' | 'placeholder' | 'alternate' | 'composite';
20
+ }
21
+ export interface ResolveOptions {
22
+ /** Primary CSS selector */
23
+ selector?: string;
24
+ /** Semantic target description */
25
+ target?: SemanticTarget;
26
+ /** Fallback selectors */
27
+ selectorAlternates?: string[];
28
+ /** Timeout for visibility check (ms). Default: 3000 */
29
+ timeoutMs?: number;
30
+ }
31
+ /**
32
+ * Resolves an element on the page using the best available method.
33
+ * Returns the first visible locator found, or null if nothing matches.
34
+ */
35
+ export declare function resolveTarget(page: Page, options: ResolveOptions): Promise<ResolvedTarget | null>;
@@ -0,0 +1,161 @@
1
+ /**
2
+ * Capture Agent — Semantic Target Resolver
3
+ *
4
+ * Resolves a SemanticTarget to a concrete Playwright locator.
5
+ * This is the core mechanism that allows opcodes to work WITHOUT CSS selectors.
6
+ *
7
+ * Resolution cascade:
8
+ * 1. CSS selector (if provided, fast path)
9
+ * 2. Playwright semantic locators (getByRole, getByText, getByLabel, getByPlaceholder)
10
+ * 3. Selector alternates
11
+ * 4. Composite: role + name + near (for disambiguation)
12
+ *
13
+ * All resolution happens via Playwright's built-in locator API — no AKTree needed.
14
+ */
15
+ /**
16
+ * Resolves an element on the page using the best available method.
17
+ * Returns the first visible locator found, or null if nothing matches.
18
+ */
19
+ export async function resolveTarget(page, options) {
20
+ const timeout = options.timeoutMs ?? 3000;
21
+ // 1. Primary CSS selector
22
+ if (options.selector) {
23
+ const locator = page.locator(options.selector).first();
24
+ if (await isVisible(locator, timeout)) {
25
+ return { locator, method: 'selector' };
26
+ }
27
+ }
28
+ // 2. Semantic locators from target
29
+ if (options.target) {
30
+ const resolved = await resolveSemanticTarget(page, options.target, timeout);
31
+ if (resolved)
32
+ return resolved;
33
+ }
34
+ // 3. Alternate selectors
35
+ if (options.selectorAlternates) {
36
+ for (const alt of options.selectorAlternates) {
37
+ const locator = page.locator(alt).first();
38
+ if (await isVisible(locator, timeout)) {
39
+ return { locator, method: 'alternate' };
40
+ }
41
+ }
42
+ }
43
+ return null;
44
+ }
45
+ /**
46
+ * Resolves a SemanticTarget using Playwright's semantic locator API.
47
+ */
48
+ async function resolveSemanticTarget(page, target, timeout) {
49
+ const exact = target.exact ?? false;
50
+ // Strategy A: getByRole with name (most precise)
51
+ if (target.role && (target.text || target.label)) {
52
+ const name = target.label || target.text;
53
+ try {
54
+ let locator = page.getByRole(target.role, {
55
+ name: name,
56
+ exact,
57
+ });
58
+ if (target.near) {
59
+ locator = narrowByNear(page, locator, target.near);
60
+ }
61
+ locator = locator.first();
62
+ if (await isVisible(locator, timeout)) {
63
+ return { locator, method: 'role' };
64
+ }
65
+ }
66
+ catch {
67
+ // Invalid role or no match
68
+ }
69
+ }
70
+ // Strategy B: getByRole without name
71
+ if (target.role && !target.text && !target.label) {
72
+ try {
73
+ let locator = page.getByRole(target.role);
74
+ if (target.near) {
75
+ locator = narrowByNear(page, locator, target.near);
76
+ }
77
+ locator = locator.first();
78
+ if (await isVisible(locator, timeout)) {
79
+ return { locator, method: 'role' };
80
+ }
81
+ }
82
+ catch {
83
+ // Invalid role
84
+ }
85
+ }
86
+ // Strategy C: getByText
87
+ if (target.text) {
88
+ let locator = page.getByText(target.text, { exact });
89
+ if (target.near) {
90
+ locator = narrowByNear(page, locator, target.near);
91
+ }
92
+ locator = locator.first();
93
+ if (await isVisible(locator, timeout)) {
94
+ return { locator, method: 'text' };
95
+ }
96
+ }
97
+ // Strategy D: getByLabel
98
+ if (target.label) {
99
+ let locator = page.getByLabel(target.label, { exact });
100
+ if (target.near) {
101
+ locator = narrowByNear(page, locator, target.near);
102
+ }
103
+ locator = locator.first();
104
+ if (await isVisible(locator, timeout)) {
105
+ return { locator, method: 'label' };
106
+ }
107
+ }
108
+ // Strategy E: getByPlaceholder (for inputs)
109
+ if (target.placeholder) {
110
+ let locator = page.getByPlaceholder(target.placeholder, { exact });
111
+ if (target.near) {
112
+ locator = narrowByNear(page, locator, target.near);
113
+ }
114
+ locator = locator.first();
115
+ if (await isVisible(locator, timeout)) {
116
+ return { locator, method: 'placeholder' };
117
+ }
118
+ }
119
+ // Strategy F: Composite — try role-based with looser matching
120
+ if (target.role) {
121
+ try {
122
+ const allByRole = page.getByRole(target.role);
123
+ const count = await allByRole.count();
124
+ for (let i = 0; i < Math.min(count, 10); i++) {
125
+ const candidate = allByRole.nth(i);
126
+ if (await isVisible(candidate, 500)) {
127
+ const text = await candidate.textContent().catch(() => null);
128
+ if (text && target.text && text.toLowerCase().includes(target.text.toLowerCase())) {
129
+ return { locator: candidate, method: 'composite' };
130
+ }
131
+ }
132
+ }
133
+ }
134
+ catch {
135
+ // No match
136
+ }
137
+ }
138
+ return null;
139
+ }
140
+ /**
141
+ * Narrows a locator to one near a specific text/heading on the page.
142
+ * Uses Playwright's `.filter()` with a parent locator containing the near text.
143
+ */
144
+ function narrowByNear(page, locator, nearText) {
145
+ // Find a section/container that contains the near text
146
+ const container = page.locator(`section:has-text("${escapeForSelector(nearText)}"), div:has-text("${escapeForSelector(nearText)}"), [role="region"]:has-text("${escapeForSelector(nearText)}")`).first();
147
+ return container.locator(locator);
148
+ }
149
+ async function isVisible(locator, timeout) {
150
+ try {
151
+ await locator.waitFor({ state: 'visible', timeout });
152
+ return true;
153
+ }
154
+ catch {
155
+ return false;
156
+ }
157
+ }
158
+ function escapeForSelector(text) {
159
+ return text.replace(/"/g, '\\"').replace(/\n/g, ' ');
160
+ }
161
+ //# sourceMappingURL=semantic-resolver.js.map
@@ -0,0 +1,125 @@
1
+ import type { SupabaseClient } from '@supabase/supabase-js';
2
+ export type BillingPlanId = 'free' | 'maker' | 'team';
3
+ export interface BillingPlanEntitlements {
4
+ creditsPerMonth: number;
5
+ maxProjects: number | null;
6
+ maxPresetsPerProject: number | null;
7
+ allowFullPageCapture: boolean;
8
+ allowElementCapture: boolean;
9
+ retentionDays: number;
10
+ watermarkScreenshots: boolean;
11
+ maxLanguages: number | null;
12
+ maxThemes: number | null;
13
+ apiAccess: boolean;
14
+ captureCompleteWebhook: boolean;
15
+ priorityQueue: boolean;
16
+ maxParallelCaptures: number;
17
+ teamMembers: boolean;
18
+ aiDailyCostLimitUsd: number;
19
+ apiRateLimitRpm: number;
20
+ maxDevLinks: number | null;
21
+ maxCompositions: number | null;
22
+ maxTeamMembersPerProject: number | null;
23
+ }
24
+ export interface BillingPlan {
25
+ id: BillingPlanId;
26
+ nameKey: BillingPlanId;
27
+ descriptionKey: 'forEvaluation' | 'forMakers' | 'forTeams';
28
+ monthlyPriceEur: number;
29
+ yearlyPriceEur: number;
30
+ highlighted?: boolean;
31
+ previewCurrent?: boolean;
32
+ highlights: string[];
33
+ entitlements: BillingPlanEntitlements;
34
+ }
35
+ export interface BillingAccount {
36
+ user_id: string;
37
+ email: string | null;
38
+ admin_override_plan_id: BillingPlanId | null;
39
+ stripe_customer_id: string | null;
40
+ stripe_subscription_id: string | null;
41
+ stripe_plan_id: BillingPlanId | null;
42
+ stripe_subscription_status: string | null;
43
+ stripe_current_period_start: string | null;
44
+ stripe_current_period_end: string | null;
45
+ allow_capture_overages: boolean;
46
+ capture_overage_limit_cents: number | null;
47
+ signup_bonus_credits: number;
48
+ created_at: string;
49
+ }
50
+ export declare class PlanLimitError extends Error {
51
+ status: number;
52
+ code: string;
53
+ constructor(message: string, status?: number, code?: string);
54
+ }
55
+ export declare const SCREENSHOT_CREDIT_COST = 1;
56
+ export declare function getBillingPlan(planId: BillingPlanId): BillingPlan;
57
+ export declare function coerceBillingPlanId(value: unknown): BillingPlanId | null;
58
+ export declare function getBillingAccountForUser(supabase: SupabaseClient, userId: string): Promise<BillingAccount | null>;
59
+ export declare function getProjectOwnerBillingContext(supabase: SupabaseClient, projectId: string): Promise<{
60
+ ownerUserId: string;
61
+ plan: BillingPlan;
62
+ }>;
63
+ export declare function shouldUseStripePlan(status: string | null | undefined): boolean;
64
+ export declare function isYearlySubscription(account: BillingAccount | null): boolean;
65
+ export declare function getStripeOveragePriceIdForPlan(planId: BillingPlanId): string | null;
66
+ export declare function recordStripeMeterEvent(params: {
67
+ customerId: string;
68
+ value: number;
69
+ identifier: string;
70
+ }): Promise<void>;
71
+ export declare function getCaptureConfigLimitViolations(config: {
72
+ langs: string[];
73
+ themes: string[];
74
+ elements?: unknown[];
75
+ }, entitlements: BillingPlanEntitlements): string[];
76
+ export declare function ensureCaptureConfigAllowed(plan: BillingPlan, config: {
77
+ langs: string[];
78
+ themes: string[];
79
+ elements?: unknown[];
80
+ }): void;
81
+ export declare function getLockedResourceIds(supabase: SupabaseClient, ownerUserId: string, plan: BillingPlan): Promise<{
82
+ lockedProjectIds: Set<string>;
83
+ lockedPresetIdsByProject: Map<string, Set<string>>;
84
+ }>;
85
+ export declare function ensureResourceNotLocked(resourceId: string, lockedIds: Set<string>, resourceType?: 'project' | 'preset'): void;
86
+ export declare function getRemainingOverageCredits(params: {
87
+ planId: BillingPlanId;
88
+ quota: number;
89
+ usedCredits: number;
90
+ overageLimitCents: number | null;
91
+ }): number | null;
92
+ export declare function getCaptureOverageState(params: {
93
+ planId: BillingPlanId;
94
+ quota: number;
95
+ usedCredits: number;
96
+ allowOverages: boolean;
97
+ overageLimitCents: number | null;
98
+ hasActiveSubscription: boolean;
99
+ hasOveragePrice: boolean;
100
+ isYearlySubscription: boolean;
101
+ }): {
102
+ eligible: boolean;
103
+ enabled: boolean;
104
+ limitReached: boolean;
105
+ spendCents: number;
106
+ remainingBudgetCents: number | null;
107
+ remainingCredits: number | null;
108
+ };
109
+ export declare function getSignupBonusCredits(account: {
110
+ signup_bonus_credits?: number;
111
+ created_at?: string;
112
+ } | null, billingPeriodStart: string): number;
113
+ export declare function ensureMonthlyCreditsQuota(plan: BillingPlan, usedCredits: number, requestedCredits: number, allowOverage?: boolean, overageLimitCents?: number | null, bonusCredits?: number): void;
114
+ export declare function getOwnerBillingUsage(supabase: SupabaseClient, ownerUserId: string, billingPeriodStartOverride?: string): Promise<{
115
+ billingPeriodStart: string;
116
+ credits: number;
117
+ }>;
118
+ export declare function getIncrementalOverageCount(params: {
119
+ quota: number;
120
+ usedBefore: number;
121
+ completedCount: number;
122
+ }): number;
123
+ export declare function cleanupExpiredCapturesForOwner(supabase: SupabaseClient, ownerUserId: string): Promise<{
124
+ deletedCaptures: number;
125
+ }>;