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,362 @@
1
+ # AI Provider Configuration
2
+
3
+ Explorbot connects to AI providers through the [Vercel AI SDK](https://sdk.vercel.ai/). Use any supported provider, and mix providers across different models.
4
+
5
+ > The `export default` config block inside each `<!-- START/END provider -->` marker is generated from [`models.json`](../../models.json). After editing that file, run `bunosh docs:sync`. Everything else — including the import blocks — is hand-written.
6
+
7
+ ## Requirements
8
+
9
+ Your model must support:
10
+ - Structured output (JSON mode)
11
+ - Tool use (function calling)
12
+
13
+ To analyze screenshots, you also need a vision-capable model.
14
+
15
+ Explorbot uses three roles:
16
+
17
+ - `model` for token-heavy page reading of ARIA & HTMLs (cheap & fast).
18
+ - `visionModel` for screenshot analysis
19
+ - `agenticModel` as advisor and planner.
20
+
21
+ Pick a fast, cheap model for the first two and a stronger one for the third. When a provider has no recommended model for one of these roles, combine it with another provider for that role.
22
+
23
+ ### OpenRouter
24
+
25
+ Start with OpenRouter. One key reaches [many providers and models](https://openrouter.ai/models).
26
+ Openrouter is an optimal solution as you can balance the models and provider for best price and speed.
27
+ So if your goal is to optimize costs, choose Openrouter.
28
+
29
+ > Openrouter is recommended to start as it serves best models
30
+
31
+ Install the provider package:
32
+
33
+ ```bash
34
+ npm i @openrouter/ai-sdk-provider
35
+ ```
36
+
37
+ Import it inside `explorbot.config.ts` and create the client from your API key:
38
+
39
+ ```javascript
40
+ import { createOpenRouter } from '@openrouter/ai-sdk-provider';
41
+
42
+ const openrouter = createOpenRouter({
43
+ apiKey: process.env.OPENROUTER_API_KEY,
44
+ });
45
+ ```
46
+
47
+ Set the recommended models in the exported config:
48
+
49
+ <!-- START provider:openrouter -->
50
+ ```javascript
51
+ export default {
52
+ ai: {
53
+ model: openrouter('openai/gpt-oss-20b:nitro'),
54
+ visionModel: openrouter('google/gemma-4-31b-it:nitro'),
55
+ agenticModel: openrouter('google/gemma-4-31b-it:nitro'),
56
+ },
57
+ };
58
+ ```
59
+ <!-- END provider:openrouter -->
60
+
61
+ Pick model IDs from [OpenRouter](https://openrouter.ai/) that support structured output and tools. The `:nitro` variants route to the fastest available host.
62
+
63
+ ### Groq
64
+
65
+ Install the provider package:
66
+
67
+ ```bash
68
+ npm i @ai-sdk/groq
69
+ ```
70
+
71
+ Import it inside `explorbot.config.ts` and create the client from your API key:
72
+
73
+ ```javascript
74
+ import { createGroq } from '@ai-sdk/groq';
75
+
76
+ const groq = createGroq({
77
+ apiKey: process.env.GROQ_API_KEY,
78
+ });
79
+ ```
80
+
81
+ Set the recommended models in the exported config:
82
+
83
+ <!-- START provider:groq -->
84
+ ```javascript
85
+ export default {
86
+ ai: {
87
+ model: groq('openai/gpt-oss-20b'),
88
+ visionModel: groq('qwen/qwen3.6-27b'),
89
+ agenticModel: groq('qwen/qwen3.6-27b'),
90
+ },
91
+ };
92
+ ```
93
+ <!-- END provider:groq -->
94
+
95
+ The gpt-oss models are fast and cheap; the larger 120B handles the agenticModel role.
96
+
97
+ ### OpenAI
98
+
99
+ Install the provider package:
100
+
101
+ ```bash
102
+ npm i @ai-sdk/openai
103
+ ```
104
+
105
+ Import it inside `explorbot.config.ts` and create the client from your API key:
106
+
107
+ ```javascript
108
+ import { createOpenAI } from '@ai-sdk/openai';
109
+
110
+ const openai = createOpenAI({
111
+ apiKey: process.env.OPENAI_API_KEY,
112
+ });
113
+ ```
114
+
115
+ Set the recommended models in the exported config:
116
+
117
+ <!-- START provider:openai -->
118
+ ```javascript
119
+ export default {
120
+ ai: {
121
+ model: openai('gpt-5.4-nano'),
122
+ visionModel: openai('gpt-5.4-nano'),
123
+ agenticModel: openai('gpt-5.6-luna'),
124
+ },
125
+ };
126
+ ```
127
+ <!-- END provider:openai -->
128
+
129
+ ### Anthropic
130
+
131
+ Claude Haiku is the only Anthropic model suited to Explorbot, and even it is too costly per token for the token-heavy roles, so we recommend it only for the low-volume agenticModel. Use a cheaper provider for `model` and `visionModel` (see [Multi-Provider Configuration](#multi-provider-configuration)).
132
+
133
+ Install the provider package:
134
+
135
+ ```bash
136
+ npm i @ai-sdk/anthropic
137
+ ```
138
+
139
+ Import it inside `explorbot.config.ts` and create the client from your API key:
140
+
141
+ ```javascript
142
+ import { createAnthropic } from '@ai-sdk/anthropic';
143
+
144
+ const anthropic = createAnthropic({
145
+ apiKey: process.env.ANTHROPIC_API_KEY,
146
+ });
147
+ ```
148
+
149
+ Set the recommended model in the exported config:
150
+
151
+ <!-- START provider:anthropic -->
152
+ ```javascript
153
+ export default {
154
+ ai: {
155
+ agenticModel: anthropic('claude-haiku-4-5-20251001'),
156
+ },
157
+ };
158
+ ```
159
+
160
+ > [!NOTE]
161
+ > This provider currently doesn't serve `model` and `visionModel`, which is required for Explorbot to run at optimal cost and speed.
162
+ > It is recommended to pair it with another AI provider.
163
+ <!-- END provider:anthropic -->
164
+
165
+ ### Azure OpenAI
166
+
167
+ Install the provider package:
168
+
169
+ ```bash
170
+ npm i @ai-sdk/azure
171
+ ```
172
+
173
+ Import it inside `explorbot.config.ts` and create the client from your resource name and API key:
174
+
175
+ ```javascript
176
+ import { createAzure } from '@ai-sdk/azure';
177
+
178
+ const azure = createAzure({
179
+ resourceName: process.env.AZURE_RESOURCE_NAME,
180
+ apiKey: process.env.AZURE_API_KEY,
181
+ });
182
+ ```
183
+
184
+ Set the models in the exported config, using the deployment names you created in your resource:
185
+
186
+ ```javascript
187
+ export default {
188
+ ai: {
189
+ model: azure('your-deployment-name'),
190
+ visionModel: azure('your-deployment-name'),
191
+ agenticModel: azure('your-deployment-name'),
192
+ },
193
+ };
194
+ ```
195
+
196
+ Azure addresses models by the deployment names you create in your resource, not by public model IDs. Use separate deployments if chat and vision run on different endpoints.
197
+
198
+ ### Google (Gemini)
199
+
200
+ An API key from [Google AI Studio](https://aistudio.google.com/apikey) already has the Gemini API enabled. A key from the Google Cloud console may need the API enabled first, and service-account (Vertex Express) keys use a different API surface than the one this provider targets.
201
+
202
+ Install the provider package:
203
+
204
+ ```bash
205
+ npm i @ai-sdk/google
206
+ ```
207
+
208
+ Import it inside `explorbot.config.ts` and create the client from your API key:
209
+
210
+ ```javascript
211
+ import { createGoogleGenerativeAI } from '@ai-sdk/google';
212
+
213
+ const google = createGoogleGenerativeAI({
214
+ apiKey: process.env.GOOGLE_API_KEY,
215
+ });
216
+ ```
217
+
218
+ Set the recommended models in the exported config:
219
+
220
+ <!-- START provider:google -->
221
+ ```javascript
222
+ export default {
223
+ ai: {
224
+ model: google('gemini-3.1-flash-lite'),
225
+ visionModel: google('gemini-3.1-flash-lite'),
226
+ agenticModel: google('gemini-3.5-flash'),
227
+ },
228
+ };
229
+ ```
230
+ <!-- END provider:google -->
231
+
232
+ The flash-lite tier is the cheapest current option for the token-heavy `model` and `visionModel` roles; the full flash is stronger for the low-volume `agenticModel`.
233
+
234
+ On a free (no-billing) key the `agenticModel` is heavily rate-limited and will fail with quota errors mid-session — keep every role on the flash-lite model or enable billing. Google also retires older models for new accounts: `gemini-2.5-flash` and `gemini-2.5-flash-lite` return a 404 for keys created after their cutoff, and enabling billing does not bring them back.
235
+
236
+ Note: Gemini models are slower than hosted OSS models on Groq or Cerebras. Everything works, sessions just take more wall-clock time.
237
+
238
+ ### Mistral
239
+
240
+ Install the provider package:
241
+
242
+ ```bash
243
+ npm i @ai-sdk/mistral
244
+ ```
245
+
246
+ Import it inside `explorbot.config.ts` and create the client from your API key:
247
+
248
+ ```javascript
249
+ import { createMistral } from '@ai-sdk/mistral';
250
+
251
+ const mistral = createMistral({
252
+ apiKey: process.env.MISTRAL_API_KEY,
253
+ });
254
+ ```
255
+
256
+ Set the recommended models in the exported config:
257
+
258
+ <!-- START provider:mistral -->
259
+ ```javascript
260
+ export default {
261
+ ai: {
262
+ model: mistral('mistral-small-latest'),
263
+ visionModel: mistral('mistral-small-latest'),
264
+ agenticModel: mistral('mistral-large-latest'),
265
+ },
266
+ };
267
+ ```
268
+ <!-- END provider:mistral -->
269
+
270
+ Mistral Small covers the token-heavy `model` and `visionModel` roles — it accepts image input, so it can read screenshots. Mistral Large, the larger multimodal flagship, handles the low-volume `agenticModel`. The `-latest` aliases track Mistral's newest release of each, so recommendations keep up as models ship.
271
+
272
+ ### Poolside
273
+
274
+ Poolside serves an OpenAI-compatible endpoint, so it uses the OpenAI provider package with a custom `baseURL`:
275
+
276
+ ```bash
277
+ npm i @ai-sdk/openai
278
+ ```
279
+
280
+ Import it inside `explorbot.config.ts` and point the client at the poolside endpoint:
281
+
282
+ ```javascript
283
+ import { createOpenAI } from '@ai-sdk/openai';
284
+
285
+ const poolside = createOpenAI({
286
+ apiKey: process.env.POOLSIDE_API_KEY,
287
+ baseURL: 'https://inference.poolside.ai/v1',
288
+ });
289
+ ```
290
+
291
+ Set the recommended models in the exported config:
292
+
293
+ <!-- START provider:poolside -->
294
+ ```javascript
295
+ export default {
296
+ ai: {
297
+ model: poolside('poolside/laguna-xs-2.1'),
298
+ },
299
+ };
300
+ ```
301
+
302
+ > [!NOTE]
303
+ > This provider currently doesn't serve `visionModel` and `agenticModel`, which is required for Explorbot to run at optimal cost and speed.
304
+ > It is recommended to pair it with another AI provider.
305
+ <!-- END provider:poolside -->
306
+
307
+ Laguna XS is an agentic coding model — fast, cheap, and reliable at tool calling, which makes it a good fit for the token-heavy `model` role that reads page HTML and drives the browser.
308
+
309
+ Keep `agenticModel` on another provider. Poolside's endpoint accepts `response_format: json_schema` but does not enforce it, so structured-output calls depend on the model volunteering valid JSON. Laguna XS usually does; Laguna S answers in prose instead, which makes it unusable for the Planner, Pilot, and Captain. Laguna S is also slow enough under page-sized prompts to hit Explorbot's request timeouts, so it is not a substitute for Laguna XS in the `model` role either.
310
+
311
+ ## Multi-Provider Configuration
312
+
313
+ Mix clients the same way you assign `model`, `visionModel`, and `agenticModel`. Each field can use a different provider instance — a fast provider does the token-heavy reading while a stronger one makes the decisions:
314
+
315
+ ```javascript
316
+ import { createGroq } from '@ai-sdk/groq';
317
+ import { createOpenRouter } from '@openrouter/ai-sdk-provider';
318
+
319
+ const groq = createGroq({ apiKey: process.env.GROQ_API_KEY });
320
+ const openrouter = createOpenRouter({ apiKey: process.env.OPENROUTER_API_KEY });
321
+
322
+ export default {
323
+ ai: {
324
+ model: groq('openai/gpt-oss-20b'),
325
+ visionModel: groq('meta-llama/llama-4-scout-17b-16e-instruct'),
326
+ agenticModel: openrouter('minimax/minimax-m2.5:nitro'),
327
+ },
328
+ };
329
+ ```
330
+
331
+ ## Per-Agent Model Configuration
332
+
333
+ Any agent can override the defaults. Add an `agents` block and set per-agent options — a different `model` (using any client shown above) or a `reasoning` level:
334
+
335
+ ```javascript
336
+ export default {
337
+ ai: {
338
+ // ...your model, visionModel, agenticModel...
339
+ agents: {
340
+ researcher: { reasoning: 'low' },
341
+ planner: { reasoning: 'none' },
342
+ tester: { reasoning: 'none' },
343
+ },
344
+ },
345
+ };
346
+ ```
347
+
348
+ See [Configuration](../reference/configuration.md) for every per-agent option.
349
+
350
+ ## Environment Variables
351
+
352
+ Set your API key as an environment variable, or use a `.env` file in your project root:
353
+
354
+ ```bash
355
+ export OPENROUTER_API_KEY=your-key-here
356
+ export GROQ_API_KEY=your-key-here
357
+ export CEREBRAS_API_KEY=your-key-here
358
+ export OPENAI_API_KEY=your-key-here
359
+ export ANTHROPIC_API_KEY=your-key-here
360
+ export GOOGLE_API_KEY=your-key-here
361
+ export MISTRAL_API_KEY=your-key-here
362
+ ```
@@ -0,0 +1,78 @@
1
+ # Running Explorbot: TUI and CLI
2
+
3
+ There are two ways to run Explorbot: an interactive terminal UI where you watch and steer, and plain CLI commands that do one job and exit. Same engine, same config, same artifacts — the difference is whether you are in the loop.
4
+
5
+ | Use | Choose it when | Start with |
6
+ |-----|----------------|------------|
7
+ | **TUI** | You are learning, steering, or debugging interactively | `npx explorbot start /path` |
8
+ | **CLI** | You want one repeatable task that prints a result and exits | `npx explorbot explore /path` |
9
+ | **Persistent browser** | You run several local commands and want to avoid starting a new browser process each time | `npx explorbot browser start --show` |
10
+ | **CI** | You need unattended, scheduled, or pipeline runs with saved reports | `npx explorbot explore /path --max-tests 10` |
11
+
12
+ Persistent browser is an optimization for local TUI or CLI work, while CI uses CLI commands. Each command still creates a fresh browser context; use `--session` when cookies and login state must carry over. See [Persistent Browser](../reference/commands.md#persistent-browser) and [Continuous Integration](../workflow/ci.md) for setup details.
13
+
14
+ ## TUI mode
15
+
16
+ `npx explorbot start` opens the interactive terminal UI. Pass a path to start on a specific page:
17
+
18
+ ```bash
19
+ npx explorbot start /admin/projects
20
+ ```
21
+
22
+ The screen splits into a log pane, where everything Explorbot does is printed as it happens, and an input line at the bottom. Type slash-commands to drive it:
23
+
24
+ ```
25
+ /explore # full loop: research, plan, test, repeat
26
+ /research # analyze the current page
27
+ /plan # propose test scenarios
28
+ /test # run the next test
29
+ ```
30
+
31
+ You can also type raw CodeceptJS commands — `I.click('Save')`, `I.amOnPage('/login')` — and they execute in the browser immediately. In interactive mode the bot asks you for help when it gets stuck, instead of giving up.
32
+
33
+ Use the TUI for:
34
+
35
+ - **First runs.** You see every step and every mistake as it happens.
36
+ - **Teaching Explorbot your app.** Watch it fail, add a knowledge file, retry — the tight loop is what the TUI is for.
37
+ - **Debugging a failing scenario.** Replay it step by step with slash-commands and raw `I.*` commands.
38
+
39
+ The TUI needs a modern terminal — iTerm2, WARP, Kitty, Ghostty, or Windows Terminal with WSL; see [Prerequisites](./prerequisites.md) for the compatibility notes.
40
+
41
+ ## CLI mode
42
+
43
+ Every other command runs without the TUI: it launches a browser (headless by default), does its job, prints the result, and exits.
44
+
45
+ | Command | What it does | Docs |
46
+ |---------|--------------|------|
47
+ | `explore <path>` | Research a page, plan tests, run them, move to sub-pages | [Web Testing Basics](../web-testing/basics.md) |
48
+ | `plan <path>` | Generate a test plan as markdown and exit | [Test Plans](../workflow/test-plans.md) |
49
+ | `test <planfile> [index]` | Run tests from a saved plan | [Test Plans](../workflow/test-plans.md) |
50
+ | `rerun <file>` | Re-run generated tests with AI healing | [Rerun](../web-testing/rerun.md) |
51
+ | `docs collect <url>` | Crawl pages and generate documentation | [Doc Collection](../doc-collection/basics.md) |
52
+ | `api plan` / `api test` / `api explore` | Plan and run API tests | [API Testing](../api-testing/basics.md) |
53
+
54
+ The full list, with every option, is in the [Commands reference](../reference/commands.md).
55
+
56
+ ### Exit codes
57
+
58
+ CLI commands follow one rule: exit `0` when the run completed, `1` when the run itself failed — a config error, an unreachable start page, a provider that won't respond. Before exiting, the CLI shows a short session summary if anything happened during the run.
59
+
60
+ For `explore` and `test`, a failing test does **not** change the exit code. The run completed; the failure is a result, printed in the console summary and recorded in the reports. So `npx explorbot explore / || echo broken` catches crashes, not bugs. To gate a pipeline on test results, read the reports — see [Continuous Integration](../workflow/ci.md).
61
+
62
+ A few commands have sharper semantics you can script against:
63
+
64
+ - `plan` exits `1` when no test scenarios could be generated.
65
+ - `navigate <url>` exits `0` when the page was reached, `1` when not — a cheap "is the app up and can we log in" probe.
66
+ - `api test` and `api explore` exit `1` when any test failed.
67
+
68
+ ## Flags that matter in both modes
69
+
70
+ The browser runs headless by default; `--show` opens a visible window and `--headless` forces it hidden. `--session [file]` saves and restores the browser session (cookies, localStorage) — the default file is `output/session.json` — so login happens once and later runs skip it. `--incognito` runs without recording experience, useful for throwaway runs. `--verbose` prints debug logs. See the [Commands reference](../reference/commands.md) for the rest.
71
+
72
+ ## Driving Explorbot from other tools
73
+
74
+ CLI mode makes Explorbot scriptable by anything that can run a shell command — including coding agents like Claude Code. Every input and output is plain markdown: plans land in `output/plans/`, reports in `output/reports/`, and hints live in `knowledge/`. An agent can run `explorbot plan /checkout`, read the generated plan, edit or extend it, run `explorbot test` on it, read the report, then write a knowledge file to fix what confused the bot — and iterate. No API or SDK needed; the files are the interface.
75
+
76
+ ## Running in CI
77
+
78
+ Because CLI commands exit cleanly and keep their learning in cacheable directories, Explorbot fits scheduled pipelines: run `explore` nightly with a test budget, cache `experience/` and `output/` between runs, and upload the reports. See [Continuous Integration](../workflow/ci.md) for worked examples.
@@ -0,0 +1,57 @@
1
+ # AI Agent Integration Tests
2
+
3
+ We test AI agents with [`@copilotkit/aimock`](https://github.com/CopilotKit/aimock), an HTTP mock server that speaks LLM provider protocols. Unlike in-process model stubs, it runs the real `Provider` class and lets you inspect the HTTP requests through its Journal.
4
+
5
+ Reference implementation: `tests/integration/planner.test.ts`.
6
+
7
+ ## Principles
8
+
9
+ ### What we mock
10
+
11
+ - **The AI provider** — via the aimock HTTP server. Point the Vercel AI SDK at `mock.url/v1` with `createOpenAI({ compatibility: 'compatible' })` and `openai.chat('model-name')`. The `compatibility: 'compatible'` option keeps the mock on the Chat Completions API; without it, the SDK defaults to the Responses API, which aimock does not fully implement.
12
+ - **Explorer, StateManager, Researcher, ExperienceTracker** — duck-typed mocks with only the methods the agent under test calls. Each agent runs in isolation; downstream agents (such as Researcher when testing Planner) return canned output.
13
+ - **`withPage`** — resolves with a fake page object for agents that validate locators, since no browser runs in these tests.
14
+
15
+ ### What we don't mock
16
+
17
+ - The real `Provider` class, so tests exercise serialization, retry, and telemetry paths.
18
+ - Parsers, result objects, and markdown processing — the real pipeline runs.
19
+ - `ActionResult.fromState()`, which works without the filesystem when `state.html` is inline.
20
+
21
+ ### What we test
22
+
23
+ - **Output correctness**: the plan or research markdown the agent returns matches the canned AI response.
24
+ - **Prompt construction** (via Journal): `mock.getLastRequest()` returns the messages sent to the AI, so you assert on what the agent prompted, not just what it returned. This is the main reason to use aimock.
25
+ - **Control flow**: cache hits, dedup, retries, error paths, and style or feature injection. Inspect the request count and prompt content.
26
+
27
+ ### Fixture types
28
+
29
+ - Text response (for `chat()` / `invokeConversation()`): `mock.on({}, { content: 'text' })`
30
+ - Structured output (for `generateObject()`): `mock.on({}, { content: JSON.stringify(obj) })` — the SDK parses it back via `response_format: json_schema`
31
+ - Sequential responses: `mock.on({ sequenceIndex: 0 }, ...)`, `sequenceIndex: 1`, ...
32
+ - Errors: `mock.on({}, { error: {...}, status: 500 })`
33
+ - See aimock docs for matching by user message, tool name, regex, or predicate.
34
+
35
+ ### Test data
36
+
37
+ - Canned UI maps live in `test-data/ui-maps/`.
38
+ - Use fictional applications (Task Tracker, and so on). Never use real product data or user names.
39
+ - Two formats exist, depending on the agent under test:
40
+ - **Planner-input** (`task-board.md`): Element and Type columns only — what the Planner sees after its own table-column filtering.
41
+ - **Researcher-output** (`task-board-research.md`): full Element, Type, ARIA, CSS, and Coordinates columns — the raw Researcher AI output format.
42
+
43
+ ### Module-level caches
44
+
45
+ Many agents hold module-level state: plan registry, session dedup, style cache, research cache. Each module that caches across calls must export a `clearXxx()` function for use in `beforeEach`. See the existing exports:
46
+
47
+ - `src/ai/planner/subpages.ts` — `clearPlanRegistry()`
48
+ - `src/ai/planner/session-dedup.ts` — `clearSessionDedup()`
49
+ - `src/ai/planner/styles.ts` — `clearStyleCache()`
50
+ - `src/ai/researcher/cache.ts` — `clearResearchCache()`
51
+
52
+ ## Running
53
+
54
+ ```bash
55
+ bun test tests/integration/planner.test.ts
56
+ bun test tests/integration/
57
+ ```
@@ -0,0 +1,90 @@
1
+ # Contributing to Explorbot
2
+
3
+ ## Project Philosophy
4
+
5
+ Explorbot is general-purpose. It works with any web application, with no site-specific code. Keep this in mind when you contribute:
6
+
7
+ - Solutions must work across different websites.
8
+ - Don't hardcode locators or site-specific selectors.
9
+ - Prefer universal patterns: ARIA, semantic HTML, common UI conventions.
10
+ - A fix that only helps one site is probably the wrong approach.
11
+
12
+ ## Before You Start
13
+
14
+ Discuss first, code second. Open an issue to propose your idea before you send a PR. This saves wasted effort and aligns on the approach.
15
+
16
+ If Explorbot struggles on your site, try the built-in extension points first:
17
+
18
+ - Knowledge files teach Explorbot about your pages (credentials, wait conditions, hints).
19
+ - Rules add agent-specific guidance for navigation, research, and planning.
20
+ - Hooks run custom logic before and after actions.
21
+ - Configuration adjusts models, timeouts, and browser settings.
22
+
23
+ See the [knowledge](../workflow/knowledge.md), [hooks](../web-testing/hooks.md), and [configuration](../reference/configuration.md) docs.
24
+
25
+ ## Pull Requests
26
+
27
+ We accept PRs that help a variety of users. Here is what gets merged.
28
+
29
+ ### Tiny PRs get merged first
30
+
31
+ Small, focused changes are reviewed and merged quickly. Examples:
32
+
33
+ - Fix a typo in a prompt.
34
+ - Add a missing ARIA selector pattern.
35
+ - Improve an error message.
36
+ - Fix a bug with a clear reproduction.
37
+
38
+ ### PRs that change agent logic require manual testing
39
+
40
+ Changes to agents (tester, navigator, researcher, pilot, and others) affect how Explorbot interacts with every website. These PRs must be:
41
+
42
+ - Polished — clean code, no leftover debug artifacts.
43
+ - Tested by a person on real websites.
44
+ - Described clearly: what changed and why.
45
+
46
+ ### PRs that change prompts require execution traces
47
+
48
+ If you change internal AI prompts or rules, you must provide a [Langfuse](https://langfuse.com) execution trace that shows the change improved behavior. "It should work better" is not evidence. Show the before and after.
49
+
50
+ ### We accept agentic PRs
51
+
52
+ AI-generated contributions are welcome if they follow the rules above: small, focused, tested, with clear explanations.
53
+
54
+ ### What NOT to send
55
+
56
+ - PRs that reformat code differently. We use [Biome](https://biomejs.dev/) for formatting. Run `bun run format` before submitting.
57
+ - Large refactoring PRs without prior discussion.
58
+ - Site-specific fixes that only help one website.
59
+ - Changes that break existing tests.
60
+
61
+ ## Development Setup
62
+
63
+ ```bash
64
+ bun install
65
+ bunx playwright install
66
+ ```
67
+
68
+ ## Code Style
69
+
70
+ - Biome for formatting and linting. Run `bun run format` after every change.
71
+ - No comments unless explicitly needed.
72
+ - Early returns instead of nested if/else.
73
+ - KISS/YAGNI — make the smallest change possible.
74
+ - No code duplication. Check if it already exists.
75
+ - Use dedent for formatting prompts.
76
+ - No ternary operators.
77
+
78
+ See `CLAUDE.md` for the full guidelines.
79
+
80
+ ## Testing
81
+
82
+ Run `bun run format`, `bun run lint`, `bun run test:unit`, and `bun run test:node` before you submit a PR — all checks must pass. See the [testing guide](testing.md) for details, [AI integration tests](ai-integration-tests.md) for mocked-LLM agent tests, and [regression tests](regression-tests.md) for the real-AI end-to-end harness.
83
+
84
+ ## Using Claude Code
85
+
86
+ This project includes Claude Code skills to help with development. See the `.claude/skills/` directory: changelog, demo-video, explorbot-debug, explorbot-fix-session, image-processing, prompt-audit, xpath-testing.
87
+
88
+ ## Questions?
89
+
90
+ Open an issue on GitHub for questions or discussion.
@@ -0,0 +1,36 @@
1
+ # Demo Videos
2
+
3
+ Explorbot sessions can be turned into demo videos for social media and presentations. The generator composites the browser screencast of a test with a simulated terminal that replays the session's real log lines at their original pace, over an abstract background with window chrome and shadows. Everything shown is real recorded data: no more than 1.25x speedup, successful runs only.
4
+
5
+ Implementation lives in `.claude/skills/demo-video/` (`demo-video.ts` exports `analyzeDemoCandidates` and `createDemoVideo`; the Bunoshfile wraps them as commands).
6
+
7
+ ## Prerequisites
8
+
9
+ - `vhs` and `ttyd` — render the terminal simulation (`go install github.com/charmbracelet/vhs@latest`)
10
+ - `ffmpeg` and ImageMagick
11
+ - IBM Plex Mono font (optional — VHS falls back to its default mono font)
12
+ - A session recorded with screencasts: enable `ai.agents.historian.screencast` in `explorbot.config.js` so `output/screencasts/*.webm` exist alongside `output/explorbot.log`
13
+
14
+ ## Usage
15
+
16
+ ```bash
17
+ bunx bunosh demo:analyze output/explorbot.log --screencasts output/screencasts
18
+ bunx bunosh demo:video --size landscape --app-title "My App"
19
+ bunx bunosh demo:video "upload a file" --size vertical --terminal-theme light
20
+ ```
21
+
22
+ `demo:analyze` lists candidate segments ranked by how well they will read on video. `demo:video` renders the best one, or the test whose scenario name matches the first argument. Key options: `--duration` (target seconds, default 30), `--size` (`landscape`, `square`, `vertical`, or `WxH`), `--app-title` (browser window title, defaults to the tested app's host), `--terminal-theme` (`dark` or `light`), `--bg-image` (`auto` fetches a random abstract photo from Unsplash, `gradient` generates one offline, or pass a file/URL). Run `bunx bunosh demo:video --help` for the full list.
23
+
24
+ The renderer verifies its output and writes three check frames (`*-frame-first/mid/last.png`) next to the video — review them before publishing.
25
+
26
+ ## How segments are picked
27
+
28
+ Only successful tests with an existing screencast qualify. Within a test, the scorer prefers windows that:
29
+
30
+ - are dense in visible actions (click, fill, type, navigate) rather than thinking or verification steps
31
+ - have no dead air — inter-step gaps stay under 10 seconds
32
+ - show forward progress — windows dominated by repeated retry steps are rejected
33
+ - were executed live — batch-logged step bursts cannot sync with the video and are rejected
34
+ - do not end on a failure note or mid-navigation on a blank page
35
+
36
+ The log's `Saved screencast:` line joins a test to its `.webm`; video time is calibrated from that timestamp minus the video duration. If a screencast file was overwritten by a run outside the log, it is skipped.