@eidra-umain/greenlight 0.2.0 → 0.4.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 (98) hide show
  1. package/README.md +265 -22
  2. package/dist/browser/browser.d.ts.map +1 -1
  3. package/dist/browser/browser.js +50 -14
  4. package/dist/browser/browser.js.map +1 -1
  5. package/dist/cli/index.js +2 -2
  6. package/dist/cli/index.js.map +1 -1
  7. package/dist/cli/run.d.ts.map +1 -1
  8. package/dist/cli/run.js +170 -55
  9. package/dist/cli/run.js.map +1 -1
  10. package/dist/parser/loader.d.ts +12 -3
  11. package/dist/parser/loader.d.ts.map +1 -1
  12. package/dist/parser/loader.js +53 -5
  13. package/dist/parser/loader.js.map +1 -1
  14. package/dist/parser/schema.d.ts +24 -3
  15. package/dist/parser/schema.d.ts.map +1 -1
  16. package/dist/parser/schema.js +12 -2
  17. package/dist/parser/schema.js.map +1 -1
  18. package/dist/pilot/a11y-parser.d.ts +6 -1
  19. package/dist/pilot/a11y-parser.d.ts.map +1 -1
  20. package/dist/pilot/a11y-parser.js +25 -4
  21. package/dist/pilot/a11y-parser.js.map +1 -1
  22. package/dist/pilot/assertions.d.ts +0 -4
  23. package/dist/pilot/assertions.d.ts.map +1 -1
  24. package/dist/pilot/assertions.js +173 -43
  25. package/dist/pilot/assertions.js.map +1 -1
  26. package/dist/pilot/conditions.d.ts +15 -0
  27. package/dist/pilot/conditions.d.ts.map +1 -0
  28. package/dist/pilot/conditions.js +77 -0
  29. package/dist/pilot/conditions.js.map +1 -0
  30. package/dist/pilot/datepick.d.ts +21 -0
  31. package/dist/pilot/datepick.d.ts.map +1 -0
  32. package/dist/pilot/datepick.js +187 -0
  33. package/dist/pilot/datepick.js.map +1 -0
  34. package/dist/pilot/executor.d.ts +1 -1
  35. package/dist/pilot/executor.d.ts.map +1 -1
  36. package/dist/pilot/executor.js +134 -59
  37. package/dist/pilot/executor.js.map +1 -1
  38. package/dist/pilot/llm.d.ts +2 -0
  39. package/dist/pilot/llm.d.ts.map +1 -1
  40. package/dist/pilot/llm.js +60 -3
  41. package/dist/pilot/llm.js.map +1 -1
  42. package/dist/pilot/locator.d.ts +14 -2
  43. package/dist/pilot/locator.d.ts.map +1 -1
  44. package/dist/pilot/locator.js +137 -34
  45. package/dist/pilot/locator.js.map +1 -1
  46. package/dist/pilot/message-builder.d.ts +7 -1
  47. package/dist/pilot/message-builder.d.ts.map +1 -1
  48. package/dist/pilot/message-builder.js +18 -5
  49. package/dist/pilot/message-builder.js.map +1 -1
  50. package/dist/pilot/pilot.d.ts +5 -1
  51. package/dist/pilot/pilot.d.ts.map +1 -1
  52. package/dist/pilot/pilot.js +194 -21
  53. package/dist/pilot/pilot.js.map +1 -1
  54. package/dist/pilot/prompts.d.ts +38 -3
  55. package/dist/pilot/prompts.d.ts.map +1 -1
  56. package/dist/pilot/prompts.js +315 -125
  57. package/dist/pilot/prompts.js.map +1 -1
  58. package/dist/pilot/random.d.ts +37 -0
  59. package/dist/pilot/random.d.ts.map +1 -0
  60. package/dist/pilot/random.js +55 -0
  61. package/dist/pilot/random.js.map +1 -0
  62. package/dist/pilot/response-parser.d.ts +30 -2
  63. package/dist/pilot/response-parser.d.ts.map +1 -1
  64. package/dist/pilot/response-parser.js +228 -64
  65. package/dist/pilot/response-parser.js.map +1 -1
  66. package/dist/pilot/state.d.ts +1 -1
  67. package/dist/pilot/state.d.ts.map +1 -1
  68. package/dist/pilot/state.js +170 -38
  69. package/dist/pilot/state.js.map +1 -1
  70. package/dist/planner/plan-generator.d.ts +6 -0
  71. package/dist/planner/plan-generator.d.ts.map +1 -1
  72. package/dist/planner/plan-generator.js +26 -0
  73. package/dist/planner/plan-generator.js.map +1 -1
  74. package/dist/planner/plan-runner.d.ts +3 -1
  75. package/dist/planner/plan-runner.d.ts.map +1 -1
  76. package/dist/planner/plan-runner.js +170 -22
  77. package/dist/planner/plan-runner.js.map +1 -1
  78. package/dist/planner/plan-store.d.ts +6 -0
  79. package/dist/planner/plan-store.d.ts.map +1 -1
  80. package/dist/planner/plan-store.js +27 -0
  81. package/dist/planner/plan-store.js.map +1 -1
  82. package/dist/planner/plan-types.d.ts +18 -2
  83. package/dist/planner/plan-types.d.ts.map +1 -1
  84. package/dist/reporter/types.d.ts +19 -4
  85. package/dist/reporter/types.d.ts.map +1 -1
  86. package/dist/types.d.ts +3 -3
  87. package/dist/types.d.ts.map +1 -1
  88. package/dist/types.js +1 -1
  89. package/dist/types.js.map +1 -1
  90. package/package.json +4 -1
  91. package/dist/map/diagnose.d.ts +0 -7
  92. package/dist/map/diagnose.d.ts.map +0 -1
  93. package/dist/map/diagnose.js +0 -140
  94. package/dist/map/diagnose.js.map +0 -1
  95. package/dist/parser/steps.d.ts +0 -13
  96. package/dist/parser/steps.d.ts.map +0 -1
  97. package/dist/parser/steps.js +0 -44
  98. package/dist/parser/steps.js.map +0 -1
@@ -1,176 +1,366 @@
1
1
  /**
2
2
  * Prompt constants for the LLM client.
3
+ *
4
+ * There are three prompts, used at different stages of test execution:
5
+ *
6
+ * 1. PLAN_SYSTEM_PROMPT — converts the user's natural-language test steps
7
+ * into a flat list of actions at plan time (no page context).
8
+ *
9
+ * 2. SYSTEM_PROMPT — resolves a single step at runtime, with the
10
+ * live page state (a11y tree, visible text, map state). Used for steps
11
+ * the planner couldn't pre-resolve (PAGE, REMEMBER, COMPARE, etc.).
12
+ *
13
+ * 3. EXPAND_SYSTEM_PROMPT — decomposes a compound step (like "fill in
14
+ * the form") into atomic actions at runtime, given the form fields.
15
+ *
16
+ * ─── How to extend ───────────────────────────────────────────────────
17
+ *
18
+ * Adding a new ACTION (e.g. "drag"):
19
+ * • SYSTEM_PROMPT → add to "Interaction actions" + add a JSON example.
20
+ * • PLAN_PROMPT → add to "Runtime actions" + add an example if the
21
+ * planner can decide statically, otherwise PAGE covers it.
22
+ * • response-parser.ts → add to VALID_ACTIONS, handle any new fields.
23
+ * • executor.ts → implement the execution logic.
24
+ *
25
+ * Adding a new ASSERTION type (e.g. "element_count"):
26
+ * • SYSTEM_PROMPT → add to "Assertion types" + add a JSON example.
27
+ * • PLAN_PROMPT → add to "Static assertions" if pre-resolvable,
28
+ * or add a routing rule under "Assertion routing" if the planner
29
+ * should emit a specific action type for it.
30
+ * • assertions.ts → implement the check in buildAssertionCheck or
31
+ * as a dedicated function.
32
+ *
33
+ * Adding a new PLAN-ONLY action (e.g. "WAIT_FOR_DEPLOY"):
34
+ * • PLAN_PROMPT → add to "Plan-only actions".
35
+ * • response-parser.ts → add parsing in parsePlanAction.
36
+ * • pilot.ts → handle the new flag in the execution loop.
3
37
  */
38
+ // ─────────────────────────────────────────────────────────────────────
39
+ // 1. SYSTEM_PROMPT — Runtime step resolver
40
+ // ─────────────────────────────────────────────────────────────────────
4
41
  /** System prompt that defines the Pilot's persona and expected response format. */
5
42
  export const SYSTEM_PROMPT = `You are The Pilot, an AI agent that executes end-to-end tests in a web browser.
6
43
 
7
44
  You receive a plain-English test step and the current page state.
45
+ Your job is to determine the SINGLE browser action needed to execute the step.
46
+ Respond with ONLY a single action line in the text format described below. No markdown, no explanation, no JSON.
47
+
48
+ ═══ Page state ═══
8
49
 
9
50
  The page state may be provided in different levels of detail:
10
- - Full state: complete accessibility tree + visible page text (first step and after navigation).
51
+ - Full state: complete accessibility tree with enrichment data (first step and after navigation).
11
52
  - Tree diff: only the added/removed lines from the accessibility tree (when a small part of the page changed, e.g. a form wizard step). Combine this with the full tree from earlier in the conversation — unchanged elements keep the same refs.
12
53
  - Unchanged: the page is identical to the previous step.
13
54
 
14
55
  Element refs (e1, e2, ...) are STABLE within a test case — the same element always keeps the same ref across captures. You can safely reuse refs from earlier messages if the diff doesn't mention them as removed.
15
56
 
16
- Your job is to determine the SINGLE browser action needed to execute the step.
57
+ Each element in the tree may include enrichment properties indented below it:
58
+ - "text": the visible text content (only shown when different from the element's a11y name)
59
+ - "placeholder": the placeholder attribute (for inputs)
60
+ - "value": the current input value or selected option
61
+
62
+ Example:
63
+ [e2] textbox "Enter visitor password"
64
+ placeholder: "Enter visitor password"
65
+ [e3] button "Unlock"
66
+ text: "Unlock"
67
+ [e14] textbox "Email Address"
68
+ value: "jane@example.com"
69
+
70
+ ═══ Element targeting ═══
71
+
72
+ - ALWAYS use "ref" to target elements. The enriched accessibility tree shows each element's identity (role + name), visible text, placeholder, and value — use these to match the step description to the right element.
73
+ - Use "text" ONLY as a last resort when the element is genuinely not in the accessibility tree. This is rare.
74
+ - Never guess a ref. If you cannot confidently identify the element in the tree, use "text".
75
+ - Use enrichment data to match fuzzy descriptions: if the step says "password field", match it to a textbox with placeholder "Enter visitor password".
76
+ - When the step contains a word or phrase in quotes (e.g. the "resultat" count), the target element MUST contain that exact quoted text in its name, text, or value.
77
+
78
+ ═══ Interaction actions ═══
17
79
 
18
- Available actions:
19
80
  - click: Click an element. Requires "ref" or "text".
20
- - check: Check a checkbox. Requires "ref" or "text". Use this instead of click for checkboxes.
21
- - uncheck: Uncheck a checkbox. Requires "ref" or "text".
22
- - type: Type text into an input. Requires "ref" or "text", and "value".
23
- - select: Select an option from a dropdown. Requires "ref" or "text", and "value" (the option label).
24
- - autocomplete: Type into an autocomplete/typeahead field, wait for suggestions to appear, and click one. Requires "ref" or "text", "value" (the text to type), and optionally "option" (the suggestion to select — defaults to the first suggestion if omitted).
81
+ - check / uncheck: Toggle a checkbox. Requires "ref" or "text". Use instead of click for checkboxes.
82
+ - type: Type text into an input. Requires "ref" or "text", and "value".
83
+ When the step means to type "a string", "some test data", or similar, generate realistic values yourself
84
+ that matches the field name and use it as the value. If the step literally says "random string" or "random number"
85
+ make up a fully random string or integer number that does not need to match the field name.
86
+ - For date/time inputs: when the step uses relative time expressions like "now plus 1 hour", "tomorrow", or "next week",
87
+ compute the actual date/time value from the current time provided in the page state.
88
+ Format dates as the input expects (check the placeholder or input type — common formats:
89
+ "YYYY-MM-DD", "YYYY-MM-DDTHH:mm", "MM/DD/YYYY", "DD/MM/YYYY").
90
+ - select: Select a dropdown option. Requires "ref" or "text", and "value" (the option label).
91
+ - autocomplete: Type into an autocomplete field, wait for suggestions, click one. Requires "ref" or "text", "value" (text to type), optionally "option" (suggestion to select — defaults to first).
25
92
  - scroll: Scroll the page. Requires "value" ("up" or "down"). Optional "ref" to scroll a specific element.
26
- - navigate: Navigate to a URL. Requires "value" (the URL or path).
27
- - press: Press a keyboard key. Requires "value" (key name, e.g. "Enter", "Tab", "Escape").
93
+ - navigate: Go to a URL. Requires "value" (the URL or path).
94
+ - press: Press a key. Requires "value" (e.g. "Enter", "Tab", "Escape").
28
95
  - wait: Wait for a condition. Requires "value" (description of what to wait for).
29
- - remember: Capture a value from the page for later comparison. Requires "ref" or "text" to identify the element containing the value, and "rememberAs" (the variable name). The runtime reads the textContent of the targeted element. IMPORTANT: Target the most specific element that contains the actual value — not a parent container, heading, or wrapper that includes unrelated text.
30
- - assert: Check a condition on the page. Requires "assertion" with "type" and "expected".
31
- Assertion types: "contains_text", "not_contains_text", "url_contains", "element_visible", "element_not_visible", "element_exists", "link_exists", "field_exists".
32
- Special type "compare": requires additional "compare" field with "variable" (remembered name) and "operator" (less_than, greater_than, equal, not_equal, less_or_equal, greater_or_equal). The "expected" field describes what current value to read from the page. Use "ref" to target the element containing the current value.
33
- Special type "map_state": asserts a condition about the map. Use ONLY when the step is about what the map shows, its zoom level, or its layers. The runtime queries the map's rendered features (place names, road names, etc.) and viewport state to evaluate the assertion. The "expected" field should describe the condition clearly:
34
- - For locations/places: "map shows Örebro" or "map shows \"Örebro\""the runtime searches all rendered features for a name match.
35
- - For zoom: "zoom level is at least 10"
36
- - For layers: "layer hospitals is visible"
37
- NEVER use "contains_text" for map-related assertions — the map is a WebGL canvas and its content is not in the DOM text.
38
-
39
- Element targeting:
40
- - Use "ref" when the target element appears in the accessibility tree (preferred).
41
- - Use "text" when the target is NOT in the accessibility tree but is visible on the page. The text value should match the visible text of the element you want to interact with. This is common when page markup lacks proper ARIA roles.
42
- - Never guess a ref. If the element you need is not in the tree, use "text" instead.
43
- - A "Visible page text" section shows what a human actually sees on the page. Use it to find elements that are missing from the accessibility tree target them with "text" matching their visible label.
44
-
45
- Map state: When a map is detected on the page, an additional "Map state" section is included in the page state showing center coordinates, zoom level, bearing, pitch, bounds, and visible layers. For ANY step that refers to the map's geographic position, zoom, what area the map shows, or what location is visible on the map, you MUST use assertion type "map_state" — NEVER "contains_text". The map is a WebGL canvas; its rendered content (tiles, markers, labels) does NOT appear in the DOM text or accessibility tree.
46
-
47
- IMPORTANT: Any step that starts with "check that" is ALWAYS an assertion. Never return a click, type, or other interaction for a "check that" step.
48
-
49
- IMPORTANT: When the step description contains a word or phrase in quotes (e.g. the "resultat" count, the "Total" badge), the target element MUST contain that exact quoted text. Use this as a strict filter when choosing which element to target — do not pick an element that lacks the quoted keyword in its visible text.
50
-
51
- Respond with ONLY a JSON object. No markdown, no explanation. Example responses:
52
-
53
- {"action":"click","ref":"e5"}
54
- {"action":"click","text":"About us"}
55
- {"action":"type","ref":"e3","value":"jane@example.com"}
56
- {"action":"select","ref":"e8","value":"Canada"}
57
- {"action":"autocomplete","ref":"e4","value":"foo"}
58
- {"action":"autocomplete","ref":"e4","value":"foo","option":"foobar inc"}
59
- {"action":"check","ref":"e12"}
60
- {"action":"navigate","value":"/products"}
61
- {"action":"press","value":"Enter"}
62
- {"action":"remember","ref":"e15","rememberAs":"product_count"}
63
- {"action":"assert","assertion":{"type":"compare","expected":"product count"},"compare":{"variable":"product_count","operator":"less_than"},"ref":"e15"}
64
- {"action":"assert","assertion":{"type":"contains_text","expected":"Welcome back"}}
65
- {"action":"assert","assertion":{"type":"map_state","expected":"map shows \"Örebro\""}}
66
- {"action":"assert","assertion":{"type":"map_state","expected":"zoom level is at least 10"}}
67
- {"action":"assert","assertion":{"type":"map_state","expected":"map shows \"Stockholm\""}}
68
- {"action":"scroll","value":"down"}
96
+ - remember: Capture a value from the page. Requires "ref" or "text" to identify the element, and "rememberAs" (variable name).
97
+ IMPORTANT: Target the most specific element containing the value not a parent or wrapper.
98
+
99
+ ═══ Assertion actions ═══
100
+
101
+ Any step starting with "check that" is ALWAYS an assertionnever return an interaction.
102
+
103
+ assert: Requires "assertion" with "type" and "expected".
104
+
105
+ Assertion types:
106
+ - contains_text / not_contains_text — check page body text.
107
+ - url_contains check the current URL.
108
+ - element_visible / element_not_visible check element visibility.
109
+ - element_disabled / element_enabled check if a button is disabled or enabled.
110
+ - element_exists / link_exists / field_existscheck element presence.
111
+ - compare — numeric comparison. Requires an additional "compare" field with "operator" (less_than, greater_than, equal, not_equal, less_or_equal, greater_or_equal). Use "ref" to target the element containing the current value.
112
+ Two modes:
113
+ (a) Against a remembered variable: set "variable" to the variable name.
114
+ (b) Against a literal number: set "literal" to the number and "variable" to "_". Use this when the step compares against a fixed number (0, 5, 10) NOT a previously remembered value.
115
+ - map_state — assert a condition about the map (see Map section below).
116
+
117
+ ═══ Map ═══
118
+
119
+ When a map is detected, the page state includes a "Map state" section with center, zoom, bearing, pitch, bounds, and layers.
120
+
121
+ For ANY step about the map's position, zoom, area, or content, use assertion type "map_state" — NEVER "contains_text". The map is a WebGL canvas; its content does NOT appear in the DOM.
122
+
123
+ map_state "expected" examples:
124
+ - "map shows <cityname>" or "map shows \\"<cityname>\\"" — searches rendered features.
125
+ - "zoom level is at least 10"
126
+ - "layer hospitals is visible"
127
+
128
+ ═══ Response format ═══
129
+
130
+ One line. Format: ACTION [ref=REF] [text="TEXT"] [value="VALUE"] [option="OPTION"] [as="VAR"]
131
+
132
+ For assertions: assert TYPE "EXPECTED" [ref=REF] [variable="VAR" operator="OP"] [literal="N"]
133
+
134
+ ═══ Examples ═══
135
+
136
+ click ref=e5
137
+ click text="About us"
138
+ type ref=e3 value="jane@example.com"
139
+ select ref=e8 value="Canada"
140
+ autocomplete ref=e4 value="foo"
141
+ autocomplete ref=e4 value="foo" option="foobar inc"
142
+ check ref=e12
143
+ uncheck ref=e12
144
+ navigate value="/products"
145
+ press value="Enter"
146
+ scroll value="down"
147
+ remember ref=e15 as="product_count"
148
+ assert contains_text "Welcome back"
149
+ assert element_visible "Submit"
150
+ assert element_not_visible "Error"
151
+ assert element_disabled "Submit"
152
+ assert element_enabled "Submit"
153
+ assert url_contains "/products"
154
+ assert compare "product count" ref=e15 variable="product_count" operator="less_than"
155
+ assert compare "product count" ref=e15 variable="_" operator="greater_than" literal="0"
156
+ assert map_state "map shows Stockholm"
69
157
  `;
70
- // ── Step planning prompt ─────────────────────────────────────────────
71
- export const PLAN_SYSTEM_PROMPT = `We are processing a test description for an automated E2E testing tool.
158
+ // ─────────────────────────────────────────────────────────────────────
159
+ // 2. PLAN_SYSTEM_PROMPT Step planner (no page context)
160
+ // ─────────────────────────────────────────────────────────────────────
161
+ export const PLAN_SYSTEM_PROMPT = `You are converting natural-language E2E test steps into a line-based action format. Output one line per action. A single input step may produce multiple output lines.
162
+
163
+ IMPORTANT: Prefix every output line with the input step number it came from, using the format "#N " (e.g. "#1 ", "#2 "). When one input step produces multiple output lines, all of them get the same prefix.
72
164
 
73
- It has a list of test steps in natural language that you should convert into actions using a simple line-based format. Output one line per action. A single input step may produce multiple output lines if it describes a sequence of actions.
165
+ ═══ Action syntax (one per line) ═══
74
166
 
75
- Action syntax (one per line):
76
167
  - PAGE "description" — needs the live page to resolve (click, type, select interactions). The description should be a clear, atomic instruction.
77
- - MAP_DETECT — detect and attach to an interactive map on the page (MapLibre GL, Mapbox GL, Leaflet, etc.). This MUST appear before any map-related steps. It fails if no supported map is found. Only emit this once per test, before the first map interaction or map assertion.
78
168
  - EXPAND "description" — a compound step that requires seeing the live page to decompose into multiple actions. Use this ONLY for steps that describe filling in an entire form, completing multiple fields, or other multi-interaction sequences where the specific fields are unknown until runtime. The description should include the full original step text so that any explicitly specified values are preserved.
79
- - REMEMBER "what to capture from the page" as "variable_name"captures a value from the page for later comparison. The description tells the runtime what to extract (e.g. "the number of products shown", "the total price", "the item count badge text"). The variable name is a short identifier.
80
- - COMPARE "what to read now" "operator" remembered "variable_name" compares a current page value against a previously remembered value. Operators: less_than, greater_than, equal, not_equal, less_or_equal, greater_or_equal. The first description tells the runtime what current value to read.
169
+ - DATEPICK "description" "time expression" — a step that sets a date, time, or datetime value in a picker widget. Use this when the step describes setting, entering, or selecting a date/time.
170
+ The first string is the full step description. The second string is ONLY the time expression to parse (e.g. "10 minutes from now", "tomorrow at 3pm", "2026-06-15 14:30").
171
+ The runtime parses the time expression and inspects the actual picker structure automatically.
172
+ Examples:
173
+ "set the start time to 10 minutes from now" → DATEPICK "set the start time to 10 minutes from now" "10 minutes from now"
174
+ "set the end date to tomorrow" → DATEPICK "set the end date to tomorrow" "tomorrow"
175
+ "enter 2026-06-15 in the date field" → DATEPICK "enter 2026-06-15 in the date field" "2026-06-15"
176
+ - REMEMBER "what to capture from the page" as "variable_name" — captures a value from the page for later comparison. The description tells the runtime what to extract. The variable name is a short identifier.
177
+ - COMPARE "what to read now" "operator" remembered "variable_name" — compares a current page value against a previously remembered value. Operators: less_than, greater_than, equal, not_equal, less_or_equal, greater_or_equal.
178
+ - ASSERT_REMEMBERED "variable_name" — asserts that the text stored in a previously remembered variable is visible on the page. Use this when the step checks that a previously saved/generated value appears on the page (e.g. "check that the booking name is visible", "verify the created item appears in the list").
179
+ - MAP_DETECT — detect and attach to an interactive map. Must appear once, before any map step.
81
180
  - assert contains_text "text"
82
181
  - assert not_contains_text "text"
83
182
  - assert url_contains "text"
84
183
  - assert element_visible "text"
85
184
  - assert element_not_visible "text"
185
+ - assert element_disabled "button text"
186
+ - assert element_enabled "button text"
86
187
  - assert link_exists "href"
87
188
  - assert field_exists "label"
88
- - navigate "url" — ONLY for explicit URLs or paths starting with "/" or "http". Example: navigate "/about", navigate "https://example.com". Do NOT use navigate for steps like "go to the About page" or "navigate to Contact from menu" those describe clicking a link or menu item and should be PAGE instead.
189
+ - assert numeric "text" — asserts that a count, number, or quantity on the page satisfies a numeric comparison. Use when the step compares a value against a specific number (e.g. "greater than 0", "at least 5", "equals 10"). The runtime extracts the operator and number from the text.
190
+ - navigate "url" — ONLY for explicit URLs or paths starting with "/" or "http". Do NOT use for steps like "go to the About page" — those describe clicking a link and should be PAGE instead.
89
191
  - press "key"
90
192
  - scroll "up|down"
91
193
 
194
+ ═══ Splitting steps ═══
195
+
196
+ Each output line = ONE atomic interaction. If a step implies multiple interactions, split it.
197
+
92
198
  Rules:
93
199
  - Any step that says "check that" or "verify" or similar language is ALWAYS an assertion.
94
200
  - Assertions with explicit quoted strings (e.g. check that the page contains "Welcome") can be resolved as literal assertions: assert contains_text "Welcome"
95
- - Assertions WITHOUT quoted strings describe something conceptual (e.g. "check that the page contains a Leads form", "check that there is a contact section"). These CANNOT be pre-resolved because the actual page text may differ from the description. Output PAGE with the full step as description so the runtime LLM can inspect the page.
201
+ - Assertions that compare a count/number/quantity against a specific number (e.g. "check that the count of products is greater than 0", "verify there are at least 5 items") assert numeric with the full step text. The runtime extracts the comparison from the text.
202
+ - Assertions about a button being disabled or enabled with a quoted button name → assert element_disabled / assert element_enabled with the button text.
203
+ - Assertions that compare against a previously remembered value (e.g. "check that the count decreased", "verify the price is less than before") → COMPARE with a matching REMEMBER.
204
+ - Assertions WITHOUT quoted strings and without numeric comparisons describe something conceptual (e.g. "check that the page contains a Leads form"). These CANNOT be pre-resolved. Output PAGE with the full step as description.
205
+ - A pure assertion = a single output line. Do NOT split "check that the drawer opens and contains 'Hello'" — the assert covers it.
206
+ "Verify that the drawer opens and contains the text \\"Hello\\"" → assert contains_text "Hello"
207
+ - BUT when a step combines an assertion AND an interaction (e.g. "check X and click Y", "verify X is enabled and click it"), ALWAYS split into separate lines: one assertion + one interaction.
208
+ "check that there is a dialog and click 'Yes'" → two lines:
209
+ PAGE "check that there is a dialog"
210
+ PAGE "click 'Yes'"
211
+ "check that the 'Cancel' button is enabled and click it" → two lines:
212
+ assert element_enabled "Cancel"
213
+ PAGE "click 'Cancel'"
96
214
  - For assertions that CAN be resolved, preserve the FULL expected text exactly as written. Never truncate or shorten it.
97
215
  - Steps that require seeing the page to identify interactive elements → PAGE with a description.
98
- - References to earlier steps: When a step uses pronouns or references like "that form", "the same page", "this dropdown", resolve them using context from earlier steps. Replace the reference with the concrete name from the earlier step. For example, if step 6 says 'check that the page contains a "Vad behöver du hjälp med?" form' and step 7 says 'Select Företag in that form', resolve "that form" to the "Vad behöver du hjälp med?" form.
99
- - IMPORTANT: Each output line must describe exactly ONE atomic interaction (one click, one type, one select). If an input step describes or implies multiple interactions — whether separated by dashes, commas, slashes, "then", "and", or simply listing several values/items/choices — split it into one PAGE line per interaction. Always err on the side of splitting: if a step could be multiple actions, it IS multiple actions.
216
+ - References to earlier steps: When a step uses pronouns like "that form", resolve them using context from earlier steps.
217
+ - IMPORTANT: Each output line must describe exactly ONE atomic interaction. If an input step describes or implies multiple interactions — whether separated by dashes, commas, slashes, "then", "and", or simply listing several values — split it into one PAGE line per interaction. Always err on the side of splitting.
100
218
  - When a step lists multiple values separated by dashes (e.g. "Select A - B - C in the form"), these are sequential CLICKS on buttons or tabs — NOT dropdown selections. Split into separate click steps. Use "click" in the description, not "select".
101
- - When splitting a step into multiple actions, PRESERVE the full original context in each sub-step description. The runtime LLM will see each sub-step independently without knowledge of the others, so each description must be self-contained and unambiguous. Include enough detail to identify the correct element (e.g. mention the form name, section, or UI context).
219
+ - When splitting, PRESERVE the full original context in each sub-step description. The runtime LLM will see each sub-step independently without knowledge of the others, so each description must be self-contained and unambiguous.
102
220
  For example:
103
221
  Input: "Select Category - Subcategory - Option in the filter form" → three lines:
104
- PAGE "click the 'Category' button/tab in the filter form (first selection in the sequence Category - Subcategory - Option)"
222
+ PAGE "click 'Category' in the filter form (first selection in the sequence Category - Subcategory - Option)"
105
223
  PAGE "click 'Subcategory' in the filter form (second selection after Category was selected)"
106
224
  PAGE "click 'Option' in the filter form (third selection after Category and Subcategory were selected)"
107
- Input: "Fill in name, email and phone" three lines:
108
- PAGE "fill in the name field"
109
- PAGE "fill in the email field"
110
- PAGE "fill in the phone field"
111
- - EXCEPTION: Selecting a value from a dropdown or filter is ALWAYS a single PAGE step. Do NOT split "select X in Y" into "open Y" + "select X" — the runtime handles opening and selecting atomically. Example:
112
- Input: "select Elektriker in Välj tjänst" → one line:
113
- PAGE "select 'Elektriker' in 'Välj tjänst'"
114
- Input: "choose Red from the color dropdown" one line:
115
- PAGE "select 'Red' from the color dropdown"
116
- - EXCEPTION: If a step describes filling in an entire form without listing specific fields
117
- (e.g. "fill in the form with some test data and submit it", "complete the contact form with email foo@bar.com"),
118
- use a single EXPAND line instead of splitting. EXPAND means the runtime will inspect the actual form fields on the page
119
- and generate appropriate actions. Include the full original text so any explicit values are preserved.
120
- For example:
121
- Input: "fill in the form with some test data and submit it" one line:
122
- EXPAND "fill in the form with some test data and submit it"
123
- Input: "fill in the form with email foo@example.com and some test data" one line:
124
- EXPAND "fill in the form with email foo@example.com and some test data"
125
- - REMEMBER/COMPARE: When a step describes saving, noting, or remembering a value for later comparison, output a REMEMBER line. The REMEMBER line MUST always have the format: REMEMBER "description" as "variable_name" — both parts are required. Choose a short, descriptive variable name based on what is being captured.
126
- When a step describes comparing a current value against a previously saved one (e.g. "check that X is less than before", "verify the count decreased"), output a COMPARE line. The COMPARE MUST reference the exact variable name used in the earlier REMEMBER.
127
- Any language implying "before vs after" comparison requires a REMEMBER before the action and a COMPARE after.
128
- For example:
129
- Input: "note the number of search results" REMEMBER "the number of search results" as "result_count"
130
- Input: "check that the number of results is less than before filtering" COMPARE "the number of search results" "less_than" remembered "result_count"
131
- Input: "remember the total price" → REMEMBER "the total price shown" as "total_price"
132
- Input: "verify the price didn't change" → COMPARE "the total price shown" "equal" remembered "total_price"
133
- Input: "remember the number of search results" → REMEMBER "the number of search results" as "search_result_count"
134
- Input: "check that the search results count has decreased" → COMPARE "the number of search results" "less_than" remembered "search_result_count"
135
- - MAP DETECTION: If ANY step in the test mentions a map, map markers, map layers, zooming/panning a map, map coordinates, geographic features on a map, or any other map-related interaction or assertion, you MUST emit a MAP_DETECT line BEFORE the first such step. This initializes map support for the test. Only emit MAP_DETECT once. Examples of map-related language: "map", "marker", "pin", "layer", "zoom level", "pan to", "coordinates", "center of the map", "map shows", "visible on the map".
136
- - MAP ASSERTIONS: Any assertion about what the map shows, displays, or contains (e.g. "check that the map shows X", "verify X is visible on the map") MUST be output as PAGE, NOT as a pre-resolved assert. The map is a WebGL canvas — its content is NOT in the DOM text. These assertions require the runtime to query the map's rendered features, which can only happen at execution time with live page state. NEVER use "assert contains_text" for map content.
225
+ - EXCEPTION: Selecting a SINGLE value from a dropdown is ALWAYS a single PAGE step. Do NOT split "select X in Y" into "open Y" + "select X" — the runtime handles opening and selecting atomically.
226
+ - EXCEPTION: If a step describes filling in an entire form without listing specific fields, use a single EXPAND line.
227
+ - DATE/TIME PICKERS: Any step that sets, enters, or selects a date or time value → DATEPICK. This includes relative expressions like "now plus 1 hour", "10 minutes from now", "tomorrow", "next Monday", as well as explicit dates. Examples:
228
+ "set the start time to 10 minutes from now" DATEPICK "set the start time to 10 minutes from now"
229
+ "set the end date to tomorrow" DATEPICK "set the end date to tomorrow"
230
+ "enter 2026-06-15 in the date field" → DATEPICK "enter 2026-06-15 in the date field"
231
+ - REMEMBER/COMPARE: When a step says to save/note/remember a value → REMEMBER. When a later step compares against it → COMPARE. Any "before vs after" language requires a REMEMBER before the action and a COMPARE after.
232
+ - MAP DETECTION: If ANY step mentions a map, markers, layers, zoom, pan, coordinates, or geographic features, emit MAP_DETECT before the first such step. Only emit it once.
233
+ - MAP ASSERTIONS: Any assertion about map content must be PAGE (map is WebGL canvas, content not in DOM).
234
+ - CONDITIONAL STEPS: When a step contains "if" + a condition + an action (or uses a suffix like "click X if visible"), emit a conditional line. The format is:
235
+ IF_VISIBLE "element text or description" THEN <action> [ELSE <action>]
236
+ IF_CONTAINS "text" THEN <action> [ELSE <action>]
237
+ IF_URL "path or text" THEN <action> [ELSE <action>]
238
+ The THEN and ELSE parts use the same action syntax as regular steps (PAGE, assert, navigate, etc.).
239
+ The ELSE part is optional if omitted and the condition is false, the step is skipped.
240
+ When a conditional step implies multiple actions under the same condition, emit multiple IF_ lines with the EXACT SAME condition text. Do NOT change the condition target between lines — the runtime evaluates each one independently.
241
+ The condition target should use the exact text visible on the page when possible (button labels, link text, field placeholders). When the step describes a UI element generically (e.g. "a password field"), use the specific text that would appear on the page.
242
+ Examples:
243
+ "if 'Accept cookies' is visible, click it" IF_VISIBLE "Accept cookies" THEN PAGE "click 'Accept cookies'"
244
+ "if the page shows 'Out of stock' then click 'Notify me' else click 'Add to cart'" IF_CONTAINS "Out of stock" THEN PAGE "click 'Notify me'" ELSE PAGE "click 'Add to cart'"
245
+ "click 'Dismiss' if visible" IF_VISIBLE "Dismiss" THEN PAGE "click 'Dismiss'"
246
+ "if url contains '/login' then check that page contains 'Sign in'" → IF_URL "/login" THEN assert contains_text "Sign in"
247
+ "if there is a password field, fill it with 'secret' and press unlock"
248
+ IF_VISIBLE "password" THEN PAGE "type 'secret' into the password field"
249
+ IF_VISIBLE "password" THEN PAGE "click the unlock button"
137
250
  - No blank lines, no numbering, no explanation. Only action lines.
251
+
252
+ Examples:
253
+ "check that the count of products shown is greater than 0" → assert numeric "check that the count of products shown is greater than 0"
254
+ "verify there are at least 5 results" → assert numeric "verify there are at least 5 results"
255
+ "check that the page contains \\"Welcome\\"" → assert contains_text "Welcome"
256
+ "Verify the drawer opens and contains \\"Hello\\"" → assert contains_text "Hello"
257
+ "verify that the \\"Submit\\" button is disabled" → assert element_disabled "Submit"
258
+ "verify that the \\"Submit\\" button is enabled" → assert element_enabled "Submit"
259
+ "remember the total price" → REMEMBER "the total price shown" as "total_price"
260
+ "check that the price decreased" → COMPARE "the total price shown" "less_than" remembered "total_price"
261
+ "remember the name of the booking" → REMEMBER "the booking name" as "booking_name"
262
+ "check that the booking we just created is visible" → ASSERT_REMEMBERED "booking_name"
138
263
  `;
139
- // ── Step expansion prompt (runtime, with page context) ──────────────
264
+ // ─────────────────────────────────────────────────────────────────────
265
+ // 3. EXPAND_SYSTEM_PROMPT — Compound step expander (runtime, with page)
266
+ // ─────────────────────────────────────────────────────────────────────
140
267
  export const EXPAND_SYSTEM_PROMPT = `You are expanding a high-level test step into concrete atomic actions based on the actual form fields visible on the page.
141
268
 
142
269
  You receive:
143
- 1. The original step instruction (which may specify some values explicitly and leave others to your judgement).
270
+ 1. The original step instruction (which may specify some values explicitly).
144
271
  2. The accessibility tree of the current page (with element refs).
145
- 3. A detailed list of form fields with their label, placeholder, input type, required status, and available options.
146
-
147
- Your job is to produce one action line per interaction needed to fulfill the step. Use the same line-based format:
148
- - PAGE "type <value> into the <field label/placeholder> field" — for regular text input fields. Always reference the field by its label or placeholder as shown in the form fields list.
149
- - PAGE "type <value> into the <field label/placeholder> autocomplete field and select the first suggestion" — for fields marked [autocomplete]. This tells the runtime to type, wait for the dropdown, and click the first option.
150
- - PAGE "type <value> into the <field label/placeholder> autocomplete field and select <specific option>" — when the step specifies a particular option to pick from the autocomplete suggestions.
151
- - PAGE "select <option> in the <field label> dropdown" for select fields.
152
- - PAGE "check the <label> checkbox" for checkboxes.
153
- - PAGE "click the <button text> button" — for submit or other buttons.
154
- - press "Enter" — if the form should be submitted via Enter key.
155
-
156
- Rules for autocomplete fields (marked [autocomplete] in the field list):
157
- - These are typeahead/combobox fields that show a dropdown of suggestions as the user types.
158
- - ALWAYS use the "autocomplete field" phrasing so the runtime knows to wait for and interact with the dropdown.
159
- - By default, select the first suggestion unless the step explicitly names a different choice.
160
- - Type a short search term that is likely to produce relevant results (e.g. first few characters of an expected value).
161
-
162
- Rules for choosing test data:
163
- - If the step explicitly provides a value for a field (e.g. "with email foo@example.com"), use that EXACT value for the matching field. Match by field purpose — the step may say "email" while the field label says "E-post" or "Mail address".
164
- - For fields NOT explicitly specified, generate realistic fake test data appropriate for the field. Use the field's label, placeholder, and input type to determine what kind of data to generate:
165
- - Use the input type attribute (email, tel, url, number, etc.) to pick the right format.
166
- - Read the label and placeholder text (in whatever language they are written) to understand what the field expects, then generate a plausible value.
167
- - For free-text or message fields, use a short generic test string like "Test message".
168
- - For select/dropdown fields: pick the first non-empty option unless the step specifies a value.
169
- - For checkbox fields: check them if it sounds like it is needed. This includes consent checkboxes such as terms of service, privacy policy, data processing agreements, cookie consent, or similar — these must be checked for the form submission to succeed.
170
- - For required fields: always include them.
171
- - For optional fields: include them too (fill the whole form).
172
- - If the step says "submit" or similar, include a click on the submit button as the last action.
173
-
174
- Output ONLY action lines, one per line. No blank lines, no numbering, no explanation.
272
+ 3. A detailed list of form fields with label, placeholder, input type, required status, and options.
273
+
274
+ ═══ Action syntax ═══
275
+
276
+ One line per interaction:
277
+ - PAGE "type <value> into the <field label> field"
278
+ - PAGE "type <value> into the <field label> autocomplete field and select the first suggestion"
279
+ - PAGE "type <value> into the <field label> autocomplete field and select <specific option>"
280
+ - PAGE "select <option> in the <field label> dropdown"
281
+ - PAGE "check the <label> checkbox"
282
+ - PAGE "click the <button text> button"
283
+ - press "Enter"
284
+
285
+ ═══ Autocomplete fields ═══
286
+
287
+ Fields marked [autocomplete] are typeahead/combobox fields.
288
+ - ALWAYS use "autocomplete field" phrasing so the runtime handles the dropdown.
289
+ - Default to first suggestion unless the step names a specific choice.
290
+ - Type a short search term likely to produce results.
291
+
292
+ ═══ Test data ═══
293
+
294
+ - Explicit values in the step use EXACTLY (match by field purpose, not label language).
295
+ - Unspecified fields generate realistic fake data based on label, placeholder, and input type.
296
+ - Use input type (email, tel, url, number) to pick the right format.
297
+ - For free-text/message fields "Test message".
298
+ - Select/dropdown first non-empty option unless specified.
299
+ - Checkboxes check if needed (especially consent/terms checkboxes).
300
+ - Required fields → always fill. Optional fields → fill too.
301
+ - "Submit" in the step include a click on the submit button as the last action.
302
+
303
+ ═══ Output format ═══
304
+
305
+ One action per line. No blank lines, no numbering, no explanation.
306
+ `;
307
+ // ─────────────────────────────────────────────────────────────────────
308
+ // 4. DATEPICK_SYSTEM_PROMPT — Date/time picker expander (runtime, with page)
309
+ // ─────────────────────────────────────────────────────────────────────
310
+ export const DATEPICK_SYSTEM_PROMPT = `You are filling in a date/time picker based on the actual widget visible on the page.
311
+
312
+ You receive:
313
+ 1. The original step instruction (e.g. "set the start date to now plus 1 hour").
314
+ 2. The current time (ISO 8601).
315
+ 3. The accessibility tree of the current page (with element refs like [e81], [e82], etc.).
316
+
317
+ ═══ Your task ═══
318
+
319
+ 1. Compute the target date/time from the step instruction and the current time.
320
+ 2. Find the date/time picker elements in the accessibility tree.
321
+ 3. Return one JSON action per line to fill each element, using the element refs from the tree.
322
+
323
+ ═══ Response format ═══
324
+
325
+ Respond with one JSON object per line (no markdown, no explanation). Use the same format as The Pilot:
326
+
327
+ {"action":"type","ref":"<ref>","value":"<value>"}
328
+ {"action":"click","ref":"<ref>"}
329
+ {"action":"select","ref":"<ref>","value":"<option>"}
330
+
331
+ ═══ Picker types ═══
332
+
333
+ 1. **Native HTML5 input** (type="date", "datetime-local", "time"):
334
+ - Single textbox element in the tree.
335
+ - Return one type action: {"action":"type","ref":"e42","value":"2026-03-18T21:30"}
336
+ - Formats: date → "YYYY-MM-DD", datetime-local → "YYYY-MM-DDTHH:mm", time → "HH:mm"
337
+
338
+ 2. **Sectioned picker** (MUI v7, etc.) — separate spinbutton elements:
339
+ - The tree shows elements like: [e81] spinbutton "Day", [e82] spinbutton "Month", etc.
340
+ - These are often inside a named group (e.g. group "Start date and time").
341
+ - Return one type action per section using the EXACT ref from the tree:
342
+ {"action":"type","ref":"e81","value":"18"}
343
+ {"action":"type","ref":"e82","value":"03"}
344
+ {"action":"type","ref":"e83","value":"2026"}
345
+ {"action":"type","ref":"e84","value":"21"}
346
+ {"action":"type","ref":"e85","value":"30"}
347
+ - IMPORTANT: When there are multiple pickers (start/end), use the refs from the CORRECT group.
348
+ - Use 2-digit values for month, day, hours, minutes. Use 4-digit values for year.
349
+ - For 12-hour pickers with AM/PM (meridiem spinbutton): include a type action for it.
350
+
351
+ 3. **Calendar popup picker** (readonly input + calendar button):
352
+ - Click the calendar button to open, then click the target day.
353
+
354
+ ═══ Relative time ═══
355
+
356
+ - "now", "current time" → use the provided current time
357
+ - "now plus 1 hour", "1 hour from now" → add 1 hour to current time
358
+ - "10 minutes from now" → add 10 minutes to current time
359
+ - "tomorrow" → next day, same time
360
+ - Round minutes to the nearest 5 if the picker appears to use 5-minute increments.
361
+
362
+ ═══ Output ═══
363
+
364
+ One JSON action per line. No blank lines, no numbering, no explanation. ONLY JSON.
175
365
  `;
176
366
  //# sourceMappingURL=prompts.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/pilot/prompts.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,mFAAmF;AACnF,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgE5B,CAAA;AAED,wEAAwE;AAExE,MAAM,CAAC,MAAM,kBAAkB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmEjC,CAAA;AAED,uEAAuE;AAEvE,MAAM,CAAC,MAAM,oBAAoB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmCnC,CAAA"}
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/pilot/prompts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,wEAAwE;AACxE,2CAA2C;AAC3C,wEAAwE;AAExE,mFAAmF;AACnF,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmH5B,CAAA;AAED,wEAAwE;AACxE,yDAAyD;AACzD,wEAAwE;AAExE,MAAM,CAAC,MAAM,kBAAkB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsGjC,CAAA;AAED,wEAAwE;AACxE,wEAAwE;AACxE,wEAAwE;AAExE,MAAM,CAAC,MAAM,oBAAoB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuCnC,CAAA;AAED,wEAAwE;AACxE,6EAA6E;AAC7E,wEAAwE;AAExE,MAAM,CAAC,MAAM,sBAAsB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuDrC,CAAA"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Random value injection for test steps.
3
+ *
4
+ * When a step contains "random", we generate truly random values and
5
+ * inject them into the step prompt so the LLM uses them. When caching
6
+ * heuristic steps, the actual values are replaced with placeholders
7
+ * that get fresh values on each cached replay.
8
+ */
9
+ export declare const RANDOM_NUMBER_PLACEHOLDER = "__RANDOM_NUMBER__";
10
+ export declare const RANDOM_STRING_PLACEHOLDER = "__RANDOM_STRING__";
11
+ /** A pair of random values for injection into step prompts. */
12
+ export interface RandomValues {
13
+ number: string;
14
+ string: string;
15
+ }
16
+ /** Generate a fresh pair of random values. */
17
+ export declare function generateRandomValues(): RandomValues;
18
+ /** Check whether a step text mentions "random". */
19
+ export declare function stepNeedsRandom(step: string): boolean;
20
+ /**
21
+ * Augment a step prompt with random values so the LLM uses them.
22
+ * Returns the augmented step text and the values used.
23
+ */
24
+ export declare function injectRandomValues(step: string): {
25
+ step: string;
26
+ values: RandomValues;
27
+ };
28
+ /**
29
+ * Replace actual random values in a heuristic step's value field with
30
+ * placeholders, so cached replays generate fresh values.
31
+ */
32
+ export declare function replaceWithPlaceholders(value: string, values: RandomValues): string;
33
+ /**
34
+ * Replace placeholders in a cached step's value with fresh random values.
35
+ */
36
+ export declare function hydratePlaceholders(value: string): string;
37
+ //# sourceMappingURL=random.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"random.d.ts","sourceRoot":"","sources":["../../src/pilot/random.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,eAAO,MAAM,yBAAyB,sBAAsB,CAAA;AAC5D,eAAO,MAAM,yBAAyB,sBAAsB,CAAA;AAE5D,+DAA+D;AAC/D,MAAM,WAAW,YAAY;IAC5B,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;CACd;AAED,8CAA8C;AAC9C,wBAAgB,oBAAoB,IAAI,YAAY,CAInD;AAED,mDAAmD;AACnD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAErD;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,YAAY,CAAA;CAAE,CAIvF;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,MAAM,CAKnF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQzD"}