explorbot 0.1.28 → 0.1.30

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 (68) hide show
  1. package/README.md +83 -245
  2. package/bin/explorbot-cli.ts +1 -0
  3. package/boat/doc-collector/src/ai/documentarian.ts +37 -13
  4. package/boat/doc-collector/src/ai/tools.ts +60 -20
  5. package/boat/doc-collector/src/cli.ts +3 -0
  6. package/boat/doc-collector/src/config.ts +7 -0
  7. package/boat/doc-collector/src/docbot.ts +23 -5
  8. package/boat/doc-collector/src/docs-renderer.ts +14 -1
  9. package/boat/doc-collector/src/screenshots.ts +126 -0
  10. package/dist/bin/explorbot-cli.js +1 -0
  11. package/dist/boat/doc-collector/src/ai/documentarian.js +15 -11
  12. package/dist/boat/doc-collector/src/ai/tools.js +53 -20
  13. package/dist/boat/doc-collector/src/cli.js +3 -0
  14. package/dist/boat/doc-collector/src/config.js +3 -0
  15. package/dist/boat/doc-collector/src/docbot.js +19 -4
  16. package/dist/boat/doc-collector/src/docs-renderer.js +12 -1
  17. package/dist/boat/doc-collector/src/screenshots.js +90 -0
  18. package/dist/package.json +8 -6
  19. package/dist/rules/navigator/verification-actions.md +2 -0
  20. package/dist/src/action.js +26 -23
  21. package/dist/src/ai/fisherman.js +14 -3
  22. package/dist/src/ai/historian/codeceptjs.js +3 -2
  23. package/dist/src/ai/historian/experience.js +48 -6
  24. package/dist/src/ai/historian/playwright.js +2 -1
  25. package/dist/src/ai/historian/utils.js +1 -19
  26. package/dist/src/ai/historian.js +1 -1
  27. package/dist/src/ai/pilot.js +19 -4
  28. package/dist/src/ai/planner.js +16 -5
  29. package/dist/src/ai/provider.js +53 -18
  30. package/dist/src/ai/quartermaster.js +2 -2
  31. package/dist/src/ai/researcher.js +7 -1
  32. package/dist/src/ai/rules.js +44 -0
  33. package/dist/src/ai/tester.js +73 -7
  34. package/dist/src/ai/tools.js +66 -1
  35. package/dist/src/experience-tracker.js +1 -1
  36. package/dist/src/explorbot.js +14 -3
  37. package/dist/src/explorer.js +30 -27
  38. package/dist/src/stats.js +16 -0
  39. package/dist/src/utils/aria.js +66 -6
  40. package/dist/src/utils/browser-errors.js +5 -0
  41. package/dist/src/utils/page-readiness.js +48 -0
  42. package/dist/src/utils/step-analyzer.js +68 -0
  43. package/package.json +8 -6
  44. package/rules/navigator/verification-actions.md +2 -0
  45. package/src/action.ts +24 -26
  46. package/src/ai/fisherman.ts +14 -3
  47. package/src/ai/historian/codeceptjs.ts +3 -2
  48. package/src/ai/historian/experience.ts +51 -6
  49. package/src/ai/historian/playwright.ts +2 -1
  50. package/src/ai/historian/utils.ts +1 -21
  51. package/src/ai/historian.ts +1 -1
  52. package/src/ai/pilot.ts +19 -4
  53. package/src/ai/planner.ts +16 -5
  54. package/src/ai/provider.ts +51 -19
  55. package/src/ai/quartermaster.ts +2 -2
  56. package/src/ai/researcher.ts +8 -1
  57. package/src/ai/rules.ts +46 -0
  58. package/src/ai/tester.ts +77 -7
  59. package/src/ai/tools.ts +79 -1
  60. package/src/config.ts +2 -0
  61. package/src/experience-tracker.ts +1 -1
  62. package/src/explorbot.ts +13 -3
  63. package/src/explorer.ts +28 -27
  64. package/src/stats.ts +18 -0
  65. package/src/utils/aria.ts +63 -6
  66. package/src/utils/browser-errors.ts +6 -0
  67. package/src/utils/page-readiness.ts +59 -0
  68. package/src/utils/step-analyzer.ts +73 -0
package/README.md CHANGED
@@ -1,336 +1,178 @@
1
- # Explorbot
1
+ <p align="center">
2
+ <img src="assets/explorbot-logo.png" alt="Explorbot" width="560">
3
+ </p>
2
4
 
3
- **The vibe-testing agent for web applications.**
5
+ <p align="center"><b>The vibe-testing agent for web applications.</b></p>
4
6
 
5
7
  ![Explorbot Terminal UI](https://github.com/testomatio/explorbot/blob/main/assets/screenshot.png)
6
8
 
7
- Explorbot explores your web app like a curious human would — clicking around, filling forms, finding bugs, and learning as it goes. No test scripts required. Just point it at your app and let it work.
9
+ Explorbot is an AI agent that investigates your product like your most relentless QA engineer — clicking around, filling forms, and finding bugs. It turns every discovery into a test you can keep. No test scripts required. Just point it at your app and let it work.
8
10
 
9
11
  ```bash
10
12
  npx explorbot start https://your-app.com
11
13
  ```
12
14
 
13
- Explorbot is your first assitant in testing.
14
- It will do its best to use your application with no babysitting. It will use application and provide you valuable feedback.
15
+ It runs with no babysitting and reports back what it finds. This is vibe-testing.
16
+
17
+ New here? Read the [Getting Started guide](docs/getting-started.md).
15
18
 
16
19
  ## Use Cases
17
20
 
18
- * Autonomously test web application or its parts
21
+ * Autonomously test a web application or parts of it
19
22
  * Discover test scenarios and get automated tests for them
20
- * Write manual test cases from exploring website
21
- * 24h/7d of monkey-testing for web application that can reveal hidden errors
23
+ * Write manual test cases from exploring a website
24
+ * 24/7 monkey-testing that reveals hidden errors
22
25
  * Quick-test for MVPs and prototypes
23
26
 
24
- Explorbot can start testing features which were not covered by unit tests or browser tests.
27
+ Explorbot tests features that unit tests and scripted browser tests never reach.
25
28
 
26
29
  ## Demo
27
30
 
28
31
  ![Explorbot in action](https://github.com/testomatio/explorbot/blob/main/assets/demo.gif)
29
32
 
30
- ## Requirements
31
-
32
- - NodeJS 24+ or **Bun**
33
- - **AI provider API key** — OpenRouter recommended; Groq, Cerebras, OpenAI, Anthropic, or others via [Vercel AI SDK](https://sdk.vercel.ai/providers)
34
- - **Modern terminal** — iTerm2, WARP, Kitty, Ghostty. WSL if running on Windows
35
- - **Compatible web app** — Check [docs/prerequisites.md](docs/prerequisites.md) to verify your app works with Explorbot
36
-
37
- ## Quick Start
38
-
39
- **1. Install dependencies**
40
-
41
- ```bash
42
- npm i explorbot --save
43
- npx playwright install
44
- ```
45
-
46
- **2. Initialize config**
47
-
48
- ```bash
49
- npx explorbot init
50
- ```
51
-
52
- **3. Edit `explorbot.config.js`** — set your app URL and AI provider:
53
-
54
- > [!IMPORTANT]
55
- > **Explorbot uses three types of models:**
56
- >
57
- > | Type | Config key | Purpose | Recommendation |
58
- > |------|-----------|---------|----------------|
59
- > | **model** | `ai.model` | Standard model for HTML/ARIA processing. Used by Tester, Navigator, Researcher. Should be fast and cheap — these agents are token-hungry. | e.g. `openai/gpt-oss-20b` |
60
- > | **visionModel** | `ai.visionModel` | Screenshot analysis. Used when agents need to visually inspect the page. | e.g. `meta-llama/llama-4-scout-17b-16e-instruct` |
61
- > | **agenticModel** | `ai.agenticModel` | Exceptional decision making. Used by Captain and Pilot — agents that read compact action logs and make high-level decisions. Benefits from a smarter model. | Strong agentic models but fast (MiniMax 2.5, Grok Fast, Qwen, …) |
62
- >
63
- > See [OpenRouter](https://openrouter.ai/rankings#performance) for latency-focused model picks.
64
-
65
- This example uses **OpenRouter** (one API key, many providers). Any Vercel AI SDK provider works; see [docs/providers.md](docs/providers.md).
66
-
67
- ```javascript
68
- import { createOpenRouter } from '@openrouter/ai-sdk-provider';
69
-
70
- const openrouter = createOpenRouter({
71
- apiKey: process.env.OPENROUTER_API_KEY,
72
- });
73
-
74
- export default {
75
- web: {
76
- url: 'https://your-app.com',
77
- },
78
- ai: {
79
- model: openrouter('openai/gpt-oss-20b'),
80
- visionModel: openrouter('meta-llama/llama-4-scout-17b-16e-instruct'),
81
- agenticModel: openrouter('minimax/minimax-m2.5:nitro'),
82
- },
83
- };
84
- ```
85
-
86
- > [!TIP]
87
- > Captain and Pilot barely use tokens (just action summaries), so a smarter `agenticModel` costs very little while significantly improving test quality. You can also override any agent's model individually via `ai.agents.<name>.model`.
88
-
89
- **4. Add knowledge** (optional but recommended)
90
-
91
- If your app requires authentication, tell Explorbot how to log in:
92
-
93
- ```bash
94
- # Interactive mode
95
- npx explorbot learn
96
-
97
- # Or via CLI
98
- npx explorbot learn "/login" "Use credentials: admin@example.com / secret123"
99
- ```
100
-
101
- > [!TIP]
102
- > Use `--session` to persist browser cookies and localStorage between runs. Log in once, and Explorbot will restore the session on next start:
103
- > ```bash
104
- > npx explorbot start /login --session # saves to output/session.json
105
- > npx explorbot start /dashboard --session # restores session, skips login
106
- > npx explorbot start /app --session auth.json # custom session file
107
- > ```
108
-
109
- > [!NOTE]
110
- > Use `*` as URL pattern to add general knowledge that applies to all pages. See [docs/knowledge.md](docs/knowledge.md) for more.
111
-
112
- **5. Run**
113
-
114
- ```bash
115
- npx explorbot start /admin/users
116
- ```
117
-
118
- Start from a small functional area of your app (admin panel, settings, any CRUD section) so Explorbot can quickly understand its business purpose and context.
33
+ ## A new layer of testing
119
34
 
120
- Browser runs headless by defaultuse `--show` to see it:
35
+ Unit tests check a function. End-to-end tests replay fixed user journeys. **Exploratory tests** investigate the app the way a curious tester would taking new paths every run and catching what no one thought to script.
121
36
 
122
- ```bash
123
- npx explorbot start /settings --show
124
- ```
37
+ Explorbot makes that third layer routine. It runs on your CI next to the other two, and everything stays local — no cloud service touches your app.
125
38
 
126
- Requires a modern terminal (iTerm2, WARP, Kitty, Ghostty, Windows Terminal). On Windows, use WSL.
39
+ ## How a session works
127
40
 
128
- ## How It Works
41
+ Give Explorbot a goal and a URL. A crew of agents takes it from there — no scripts, no human in the loop.
129
42
 
130
- Explorbot explores websites, analyzes their UI, and proposes tests which it can then execute. It controls its own browser through CodeceptJS → Playwright (no MCP involved).
43
+ 1. **Research** map the page into sections and index every element. No source or docs needed.
44
+ 2. **Plan** — draft test scenarios across normal, curious, and edge styles.
45
+ 3. **Execute** — drive the browser step by step, adapting as the app changes.
46
+ 4. **Verify** — confirm each outcome, cluster findings by root cause, and capture evidence.
47
+ 5. **Keep** — save passing flows as real tests, with reports and screencasts — and learn for next run.
131
48
 
132
49
  ![Explorbot Architecture](assets/architecture.png)
133
50
 
134
- Run `/explore` in TUI or use `explorbot explore` from CLI to watch the cycle: research → plan → test → repeat.
51
+ ## The crew
135
52
 
136
- **Supporting components:**
53
+ Cheap, fast workers do the clicking and reading; smart managers make the calls — so a full session costs cents, not dollars.
137
54
 
138
- * **Pilot** supervises Tester from a separate conversation: reviews action logs, detects stuck patterns, makes final pass/fail decisions. Uses `agenticModel` since it only processes compact summaries, not raw HTML
139
- * **Historian** — saves sessions as CodeceptJS code, learns from experience
140
- * **Quartermaster** analyzes pages for A11y issues (axe-core + semantic)
141
- * **Reporter** sends test results to Testomat.io
55
+ | | | |
56
+ |---|---|---|
57
+ | [Researcher](docs/reference/agents.md) | [Planner](docs/reference/agents.md) | [Tester](docs/reference/agents.md) |
58
+ | [Pilot](docs/reference/agents.md) | [Captain](docs/reference/agents.md) | [Navigator](docs/reference/agents.md) |
59
+ | [Analyst](docs/reference/agents.md) | [Historian](docs/reference/agents.md) | [Fisherman](docs/reference/agents.md) |
142
60
 
143
- ## Basic Usage
61
+ See [Agents](docs/reference/agents.md) for what each one does.
144
62
 
145
- Once in the terminal UI:
63
+ ## Core Philosophy
146
64
 
147
- ```
148
- /explore # Full cycle: research → plan → test
149
- /research # Analyze current page
150
- /plan # Generate test scenarios
151
- /test # Run next test
152
- /navigate /settings # Go to a page
153
- ```
65
+ **Strategic decisions are deterministic** — the workflow (research → plan → test) is predictable and consistent.
154
66
 
155
- You can also run CodeceptJS commands directly:
67
+ **Tactical decisions are AI-driven** how to click a button, what to do when a modal appears, how to recover from an error.
156
68
 
157
- ```
158
- I.click('Login')
159
- I.fillField('email', 'test@example.com')
160
- I.see('Welcome')
161
- ```
69
+ **Cheap workers, smart managers** — token-hungry agents run on a fast, cheap model. The decision-makers read only short action logs, so a smarter model there costs almost nothing.
162
70
 
163
- See [docs/commands.md](docs/commands.md) for all commands.
71
+ **Explorbot learns from failure** — it reuses past experience with a page to make faster, better decisions next time.
164
72
 
165
- > [!NOTE]
166
- > Most TUI commands also have CLI equivalents that run headless and exit. For example, `explorbot research <url>` and `explorbot plan <path>` work without launching TUI. See [docs/commands.md](docs/commands.md) for the full mapping.
73
+ **Explorbot needs your knowledge** — you guide it with plain-text notes and domain hints, loaded when the matching page opens.
167
74
 
168
- ## What You Get
75
+ When tuned, Explorbot **runs autonomously for hours**, trying new scenarios on its own. The more it runs, the more it learns.
169
76
 
170
- | Output | Location | Description |
171
- |--------|----------|-------------|
172
- | Test files | `output/tests/*.spec.ts` or `*.js` | Runnable Playwright or CodeceptJS tests |
173
- | Test plans | `output/plans/*.md` | Markdown documentation of scenarios |
174
- | Experience | `./experience/` | What Explorbot learned about your app |
77
+ ## What you get
175
78
 
176
- Every run is saved as a real Playwright or CodeceptJS test you can commit and run from CI. Configure the Historian to choose the output framework, record screencasts of every run, or both:
79
+ Every run leaves behind:
177
80
 
178
- ```js
179
- ai: {
180
- agents: {
181
- historian: {
182
- framework: 'playwright', // or 'codeceptjs' (default)
183
- screencast: true, // record .webm video per scenario, chapters labelled with each step
184
- // screencast: { size: { width: 1280, height: 720 }, quality: 95 }
185
- },
186
- },
187
- }
188
- ```
81
+ - **Runnable tests** — Playwright or CodeceptJS specs for every flow, ready to commit and run in CI.
82
+ - **Reports** — a pass/fail breakdown with a written analysis, as HTML and Markdown, or in Testomat.io.
83
+ - **Videos** — step-by-step screencasts of every run.
84
+ - **Experience** — what Explorbot learned, reused to test smarter next time.
189
85
 
190
- Screencasts land in `output/screencasts/<plan>-<n>-<scenario>.webm` and are listed alongside generated tests at the end of every run.
86
+ See [Automated Tests](docs/guides/automated-tests.md) for the test output and [Reporting](docs/guides/reporting.md) for reports.
191
87
 
192
- Playwright output uses the actual `page.locator(...)` calls executed during the run, with each action wrapped in `test.step` so failures land on a labelled step:
88
+ ## It works with your suite
193
89
 
194
- ```ts
195
- test('Create a new manual plan', async ({ page }) => {
196
- await test.step("Click the 'New plan' button in toolbar", async () => {
197
- await page.getByRole('button', { name: 'New plan' }).first().click();
198
- });
90
+ Explorbot won't replace your regression tests — it covers what they can't. Your Playwright or CodeceptJS suites replay the same fixed steps every build. Explorbot re-explores the same pages new ways, clicking UI and paths your scripts never touch. Point it at a brand-new feature with zero coverage, and it works out the basic test cases and runs them right away.
199
91
 
200
- await test.step('Select Manual plan type in modal', async () => {
201
- await page.locator('#portal-container').getByRole('button', { name: 'Manual' }).click();
202
- });
92
+ ## Requirements
203
93
 
204
- await test.step('Verification', async () => {
205
- await expect(page).toContainText('Test Plan UI Creation 001');
206
- });
207
- });
208
- ```
94
+ - Node.js 24+ or **Bun**
95
+ - An **AI provider key** — OpenRouter recommended; Groq, Cerebras, OpenAI, Anthropic, and others via the [Vercel AI SDK](https://sdk.vercel.ai/providers)
96
+ - A **modern terminal** — iTerm2, WARP, Kitty, Ghostty, or Windows Terminal with WSL
97
+ - A **compatible web app** — CRUD-heavy apps fit best. See [Prerequisites](docs/reference/prerequisites.md)
209
98
 
210
- See [Automated Tests](docs/automated-tests.md) for the CodeceptJS version and how failed or unfinished scenarios are handled.
99
+ If your CI runs Playwright, it runs Explorbot. No GPUs, no special runners.
211
100
 
212
- ## Two Ways to Run
101
+ ## Quick Start
213
102
 
214
- **Interactive mode** — Launch TUI, guide exploration, get real-time feedback:
103
+ **1. Install dependencies**
215
104
 
216
105
  ```bash
217
- npx explorbot start https://your-app.com
106
+ npm i explorbot --save
107
+ npx playwright install
218
108
  ```
219
109
 
220
- **Autonomous mode** — Non-interactive testing and planning:
110
+ **2. Initialize config**
221
111
 
222
112
  ```bash
223
- npx explorbot explore /admin/users
113
+ npx explorbot init
224
114
  ```
225
115
 
226
- **Freesail mode** Fully autonomous, continuous exploration across multiple pages:
227
-
228
- ```bash
229
- npx explorbot freesail /admin # explore and test pages indefinitely
230
- npx explorbot freesail /app --deep # depth-first: explore nearby pages first
231
- npx explorbot freesail /app --shallow # breadth-first: spread across many pages
232
- npx explorbot freesail /app --scope /admin # restrict to URLs under /admin
233
- ```
116
+ **3. Configure and run**
234
117
 
235
- Freesail navigates to a page, researches it, runs tests, then moves on to the next least-visited page — repeating until stopped. Also available as `/freesail` in TUI.
236
-
237
- ## API Testing
238
-
239
- Explorbot also tests REST APIs. Add an `api` section to your config and point it at your API:
240
-
241
- ```javascript
242
- export default {
243
- web: {
244
- url: 'http://localhost:3000',
245
- },
246
- ai: {
247
- model: openrouter('openai/gpt-oss-20b'),
248
- agenticModel: openrouter('minimax/minimax-m2.5:nitro'),
249
- },
250
- api: {
251
- baseEndpoint: 'http://localhost:3000/api/v1',
252
- spec: ['http://localhost:3000/api/openapi.json'],
253
- headers: {
254
- 'Authorization': 'Bearer <token>',
255
- },
256
- },
257
- };
258
- ```
118
+ Add your AI provider key to `.env`, set your app URL in `explorbot.config.js`, then point Explorbot at a focused page — an admin panel, settings, or any CRUD section:
259
119
 
260
120
  ```bash
261
- npx explorbot api explore /users # full cycle: plan + test all styles
262
- npx explorbot api plan /users # generate test plan only
263
- npx explorbot api test plans/users.md * # run all tests from a plan
121
+ npx explorbot start /admin/users
264
122
  ```
265
123
 
266
- The API tester uses two agents **Chief** (plans test scenarios across styles: normal, curious, psycho, hacker) and **Curler** (executes HTTP requests and verifies responses). Both use `agenticModel` by default.
267
-
268
- See [docs/api-testing.md](docs/api-testing.md) for setup, authentication hooks, and full command reference.
124
+ Type `/explore`, and Explorbot runs its loop on its own research, plan, test, repeat learning from every run.
269
125
 
270
- ## Core Philosophy
271
-
272
- **Strategic decisions are deterministic** — The workflow (research → plan → test) is predictable and consistent.
273
-
274
- **Tactical decisions are AI-driven** — How to click that button, what to do when a modal appears, how to recover from errors.
275
-
276
- **Cheap workers, smart managers** — Tester, Navigator, and Researcher are token-hungry agents that chew through HTML and ARIA on every step. They run on the fast, cheap `model`. Captain and Pilot are the decision-makers — they read only compact action logs and make high-level choices. Set `agenticModel` to a smarter model for better results at negligible extra cost.
126
+ That's the gist. The [**Getting Started guide**](docs/getting-started.md) walks through the full setup — choosing models, teaching Explorbot to log in, and picking the right feature to start on.
277
127
 
278
- **Explorbot learns from its failures** — It uses previous experience interacting with a web page for faster and better decisions on next runs.
128
+ ## Teaching Explorbot
279
129
 
280
- **Explorbot needs your knowledge** You adjust Explorbot prompts by passing suggestions, UI explanations, and domain knowledge as text files, which are loaded when the corresponding page is opened.
130
+ Explorbot gets better when you tell it about your app:
281
131
 
282
- When tuned, Explorbot **can run autonomously for hours** navigating a web application and trying different scenarios. You don't need to watch it. The more Explorbot runs, the more it learns and the more complex scenarios it can test.
132
+ - **Knowledge** credentials, form rules, navigation quirks. See [Knowledge](docs/guides/knowledge.md).
133
+ - **Rules** — per-agent, per-page instructions. See [Configuration](docs/reference/configuration.md#rules).
134
+ - **Experience** — learned automatically from what works.
283
135
 
136
+ Handling logins, cookie banners, modals, and test data takes a few lines — see [Customization](docs/guides/customization.md).
284
137
 
285
- ## Teaching Explorbot
138
+ ## It also tests REST APIs
286
139
 
287
- * **Knowledge** (`./knowledge/`) Tell Explorbot about your app: credentials, form rules, navigation quirks. See [docs/knowledge.md](docs/knowledge.md).
288
- * **Rules** (`./rules/`) — Customize agent behavior with markdown files. Add page-specific instructions, override planning styles, or tune how agents work on different parts of your app. See [docs/configuration.md](docs/configuration.md#rules).
289
- * **Experience** (`./experience/`) — Explorbot learns automatically from successful interactions and saves what works.
140
+ Point Explorbot at an OpenAPI spec and it plans and runs API tests too. See [API Testing](docs/guides/api-testing.md).
290
141
 
291
- ## Further Reading
142
+ ## Keep going
292
143
 
293
- - [docs/prerequisites.md](docs/prerequisites.md) — Application compatibility checklist
294
- - [docs/commands.md](docs/commands.md) — Terminal command reference
295
- - [docs/api-testing.md](docs/api-testing.md) — API testing setup and commands
296
- - [docs/knowledge.md](docs/knowledge.md) — Knowledge system and URL patterns
297
- - [docs/providers.md](docs/providers.md) — AI provider configuration
298
- - [docs/agents.md](docs/agents.md) — Agent descriptions and capabilities
299
- - [docs/planner.md](docs/planner.md) — Planner agent: planning styles and customization
300
- - [docs/scripting.md](docs/scripting.md) — Building custom autonomous scripts
301
- - [docs/observability.md](docs/observability.md) — Langfuse tracing and debugging
302
- - [docs/page-interaction.md](docs/page-interaction.md) — How agents interact with pages
144
+ When you're ready to go deeper, the [full documentation](docs/README.md) covers everything, starting with the [Getting Started guide](docs/getting-started.md).
303
145
 
304
146
  ## FAQ
305
147
 
306
- **Can I run it in Cursor? or Claude Code?**
307
- No, Explorbot is a separate application designed for constant testing. Cursor, Codex, or Claude Code are coding agents — not relevant here.
148
+ **Can I run it in Cursor or Claude Code?**
149
+ No, Explorbot is a separate application designed for constant testing. Cursor, Codex, and Claude Code are coding agents — not relevant here.
308
150
 
309
- > However, Explorbot can be used as subagent or terminal command which is controlled by coding agent.
151
+ > However, Explorbot can be used as a subagent or terminal command controlled by a coding agent.
310
152
 
311
- **Can I bring Cursor or OpenAI Subscription?**
312
- No Cursor and OpenAI subscription can't be used. Mostly because their models are slow for Explorbot's usage. We recommend using pay-per-token via Groq and OpenRouter.
153
+ **Can I bring a Cursor or OpenAI subscription?**
154
+ No. Their models are too slow for the way Explorbot works. Use pay-per-token providers like Groq and OpenRouter.
313
155
 
314
156
  **I want to use Opus!!!**
315
- Opus is great for coding. But for testing we need a simpler model that can safely consume lots of HTML tokens. Opus must be used for sophisticated decision-making, while explorbot needs to collect knowledge from webpages and do it fast.
157
+ Opus is great for coding. Testing needs a simpler model that can safely consume lots of HTML tokens, fast. Save the expensive models for sophisticated decision-making.
316
158
 
317
- **Is that expensive?**
159
+ **Is it expensive?**
318
160
  No. With fast open models (e.g. `openai/gpt-oss-20b` on OpenRouter or Groq), expect roughly **~$1/hour of continuous run**, depending on provider and traffic.
319
161
 
320
162
  **Does Explorbot have MCP?**
321
163
  Not yet.
322
164
 
323
165
  **Can I build my own agents with it?**
324
- Yes, use the programmatic API. See [docs/scripting.md](docs/scripting.md).
166
+ Yes, use the programmatic API. See [Scripting](docs/contributing/scripting.md).
325
167
 
326
- **Ok, but I can do the same in Cursor with Playwright MCP!**
168
+ **Can I do the same in Cursor with Playwright MCP?**
327
169
  Good luck running it on CI!
328
170
 
329
171
  ## Development
330
172
 
331
173
  * Clone this repository
332
174
  * Use **Bun** to run TS and TSX with no building
333
- * Create a sample project under `example` directory:
175
+ * Create a sample project under the `example` directory:
334
176
 
335
177
  ```
336
178
  ./bin/explorbot-cli.ts init --path example
@@ -351,7 +193,3 @@ Explorbot is licensed under the [Elastic License 2.0 (ELv2)](LICENSE).
351
193
  The only restriction: you may not offer Explorbot itself as a hosted/managed service (i.e., resell it as a product). This license is used by Elastic, Grafana, and other open-source companies.
352
194
 
353
195
  Explorbot is built by [Testomat.io](https://testomat.io).
354
-
355
- ---
356
-
357
- Explorbot learns as it explores. The more it tests your app, the better it gets at testing your app. That's vibe-testing.
@@ -338,6 +338,7 @@ addCommonOptions(program.command('test <planfile> [index]').description('Execute
338
338
  const cmd = new TestCommand(explorBot);
339
339
  await cmd.execute(args);
340
340
 
341
+ await explorBot.printSessionAnalysis();
341
342
  await explorBot.stop();
342
343
  await showStatsAndExit(0);
343
344
  } catch (error) {
@@ -45,7 +45,7 @@ class Documentarian {
45
45
  try {
46
46
  tag('info').log('Starting interactive exploration...');
47
47
 
48
- const deterministicInteractions = await collectDocInteractions(this.explorer!, state, research);
48
+ const deterministicInteractions = await collectDocInteractions(this.explorer!, state, research, this.config);
49
49
  const meaningfulInteractions = this.getMeaningfulInteractions(deterministicInteractions);
50
50
  if (meaningfulInteractions.length > 0) {
51
51
  tag('success').log(`Collected ${meaningfulInteractions.length} deterministic interactions`);
@@ -240,10 +240,15 @@ class Documentarian {
240
240
  }
241
241
 
242
242
  private normalizeDocumentation(documentation: PageDocumentation, _state: WebPageState, _research: string): PageDocumentation {
243
- const qualityNotes = this.evaluateDocumentationQuality(documentation);
243
+ const normalized = { ...documentation };
244
+ if (!normalized.interactions) {
245
+ normalized.interactions = undefined;
246
+ }
247
+
248
+ const qualityNotes = this.evaluateDocumentationQuality(normalized);
244
249
 
245
250
  return {
246
- ...documentation,
251
+ ...normalized,
247
252
  qualityNotes,
248
253
  };
249
254
  }
@@ -321,36 +326,55 @@ const stateTransitionSchema = z.object({
321
326
  action: z.string(),
322
327
  before: z.string(),
323
328
  after: z.string(),
324
- targetUrl: z.string().optional(),
325
- discoveredUrls: z.array(z.string()).optional(),
326
- newCapabilities: z.array(z.string()).optional(),
329
+ targetUrl: z.string().nullable(),
330
+ discoveredUrls: z.array(z.string()).nullable(),
331
+ newCapabilities: z.array(z.string()).nullable(),
327
332
  element: z
328
333
  .object({
329
334
  role: z.string(),
330
335
  name: z.string(),
331
336
  section: z.string(),
332
- container: z.string().optional(),
333
- locator: z.string().optional(),
337
+ container: z.string().nullable(),
338
+ locator: z.string().nullable(),
334
339
  })
335
- .optional(),
340
+ .nullable(),
336
341
  changes: z
337
342
  .object({
338
343
  urlChanged: z.boolean(),
339
344
  newElements: z.number(),
340
345
  removedElements: z.number(),
341
346
  })
342
- .optional(),
347
+ .nullable(),
343
348
  });
344
349
 
345
350
  const pageDocumentationSchema = z.object({
346
351
  summary: z.string(),
347
352
  can: z.array(capabilitySchema),
348
353
  might: z.array(capabilitySchema),
349
- interactions: z.array(stateTransitionSchema).optional(),
354
+ interactions: z.array(stateTransitionSchema).nullable(),
350
355
  });
351
356
 
352
- type StateTransition = z.infer<typeof stateTransitionSchema>;
353
- type PageDocumentation = z.infer<typeof pageDocumentationSchema> & {
357
+ type StateTransition = {
358
+ action: string;
359
+ before: string;
360
+ after: string;
361
+ targetUrl?: string | null;
362
+ discoveredUrls?: string[] | null;
363
+ newCapabilities?: string[] | null;
364
+ element?: {
365
+ role: string;
366
+ name: string;
367
+ section: string;
368
+ container?: string | null;
369
+ locator?: string | null;
370
+ } | null;
371
+ changes?: {
372
+ urlChanged: boolean;
373
+ newElements: number;
374
+ removedElements: number;
375
+ } | null;
376
+ };
377
+ type PageDocumentation = Omit<z.infer<typeof pageDocumentationSchema>, 'interactions'> & {
354
378
  interactions?: StateTransition[];
355
379
  qualityNotes?: string[];
356
380
  };