autokap 1.0.7 → 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 (278) hide show
  1. package/assets/cursors/macos.svg +4 -0
  2. package/assets/cursors/windows.svg +15 -0
  3. package/assets/skill/OPCODE-REFERENCE.md +607 -0
  4. package/assets/skill/README.md +39 -0
  5. package/assets/skill/SKILL.md +453 -468
  6. package/assets/skill/STUDIO-SKILL.md +476 -0
  7. package/assets/skill/references/examples.md +104 -0
  8. package/assets/skill/references/interactive-demo.md +225 -0
  9. package/assets/skill/references/mock-data.md +178 -0
  10. package/dist/action-verifier.d.ts +29 -0
  11. package/dist/action-verifier.js +133 -0
  12. package/dist/agent-action-recovery.d.ts +45 -0
  13. package/dist/agent-action-recovery.js +370 -0
  14. package/dist/agent-message-utils.d.ts +21 -0
  15. package/dist/agent-message-utils.js +77 -0
  16. package/dist/agent-url-utils.d.ts +30 -0
  17. package/dist/agent-url-utils.js +138 -0
  18. package/dist/agent.d.ts +92 -8
  19. package/dist/agent.js +2936 -781
  20. package/dist/ak-tree.d.ts +39 -0
  21. package/dist/ak-tree.js +368 -0
  22. package/dist/alt-text.d.ts +26 -0
  23. package/dist/alt-text.js +55 -0
  24. package/dist/auth-capture.d.ts +17 -0
  25. package/dist/auth-capture.js +164 -0
  26. package/dist/benchmark.d.ts +59 -0
  27. package/dist/benchmark.js +135 -0
  28. package/dist/browser-bar.d.ts +14 -6
  29. package/dist/browser-bar.js +145 -8
  30. package/dist/browser-pool.d.ts +7 -0
  31. package/dist/browser-pool.js +15 -5
  32. package/dist/browser-utils.d.ts +31 -0
  33. package/dist/browser-utils.js +97 -0
  34. package/dist/browser.d.ts +51 -1
  35. package/dist/browser.js +1481 -31
  36. package/dist/capture-alt-text.js +2 -1
  37. package/dist/capture-language-preflight.js +14 -0
  38. package/dist/capture-llm-page-identity.js +22 -10
  39. package/dist/capture-page-identity.d.ts +5 -7
  40. package/dist/capture-page-identity.js +211 -78
  41. package/dist/capture-preset-credentials.d.ts +50 -0
  42. package/dist/capture-preset-credentials.js +127 -0
  43. package/dist/capture-request-plan.d.ts +2 -2
  44. package/dist/capture-request-plan.js +64 -16
  45. package/dist/capture-run-optimizer.js +48 -33
  46. package/dist/capture-selector-memory.d.ts +5 -0
  47. package/dist/capture-selector-memory.js +18 -0
  48. package/dist/capture-strategy.d.ts +36 -0
  49. package/dist/capture-strategy.js +95 -0
  50. package/dist/capture-studio-sync.d.ts +1 -0
  51. package/dist/capture-studio-sync.js +9 -3
  52. package/dist/capture-surface-contract.d.ts +36 -0
  53. package/dist/capture-surface-contract.js +299 -0
  54. package/dist/capture-transition-engine.d.ts +28 -0
  55. package/dist/capture-transition-engine.js +292 -0
  56. package/dist/capture-variant-state.d.ts +2 -0
  57. package/dist/capture-variant-state.js +26 -0
  58. package/dist/capture-verification.d.ts +35 -0
  59. package/dist/capture-verification.js +95 -0
  60. package/dist/capture-viewport-lock.d.ts +48 -0
  61. package/dist/capture-viewport-lock.js +74 -0
  62. package/dist/circuit-breaker.d.ts +42 -0
  63. package/dist/circuit-breaker.js +119 -0
  64. package/dist/cli-config.d.ts +8 -1
  65. package/dist/cli-config.js +62 -6
  66. package/dist/cli-contract.d.ts +15 -0
  67. package/dist/cli-contract.js +167 -0
  68. package/dist/cli-runner-local.d.ts +12 -0
  69. package/dist/cli-runner-local.js +102 -0
  70. package/dist/cli-runner.d.ts +34 -0
  71. package/dist/cli-runner.js +433 -0
  72. package/dist/cli-utils.d.ts +0 -1
  73. package/dist/cli-utils.js +2 -5
  74. package/dist/cli.js +1005 -267
  75. package/dist/clip-orchestrator.js +9 -2
  76. package/dist/clip-postprocess.js +25 -16
  77. package/dist/cookie-dismiss.d.ts +2 -0
  78. package/dist/cookie-dismiss.js +48 -13
  79. package/dist/cost-logging.d.ts +8 -0
  80. package/dist/cost-logging.js +160 -46
  81. package/dist/cost-resolution-monitor.d.ts +16 -0
  82. package/dist/cost-resolution-monitor.js +34 -0
  83. package/dist/credential-templates.js +2 -2
  84. package/dist/cursor-overlay-script.d.ts +6 -0
  85. package/dist/cursor-overlay-script.js +169 -0
  86. package/dist/dom-css-purger.d.ts +65 -0
  87. package/dist/dom-css-purger.js +333 -0
  88. package/dist/dom-font-inliner.d.ts +45 -0
  89. package/dist/dom-font-inliner.js +148 -0
  90. package/dist/dom-patch-resolver.d.ts +52 -0
  91. package/dist/dom-patch-resolver.js +242 -0
  92. package/dist/dom-serializer.d.ts +82 -0
  93. package/dist/dom-serializer.js +378 -0
  94. package/dist/element-capture.d.ts +1 -41
  95. package/dist/element-capture.js +202 -446
  96. package/dist/env-validation.d.ts +5 -0
  97. package/dist/env-validation.js +29 -0
  98. package/dist/execution-schema.d.ts +4423 -0
  99. package/dist/execution-schema.js +507 -0
  100. package/dist/execution-types.d.ts +886 -0
  101. package/dist/execution-types.js +65 -0
  102. package/dist/fonts-loader.d.ts +14 -0
  103. package/dist/fonts-loader.js +55 -0
  104. package/dist/hybrid-navigator.js +12 -12
  105. package/dist/index.d.ts +9 -6
  106. package/dist/index.js +10 -4
  107. package/dist/legacy/agent-action-recovery.d.ts +45 -0
  108. package/dist/legacy/agent-action-recovery.js +370 -0
  109. package/dist/legacy/agent-message-utils.d.ts +21 -0
  110. package/dist/legacy/agent-message-utils.js +77 -0
  111. package/dist/legacy/agent-url-utils.d.ts +30 -0
  112. package/dist/legacy/agent-url-utils.js +138 -0
  113. package/dist/legacy/agent.d.ts +226 -0
  114. package/dist/legacy/agent.js +6666 -0
  115. package/dist/legacy/clip-orchestrator.d.ts +148 -0
  116. package/dist/legacy/clip-orchestrator.js +957 -0
  117. package/dist/legacy/credential-templates.d.ts +5 -0
  118. package/dist/legacy/credential-templates.js +60 -0
  119. package/dist/legacy/hybrid-navigator.d.ts +138 -0
  120. package/dist/legacy/hybrid-navigator.js +468 -0
  121. package/dist/legacy/llm-usage.d.ts +17 -0
  122. package/dist/legacy/llm-usage.js +45 -0
  123. package/dist/legacy/prompt-cache.d.ts +10 -0
  124. package/dist/legacy/prompt-cache.js +24 -0
  125. package/dist/legacy/prompts.d.ts +175 -0
  126. package/dist/legacy/prompts.js +1038 -0
  127. package/dist/legacy/tools.d.ts +4 -0
  128. package/dist/legacy/tools.js +216 -0
  129. package/dist/legacy/video-agent.d.ts +143 -0
  130. package/dist/legacy/video-agent.js +4788 -0
  131. package/dist/legacy/video-observation.d.ts +36 -0
  132. package/dist/legacy/video-observation.js +192 -0
  133. package/dist/legacy/video-planner.d.ts +12 -0
  134. package/dist/legacy/video-planner.js +501 -0
  135. package/dist/legacy/video-prompts.d.ts +37 -0
  136. package/dist/legacy/video-prompts.js +569 -0
  137. package/dist/legacy/video-tools.d.ts +3 -0
  138. package/dist/legacy/video-tools.js +59 -0
  139. package/dist/legacy/video-variant-state.d.ts +29 -0
  140. package/dist/legacy/video-variant-state.js +80 -0
  141. package/dist/legacy/vision-model.d.ts +17 -0
  142. package/dist/legacy/vision-model.js +74 -0
  143. package/dist/llm-healer.d.ts +63 -0
  144. package/dist/llm-healer.js +166 -0
  145. package/dist/llm-provider.d.ts +29 -0
  146. package/dist/llm-provider.js +80 -0
  147. package/dist/logger.d.ts +6 -2
  148. package/dist/logger.js +15 -1
  149. package/dist/mockup-html.js +35 -25
  150. package/dist/mockup.d.ts +95 -2
  151. package/dist/mockup.js +427 -166
  152. package/dist/mouse-animation.d.ts +2 -2
  153. package/dist/mouse-animation.js +34 -20
  154. package/dist/opcode-actions.d.ts +42 -0
  155. package/dist/opcode-actions.js +511 -0
  156. package/dist/opcode-runner.d.ts +51 -0
  157. package/dist/opcode-runner.js +770 -0
  158. package/dist/openrouter-client.d.ts +40 -0
  159. package/dist/openrouter-client.js +16 -0
  160. package/dist/overlay-engine.d.ts +24 -0
  161. package/dist/overlay-engine.js +176 -0
  162. package/dist/postcondition.d.ts +16 -0
  163. package/dist/postcondition.js +269 -0
  164. package/dist/program-patcher.d.ts +25 -0
  165. package/dist/program-patcher.js +44 -0
  166. package/dist/prompts.d.ts +13 -5
  167. package/dist/prompts.js +224 -351
  168. package/dist/provider-config.d.ts +12 -0
  169. package/dist/provider-config.js +15 -0
  170. package/dist/recovery-chain.d.ts +37 -0
  171. package/dist/recovery-chain.js +350 -0
  172. package/dist/remote-browser.d.ts +28 -4
  173. package/dist/remote-browser.js +60 -5
  174. package/dist/safari-browser-bar.d.ts +15 -0
  175. package/dist/safari-browser-bar.js +95 -0
  176. package/dist/safari-toolbar-asset.d.ts +15 -0
  177. package/dist/safari-toolbar-asset.js +12 -0
  178. package/dist/security.d.ts +2 -1
  179. package/dist/security.js +49 -10
  180. package/dist/selector-resolver.d.ts +34 -0
  181. package/dist/selector-resolver.js +181 -0
  182. package/dist/semantic-resolver.d.ts +35 -0
  183. package/dist/semantic-resolver.js +161 -0
  184. package/dist/server-capture-runtime.d.ts +5 -3
  185. package/dist/server-capture-runtime.js +42 -95
  186. package/dist/server-credit-usage.d.ts +2 -2
  187. package/dist/server-project-webhooks.d.ts +15 -1
  188. package/dist/server-project-webhooks.js +34 -8
  189. package/dist/server-screenshot-watermark.js +27 -5
  190. package/dist/session-profile.js +164 -1
  191. package/dist/sf-pro-symbols.d.ts +1 -0
  192. package/dist/sf-pro-symbols.js +55 -0
  193. package/dist/skill-packaging.d.ts +28 -0
  194. package/dist/skill-packaging.js +169 -0
  195. package/dist/smart-wait.d.ts +27 -0
  196. package/dist/smart-wait.js +81 -0
  197. package/dist/status-bar-render.d.ts +20 -0
  198. package/dist/status-bar-render.js +410 -0
  199. package/dist/status-bar.d.ts +9 -0
  200. package/dist/status-bar.js +298 -14
  201. package/dist/svg-browser-bar.d.ts +33 -0
  202. package/dist/svg-browser-bar.js +206 -0
  203. package/dist/svg-status-bar.d.ts +36 -0
  204. package/dist/svg-status-bar.js +597 -0
  205. package/dist/svg-text.d.ts +61 -0
  206. package/dist/svg-text.js +118 -0
  207. package/dist/tools.js +89 -451
  208. package/dist/types.d.ts +240 -5
  209. package/dist/types.js +23 -1
  210. package/dist/v2/action-verifier.d.ts +29 -0
  211. package/dist/v2/action-verifier.js +133 -0
  212. package/dist/v2/alt-text.d.ts +26 -0
  213. package/dist/v2/alt-text.js +55 -0
  214. package/dist/v2/benchmark.d.ts +59 -0
  215. package/dist/v2/benchmark.js +135 -0
  216. package/dist/v2/capture-strategy.d.ts +30 -0
  217. package/dist/v2/capture-strategy.js +67 -0
  218. package/dist/v2/capture-verification.d.ts +35 -0
  219. package/dist/v2/capture-verification.js +95 -0
  220. package/dist/v2/circuit-breaker.d.ts +42 -0
  221. package/dist/v2/circuit-breaker.js +119 -0
  222. package/dist/v2/cli-runner-local.d.ts +11 -0
  223. package/dist/v2/cli-runner-local.js +91 -0
  224. package/dist/v2/cli-runner.d.ts +34 -0
  225. package/dist/v2/cli-runner.js +300 -0
  226. package/dist/v2/compiler-prompts.d.ts +27 -0
  227. package/dist/v2/compiler-prompts.js +123 -0
  228. package/dist/v2/compiler.d.ts +37 -0
  229. package/dist/v2/compiler.js +147 -0
  230. package/dist/v2/explorer.d.ts +41 -0
  231. package/dist/v2/explorer.js +56 -0
  232. package/dist/v2/index.d.ts +37 -0
  233. package/dist/v2/index.js +31 -0
  234. package/dist/v2/llm-healer.d.ts +62 -0
  235. package/dist/v2/llm-healer.js +166 -0
  236. package/dist/v2/llm-provider.d.ts +29 -0
  237. package/dist/v2/llm-provider.js +80 -0
  238. package/dist/v2/opcode-runner.d.ts +47 -0
  239. package/dist/v2/opcode-runner.js +634 -0
  240. package/dist/v2/overlay-engine.d.ts +24 -0
  241. package/dist/v2/overlay-engine.js +150 -0
  242. package/dist/v2/postcondition.d.ts +16 -0
  243. package/dist/v2/postcondition.js +249 -0
  244. package/dist/v2/program-patcher.d.ts +25 -0
  245. package/dist/v2/program-patcher.js +44 -0
  246. package/dist/v2/recovery-chain.d.ts +30 -0
  247. package/dist/v2/recovery-chain.js +368 -0
  248. package/dist/v2/schema.d.ts +2580 -0
  249. package/dist/v2/schema.js +295 -0
  250. package/dist/v2/selector-resolver.d.ts +34 -0
  251. package/dist/v2/selector-resolver.js +181 -0
  252. package/dist/v2/semantic-resolver.d.ts +35 -0
  253. package/dist/v2/semantic-resolver.js +161 -0
  254. package/dist/v2/smart-wait.d.ts +27 -0
  255. package/dist/v2/smart-wait.js +81 -0
  256. package/dist/v2/types.d.ts +444 -0
  257. package/dist/v2/types.js +19 -0
  258. package/dist/v2/web-playwright-local.d.ts +69 -0
  259. package/dist/v2/web-playwright-local.js +392 -0
  260. package/dist/version.d.ts +1 -0
  261. package/dist/version.js +5 -0
  262. package/dist/video-agent.js +18 -13
  263. package/dist/video-planner.js +2 -1
  264. package/dist/video-prompts.js +3 -3
  265. package/dist/web-playwright-local.d.ts +126 -0
  266. package/dist/web-playwright-local.js +819 -0
  267. package/dist/ws-auth.js +4 -1
  268. package/dist/ws-broadcast.d.ts +34 -0
  269. package/dist/ws-broadcast.js +85 -0
  270. package/dist/ws-connection-limits.d.ts +12 -0
  271. package/dist/ws-connection-limits.js +44 -0
  272. package/dist/ws-handler-utils.d.ts +32 -0
  273. package/dist/ws-handler-utils.js +139 -0
  274. package/dist/ws-handler.js +294 -164
  275. package/dist/ws-metrics-server.d.ts +9 -0
  276. package/dist/ws-metrics-server.js +31 -0
  277. package/dist/ws-server.js +41 -1
  278. package/package.json +51 -34
@@ -0,0 +1,295 @@
1
+ /**
2
+ * Capture Agent — Zod Validation Schemas
3
+ *
4
+ * Validates ExecutionProgram at compile output (server) and CLI input boundaries.
5
+ */
6
+ import { z } from 'zod';
7
+ // ── Postcondition ───────────────────────────────────────────────────
8
+ export const PostconditionSpecSchema = z.object({
9
+ type: z.enum([
10
+ 'route_matches',
11
+ 'element_visible',
12
+ 'element_absent',
13
+ 'text_contains',
14
+ 'overlay_dismissed',
15
+ 'screenshot_stable',
16
+ 'any_change',
17
+ 'always',
18
+ ]),
19
+ pattern: z.string().optional(),
20
+ selector: z.string().optional(),
21
+ text: z.string().optional(),
22
+ threshold: z.number().min(0).max(1).optional(),
23
+ waitMs: z.number().int().positive().optional(),
24
+ }).superRefine((value, ctx) => {
25
+ if (value.type === 'route_matches' && !value.pattern) {
26
+ ctx.addIssue({
27
+ code: z.ZodIssueCode.custom,
28
+ message: 'route_matches postconditions require `pattern`',
29
+ path: ['pattern'],
30
+ });
31
+ }
32
+ if (['element_visible', 'element_absent', 'text_contains'].includes(value.type) && !value.selector) {
33
+ ctx.addIssue({
34
+ code: z.ZodIssueCode.custom,
35
+ message: `${value.type} postconditions require \`selector\``,
36
+ path: ['selector'],
37
+ });
38
+ }
39
+ if (value.type === 'text_contains' && !value.text) {
40
+ ctx.addIssue({
41
+ code: z.ZodIssueCode.custom,
42
+ message: 'text_contains postconditions require `text`',
43
+ path: ['text'],
44
+ });
45
+ }
46
+ });
47
+ // ── Recovery policy ─────────────────────────────────────────────────
48
+ export const RecoveryPolicySchema = z.object({
49
+ retries: z.number().int().min(0).max(10),
50
+ useSelectorMemory: z.boolean(),
51
+ useAltInteraction: z.boolean(),
52
+ allowReload: z.boolean(),
53
+ allowHealer: z.boolean(),
54
+ });
55
+ // ── Opcode base fields ──────────────────────────────────────────────
56
+ const opcodeBase = {
57
+ description: z.string().min(1),
58
+ postcondition: PostconditionSpecSchema,
59
+ recovery: RecoveryPolicySchema,
60
+ timeoutMs: z.number().int().positive(),
61
+ maxFailures: z.number().int().positive(),
62
+ };
63
+ // ── Individual opcode schemas ───────────────────────────────────────
64
+ const NavigateOpcodeSchema = z.object({
65
+ kind: z.literal('NAVIGATE'),
66
+ ...opcodeBase,
67
+ url: z.string().min(1),
68
+ });
69
+ const DismissOverlaysOpcodeSchema = z.object({
70
+ kind: z.literal('DISMISS_OVERLAYS'),
71
+ ...opcodeBase,
72
+ });
73
+ const AssertRouteOpcodeSchema = z.object({
74
+ kind: z.literal('ASSERT_ROUTE'),
75
+ ...opcodeBase,
76
+ urlPattern: z.string().min(1),
77
+ });
78
+ const AssertSurfaceOpcodeSchema = z.object({
79
+ kind: z.literal('ASSERT_SURFACE'),
80
+ ...opcodeBase,
81
+ selectors: z.array(z.string().min(1)).min(1),
82
+ matchAll: z.boolean(),
83
+ });
84
+ const SemanticTargetSchema = z.object({
85
+ text: z.string().optional(),
86
+ role: z.string().optional(),
87
+ label: z.string().optional(),
88
+ near: z.string().optional(),
89
+ placeholder: z.string().optional(),
90
+ exact: z.boolean().optional(),
91
+ }).refine((value) => Boolean(value.text || value.role || value.label || value.near || value.placeholder), 'semantic targets need at least one identifying field');
92
+ const ClickOpcodeSchema = z.object({
93
+ kind: z.literal('CLICK'),
94
+ ...opcodeBase,
95
+ selector: z.string().min(1),
96
+ target: SemanticTargetSchema.optional(),
97
+ fingerprint: z.string().optional(),
98
+ selectorAlternates: z.array(z.string().min(1)).optional(),
99
+ });
100
+ const TypeOpcodeSchema = z.object({
101
+ kind: z.literal('TYPE'),
102
+ ...opcodeBase,
103
+ selector: z.string().min(1),
104
+ target: SemanticTargetSchema.optional(),
105
+ text: z.string(),
106
+ clearFirst: z.boolean(),
107
+ fingerprint: z.string().optional(),
108
+ selectorAlternates: z.array(z.string().min(1)).optional(),
109
+ });
110
+ const PressKeyOpcodeSchema = z.object({
111
+ kind: z.literal('PRESS_KEY'),
112
+ ...opcodeBase,
113
+ key: z.string().min(1),
114
+ });
115
+ const WaitForOpcodeSchema = z.object({
116
+ kind: z.literal('WAIT_FOR'),
117
+ ...opcodeBase,
118
+ selector: z.string().min(1).optional(),
119
+ target: SemanticTargetSchema.optional(),
120
+ state: z.enum(['visible', 'attached']),
121
+ }).superRefine((value, ctx) => {
122
+ if (!value.selector && !value.target) {
123
+ ctx.addIssue({
124
+ code: z.ZodIssueCode.custom,
125
+ message: 'WAIT_FOR requires either `selector` or `target`',
126
+ path: ['selector'],
127
+ });
128
+ }
129
+ });
130
+ const storageHintSchema = z.object({
131
+ storage: z.enum(['localStorage', 'sessionStorage']),
132
+ key: z.string().min(1),
133
+ value: z.string(),
134
+ });
135
+ const SetLocaleOpcodeSchema = z.object({
136
+ kind: z.literal('SET_LOCALE'),
137
+ ...opcodeBase,
138
+ locale: z.string().min(1),
139
+ method: z.enum(['browser_context', 'ui_interaction', 'storage']),
140
+ selector: z.string().optional(),
141
+ storageHints: z.array(storageHintSchema).optional(),
142
+ }).superRefine((value, ctx) => {
143
+ if (value.method === 'ui_interaction' && !value.selector) {
144
+ ctx.addIssue({
145
+ code: z.ZodIssueCode.custom,
146
+ message: 'SET_LOCALE with `ui_interaction` requires `selector`',
147
+ path: ['selector'],
148
+ });
149
+ }
150
+ if (value.method === 'storage' && (!value.storageHints || value.storageHints.length === 0)) {
151
+ ctx.addIssue({
152
+ code: z.ZodIssueCode.custom,
153
+ message: 'SET_LOCALE with `storage` requires at least one `storageHints` entry',
154
+ path: ['storageHints'],
155
+ });
156
+ }
157
+ });
158
+ const SetThemeOpcodeSchema = z.object({
159
+ kind: z.literal('SET_THEME'),
160
+ ...opcodeBase,
161
+ theme: z.enum(['light', 'dark']),
162
+ method: z.enum(['color_scheme', 'ui_interaction', 'storage']),
163
+ selector: z.string().optional(),
164
+ storageHints: z.array(storageHintSchema).optional(),
165
+ }).superRefine((value, ctx) => {
166
+ if (value.method === 'ui_interaction' && !value.selector) {
167
+ ctx.addIssue({
168
+ code: z.ZodIssueCode.custom,
169
+ message: 'SET_THEME with `ui_interaction` requires `selector`',
170
+ path: ['selector'],
171
+ });
172
+ }
173
+ if (value.method === 'storage' && (!value.storageHints || value.storageHints.length === 0)) {
174
+ ctx.addIssue({
175
+ code: z.ZodIssueCode.custom,
176
+ message: 'SET_THEME with `storage` requires at least one `storageHints` entry',
177
+ path: ['storageHints'],
178
+ });
179
+ }
180
+ });
181
+ const ScrollOpcodeSchema = z.object({
182
+ kind: z.literal('SCROLL'),
183
+ ...opcodeBase,
184
+ direction: z.enum(['up', 'down', 'left', 'right']),
185
+ amount: z.number().int().positive().optional(),
186
+ targetSelector: z.string().optional(),
187
+ target: SemanticTargetSchema.optional(),
188
+ });
189
+ const CaptureScreenshotOpcodeSchema = z.object({
190
+ kind: z.literal('CAPTURE_SCREENSHOT'),
191
+ ...opcodeBase,
192
+ captureId: z.string().optional(),
193
+ captureName: z.string().optional(),
194
+ elementSelector: z.string().optional(),
195
+ });
196
+ const BeginClipOpcodeSchema = z.object({
197
+ kind: z.literal('BEGIN_CLIP'),
198
+ ...opcodeBase,
199
+ clipId: z.string().optional(),
200
+ clipName: z.string().optional(),
201
+ });
202
+ const EndClipOpcodeSchema = z.object({
203
+ kind: z.literal('END_CLIP'),
204
+ ...opcodeBase,
205
+ clipId: z.string().optional(),
206
+ clipName: z.string().optional(),
207
+ });
208
+ // ── Discriminated union ─────────────────────────────────────────────
209
+ export const ExecutionOpcodeSchema = z.discriminatedUnion('kind', [
210
+ NavigateOpcodeSchema,
211
+ DismissOverlaysOpcodeSchema,
212
+ AssertRouteOpcodeSchema,
213
+ AssertSurfaceOpcodeSchema,
214
+ ClickOpcodeSchema,
215
+ TypeOpcodeSchema,
216
+ PressKeyOpcodeSchema,
217
+ WaitForOpcodeSchema,
218
+ SetLocaleOpcodeSchema,
219
+ SetThemeOpcodeSchema,
220
+ ScrollOpcodeSchema,
221
+ CaptureScreenshotOpcodeSchema,
222
+ BeginClipOpcodeSchema,
223
+ EndClipOpcodeSchema,
224
+ ]);
225
+ // ── Variant & precondition ──────────────────────────────────────────
226
+ export const VariantSpecSchema = z.object({
227
+ id: z.string().min(1),
228
+ viewport: z.object({
229
+ width: z.number().int().positive(),
230
+ height: z.number().int().positive(),
231
+ }),
232
+ deviceScaleFactor: z.number().positive().optional(),
233
+ locale: z.string().optional(),
234
+ theme: z.enum(['light', 'dark']).optional(),
235
+ targetId: z.string().optional(),
236
+ targetLabel: z.string().optional(),
237
+ deviceFrame: z.string().optional(),
238
+ });
239
+ const cookieSchema = z.object({
240
+ name: z.string().min(1),
241
+ value: z.string(),
242
+ domain: z.string().min(1),
243
+ path: z.string().optional(),
244
+ });
245
+ export const PreconditionSpecSchema = z.object({
246
+ auth: z.enum(['authenticated', 'anonymous', 'any']),
247
+ credentialsId: z.string().optional(),
248
+ storageState: z.any().optional(),
249
+ sessionStorage: z.record(z.string(), z.record(z.string(), z.string())).optional(),
250
+ cookies: z.array(cookieSchema).optional(),
251
+ });
252
+ // ── Artifact spec ───────────────────────────────────────────────────
253
+ export const ArtifactSpecSchema = z.object({
254
+ mediaMode: z.enum(['screenshot', 'clip']),
255
+ format: z.object({
256
+ clipFormat: z.enum(['gif', 'mp4', 'both']).optional(),
257
+ screenshotFormat: z.enum(['png', 'jpeg']).optional(),
258
+ }).optional(),
259
+ cursorTheme: z.enum(['minimal', 'macos', 'windows']).optional(),
260
+ applyMockup: z.boolean().optional(),
261
+ applyStatusBar: z.boolean().optional(),
262
+ });
263
+ // ── Full program ────────────────────────────────────────────────────
264
+ export const ExecutionProgramSchema = z.object({
265
+ presetId: z.string().min(1),
266
+ programVersion: z.number().int().positive(),
267
+ mediaMode: z.enum(['screenshot', 'clip']),
268
+ baseUrl: z.string().url(),
269
+ variants: z.array(VariantSpecSchema).min(1),
270
+ preconditions: PreconditionSpecSchema,
271
+ steps: z.array(ExecutionOpcodeSchema).min(1),
272
+ artifactPlan: ArtifactSpecSchema,
273
+ compileFingerprint: z.string().min(1),
274
+ compiledAt: z.string().datetime(),
275
+ compiledWith: z.string().optional(),
276
+ });
277
+ // ── Healer patch ────────────────────────────────────────────────────
278
+ export const HealerPatchSchema = z.object({
279
+ opcodeIndex: z.number().int().min(0),
280
+ originalOpcode: ExecutionOpcodeSchema,
281
+ replacementOpcodes: z.array(ExecutionOpcodeSchema).min(1).max(3),
282
+ reason: z.string().min(1),
283
+ patchedAt: z.string().datetime(),
284
+ });
285
+ // ── Typed parse helpers ─────────────────────────────────────────────
286
+ export function parseProgram(data) {
287
+ return ExecutionProgramSchema.parse(data);
288
+ }
289
+ export function parseOpcode(data) {
290
+ return ExecutionOpcodeSchema.parse(data);
291
+ }
292
+ export function safeParseProgramResult(data) {
293
+ return ExecutionProgramSchema.safeParse(data);
294
+ }
295
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1,34 @@
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
+ import type { RuntimeAdapter } from './types.js';
11
+ export interface ResolvedSelector {
12
+ selector: string;
13
+ strategy: 'primary' | 'fingerprint' | 'memory' | 'fuzzy_text' | 'alternate';
14
+ confidence: 'high' | 'medium' | 'low';
15
+ }
16
+ export interface SelectorResolverOptions {
17
+ /** Primary selector from the compiled opcode */
18
+ primary: string;
19
+ /** AKTree fingerprint for fuzzy matching */
20
+ fingerprint?: string;
21
+ /** Alternative selectors from the compiled opcode */
22
+ alternates?: string[];
23
+ /** Selector memory map: stepSignature -> known-good selectors */
24
+ selectorMemory?: Record<string, string[]>;
25
+ /** Step signature for memory lookup */
26
+ stepSignature?: string;
27
+ /** Human-readable description of the target element (for fuzzy matching) */
28
+ description?: string;
29
+ }
30
+ /**
31
+ * Resolves a selector by trying multiple strategies in order.
32
+ * Returns the first working selector, or null if nothing matches.
33
+ */
34
+ export declare function resolveSelector(adapter: RuntimeAdapter, options: SelectorResolverOptions): Promise<ResolvedSelector | null>;
@@ -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 './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>;