explorbot 0.2.3 → 0.2.5

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 (174) hide show
  1. package/README.md +1 -1
  2. package/bin/explorbot-cli.ts +26 -8
  3. package/boat/api-tester/src/cli.ts +17 -0
  4. package/boat/api-tester/src/config.ts +4 -2
  5. package/boat/doc-collector/bin/doc-collector-cli.ts +2 -0
  6. package/boat/doc-collector/src/ai/documentarian.ts +61 -31
  7. package/boat/doc-collector/src/cli.ts +14 -1
  8. package/boat/doc-collector/src/config.ts +4 -2
  9. package/boat/prima/bin/prima-cli.ts +0 -0
  10. package/boat/prima/src/activity-line.ts +33 -0
  11. package/boat/prima/src/cli.ts +127 -86
  12. package/boat/prima/src/envelope.ts +102 -52
  13. package/boat/prima/src/prima.ts +567 -128
  14. package/boat/prima/src/pw-parser.ts +11 -1
  15. package/boat/prima/src/pw-registry.ts +4 -5
  16. package/boat/prima/src/session-log.ts +126 -0
  17. package/dist/bin/explorbot-cli.js +26 -8
  18. package/dist/boat/api-tester/bin/apibot-cli.js +2 -0
  19. package/dist/boat/api-tester/src/cli.js +17 -0
  20. package/dist/boat/api-tester/src/config.js +4 -2
  21. package/dist/boat/doc-collector/bin/doc-collector-cli.js +2 -0
  22. package/dist/boat/doc-collector/src/ai/documentarian.js +44 -19
  23. package/dist/boat/doc-collector/src/cli.js +14 -1
  24. package/dist/boat/doc-collector/src/config.js +4 -2
  25. package/dist/boat/prima/src/activity-line.js +30 -0
  26. package/dist/boat/prima/src/cli.js +109 -77
  27. package/dist/boat/prima/src/envelope.js +94 -44
  28. package/dist/boat/prima/src/prima.js +533 -119
  29. package/dist/boat/prima/src/pw-parser.js +13 -1
  30. package/dist/boat/prima/src/pw-registry.js +4 -5
  31. package/dist/boat/prima/src/session-log.js +108 -0
  32. package/dist/package.json +3 -2
  33. package/dist/rules/navigator/verification-actions.md +20 -0
  34. package/dist/src/action-result.d.ts +7 -0
  35. package/dist/src/action-result.js +4 -0
  36. package/dist/src/action.d.ts +2 -0
  37. package/dist/src/action.js +41 -2
  38. package/dist/src/ai/captain/web-mode.js +6 -3
  39. package/dist/src/ai/captain.js +2 -0
  40. package/dist/src/ai/navigator.d.ts +34 -0
  41. package/dist/src/ai/navigator.js +237 -181
  42. package/dist/src/ai/pilot.d.ts +7 -0
  43. package/dist/src/ai/pilot.js +90 -2
  44. package/dist/src/ai/provider.d.ts +2 -2
  45. package/dist/src/ai/provider.js +14 -23
  46. package/dist/src/ai/rerunner.js +2 -1
  47. package/dist/src/ai/researcher/cache.d.ts +2 -0
  48. package/dist/src/ai/researcher/cache.js +10 -2
  49. package/dist/src/ai/researcher.js +3 -2
  50. package/dist/src/ai/rules.js +17 -10
  51. package/dist/src/ai/session-analyst.js +2 -0
  52. package/dist/src/ai/task-agent.js +4 -1
  53. package/dist/src/ai/tester.d.ts +6 -3
  54. package/dist/src/ai/tester.js +50 -46
  55. package/dist/src/ai/tools.d.ts +14 -0
  56. package/dist/src/ai/tools.js +117 -37
  57. package/dist/src/commands/config-command.d.ts +51 -0
  58. package/dist/src/commands/config-command.js +117 -0
  59. package/dist/src/commands/index.js +2 -0
  60. package/dist/src/config.d.ts +9 -1
  61. package/dist/src/config.js +53 -4
  62. package/dist/src/execution-controller.d.ts +2 -0
  63. package/dist/src/execution-controller.js +6 -0
  64. package/dist/src/explorbot.d.ts +2 -1
  65. package/dist/src/explorbot.js +7 -2
  66. package/dist/src/explorer.js +2 -3
  67. package/dist/src/playwright-recorder.js +30 -0
  68. package/dist/src/remote.d.ts +55 -0
  69. package/dist/src/remote.js +235 -0
  70. package/dist/src/reporter.d.ts +1 -0
  71. package/dist/src/reporter.js +7 -1
  72. package/dist/src/state-manager.d.ts +2 -1
  73. package/dist/src/state-manager.js +3 -1
  74. package/dist/src/stats.d.ts +1 -0
  75. package/dist/src/stats.js +1 -0
  76. package/dist/src/test-plan.d.ts +3 -0
  77. package/dist/src/test-plan.js +26 -0
  78. package/dist/src/utils/aria.d.ts +2 -8
  79. package/dist/src/utils/aria.js +69 -40
  80. package/dist/src/utils/html.js +1 -0
  81. package/dist/src/utils/logger.d.ts +7 -1
  82. package/dist/src/utils/logger.js +32 -0
  83. package/dist/src/utils/page-readiness.js +18 -1
  84. package/dist/src/utils/url-matcher.js +3 -0
  85. package/dist/src/utils/web-element.d.ts +2 -0
  86. package/dist/src/utils/web-element.js +8 -0
  87. package/dist/src/utils/web-sandbox.d.ts +1 -1
  88. package/dist/src/utils/web-sandbox.js +2 -3
  89. package/docs/api-testing/basics.md +90 -0
  90. package/docs/api-testing/planning.md +57 -0
  91. package/docs/api-testing/running-tests.md +55 -0
  92. package/docs/assets/cloud-report.png +0 -0
  93. package/docs/assets/html-report.png +0 -0
  94. package/docs/assets/langfuse-trace.png +0 -0
  95. package/docs/assets/successful-explore-run.png +0 -0
  96. package/docs/basics/getting-started.md +140 -0
  97. package/docs/basics/prerequisites.md +63 -0
  98. package/docs/basics/providers.md +362 -0
  99. package/docs/basics/running.md +78 -0
  100. package/docs/contributing/ai-integration-tests.md +57 -0
  101. package/docs/contributing/contributing.md +90 -0
  102. package/docs/contributing/demo-videos.md +36 -0
  103. package/docs/contributing/npm-package.md +138 -0
  104. package/docs/contributing/observability.md +227 -0
  105. package/docs/contributing/regression-tests.md +103 -0
  106. package/docs/contributing/testing.md +95 -0
  107. package/docs/doc-collection/basics.md +128 -0
  108. package/docs/doc-collection/crawling.md +67 -0
  109. package/docs/doc-collection/interactive-mode.md +99 -0
  110. package/docs/index.json +87 -0
  111. package/docs/reference/commands.md +997 -0
  112. package/docs/reference/configuration.md +569 -0
  113. package/docs/reference/scripting.md +303 -0
  114. package/docs/reference/websocket.md +50 -0
  115. package/docs/superpowers/plans/2026-08-01-actor-boat.md +925 -0
  116. package/docs/superpowers/plans/2026-08-01-prima-boat.md +1120 -0
  117. package/docs/superpowers/reviews/2026-08-06-prima-vs-playwright-cli.md +268 -0
  118. package/docs/superpowers/specs/2026-08-01-actor-boat-design.md +204 -0
  119. package/docs/superpowers/specs/2026-08-01-prima-boat-design.md +242 -0
  120. package/docs/superpowers/specs/2026-08-03-global-config-design.md +138 -0
  121. package/docs/superpowers/specs/2026-08-07-prima-fixes-design.md +394 -0
  122. package/docs/superpowers/specs/2026-08-18-prima-false-verdicts.md +159 -0
  123. package/docs/web-testing/agents.md +158 -0
  124. package/docs/web-testing/automated-tests.md +134 -0
  125. package/docs/web-testing/basics.md +91 -0
  126. package/docs/web-testing/customization.md +131 -0
  127. package/docs/web-testing/hooks.md +238 -0
  128. package/docs/web-testing/page-interaction.md +84 -0
  129. package/docs/web-testing/planner.md +122 -0
  130. package/docs/web-testing/rerun.md +164 -0
  131. package/docs/web-testing/researcher.md +380 -0
  132. package/docs/workflow/agentic-usage.md +233 -0
  133. package/docs/workflow/application-spec.md +73 -0
  134. package/docs/workflow/ci.md +202 -0
  135. package/docs/workflow/knowledge.md +310 -0
  136. package/docs/workflow/planning-styles.md +67 -0
  137. package/docs/workflow/reporting.md +133 -0
  138. package/docs/workflow/test-plans.md +90 -0
  139. package/package.json +3 -2
  140. package/rules/navigator/verification-actions.md +20 -0
  141. package/src/action-result.ts +11 -0
  142. package/src/action.ts +43 -3
  143. package/src/ai/captain/web-mode.ts +6 -3
  144. package/src/ai/captain.ts +3 -0
  145. package/src/ai/navigator.ts +255 -186
  146. package/src/ai/pilot.ts +104 -2
  147. package/src/ai/provider.ts +14 -24
  148. package/src/ai/rerunner.ts +2 -1
  149. package/src/ai/researcher/cache.ts +12 -2
  150. package/src/ai/researcher.ts +3 -2
  151. package/src/ai/rules.ts +17 -10
  152. package/src/ai/session-analyst.ts +2 -0
  153. package/src/ai/task-agent.ts +3 -1
  154. package/src/ai/tester.ts +52 -45
  155. package/src/ai/tools.ts +136 -37
  156. package/src/commands/config-command.ts +146 -0
  157. package/src/commands/index.ts +2 -0
  158. package/src/config.ts +60 -5
  159. package/src/execution-controller.ts +8 -0
  160. package/src/explorbot.ts +7 -3
  161. package/src/explorer.ts +2 -2
  162. package/src/playwright-recorder.ts +23 -0
  163. package/src/remote.ts +244 -0
  164. package/src/reporter.ts +7 -1
  165. package/src/state-manager.ts +6 -2
  166. package/src/stats.ts +1 -0
  167. package/src/test-plan.ts +29 -0
  168. package/src/utils/aria.ts +65 -45
  169. package/src/utils/html.ts +1 -0
  170. package/src/utils/logger.ts +33 -2
  171. package/src/utils/page-readiness.ts +24 -1
  172. package/src/utils/url-matcher.ts +3 -0
  173. package/src/utils/web-element.ts +9 -0
  174. package/src/utils/web-sandbox.ts +3 -4
@@ -0,0 +1,380 @@
1
+ # Researcher Agent
2
+
3
+ The Researcher analyzes web pages to understand their structure, identify UI elements, and build UI maps with locators.
4
+
5
+ ## Overview
6
+
7
+ Research gives other agents the context they need:
8
+
9
+ - **Planner** — calls the Researcher before generating test scenarios
10
+ - **Tester** — uses research results to understand page context during execution
11
+
12
+ You can also run research manually to inspect pages or debug locator issues.
13
+
14
+ ## Configuration
15
+
16
+ > [!IMPORTANT]
17
+ > The Researcher processes large amounts of HTML and ARIA tokens on every call. Use a **fast, cheap model** — it does not need deep thinking, just accurate element extraction. Models like `gpt-oss-20b` via Groq or Cerebras at 100+ TPS work well. On reasoning models the Researcher runs at low reasoning effort by default — see [Reasoning Effort](#reasoning-effort).
18
+
19
+ ```javascript
20
+ ai: {
21
+ agents: {
22
+ researcher: {
23
+ model: groq('openai/gpt-oss-20b'),
24
+ systemPrompt: 'Focus on form validation elements...',
25
+ sections: ['overlay', 'content', 'list'],
26
+ maxExpandableClicks: 10,
27
+ retries: 2,
28
+ },
29
+ },
30
+ }
31
+ ```
32
+
33
+ ### Options Reference
34
+
35
+ | Option | Type | Default | Description |
36
+ |--------|------|---------|-------------|
37
+ | `model` | `string` | - | Override the default model for the Researcher |
38
+ | `systemPrompt` | `string` | - | Extra instructions appended to the research prompt |
39
+ | `sections` | `string[]` | all sections | Page sections to identify (order = priority) |
40
+ | `focusSections` | `string[]` | `[]` | CSS selectors used in the truncated-response fallback, when research is split into per-section requests (first match wins). The matching element becomes the container for the focused section — see [Handling Truncated Responses](#handling-truncated-responses). |
41
+ | `maxExpandableClicks` | `number` | `10` | Max expandable elements clicked during deep research |
42
+ | `errorPageTimeout` | `number` | `10` | Seconds to wait for the page to settle before research; error pages detected during this wait abort research. Set `0` to skip the wait |
43
+ | `retries` | `number` | `2` | Retries when most locators are broken in Stage 2 |
44
+ | `reasoning` | `string` | `'low'` | AI SDK v7 reasoning effort: `'none'`, `'minimal'`, `'low'`, `'medium'`, `'high'`, `'xhigh'`, `'provider-default'` |
45
+ | `providerOptions` | `object` | - | Provider-specific options. Reasoning keys here take precedence over `reasoning`. |
46
+
47
+ See [Configuration Examples](#configuration-examples) at the end of this page for common setups.
48
+
49
+ ## Usage
50
+
51
+ ### CLI Mode
52
+
53
+ ```bash
54
+ # Research a specific path (relative to url in config)
55
+ npx explorbot research /login
56
+ npx explorbot research /admin/users
57
+
58
+ # Research with options
59
+ npx explorbot research /dashboard --deep
60
+ npx explorbot research /products --data
61
+ ```
62
+
63
+ ### TUI Mode (Interactive)
64
+
65
+ ```bash
66
+ # Research current page
67
+ /research
68
+
69
+ # Research with deep expansion (clicks dropdowns, tabs, etc.)
70
+ /research --deep
71
+
72
+ # Research with data extraction
73
+ /research --data
74
+
75
+ # Research specific path
76
+ /research /login
77
+ /research /admin/pages
78
+
79
+ # Skip locator validation and fixing
80
+ /research --no-fix
81
+ ```
82
+
83
+ Explicit research always runs fresh (bypassing the [cache](#caching)) and always captures a screenshot.
84
+
85
+ ### Automatic Research
86
+
87
+ Research also runs as part of other commands:
88
+
89
+ ```bash
90
+ # Planner researches the page before planning
91
+ npx explorbot plan /dashboard
92
+
93
+ # Explorer researches each new page it discovers
94
+ npx explorbot explore /admin
95
+ ```
96
+
97
+ ## How It Works
98
+
99
+ ### Element Indexing (eidx)
100
+
101
+ Before research begins, Explorbot injects a `data-explorbot-eidx` attribute into every interactive element on the page (buttons, links, inputs, tabs, and so on). Each element gets a unique numeric index — its **eidx**.
102
+
103
+ The eidx is a stable bridge between three representations of the same element:
104
+
105
+ | Representation | What it provides | Where eidx appears |
106
+ |----------------|------------------|--------------------|
107
+ | **HTML** | Structure, attributes, CSS selectors | `<button eidx="5">Save</button>` |
108
+ | **ARIA tree** | Accessible roles, names | Mapped back via Playwright `getByRole` |
109
+ | **Screenshot** | Visual position, color, icon | Colored label `5` drawn above the element |
110
+
111
+ When the AI produces a research table with `eidx=5`, that index is used to:
112
+ - Test the element's CSS locator against the live DOM
113
+ - Look up its coordinates from the annotated screenshot
114
+ - Generate a fallback XPath if CSS is broken
115
+
116
+ Without eidx, there would be no reliable way to match "the third button in the HTML" with "the blue button at (400, 300) on the screenshot."
117
+
118
+ ### The 5-Stage Pipeline
119
+
120
+ Research runs each page through five stages:
121
+
122
+ | Stage | Name | What happens |
123
+ |-------|------|--------------|
124
+ | 1 | **Research** (AI) | AI analyzes HTML and ARIA, produces a UI map with sections, containers, ARIA locators, CSS locators, and eidx references |
125
+ | 2 | **Test** | Test containers first, then element locators. Capture exact counts (`0 elements`, `3 elements`, `dynamic ID`). If all containers are broken or more than 80% of locators are broken, retry Stage 1 |
126
+ | 3 | **Fix** (AI, same conversation) | Continue the Stage 1 conversation with Playwright test results. AI fixes broken locators with full page context |
127
+ | 4 | **Visual** (optional) | Annotate the screenshot with eidx labels. AI extracts coordinates, colors, and icons. Merge into research by eidx |
128
+ | 5 | **Backfill** | Re-test all locators. For still-broken elements, look up the eidx in the DOM and generate an XPath from attributes. Nullify containers that are still broken |
129
+
130
+ Stage 3 reuses the Stage 1 conversation. The AI already has full context about the page HTML, so it fixes locators more accurately without extra token cost.
131
+
132
+ ### Research Modes
133
+
134
+ #### Standard Research (HTML + ARIA)
135
+
136
+ ```bash
137
+ /research
138
+ ```
139
+
140
+ Analyzes the page using HTML and the ARIA tree. Fast, and works with any model.
141
+
142
+ #### Deep Research
143
+
144
+ ```bash
145
+ /research --deep
146
+ ```
147
+
148
+ Expands hidden elements (dropdowns, accordions, tabs) to discover more UI. Clicks through interactive elements and documents what appears. Deep research also reuses what it found on previous runs — see [Reusing Previous Results](#reusing-previous-results).
149
+
150
+ #### Research with Data Extraction
151
+
152
+ ```bash
153
+ /research --data
154
+ ```
155
+
156
+ Extracts domain-specific content (articles, products, users) as structured data.
157
+
158
+ ## Page Sections
159
+
160
+ The Researcher breaks each page into sections by UI purpose. Sections are identified in priority order:
161
+
162
+ | Section | Description |
163
+ |---------|-------------|
164
+ | `overlay` | Dialog, modal, drawer, popup, or active form overlay |
165
+ | `list` | List area (items collection, table, cards, or list view) |
166
+ | `detail` | Detail area (selected item preview or full details) |
167
+ | `panes` | Screen is split into equal panes |
168
+ | `content` | Main area of the page |
169
+ | `menu` | Page menu (toolbar, context actions, filters, dropdowns) |
170
+ | `navigation` | Main navigation (top bar, sidebar, breadcrumbs) |
171
+
172
+ Each section includes:
173
+ - A **container CSS selector** that scopes all elements within it
174
+ - A **UI map table** listing interactive elements with ARIA and CSS locators
175
+
176
+ Override the default section list via `ai.agents.researcher.sections` — see [Configuration](#configuration).
177
+
178
+ ## Vision Model Support
179
+
180
+ ### Without Vision
181
+
182
+ The Researcher works with text-only models by analyzing HTML structure, the ARIA tree, and element roles and names. This is enough for most pages, and it is faster and cheaper.
183
+
184
+ ### With Vision
185
+
186
+ With a vision model configured, the Researcher can analyze screenshots for visual elements, detect icons and visual indicators, and provide element coordinates for visual clicking.
187
+
188
+ Enable vision by configuring a vision model instance:
189
+
190
+ ```javascript
191
+ ai: {
192
+ visionModel: openai('gpt-4o'),
193
+ }
194
+ ```
195
+
196
+ Explicit research always captures a screenshot; when a vision model is configured, the screenshot is analyzed in Stage 4.
197
+
198
+ Vision helps most on pages with icon-only buttons, canvas-based UIs, and when the HTML doesn't reflect the visual layout.
199
+
200
+ ## Deep Exploration
201
+
202
+ Deep exploration (the `--deep` flag) discovers hidden UI by clicking through elements to find modals, dropdowns, tabs, and menus.
203
+
204
+ For each element, the Researcher:
205
+ 1. Captures state before the click
206
+ 2. Clicks the element
207
+ 3. Detects what changed (navigation, modal, menu, UI change)
208
+ 4. Restores the original state (Escape key or navigate back)
209
+
210
+ ### Reusing Previous Results
211
+
212
+ Hidden sections discovered by deep research are saved under an **Extended Research** block in the page's research file, together with the action that revealed each one. On the next deep run for the same page — even in a later session — the researcher builds on that instead of starting from scratch:
213
+
214
+ 1. **Replay** — it re-runs the saved action for every previously found section to check it still opens.
215
+ 2. **Reuse** — sections that still open are kept as-is and are not explored again, so the run spends its click budget on what is actually new.
216
+ 3. **Re-discover** — if a section's trigger no longer works (the button moved or was renamed), it is flagged to the AI as "this section existed before, find it again", so a relocated control is recovered rather than lost.
217
+ 4. **Skip** — when every known section still opens and the click budget is already covered, the slow click-through exploration is skipped because the page is effectively unchanged.
218
+
219
+ This makes repeated deep runs faster and stops the researcher from silently losing hidden UI it had already mapped. The reuse reads the last saved research file directly, so it works across sessions and is not limited by the in-memory [cache window](#caching).
220
+
221
+ ### Selecting Elements
222
+
223
+ Not every element should be explored. During deep analysis the AI itself discovers expandable candidates from the research results — and from the annotated screenshot when a vision model is configured — picking elements that hide content until clicked (menus, dropdowns, accordions, tabs) and skipping regular links and navigation. Repeated controls, like the same expand button on every list row, collapse to a single representative. When more candidates are found than the click budget allows, the AI selects the most promising ones. The budget is set by `maxExpandableClicks` (default 10).
224
+
225
+ ## Output Format
226
+
227
+ Research results are saved to `output/research/{hash}.md`:
228
+
229
+ ```markdown
230
+ ## Summary
231
+
232
+ Brief description of the page purpose.
233
+
234
+ ## Login Modal
235
+
236
+ Modal dialog for user login...
237
+
238
+ > Container: '[role="dialog"]'
239
+ > **Focused**
240
+
241
+ | Element | Type | ARIA | CSS |
242
+ |---------|------|------|-----|
243
+ | 'Email' | textbox | { role: 'textbox', text: 'Email' } | 'input#email' |
244
+ | 'Password' | textbox | { role: 'textbox', text: 'Password' } | 'input[name="password"]' |
245
+ | 'Sign In' | button | { role: 'button', text: 'Sign In' } | 'button[type="submit"]' |
246
+
247
+ ## Content Section
248
+
249
+ Main content area...
250
+
251
+ > Container: '.main-content'
252
+
253
+ | Element | Type | ARIA | CSS | XPath | Coordinates |
254
+ |---------|------|------|-----|-------|-------------|
255
+ | 'Save' | button | { role: 'button', text: 'Save' } | 'button.save' | - | (400, 300) |
256
+ | 'Delete' | button | { role: 'button', text: 'Delete' } | - | '//button[@class="del"]' | (500, 300) |
257
+ ```
258
+
259
+ Notes:
260
+ - Sections are named after their content (never "Focus"); a focused overlay is marked with a `> **Focused**` blockquote under its container line
261
+ - The Type column is derived from the ARIA role during cleanup
262
+ - The XPath column appears only when CSS is broken and XPath was backfilled from the DOM
263
+ - Coordinates are backfilled from DOM positions for all indexed (eidx) elements; a vision model additionally contributes colors and icons
264
+ - The container is shown as a blockquote `> Container: '...'` before the table
265
+
266
+ ## Caching
267
+
268
+ Research results are cached for 6 hours:
269
+ - In memory during the session
270
+ - On disk in `output/research/`
271
+
272
+ Separately, for up to 1 hour a page whose HTML fingerprint is at least 90% similar to an already-researched state reuses that state's research.
273
+
274
+ The cache applies to research triggered automatically by other agents. Explicit `/research` always bypasses it and runs fresh.
275
+
276
+ This cache controls when a fresh result is reused within a session. It is separate from how [deep research reuses previous results](#reusing-previous-results): a deep run always reloads the last saved research file from `output/research/` to replay and verify previously discovered hidden sections, regardless of the cache window or session.
277
+
278
+ ## Configuration Examples
279
+
280
+ ### Limit Sections
281
+
282
+ ```javascript
283
+ ai: {
284
+ agents: {
285
+ researcher: {
286
+ // Only research these sections, skip navigation and menu
287
+ sections: ['overlay', 'content', 'list', 'detail'],
288
+ },
289
+ },
290
+ }
291
+ ```
292
+
293
+ ### Focus on a Single Element
294
+
295
+ `focusSections` applies when a truncated response forces the Researcher into per-section research (see [Handling Truncated Responses](#handling-truncated-responses)). It is a list of CSS selectors — the first one that matches on the current page wins, and the split research treats that element as the focused container instead of the whole page. Useful for apps that open a modal, drawer, or detail panel on top of the main layout:
296
+
297
+ ```javascript
298
+ ai: {
299
+ agents: {
300
+ researcher: {
301
+ focusSections: [
302
+ '[role="dialog"]', // open modal
303
+ '.drawer-open', // expanded side drawer
304
+ '#focused-panel', // your app's detail panel
305
+ ],
306
+ },
307
+ },
308
+ }
309
+ ```
310
+
311
+ When none of the selectors match, per-section research covers the whole page.
312
+
313
+ ### Handling Truncated Responses
314
+
315
+ The Researcher produces a lot of output for busy pages. If the model's response is cut off at `maxOutputTokens`, Explorbot retries by splitting the work into one request per section (focus, main, sidebar, and so on) and merging the results. This usually happens transparently in the logs; no configuration is needed.
316
+
317
+ If you see it often, consider:
318
+ - lowering reasoning effort (see [Reasoning Effort](#reasoning-effort) below),
319
+ - pinning the Researcher to a non-reasoning model with a larger output window,
320
+ - or narrowing the scope with `focusSections`.
321
+
322
+ ### Custom Component Guidance
323
+
324
+ ```javascript
325
+ ai: {
326
+ agents: {
327
+ researcher: {
328
+ systemPrompt: `
329
+ This app uses custom components:
330
+ - <DataGrid> renders as div with role="grid"
331
+ - <Modal> uses [data-modal] attribute
332
+ - Dropdowns have [data-dropdown] attribute
333
+
334
+ Look for data-testid attributes for reliable selectors.
335
+ `,
336
+ },
337
+ },
338
+ }
339
+ ```
340
+
341
+ ### Reasoning Effort
342
+
343
+ The Researcher runs with `reasoning: 'low'` by default. On reasoning models this keeps the chain-of-thought short, so the output budget goes to the UI map instead of thinking tokens. `reasoning` is the provider-agnostic setting from AI SDK v7 — the SDK maps it to the active provider's effort control, so the same value works across OpenAI, Anthropic, Google, Groq, and others:
344
+
345
+ ```javascript
346
+ ai: {
347
+ agents: {
348
+ researcher: {
349
+ reasoning: 'none', // 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'provider-default'
350
+ },
351
+ },
352
+ }
353
+ ```
354
+
355
+ For provider-specific control (such as an exact thinking-token budget), set the provider's own keys in `providerOptions` — they take precedence over `reasoning`.
356
+
357
+ If heavy pages still truncate the response (`AI response empty: output truncated at maxTokens`), lower `reasoning` to `'none'`, raise `maxOutputTokens`, or pin the Researcher to a non-reasoning model.
358
+
359
+ ### Vision-Heavy Research
360
+
361
+ ```javascript
362
+ ai: {
363
+ agents: {
364
+ researcher: {
365
+ systemPrompt: `
366
+ Pay attention to:
367
+ - Icon buttons without text labels
368
+ - Color indicators (red = error, green = success)
369
+ - Visual hierarchy and spacing
370
+ `,
371
+ },
372
+ },
373
+ }
374
+ ```
375
+
376
+ ## See Also
377
+
378
+ - [Configuration](../reference/configuration.md) - general configuration options
379
+ - [Agents](./agents.md) - all agent descriptions
380
+ - [Knowledge Files](../workflow/knowledge.md) - domain-specific hints
@@ -0,0 +1,233 @@
1
+ # Agentic Usage
2
+
3
+ Explorbot is a terminal command, so a coding agent — Claude Code, Cursor, Codex, or your own script — can drive it the same way it drives `git` or `npm`. This page covers the two things an agent needs: getting Explorbot configured once, and handing it a test plan it wrote itself.
4
+
5
+ The division of labour that works best: the agent decides *what* to test and writes it down as a plan; Explorbot figures out *how* to click through the app and reports what actually happened.
6
+
7
+ ## Start here: the global installation
8
+
9
+ Configure models and keys once for the machine, and every later command works in any directory with no environment variables to remember:
10
+
11
+ ```bash
12
+ npx explorbot init --global --provider openrouter --api-key sk-...
13
+ npx explorbot explore https://app.example.com/login --max-tests 3
14
+ ```
15
+
16
+ `init --global` writes `~/.explorbot/config.js` with the recommended model ids of this Explorbot version and stores the key in `~/.explorbot/.env`. It needs no terminal — with `--provider` there is no wizard, so an agent can run it unattended.
17
+
18
+ The global config holds models and keys, never a site. Most commands carry the site themselves — `explore`, `plan`, `research`, `navigate`, `context`, `shell`, `freesail`, `docs collect`. The ones that take no URL argument — `test`, `learn`, `knows`, `experience`, `compact` — read it from `EXPLORBOT_URL`, and stop with `No site to explore` when it is unset:
19
+
20
+ ```bash
21
+ EXPLORBOT_URL=https://app.example.com npx explorbot learn "/login" 'Sign in as ${env.APP_USER}'
22
+ ```
23
+
24
+ This is the form to prefer. Each site explored gets its own folder under `~/.explorbot/sites/<host>/` holding `knowledge/`, `experience/`, and `output/`, so what Explorbot learns about an app is still there on the next run — the agent that explored `/checkout` yesterday does not start from zero today. Later runs can name the site by host instead of repeating the URL:
25
+
26
+ ```bash
27
+ npx explorbot explore app.example.com/dashboard
28
+ npx explorbot sites # what is registered, and when it last ran
29
+ ```
30
+
31
+ The `EXPLORBOT_*` variables below still win over it: setting `EXPLORBOT_AI_PROVIDER` or `EXPLORBOT_AI_MODEL` builds the configuration from the environment and the global config is skipped. So an agent can install once and still override models or the URL per command.
32
+
33
+ ## One-liner API
34
+
35
+ When nothing can be installed — a CI job, a container, someone else's machine — set `EXPLORBOT_AI_PROVIDER` and Explorbot builds a config from `EXPLORBOT_*` environment variables instead. Name a provider and you get its recommended models:
36
+
37
+ ```bash
38
+ EXPLORBOT_URL=https://app.example.com \
39
+ EXPLORBOT_AI_PROVIDER=openrouter \
40
+ npx explorbot explore /login --max-tests 3
41
+ ```
42
+
43
+ No `init`, no config file, no project directory, no model IDs to look up. These variables win over the global installation, so a run can always be pinned to its own models. A project `explorbot.config.js` still wins over them, so adding these variables never changes the behavior of an existing project.
44
+
45
+ ### Variables
46
+
47
+ <!-- START env -->
48
+ | Variable | Required | Meaning |
49
+ |---|---|---|
50
+ | `EXPLORBOT_AI_PROVIDER` | yes | Provider name; fills every model role from its recommended models. Turns on config-free mode |
51
+ | `EXPLORBOT_AI_MODEL` | no | Pins the main model — a model id for the provider, or a standalone provider/model-id |
52
+ | `EXPLORBOT_URL` | yes | Base URL to test; the API boat reads it as the base endpoint |
53
+ | `EXPLORBOT_VISION_MODEL` | no | Screenshot analysis; overrides the provider recommendation |
54
+ | `EXPLORBOT_AGENTIC_MODEL` | no | Captain and Pilot decisions; overrides the provider recommendation |
55
+ | `EXPLORBOT_OUTPUT` | no | Output root for states, plans, research, and reports. Defaults to the site dir under ~/.explorbot/sites |
56
+ | `EXPLORBOT_EPHEMERAL` | no | Keep no state between runs — output goes to a fresh temp directory instead of the site dir |
57
+ | `EXPLORBOT_KNOWLEDGE` | no | Inline knowledge text, applied to every page |
58
+ | `EXPLORBOT_KNOWLEDGE_FILE` | no | Path to a knowledge markdown file |
59
+ | `EXPLORBOT_API_SPEC` | no | OpenAPI spec path for the API boat |
60
+ | `EXPLORBOT_NO_BANNER` | no | Suppress the startup banner, for machine-readable output |
61
+ <!-- END env -->
62
+
63
+ `EXPLORBOT_URL` is optional when the command itself carries an absolute URL, as `docs collect https://…` does. The [API boat](../api-testing/basics.md) reads it as the base endpoint.
64
+
65
+ This table is generated from the registry in `src/config.ts`, which also feeds `explorbot --help` — so `npx explorbot --help` lists the same variables on any command, and an agent can discover them without reading these docs.
66
+
67
+ ### Naming models
68
+
69
+ Set `EXPLORBOT_AI_PROVIDER` to a provider name and Explorbot uses that provider's recommended model for every role — the same IDs listed in [Providers](../basics/providers.md), maintained in [`models.json`](../../models.json):
70
+
71
+ ```bash
72
+ EXPLORBOT_AI_PROVIDER=openrouter # model, visionModel, and agenticModel all filled in
73
+ ```
74
+
75
+ This is the form to reach for when you do not care which model runs, only that the run works. Recommendations change as models are released, so a provider name keeps up while a pinned ID does not.
76
+
77
+ To pin the main model, add `EXPLORBOT_AI_MODEL`. With a provider set, it is the model id for that provider, used verbatim — slashes and all:
78
+
79
+ ```bash
80
+ EXPLORBOT_AI_PROVIDER=openrouter \
81
+ EXPLORBOT_AI_MODEL=openai/gpt-oss-120b:nitro \
82
+ npx explorbot explore /checkout
83
+ ```
84
+
85
+ On its own, without a provider, `EXPLORBOT_AI_MODEL` must carry the provider as `provider/model-id`, and it sets only the main `model` — `visionModel` and `agenticModel` stay unset unless you add `EXPLORBOT_AI_PROVIDER` or set them explicitly. It splits on the **first** slash, so provider-qualified IDs survive intact:
86
+
87
+ ```
88
+ openrouter/openai/gpt-oss-120b:nitro → openrouter, model "openai/gpt-oss-120b:nitro"
89
+ groq/openai/gpt-oss-20b → groq, model "openai/gpt-oss-20b"
90
+ anthropic/claude-haiku-4-5-20251001 → anthropic, model "claude-haiku-4-5-20251001"
91
+ ```
92
+
93
+ `EXPLORBOT_VISION_MODEL` and `EXPLORBOT_AGENTIC_MODEL` override those roles the same way — a provider name for its recommendation, or `provider/model-id` to pin one. Mix the forms to take a provider's recommendations and override one role:
94
+
95
+ ```bash
96
+ EXPLORBOT_AI_PROVIDER=groq \
97
+ EXPLORBOT_AGENTIC_MODEL=anthropic \
98
+ npx explorbot explore /checkout
99
+ ```
100
+
101
+ Supported providers: `openai`, `anthropic`, `google`, `groq`, `mistral`, `openrouter`, `sambanova`. Each is created with its conventional API-key variable — `OPENROUTER_API_KEY`, `GROQ_API_KEY`, `MISTRAL_API_KEY`, and so on.
102
+
103
+ Not every provider has a recommendation for every role — Anthropic is recommended only for `agenticModel`, since Claude models are accurate but costly for token-heavy page reading. Naming a provider that has no recommendation for a role you asked for is an error that names the role, so combine providers as in the example above.
104
+
105
+ A `.env` file in the working directory is loaded before the config lookup, so `EXPLORBOT_*` variables and API keys can live there instead of on the command line.
106
+
107
+ ### Knowledge without a project
108
+
109
+ Both knowledge variables write into the run's knowledge directory, and both can be set at once.
110
+
111
+ `EXPLORBOT_KNOWLEDGE` is the fast path for credentials — it applies to every page:
112
+
113
+ ```bash
114
+ EXPLORBOT_KNOWLEDGE="Log in as admin@example.com / secret123. Dismiss the cookie banner first." \
115
+ EXPLORBOT_URL=https://app.example.com \
116
+ EXPLORBOT_AI_PROVIDER=openrouter \
117
+ npx explorbot explore /admin/users
118
+ ```
119
+
120
+ `EXPLORBOT_KNOWLEDGE_FILE` points at a markdown file the agent wrote. Its frontmatter is preserved, so it can target specific URLs — see [Knowledge](./knowledge.md) for the format:
121
+
122
+ ```bash
123
+ EXPLORBOT_KNOWLEDGE_FILE=./checkout-knowledge.md npx explorbot explore /checkout
124
+ ```
125
+
126
+ ### What this mode changes
127
+
128
+ Config-free runs leave no trace in the working directory:
129
+
130
+ - **Output goes to the site folder** — `~/.explorbot/sites/<host>/`, the same folder the global installation uses, so states, plans, research, and reports for one app collect in one place however the run was configured. `EXPLORBOT_OUTPUT` points them somewhere else. Read the path Explorbot resolved from the `Configuration built from EXPLORBOT_* environment variables. Output: …` line.
131
+ - **`EXPLORBOT_EPHEMERAL=1` keeps nothing between runs** — output goes to a fresh temp directory instead, for throwaway CI jobs and demos. The [prima boat](../reference/commands.md#prima-boat) exposes the same switch as `--ephemeral`.
132
+ - **Experience is written into the site folder.** What worked on a page is remembered and reused by later runs against the same host. `EXPLORBOT_EPHEMERAL=1` turns writing off, so an ephemeral run stays reproducible.
133
+ - **The Historian is off.** No generated CodeceptJS or Playwright test files — that is the one thing the global installation gives that this mode does not. Plans and reports are still written.
134
+
135
+ ### Reading results
136
+
137
+ Everything lands under the output root:
138
+
139
+ | Path | Contents |
140
+ |---|---|
141
+ | `reports/<mode>-<session>.md` | Session report: coverage, defects, execution issues |
142
+ | `plans/<page>.md` | The plan that was generated or executed |
143
+ | `states/` | Per-state HTML, ARIA snapshots, and screenshots |
144
+ | `research/` | UI maps produced by the Researcher |
145
+
146
+ The report is the artifact to parse. It clusters findings by root cause and is written for a reader, not a machine.
147
+
148
+ `explore` and `test` exit `0` whenever the session completes, and non-zero only when the run itself fails to start — a failing scenario is a result, not a crash. Do not read pass/fail from their exit code; read the report. `navigate` is the exception and exits `1` when a URL is unreachable, which makes it a useful pre-flight check.
149
+
150
+ ## Running agent-prepared plans
151
+
152
+ A [test plan](./test-plans.md) is plain markdown. An agent that has read the codebase usually knows what a feature is supposed to do better than an agent looking at rendered HTML, so writing the plan and executing it are worth separating.
153
+
154
+ Write the plan:
155
+
156
+ ```markdown
157
+ <!-- suite -->
158
+ # Checkout
159
+
160
+ ### Prerequisite
161
+
162
+ * URL: /cart
163
+
164
+ <!-- test
165
+ priority: critical
166
+ -->
167
+ # Customer completes checkout with a saved card
168
+
169
+ ## Requirements
170
+ /cart
171
+
172
+ ## Steps
173
+ * Proceed to checkout from the cart
174
+ * Pick the saved card as the payment method
175
+ * Confirm the order
176
+
177
+ ## Expected
178
+ * The order confirmation page shows an order number
179
+ * The cart is empty afterwards
180
+ ```
181
+
182
+ Then hand it to Explorbot:
183
+
184
+ ```bash
185
+ EXPLORBOT_URL=https://app.example.com \
186
+ EXPLORBOT_AI_PROVIDER=openrouter \
187
+ npx explorbot test checkout-plan.md '*'
188
+ ```
189
+
190
+ The index argument selects tests: `1`, `1,3`, `1-5`, or `*` for all. The plan file is input only — Explorbot never rewrites it, so plans stay in version control next to the code they cover.
191
+
192
+ Steps are guidance, not a script. The Tester adapts them to what the page actually shows, which is why steps should describe intent rather than selectors. Expected outcomes are the strict part: a test passes only when every one of them is verified. See the [Planner's outcome guidance](../web-testing/planner.md#built-in-styles) for what makes an outcome verifiable.
193
+
194
+ To have Explorbot invent the scenarios instead, run `explorbot plan <path>` and read the generated file from `plans/`.
195
+
196
+ ## Inspecting a page without spending tokens
197
+
198
+ Two commands help an agent orient itself before committing to a run:
199
+
200
+ ```bash
201
+ npx explorbot context /login # URL, headings, knowledge, interactive elements
202
+ npx explorbot shell /login 'I.click("Sign in")' # run one CodeceptJS command
203
+ ```
204
+
205
+ `context` makes no AI calls. Use it to check that a page loads, that login knowledge applies, and that the elements a plan assumes are actually there.
206
+
207
+ ## The other boats
208
+
209
+ The same variables drive API testing and doc collection.
210
+
211
+ ```bash
212
+ EXPLORBOT_URL=https://api.example.com \
213
+ EXPLORBOT_API_SPEC=./openapi.yaml \
214
+ EXPLORBOT_AI_PROVIDER=openrouter \
215
+ npx explorbot api explore
216
+ ```
217
+
218
+ ```bash
219
+ EXPLORBOT_AI_PROVIDER=openrouter \
220
+ npx explorbot docs collect https://app.example.com/dashboard --max-pages 20
221
+ ```
222
+
223
+ `docs collect` takes its base URL from the absolute path argument, so `EXPLORBOT_URL` is optional there.
224
+
225
+ Knowledge written by `EXPLORBOT_KNOWLEDGE` carries `endpoint: '*'` frontmatter alongside `url: '*'`, matching the convention `api init` and `api know` use. The API boat does not read knowledge at runtime yet; the frontmatter is there for when it does, and the web side ignores it.
226
+
227
+ ## See Also
228
+
229
+ - [Test Plans](./test-plans.md) — the plan format in full
230
+ - [Knowledge](./knowledge.md) — teaching Explorbot about your app
231
+ - [Commands](../reference/commands.md) — every CLI command
232
+ - [Continuous integration](./ci.md) — scheduled runs with cached experience
233
+ - [Scripting](../reference/scripting.md) — the programmatic API when a CLI call is not enough
@@ -0,0 +1,73 @@
1
+ # Application Specs
2
+
3
+ An application spec is a versioned Markdown bundle that gives Explorbot previously collected information about an application. It can be produced by Docbot, another documentation tool, or by hand.
4
+
5
+ Live HTML, ARIA, and screenshots remain the source of truth. Explorbot uses matching spec pages as supporting context and does not load the whole bundle into every prompt.
6
+
7
+ ## Configure
8
+
9
+ Set the bundle directory in `explorbot.config.js`:
10
+
11
+ ```javascript
12
+ export default {
13
+ dirs: {
14
+ spec: 'spec',
15
+ },
16
+ };
17
+ ```
18
+
19
+ Paths are resolved from the project directory. Use `--spec <path>` on a web command to override the configured bundle for one run. Both the bundle directory and its `index.md` path are accepted.
20
+
21
+ ## Bundle structure
22
+
23
+ ```text
24
+ spec/
25
+ |-- index.md
26
+ `-- pages/
27
+ |-- home.md
28
+ `-- users.md
29
+ ```
30
+
31
+ `index.md` is required and serves as a human-readable entry point. Its contents are not injected into agents. Page files may be nested anywhere below `pages/` and must use the contract below.
32
+
33
+ ## Page contract
34
+
35
+ Every page is a Markdown file with YAML front matter:
36
+
37
+ ```markdown
38
+ ---
39
+ format: explorbot-application-spec
40
+ version: 1
41
+ url: /users
42
+ ---
43
+
44
+ # Users
45
+
46
+ ## Purpose
47
+
48
+ Lists the application's users.
49
+
50
+ ## User Can
51
+
52
+ - user can search users by name
53
+ Proof: A search field is visible above the user list.
54
+
55
+ ## User Might
56
+
57
+ - user might export the user list
58
+ Signal: An unlabeled download control is present.
59
+ ```
60
+
61
+ The front matter fields are mandatory:
62
+
63
+ - `format` must be `explorbot-application-spec`.
64
+ - `version` must be `1`.
65
+ - `url` is the URL pattern used to select the page for the current browser state. It supports the same patterns as [knowledge files](./knowledge.md#url-patterns).
66
+
67
+ The Markdown body is supplied to agents as written, so headings beyond those shown above are allowed. Use `User Can` only for observed capabilities and transitions. Put inferred or unverified capabilities under `User Might`; Explorbot will require confirmation from the live UI before relying on them.
68
+
69
+ Screenshots and other relative links may be included for readers, but Explorbot currently consumes the Markdown text only.
70
+
71
+ ## Validation
72
+
73
+ Explorbot rejects a bundle when `index.md` or `pages/` is missing, when it contains no page files, or when a page has an unsupported format, version, or missing URL.