@eidra-umain/greenlight 0.1.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 (142) hide show
  1. package/README.md +391 -0
  2. package/dist/browser/browser.d.ts +24 -0
  3. package/dist/browser/browser.d.ts.map +1 -0
  4. package/dist/browser/browser.js +44 -0
  5. package/dist/browser/browser.js.map +1 -0
  6. package/dist/cli/index.d.ts +3 -0
  7. package/dist/cli/index.d.ts.map +1 -0
  8. package/dist/cli/index.js +140 -0
  9. package/dist/cli/index.js.map +1 -0
  10. package/dist/cli/run.d.ts +9 -0
  11. package/dist/cli/run.d.ts.map +1 -0
  12. package/dist/cli/run.js +277 -0
  13. package/dist/cli/run.js.map +1 -0
  14. package/dist/config.d.ts +48 -0
  15. package/dist/config.d.ts.map +1 -0
  16. package/dist/config.js +107 -0
  17. package/dist/config.js.map +1 -0
  18. package/dist/globals.d.ts +21 -0
  19. package/dist/globals.d.ts.map +1 -0
  20. package/dist/globals.js +24 -0
  21. package/dist/globals.js.map +1 -0
  22. package/dist/parser/loader.d.ts +7 -0
  23. package/dist/parser/loader.d.ts.map +1 -0
  24. package/dist/parser/loader.js +43 -0
  25. package/dist/parser/loader.js.map +1 -0
  26. package/dist/parser/schema.d.ts +42 -0
  27. package/dist/parser/schema.d.ts.map +1 -0
  28. package/dist/parser/schema.js +33 -0
  29. package/dist/parser/schema.js.map +1 -0
  30. package/dist/parser/steps.d.ts +13 -0
  31. package/dist/parser/steps.d.ts.map +1 -0
  32. package/dist/parser/steps.js +44 -0
  33. package/dist/parser/steps.js.map +1 -0
  34. package/dist/parser/variables.d.ts +18 -0
  35. package/dist/parser/variables.d.ts.map +1 -0
  36. package/dist/parser/variables.js +44 -0
  37. package/dist/parser/variables.js.map +1 -0
  38. package/dist/pilot/a11y-parser.d.ts +26 -0
  39. package/dist/pilot/a11y-parser.d.ts.map +1 -0
  40. package/dist/pilot/a11y-parser.js +195 -0
  41. package/dist/pilot/a11y-parser.js.map +1 -0
  42. package/dist/pilot/assertions.d.ts +30 -0
  43. package/dist/pilot/assertions.d.ts.map +1 -0
  44. package/dist/pilot/assertions.js +219 -0
  45. package/dist/pilot/assertions.js.map +1 -0
  46. package/dist/pilot/checkbox.d.ts +12 -0
  47. package/dist/pilot/checkbox.d.ts.map +1 -0
  48. package/dist/pilot/checkbox.js +104 -0
  49. package/dist/pilot/checkbox.js.map +1 -0
  50. package/dist/pilot/executor.d.ts +17 -0
  51. package/dist/pilot/executor.d.ts.map +1 -0
  52. package/dist/pilot/executor.js +462 -0
  53. package/dist/pilot/executor.js.map +1 -0
  54. package/dist/pilot/form-fields.d.ts +34 -0
  55. package/dist/pilot/form-fields.d.ts.map +1 -0
  56. package/dist/pilot/form-fields.js +139 -0
  57. package/dist/pilot/form-fields.js.map +1 -0
  58. package/dist/pilot/llm.d.ts +49 -0
  59. package/dist/pilot/llm.d.ts.map +1 -0
  60. package/dist/pilot/llm.js +188 -0
  61. package/dist/pilot/llm.js.map +1 -0
  62. package/dist/pilot/locator.d.ts +58 -0
  63. package/dist/pilot/locator.d.ts.map +1 -0
  64. package/dist/pilot/locator.js +248 -0
  65. package/dist/pilot/locator.js.map +1 -0
  66. package/dist/pilot/message-builder.d.ts +31 -0
  67. package/dist/pilot/message-builder.d.ts.map +1 -0
  68. package/dist/pilot/message-builder.js +112 -0
  69. package/dist/pilot/message-builder.js.map +1 -0
  70. package/dist/pilot/network.d.ts +23 -0
  71. package/dist/pilot/network.d.ts.map +1 -0
  72. package/dist/pilot/network.js +92 -0
  73. package/dist/pilot/network.js.map +1 -0
  74. package/dist/pilot/pilot.d.ts +27 -0
  75. package/dist/pilot/pilot.d.ts.map +1 -0
  76. package/dist/pilot/pilot.js +249 -0
  77. package/dist/pilot/pilot.js.map +1 -0
  78. package/dist/pilot/prompts.d.ts +8 -0
  79. package/dist/pilot/prompts.d.ts.map +1 -0
  80. package/dist/pilot/prompts.js +163 -0
  81. package/dist/pilot/prompts.js.map +1 -0
  82. package/dist/pilot/providers/anthropic.d.ts +6 -0
  83. package/dist/pilot/providers/anthropic.d.ts.map +1 -0
  84. package/dist/pilot/providers/anthropic.js +45 -0
  85. package/dist/pilot/providers/anthropic.js.map +1 -0
  86. package/dist/pilot/providers/gemini.d.ts +6 -0
  87. package/dist/pilot/providers/gemini.d.ts.map +1 -0
  88. package/dist/pilot/providers/gemini.js +55 -0
  89. package/dist/pilot/providers/gemini.js.map +1 -0
  90. package/dist/pilot/providers/index.d.ts +10 -0
  91. package/dist/pilot/providers/index.d.ts.map +1 -0
  92. package/dist/pilot/providers/index.js +25 -0
  93. package/dist/pilot/providers/index.js.map +1 -0
  94. package/dist/pilot/providers/openai-compatible.d.ts +7 -0
  95. package/dist/pilot/providers/openai-compatible.d.ts.map +1 -0
  96. package/dist/pilot/providers/openai-compatible.js +34 -0
  97. package/dist/pilot/providers/openai-compatible.js.map +1 -0
  98. package/dist/pilot/providers/types.d.ts +12 -0
  99. package/dist/pilot/providers/types.d.ts.map +1 -0
  100. package/dist/pilot/providers/types.js +2 -0
  101. package/dist/pilot/providers/types.js.map +1 -0
  102. package/dist/pilot/response-parser.d.ts +31 -0
  103. package/dist/pilot/response-parser.d.ts.map +1 -0
  104. package/dist/pilot/response-parser.js +188 -0
  105. package/dist/pilot/response-parser.js.map +1 -0
  106. package/dist/pilot/state.d.ts +19 -0
  107. package/dist/pilot/state.d.ts.map +1 -0
  108. package/dist/pilot/state.js +67 -0
  109. package/dist/pilot/state.js.map +1 -0
  110. package/dist/pilot/trace.d.ts +16 -0
  111. package/dist/pilot/trace.d.ts.map +1 -0
  112. package/dist/pilot/trace.js +117 -0
  113. package/dist/pilot/trace.js.map +1 -0
  114. package/dist/planner/hasher.d.ts +14 -0
  115. package/dist/planner/hasher.d.ts.map +1 -0
  116. package/dist/planner/hasher.js +21 -0
  117. package/dist/planner/hasher.js.map +1 -0
  118. package/dist/planner/plan-generator.d.ts +23 -0
  119. package/dist/planner/plan-generator.d.ts.map +1 -0
  120. package/dist/planner/plan-generator.js +56 -0
  121. package/dist/planner/plan-generator.js.map +1 -0
  122. package/dist/planner/plan-runner.d.ts +16 -0
  123. package/dist/planner/plan-runner.d.ts.map +1 -0
  124. package/dist/planner/plan-runner.js +375 -0
  125. package/dist/planner/plan-runner.js.map +1 -0
  126. package/dist/planner/plan-store.d.ts +22 -0
  127. package/dist/planner/plan-store.d.ts.map +1 -0
  128. package/dist/planner/plan-store.js +71 -0
  129. package/dist/planner/plan-store.js.map +1 -0
  130. package/dist/planner/plan-types.d.ts +64 -0
  131. package/dist/planner/plan-types.d.ts.map +1 -0
  132. package/dist/planner/plan-types.js +7 -0
  133. package/dist/planner/plan-types.js.map +1 -0
  134. package/dist/reporter/types.d.ts +130 -0
  135. package/dist/reporter/types.d.ts.map +1 -0
  136. package/dist/reporter/types.js +5 -0
  137. package/dist/reporter/types.js.map +1 -0
  138. package/dist/types.d.ts +51 -0
  139. package/dist/types.d.ts.map +1 -0
  140. package/dist/types.js +23 -0
  141. package/dist/types.js.map +1 -0
  142. package/package.json +64 -0
@@ -0,0 +1,462 @@
1
+ /**
2
+ * Action executor — translates LLM Action objects into Playwright browser calls.
3
+ */
4
+ import { globals } from "../globals.js";
5
+ import { resolveLocator, resolveActionTarget, extractSelectorInfo, } from "./locator.js";
6
+ import { checkCheckbox } from "./checkbox.js";
7
+ import { executeAssertion } from "./assertions.js";
8
+ /**
9
+ * Run an action that might trigger navigation.
10
+ * Listens for a 'framenavigated' event during the action — if one fires,
11
+ * waits for the new page to reach domcontentloaded. If no navigation
12
+ * happens, returns immediately with no delay.
13
+ */
14
+ export async function runWithNavigationHandling(page, action) {
15
+ // Track whether the action triggers a navigation via event callback.
16
+ // The flag is mutated asynchronously by the event handler.
17
+ const state = { navigated: false };
18
+ const onNav = () => {
19
+ state.navigated = true;
20
+ };
21
+ page.on("framenavigated", onNav);
22
+ try {
23
+ await action();
24
+ if (state.navigated) {
25
+ await page.waitForLoadState("domcontentloaded");
26
+ }
27
+ }
28
+ finally {
29
+ page.off("framenavigated", onNav);
30
+ }
31
+ }
32
+ /**
33
+ * Search the a11y tree for a node whose name contains a number and
34
+ * matches any of the given keywords. Used as a fallback when the LLM
35
+ * returns a remember action without specifying a target element.
36
+ */
37
+ function findValueInTree(nodes, keywords) {
38
+ const lowerKeywords = keywords.map((k) => k.toLowerCase());
39
+ let bestMatch = "";
40
+ function walk(nodeList) {
41
+ for (const node of nodeList) {
42
+ const name = node.name.toLowerCase();
43
+ // Check if the name contains a number
44
+ if (/\d/.test(name)) {
45
+ // Check if any keyword matches
46
+ const matches = lowerKeywords.some((kw) => name.includes(kw));
47
+ if (matches) {
48
+ // Prefer shorter, more specific matches
49
+ if (!bestMatch || node.name.length < bestMatch.length) {
50
+ bestMatch = node.name;
51
+ }
52
+ }
53
+ }
54
+ if (node.children)
55
+ walk(node.children);
56
+ }
57
+ }
58
+ walk(nodes);
59
+ return bestMatch;
60
+ }
61
+ /**
62
+ * Execute a single Action against the browser page.
63
+ */
64
+ export async function executeAction(page, action, a11yTree, _valueStore) {
65
+ const start = performance.now();
66
+ let rememberedValue;
67
+ let resolvedSelector;
68
+ try {
69
+ switch (action.action) {
70
+ case "click": {
71
+ const locator = await resolveActionTarget(page, action, a11yTree);
72
+ resolvedSelector = await extractSelectorInfo(page, action, a11yTree, locator);
73
+ await runWithNavigationHandling(page, () => locator.click());
74
+ break;
75
+ }
76
+ case "check": {
77
+ const locator = await resolveActionTarget(page, action, a11yTree);
78
+ resolvedSelector = await extractSelectorInfo(page, action, a11yTree, locator);
79
+ await checkCheckbox(page, locator, true);
80
+ break;
81
+ }
82
+ case "uncheck": {
83
+ const locator = await resolveActionTarget(page, action, a11yTree);
84
+ resolvedSelector = await extractSelectorInfo(page, action, a11yTree, locator);
85
+ await checkCheckbox(page, locator, false);
86
+ break;
87
+ }
88
+ case "type": {
89
+ if (!action.value) {
90
+ throw new Error("type action requires a value");
91
+ }
92
+ const locator = await resolveActionTarget(page, action, a11yTree);
93
+ resolvedSelector = await extractSelectorInfo(page, action, a11yTree, locator);
94
+ // Click to focus, clear existing value, then type character by
95
+ // character. pressSequentially dispatches real keydown/keypress/
96
+ // keyup/input events per keystroke, which is required for
97
+ // frameworks that rely on JS input events (React onChange, custom
98
+ // validation, etc.). fill() bypasses these.
99
+ await locator.click();
100
+ await locator.fill("");
101
+ await locator.pressSequentially(action.value, { delay: 30 });
102
+ // Verify the value landed correctly. Async UI (search dropdowns,
103
+ // autocomplete overlays) can steal focus or trigger re-renders
104
+ // that swallow the last keystrokes. If the value drifted, re-focus
105
+ // and type the missing suffix.
106
+ const actual = await locator.inputValue().catch(() => "");
107
+ if (actual !== action.value) {
108
+ if (globals.debug) {
109
+ console.log(` [type] Value drifted: got "${actual}", expected "${action.value}" — correcting`);
110
+ }
111
+ await locator.click();
112
+ if (action.value.startsWith(actual)) {
113
+ // Only the tail is missing — append it
114
+ await locator.pressSequentially(action.value.slice(actual.length), { delay: 30 });
115
+ }
116
+ else {
117
+ // Value is garbled — clear and retype
118
+ await locator.fill("");
119
+ await locator.pressSequentially(action.value, { delay: 30 });
120
+ }
121
+ }
122
+ break;
123
+ }
124
+ case "select": {
125
+ if (!action.value) {
126
+ throw new Error("select action requires a value");
127
+ }
128
+ const locator = await resolveActionTarget(page, action, a11yTree);
129
+ resolvedSelector = await extractSelectorInfo(page, action, a11yTree, locator);
130
+ // Try native <select> first; if the element is a custom dropdown
131
+ // (button/div with aria-haspopup), click to open it then click
132
+ // the option by text.
133
+ const tagName = await locator.evaluate((el) => el.tagName).catch(() => "");
134
+ if (tagName === "SELECT") {
135
+ await locator.selectOption({ label: action.value });
136
+ }
137
+ else {
138
+ if (globals.debug) {
139
+ console.log(` [select] Element is not a <select>, using click-to-open strategy`);
140
+ }
141
+ // Click to open the dropdown
142
+ await locator.click();
143
+ // After clicking the trigger, wait a moment for the popup
144
+ // to render, then find the option.
145
+ await page.waitForTimeout(500);
146
+ if (globals.debug) {
147
+ try {
148
+ const menuId = await locator.evaluate((el) => el.getAttribute("aria-controls") ??
149
+ el.getAttribute("data-controls") ?? "");
150
+ console.log(` [select] Trigger aria-controls="${menuId}"`);
151
+ // Dump all potential popup containers on the page
152
+ const selectors = [
153
+ "[role='menu']", "[role='listbox']",
154
+ "[data-part='content']", "[data-state='open']",
155
+ "[data-scope='menu']", "[aria-haspopup]",
156
+ ];
157
+ for (const sel of selectors) {
158
+ const count = await page.locator(sel).count().catch(() => 0);
159
+ if (count > 0) {
160
+ const visible = await page.locator(sel).first().isVisible().catch(() => false);
161
+ console.log(` [select] ${sel}: ${String(count)} found, first visible=${String(visible)}`);
162
+ }
163
+ }
164
+ }
165
+ catch { /* skip */ }
166
+ }
167
+ // Strategy 1: Find menu container via aria-controls and
168
+ // search within it (safe — scoped to the popup).
169
+ let clicked = false;
170
+ try {
171
+ const menuId = await locator.evaluate((el) => el.getAttribute("aria-controls") ??
172
+ el.getAttribute("data-controls") ?? "");
173
+ if (menuId) {
174
+ const menu = page.locator(`#${CSS.escape(menuId)}`);
175
+ if (await menu.isVisible().catch(() => false)) {
176
+ if (globals.debug) {
177
+ console.log(` [select] Found menu container: #${menuId}`);
178
+ }
179
+ const opt = menu.getByText(action.value, { exact: true });
180
+ if (await opt.first().isVisible().catch(() => false)) {
181
+ await opt.first().click();
182
+ clicked = true;
183
+ }
184
+ else {
185
+ // Try loose match within menu
186
+ const loose = menu.getByText(action.value);
187
+ if (await loose.first().isVisible().catch(() => false)) {
188
+ await loose.first().click();
189
+ clicked = true;
190
+ }
191
+ }
192
+ }
193
+ }
194
+ }
195
+ catch { /* try next strategy */ }
196
+ // Strategy 2: Search all visible popup-like containers
197
+ if (!clicked) {
198
+ const popupSelectors = [
199
+ "[role='menu']",
200
+ "[role='listbox']",
201
+ "[data-part='content']",
202
+ "[data-state='open'][data-scope='menu']",
203
+ "[data-radix-popper-content-wrapper]",
204
+ ];
205
+ for (const sel of popupSelectors) {
206
+ try {
207
+ const containers = page.locator(sel);
208
+ const count = await containers.count();
209
+ for (let i = 0; i < count && !clicked; i++) {
210
+ const container = containers.nth(i);
211
+ if (!await container.isVisible().catch(() => false))
212
+ continue;
213
+ const opt = container.getByText(action.value, { exact: true });
214
+ if (await opt.first().isVisible().catch(() => false)) {
215
+ if (globals.debug) {
216
+ console.log(` [select] Found option in ${sel} container`);
217
+ }
218
+ await opt.first().click();
219
+ clicked = true;
220
+ }
221
+ }
222
+ }
223
+ catch { /* try next */ }
224
+ if (clicked)
225
+ break;
226
+ }
227
+ }
228
+ // Strategy 3: Role-based page-wide (menuitem/option only)
229
+ if (!clicked) {
230
+ const roleCandidates = [
231
+ page.getByRole("menuitem", { name: action.value }),
232
+ page.getByRole("menuitemradio", { name: action.value }),
233
+ page.getByRole("option", { name: action.value }),
234
+ ];
235
+ for (const opt of roleCandidates) {
236
+ try {
237
+ if (await opt.first().isVisible().catch(() => false)) {
238
+ if (globals.debug) {
239
+ console.log(` [select] Found option via page-wide role search`);
240
+ }
241
+ await opt.first().click();
242
+ clicked = true;
243
+ break;
244
+ }
245
+ }
246
+ catch { /* try next */ }
247
+ }
248
+ }
249
+ if (!clicked) {
250
+ throw new Error(`Could not find option "${action.value}" in custom dropdown`);
251
+ }
252
+ }
253
+ break;
254
+ }
255
+ case "autocomplete": {
256
+ if (!action.value) {
257
+ throw new Error("autocomplete action requires a value");
258
+ }
259
+ const locator = await resolveActionTarget(page, action, a11yTree);
260
+ resolvedSelector = await extractSelectorInfo(page, action, a11yTree, locator);
261
+ if (globals.debug) {
262
+ console.log(` [autocomplete] Typing "${action.value}" into field (target: ${action.ref ?? action.text ?? "unknown"})`);
263
+ if (action.option) {
264
+ console.log(` [autocomplete] Will select specific option: "${action.option}"`);
265
+ }
266
+ else {
267
+ console.log(` [autocomplete] Will select first suggestion`);
268
+ }
269
+ }
270
+ // Click to focus, then type character by character to trigger autocomplete
271
+ await locator.click();
272
+ await locator.fill("");
273
+ await locator.pressSequentially(action.value, { delay: 50 });
274
+ if (globals.debug) {
275
+ console.log(` [autocomplete] Typed "${action.value}", waiting for suggestions...`);
276
+ }
277
+ // Wait for autocomplete suggestions to appear.
278
+ // Try multiple common patterns: role=option, role=listbox children,
279
+ // generic dropdown/suggestion containers.
280
+ const suggestionPatterns = [
281
+ { name: "role=option", locator: page.locator("[role='option']") },
282
+ { name: "role=listbox children", locator: page.locator("[role='listbox'] > *") },
283
+ { name: "CSS class patterns", locator: page.locator(".autocomplete-results > *, .suggestions > *, .dropdown-menu > *") },
284
+ ];
285
+ let suggestions;
286
+ let matchedPattern;
287
+ for (const pattern of suggestionPatterns) {
288
+ try {
289
+ await pattern.locator.first().waitFor({ state: "visible", timeout: 5000 });
290
+ suggestions = pattern.locator;
291
+ matchedPattern = pattern.name;
292
+ break;
293
+ }
294
+ catch {
295
+ if (globals.debug) {
296
+ console.log(` [autocomplete] Pattern "${pattern.name}" — no match`);
297
+ }
298
+ }
299
+ }
300
+ if (!suggestions) {
301
+ throw new Error("Autocomplete suggestions did not appear after typing");
302
+ }
303
+ const suggestionCount = await suggestions.count();
304
+ if (globals.debug) {
305
+ console.log(` [autocomplete] Found ${String(suggestionCount)} suggestions via "${matchedPattern ?? "unknown"}"`);
306
+ // Log first few suggestion texts
307
+ const previewCount = Math.min(suggestionCount, 5);
308
+ for (let i = 0; i < previewCount; i++) {
309
+ try {
310
+ const text = await suggestions.nth(i).textContent();
311
+ console.log(` [autocomplete] ${String(i + 1)}. ${text?.trim() ?? "(empty)"}`);
312
+ }
313
+ catch { /* skip */ }
314
+ }
315
+ if (suggestionCount > 5) {
316
+ console.log(` [autocomplete] ... and ${String(suggestionCount - 5)} more`);
317
+ }
318
+ }
319
+ // Select the target option
320
+ if (action.option) {
321
+ // Find by matching text
322
+ const optionCandidates = [
323
+ { name: "filter by hasText", locator: suggestions.filter({ hasText: action.option }).first() },
324
+ { name: "getByRole option", locator: page.getByRole("option", { name: action.option }) },
325
+ { name: "getByText exact", locator: page.getByText(action.option, { exact: true }) },
326
+ { name: "getByText loose", locator: page.getByText(action.option) },
327
+ ];
328
+ let clicked = false;
329
+ for (const candidate of optionCandidates) {
330
+ try {
331
+ if (await candidate.locator.isVisible()) {
332
+ if (globals.debug) {
333
+ console.log(` [autocomplete] Clicking option "${action.option}" via ${candidate.name}`);
334
+ }
335
+ await candidate.locator.click();
336
+ clicked = true;
337
+ break;
338
+ }
339
+ }
340
+ catch {
341
+ if (globals.debug) {
342
+ console.log(` [autocomplete] Option strategy "${candidate.name}" — no match`);
343
+ }
344
+ }
345
+ }
346
+ if (!clicked) {
347
+ throw new Error(`Autocomplete option "${action.option}" not found in suggestions`);
348
+ }
349
+ }
350
+ else {
351
+ // Click the first visible suggestion
352
+ if (globals.debug) {
353
+ const firstText = await suggestions.first().textContent();
354
+ console.log(` [autocomplete] Clicking first suggestion: "${firstText?.trim() ?? "(empty)"}"`);
355
+ }
356
+ await suggestions.first().click();
357
+ }
358
+ if (globals.debug) {
359
+ console.log(` [autocomplete] Done`);
360
+ }
361
+ break;
362
+ }
363
+ case "scroll": {
364
+ if (action.ref) {
365
+ const locator = await resolveLocator(page, a11yTree, action.ref);
366
+ resolvedSelector = await extractSelectorInfo(page, action, a11yTree, locator);
367
+ await locator.scrollIntoViewIfNeeded();
368
+ }
369
+ else {
370
+ const delta = action.value === "up" ? -500 : 500;
371
+ await page.mouse.wheel(0, delta);
372
+ }
373
+ break;
374
+ }
375
+ case "press": {
376
+ if (!action.value) {
377
+ throw new Error("press action requires a value");
378
+ }
379
+ const key = action.value;
380
+ await runWithNavigationHandling(page, () => page.keyboard.press(key));
381
+ break;
382
+ }
383
+ case "navigate": {
384
+ if (!action.value) {
385
+ throw new Error("navigate action requires a value");
386
+ }
387
+ const url = action.value.startsWith("/")
388
+ ? new URL(action.value, page.url()).href
389
+ : action.value;
390
+ await page.goto(url, { waitUntil: "domcontentloaded" });
391
+ break;
392
+ }
393
+ case "wait": {
394
+ if (!action.value) {
395
+ throw new Error("wait action requires a value");
396
+ }
397
+ // Wait for text to appear on the page
398
+ await page.getByText(action.value).waitFor({ state: "visible" });
399
+ break;
400
+ }
401
+ case "remember": {
402
+ let capturedText;
403
+ if (action.ref || action.text) {
404
+ const locator = await resolveActionTarget(page, action, a11yTree);
405
+ resolvedSelector = await extractSelectorInfo(page, action, a11yTree, locator);
406
+ capturedText = (await locator.textContent() ?? "").trim();
407
+ }
408
+ else {
409
+ // LLM didn't specify a target element. Search the a11y tree
410
+ // for nodes whose text contains a number and matches keywords
411
+ // from the step description (the variable name or step text).
412
+ if (globals.debug) {
413
+ console.log(` [remember] No ref/text target, searching a11y tree for matching value`);
414
+ }
415
+ const keywords = (action.rememberAs ?? "")
416
+ .replace(/_/g, " ")
417
+ .split(" ")
418
+ .filter((w) => w.length > 2);
419
+ capturedText = findValueInTree(a11yTree, keywords);
420
+ if (!capturedText) {
421
+ throw new Error(`remember action: LLM returned no element target and could not find a matching value in the page`);
422
+ }
423
+ if (globals.debug) {
424
+ console.log(` [remember] Found by keyword search: "${capturedText}"`);
425
+ }
426
+ }
427
+ if (globals.debug) {
428
+ const preview = capturedText.length > 80
429
+ ? capturedText.slice(0, 80) + "..."
430
+ : capturedText;
431
+ console.log(` [remember] Captured "${preview}" as "${action.rememberAs ?? ""}"`);
432
+ }
433
+ rememberedValue = capturedText;
434
+ break;
435
+ }
436
+ case "assert": {
437
+ if (!action.assertion) {
438
+ throw new Error("assert action requires an assertion");
439
+ }
440
+ await executeAssertion(page, action, a11yTree);
441
+ break;
442
+ }
443
+ default:
444
+ throw new Error(`Unknown action: ${action.action}`);
445
+ }
446
+ return {
447
+ success: true,
448
+ duration: performance.now() - start,
449
+ resolvedSelector,
450
+ rememberedValue,
451
+ };
452
+ }
453
+ catch (err) {
454
+ return {
455
+ success: false,
456
+ duration: performance.now() - start,
457
+ error: err instanceof Error ? err.message : String(err),
458
+ resolvedSelector,
459
+ };
460
+ }
461
+ }
462
+ //# sourceMappingURL=executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../src/pilot/executor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Form field capture and formatting for Playwright pages.
3
+ */
4
+ import type { Page } from "playwright";
5
+ /** Metadata about a single form field, extracted from the DOM. */
6
+ export interface FormFieldInfo {
7
+ /** The element ref from the a11y tree, if matched. */
8
+ ref?: string;
9
+ /** The <label> text associated with this field. */
10
+ label?: string;
11
+ /** The placeholder attribute value. */
12
+ placeholder?: string;
13
+ /** The input type (text, email, tel, number, url, etc.). */
14
+ inputType: string;
15
+ /** The tag name (input, textarea, select). */
16
+ tag: string;
17
+ /** Whether the field is required. */
18
+ required: boolean;
19
+ /** For select elements: the available option labels. */
20
+ options?: string[];
21
+ /** Whether this field is an autocomplete/typeahead/combobox that shows suggestions as you type. */
22
+ autocomplete?: boolean;
23
+ }
24
+ /**
25
+ * Capture metadata about all visible form fields on the page.
26
+ * Extracts label, placeholder, input type, required status, and select options
27
+ * directly from the DOM — information not available in the a11y tree.
28
+ */
29
+ export declare function captureFormFields(page: Page): Promise<FormFieldInfo[]>;
30
+ /**
31
+ * Format form field metadata as readable text for LLM consumption.
32
+ */
33
+ export declare function formatFormFields(fields: FormFieldInfo[]): string;
34
+ //# sourceMappingURL=form-fields.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-fields.d.ts","sourceRoot":"","sources":["../../src/pilot/form-fields.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAEtC,kEAAkE;AAClE,MAAM,WAAW,aAAa;IAC7B,sDAAsD;IACtD,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,mDAAmD;IACnD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,uCAAuC;IACvC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,4DAA4D;IAC5D,SAAS,EAAE,MAAM,CAAA;IACjB,8CAA8C;IAC9C,GAAG,EAAE,MAAM,CAAA;IACX,qCAAqC;IACrC,QAAQ,EAAE,OAAO,CAAA;IACjB,wDAAwD;IACxD,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,mGAAmG;IACnG,YAAY,CAAC,EAAE,OAAO,CAAA;CACtB;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAuH5E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,CAiBhE"}