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.
- package/README.md +1 -1
- package/bin/explorbot-cli.ts +26 -8
- package/boat/api-tester/src/cli.ts +17 -0
- package/boat/api-tester/src/config.ts +4 -2
- package/boat/doc-collector/bin/doc-collector-cli.ts +2 -0
- package/boat/doc-collector/src/ai/documentarian.ts +61 -31
- package/boat/doc-collector/src/cli.ts +14 -1
- package/boat/doc-collector/src/config.ts +4 -2
- package/boat/prima/bin/prima-cli.ts +0 -0
- package/boat/prima/src/activity-line.ts +33 -0
- package/boat/prima/src/cli.ts +127 -86
- package/boat/prima/src/envelope.ts +102 -52
- package/boat/prima/src/prima.ts +567 -128
- package/boat/prima/src/pw-parser.ts +11 -1
- package/boat/prima/src/pw-registry.ts +4 -5
- package/boat/prima/src/session-log.ts +126 -0
- package/dist/bin/explorbot-cli.js +26 -8
- package/dist/boat/api-tester/bin/apibot-cli.js +2 -0
- package/dist/boat/api-tester/src/cli.js +17 -0
- package/dist/boat/api-tester/src/config.js +4 -2
- package/dist/boat/doc-collector/bin/doc-collector-cli.js +2 -0
- package/dist/boat/doc-collector/src/ai/documentarian.js +44 -19
- package/dist/boat/doc-collector/src/cli.js +14 -1
- package/dist/boat/doc-collector/src/config.js +4 -2
- package/dist/boat/prima/src/activity-line.js +30 -0
- package/dist/boat/prima/src/cli.js +109 -77
- package/dist/boat/prima/src/envelope.js +94 -44
- package/dist/boat/prima/src/prima.js +533 -119
- package/dist/boat/prima/src/pw-parser.js +13 -1
- package/dist/boat/prima/src/pw-registry.js +4 -5
- package/dist/boat/prima/src/session-log.js +108 -0
- package/dist/package.json +3 -2
- package/dist/rules/navigator/verification-actions.md +20 -0
- package/dist/src/action-result.d.ts +7 -0
- package/dist/src/action-result.js +4 -0
- package/dist/src/action.d.ts +2 -0
- package/dist/src/action.js +41 -2
- package/dist/src/ai/captain/web-mode.js +6 -3
- package/dist/src/ai/captain.js +2 -0
- package/dist/src/ai/navigator.d.ts +34 -0
- package/dist/src/ai/navigator.js +237 -181
- package/dist/src/ai/pilot.d.ts +7 -0
- package/dist/src/ai/pilot.js +90 -2
- package/dist/src/ai/provider.d.ts +2 -2
- package/dist/src/ai/provider.js +14 -23
- package/dist/src/ai/rerunner.js +2 -1
- package/dist/src/ai/researcher/cache.d.ts +2 -0
- package/dist/src/ai/researcher/cache.js +10 -2
- package/dist/src/ai/researcher.js +3 -2
- package/dist/src/ai/rules.js +17 -10
- package/dist/src/ai/session-analyst.js +2 -0
- package/dist/src/ai/task-agent.js +4 -1
- package/dist/src/ai/tester.d.ts +6 -3
- package/dist/src/ai/tester.js +50 -46
- package/dist/src/ai/tools.d.ts +14 -0
- package/dist/src/ai/tools.js +117 -37
- package/dist/src/commands/config-command.d.ts +51 -0
- package/dist/src/commands/config-command.js +117 -0
- package/dist/src/commands/index.js +2 -0
- package/dist/src/config.d.ts +9 -1
- package/dist/src/config.js +53 -4
- package/dist/src/execution-controller.d.ts +2 -0
- package/dist/src/execution-controller.js +6 -0
- package/dist/src/explorbot.d.ts +2 -1
- package/dist/src/explorbot.js +7 -2
- package/dist/src/explorer.js +2 -3
- package/dist/src/playwright-recorder.js +30 -0
- package/dist/src/remote.d.ts +55 -0
- package/dist/src/remote.js +235 -0
- package/dist/src/reporter.d.ts +1 -0
- package/dist/src/reporter.js +7 -1
- package/dist/src/state-manager.d.ts +2 -1
- package/dist/src/state-manager.js +3 -1
- package/dist/src/stats.d.ts +1 -0
- package/dist/src/stats.js +1 -0
- package/dist/src/test-plan.d.ts +3 -0
- package/dist/src/test-plan.js +26 -0
- package/dist/src/utils/aria.d.ts +2 -8
- package/dist/src/utils/aria.js +69 -40
- package/dist/src/utils/html.js +1 -0
- package/dist/src/utils/logger.d.ts +7 -1
- package/dist/src/utils/logger.js +32 -0
- package/dist/src/utils/page-readiness.js +18 -1
- package/dist/src/utils/url-matcher.js +3 -0
- package/dist/src/utils/web-element.d.ts +2 -0
- package/dist/src/utils/web-element.js +8 -0
- package/dist/src/utils/web-sandbox.d.ts +1 -1
- package/dist/src/utils/web-sandbox.js +2 -3
- package/docs/api-testing/basics.md +90 -0
- package/docs/api-testing/planning.md +57 -0
- package/docs/api-testing/running-tests.md +55 -0
- package/docs/assets/cloud-report.png +0 -0
- package/docs/assets/html-report.png +0 -0
- package/docs/assets/langfuse-trace.png +0 -0
- package/docs/assets/successful-explore-run.png +0 -0
- package/docs/basics/getting-started.md +140 -0
- package/docs/basics/prerequisites.md +63 -0
- package/docs/basics/providers.md +362 -0
- package/docs/basics/running.md +78 -0
- package/docs/contributing/ai-integration-tests.md +57 -0
- package/docs/contributing/contributing.md +90 -0
- package/docs/contributing/demo-videos.md +36 -0
- package/docs/contributing/npm-package.md +138 -0
- package/docs/contributing/observability.md +227 -0
- package/docs/contributing/regression-tests.md +103 -0
- package/docs/contributing/testing.md +95 -0
- package/docs/doc-collection/basics.md +128 -0
- package/docs/doc-collection/crawling.md +67 -0
- package/docs/doc-collection/interactive-mode.md +99 -0
- package/docs/index.json +87 -0
- package/docs/reference/commands.md +997 -0
- package/docs/reference/configuration.md +569 -0
- package/docs/reference/scripting.md +303 -0
- package/docs/reference/websocket.md +50 -0
- package/docs/superpowers/plans/2026-08-01-actor-boat.md +925 -0
- package/docs/superpowers/plans/2026-08-01-prima-boat.md +1120 -0
- package/docs/superpowers/reviews/2026-08-06-prima-vs-playwright-cli.md +268 -0
- package/docs/superpowers/specs/2026-08-01-actor-boat-design.md +204 -0
- package/docs/superpowers/specs/2026-08-01-prima-boat-design.md +242 -0
- package/docs/superpowers/specs/2026-08-03-global-config-design.md +138 -0
- package/docs/superpowers/specs/2026-08-07-prima-fixes-design.md +394 -0
- package/docs/superpowers/specs/2026-08-18-prima-false-verdicts.md +159 -0
- package/docs/web-testing/agents.md +158 -0
- package/docs/web-testing/automated-tests.md +134 -0
- package/docs/web-testing/basics.md +91 -0
- package/docs/web-testing/customization.md +131 -0
- package/docs/web-testing/hooks.md +238 -0
- package/docs/web-testing/page-interaction.md +84 -0
- package/docs/web-testing/planner.md +122 -0
- package/docs/web-testing/rerun.md +164 -0
- package/docs/web-testing/researcher.md +380 -0
- package/docs/workflow/agentic-usage.md +233 -0
- package/docs/workflow/application-spec.md +73 -0
- package/docs/workflow/ci.md +202 -0
- package/docs/workflow/knowledge.md +310 -0
- package/docs/workflow/planning-styles.md +67 -0
- package/docs/workflow/reporting.md +133 -0
- package/docs/workflow/test-plans.md +90 -0
- package/package.json +3 -2
- package/rules/navigator/verification-actions.md +20 -0
- package/src/action-result.ts +11 -0
- package/src/action.ts +43 -3
- package/src/ai/captain/web-mode.ts +6 -3
- package/src/ai/captain.ts +3 -0
- package/src/ai/navigator.ts +255 -186
- package/src/ai/pilot.ts +104 -2
- package/src/ai/provider.ts +14 -24
- package/src/ai/rerunner.ts +2 -1
- package/src/ai/researcher/cache.ts +12 -2
- package/src/ai/researcher.ts +3 -2
- package/src/ai/rules.ts +17 -10
- package/src/ai/session-analyst.ts +2 -0
- package/src/ai/task-agent.ts +3 -1
- package/src/ai/tester.ts +52 -45
- package/src/ai/tools.ts +136 -37
- package/src/commands/config-command.ts +146 -0
- package/src/commands/index.ts +2 -0
- package/src/config.ts +60 -5
- package/src/execution-controller.ts +8 -0
- package/src/explorbot.ts +7 -3
- package/src/explorer.ts +2 -2
- package/src/playwright-recorder.ts +23 -0
- package/src/remote.ts +244 -0
- package/src/reporter.ts +7 -1
- package/src/state-manager.ts +6 -2
- package/src/stats.ts +1 -0
- package/src/test-plan.ts +29 -0
- package/src/utils/aria.ts +65 -45
- package/src/utils/html.ts +1 -0
- package/src/utils/logger.ts +33 -2
- package/src/utils/page-readiness.ts +24 -1
- package/src/utils/url-matcher.ts +3 -0
- package/src/utils/web-element.ts +9 -0
- package/src/utils/web-sandbox.ts +3 -4
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# Building and Publishing the npm Package
|
|
2
|
+
|
|
3
|
+
Explorbot develops on Bun but ships to npm as a Node.js-compatible package. This page covers how the build works and how to publish it.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
- Bun (for development and running the build)
|
|
8
|
+
- Node.js >= 24 (for verifying the build output)
|
|
9
|
+
- npm account with publish access to `explorbot` package
|
|
10
|
+
|
|
11
|
+
## How the Build Works
|
|
12
|
+
|
|
13
|
+
The source is TypeScript with `.ts` imports (enabled by `allowImportingTsExtensions` in `tsconfig.json`). Bun runs these natively, but Node.js needs compiled `.js` files.
|
|
14
|
+
|
|
15
|
+
The build runs the TypeScript compiler (`tsc`) with a dedicated `tsconfig.build.json`:
|
|
16
|
+
|
|
17
|
+
1. **TypeScript compilation** - Compiles `src/`, `bin/`, and `boat/` to `dist/`, preserving the directory structure.
|
|
18
|
+
2. **Import rewriting** - `rewriteRelativeImportExtensions` rewrites `.ts` imports to `.js` in the output (a TypeScript 5.7+ feature).
|
|
19
|
+
3. **Type declarations** - `scripts/build-types.ts` emits `.d.ts` files for the library API (see [Type Declarations](#type-declarations)).
|
|
20
|
+
4. **Asset copying** - Copies `rules/` and `assets/sample-files/` into `dist/` so runtime path resolution works.
|
|
21
|
+
5. **Shebang replacement** - Replaces `#!/usr/bin/env bun` with `#!/usr/bin/env node` in every CLI entry point declared in `bin`: `dist/bin/explorbot-cli.js` and `dist/boat/prima/bin/prima-cli.js`.
|
|
22
|
+
|
|
23
|
+
### Build Configuration
|
|
24
|
+
|
|
25
|
+
**`tsconfig.build.json`** extends the base `tsconfig.json` with:
|
|
26
|
+
|
|
27
|
+
| Option | Value | Purpose |
|
|
28
|
+
|--------|-------|---------|
|
|
29
|
+
| `noEmit` | `false` | Enable output (base config has `true`) |
|
|
30
|
+
| `outDir` | `dist` | Compilation output directory |
|
|
31
|
+
| `rewriteRelativeImportExtensions` | `true` | Rewrite `.ts` → `.js` in imports |
|
|
32
|
+
| `declaration` | `false` | The JS build emits no `.d.ts`; declarations are built separately (see below) |
|
|
33
|
+
| `sourceMap` | `false` | No source maps in the published package |
|
|
34
|
+
| `skipLibCheck` | `true` | Skip type checking of dependencies |
|
|
35
|
+
|
|
36
|
+
The build skips type checking (`--noCheck` flag) because Bun is more permissive than `tsc` strict mode. Bun enforces type safety during development.
|
|
37
|
+
|
|
38
|
+
### Package Structure
|
|
39
|
+
|
|
40
|
+
After the build, the npm package contains:
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
dist/
|
|
44
|
+
├── bin/explorbot-cli.js # CLI entry point (#!/usr/bin/env node)
|
|
45
|
+
├── src/ # Compiled application code (.js) + type declarations (.d.ts)
|
|
46
|
+
│ ├── index.js # Library entry point
|
|
47
|
+
│ └── index.d.ts # Library type declarations
|
|
48
|
+
├── boat/ # Compiled API tester module
|
|
49
|
+
├── rules/ # Agent rule files (markdown)
|
|
50
|
+
└── assets/sample-files/ # Sample files for testing
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Type Declarations
|
|
54
|
+
|
|
55
|
+
`declaration: true` doesn't work directly on this codebase: the Researcher agent is built from generic mixin factories (`WithDeepAnalysis(Base)` etc.) that return anonymous classes with `private` members, which TypeScript can't serialize into a `.d.ts` (`TS4094`). Rather than refactor those hot-path agents, `scripts/build-types.ts` generates declarations from a transformed copy of the source:
|
|
56
|
+
|
|
57
|
+
1. Copies `src/` into a temporary tree, rewriting every `private`/`protected` class modifier to `public` at its exact AST position (members are preserved; only the visibility keyword changes, which removes `TS4094`).
|
|
58
|
+
2. Runs `tsc --emitDeclarationOnly` over the copy into `dist/src/`.
|
|
59
|
+
3. Rewrites `.ts`/`.tsx` module specifiers to `.js` in the emitted `.d.ts` so they resolve for consumers.
|
|
60
|
+
4. Deletes the temporary tree.
|
|
61
|
+
|
|
62
|
+
The transform touches only the intermediate copy — the shipped `.js` keeps its real `private`/`protected` visibility. The `.d.ts` types are exact (unions, option shapes, and return types are all preserved), so Node.js/TypeScript consumers get full type-checking. Bun consumers resolve the TypeScript source directly via the `bun` export condition.
|
|
63
|
+
|
|
64
|
+
Key `package.json` fields:
|
|
65
|
+
|
|
66
|
+
```json
|
|
67
|
+
{
|
|
68
|
+
"bin": {
|
|
69
|
+
"explorbot": "./dist/bin/explorbot-cli.js",
|
|
70
|
+
"prima": "./dist/boat/prima/bin/prima-cli.js"
|
|
71
|
+
},
|
|
72
|
+
"main": "dist/src/index.js",
|
|
73
|
+
"types": "dist/src/index.d.ts",
|
|
74
|
+
"exports": {
|
|
75
|
+
".": {
|
|
76
|
+
"types": "./dist/src/index.d.ts",
|
|
77
|
+
"bun": "./src/index.ts",
|
|
78
|
+
"import": "./dist/src/index.js"
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
"files": [
|
|
82
|
+
"dist/",
|
|
83
|
+
"src/**/*.ts",
|
|
84
|
+
"src/**/*.tsx",
|
|
85
|
+
"bin/**/*.ts",
|
|
86
|
+
"boat/api-tester/src/**/*.ts",
|
|
87
|
+
"boat/doc-collector/src/**/*.ts",
|
|
88
|
+
"boat/doc-collector/bin/**/*.ts",
|
|
89
|
+
"boat/doc-collector/package.json",
|
|
90
|
+
"boat/prima/src/**/*.ts",
|
|
91
|
+
"boat/prima/bin/**/*.ts",
|
|
92
|
+
"boat/prima/package.json",
|
|
93
|
+
"rules/",
|
|
94
|
+
"assets/sample-files/"
|
|
95
|
+
],
|
|
96
|
+
"engines": { "node": ">=24.0.0" }
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
The package ships two commands: `explorbot`, and `prima` for the [prima boat](../reference/commands.md#prima-boat), so `npx -p explorbot prima <command>` works without a separate install.
|
|
101
|
+
|
|
102
|
+
Explorbot is both a CLI (`bin`) and a library (`exports`). The `.` entry point is `src/index.ts`, a side-effect-free barrel that re-exports the public API (`ExplorBot`, `Plan`, `Test`, and their types). The `exports` conditions are ordered so each consumer gets the right entry: `types` (the emitted `.d.ts`) for type-checking, `bun` (the TypeScript source) under Bun, and `import` (the compiled JS) under Node.js. This is why the source `src/**` files ship alongside `dist/`.
|
|
103
|
+
|
|
104
|
+
## Building Locally
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# Build the npm package
|
|
108
|
+
bun run build:npm
|
|
109
|
+
|
|
110
|
+
# Verify the CLIs work on Node.js
|
|
111
|
+
node dist/bin/explorbot-cli.js --help
|
|
112
|
+
node dist/boat/prima/bin/prima-cli.js --help
|
|
113
|
+
|
|
114
|
+
# Check what would be published
|
|
115
|
+
npm pack --dry-run
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Publishing
|
|
119
|
+
|
|
120
|
+
GitHub Actions publishes automatically (see below), but you can also publish manually:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
# Bump version
|
|
124
|
+
npm version patch # or minor, major
|
|
125
|
+
|
|
126
|
+
# Build and publish (prepublishOnly runs build:npm automatically)
|
|
127
|
+
npm publish
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Known Limitations
|
|
131
|
+
|
|
132
|
+
- **Type declarations are transform-generated** - Declarations come from a transformed copy of the source (see [Type Declarations](#type-declarations)), not from `tsc --declaration` directly, because the mixin-based agents can't emit declarations as written. The published `.d.ts` types are exact; the workaround only concerns how they're produced.
|
|
133
|
+
|
|
134
|
+
## CI/CD
|
|
135
|
+
|
|
136
|
+
The `test.yml` workflow verifies the npm build on every push. On Node.js 24 it runs `bun run build:npm`, then the Node smoke tests: `node --test tests/node/*.mjs`. The `publish.yml` workflow additionally checks `node dist/bin/explorbot-cli.js --help` before publishing.
|
|
137
|
+
|
|
138
|
+
The `publish.yml` workflow publishes to npm when you push a version tag (`v*` or a bare `1.2.3`-style tag). It overwrites the package version from the tag; tags containing `beta`, `alpha`, `pre`, or `rc` publish to the `beta` dist-tag instead of `latest`.
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
# Observability & Debugging
|
|
2
|
+
|
|
3
|
+
Explorbot integrates with [Langfuse](https://langfuse.com) for tracing. Use it to see what happened during a session: what data each agent received, which tools it called, and how it decided.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
## Why Observability?
|
|
8
|
+
|
|
9
|
+
Without traces, you only see the final test result and basic logs. When Explorbot runs on its own, you need to see:
|
|
10
|
+
|
|
11
|
+
- What prompts went to the AI.
|
|
12
|
+
- What tools were called, and with what parameters.
|
|
13
|
+
- Token usage and cost per session.
|
|
14
|
+
- How long each operation took.
|
|
15
|
+
- Errors and retries.
|
|
16
|
+
|
|
17
|
+
Use this data to:
|
|
18
|
+
|
|
19
|
+
- Debug failed tests. See what the AI saw and decided.
|
|
20
|
+
- Create Knowledge fixes. Find the context that was missing.
|
|
21
|
+
- Tune prompts and agent performance.
|
|
22
|
+
- Understand why a test passed or failed.
|
|
23
|
+
- Export sessions for the `/explorbot-debug` skill.
|
|
24
|
+
|
|
25
|
+
## Setting Up Langfuse
|
|
26
|
+
|
|
27
|
+
### 1. Create a Langfuse Account
|
|
28
|
+
|
|
29
|
+
Sign up at [langfuse.com](https://langfuse.com) (free tier available) or self-host.
|
|
30
|
+
|
|
31
|
+
### 2. Get Your API Keys
|
|
32
|
+
|
|
33
|
+
From your Langfuse project settings, copy:
|
|
34
|
+
- **Public Key**
|
|
35
|
+
- **Secret Key**
|
|
36
|
+
|
|
37
|
+
### 3. Configure Explorbot
|
|
38
|
+
|
|
39
|
+
Add credentials to your `.env` file:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
LANGFUSE_PUBLIC_KEY=pk-lf-xxxxxxxx
|
|
43
|
+
LANGFUSE_SECRET_KEY=sk-lf-xxxxxxxx
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Or configure in `explorbot.config.js`:
|
|
47
|
+
|
|
48
|
+
```javascript
|
|
49
|
+
export default {
|
|
50
|
+
ai: {
|
|
51
|
+
model: groq('gpt-oss-20b'),
|
|
52
|
+
langfuse: {
|
|
53
|
+
enabled: true,
|
|
54
|
+
publicKey: process.env.LANGFUSE_PUBLIC_KEY,
|
|
55
|
+
secretKey: process.env.LANGFUSE_SECRET_KEY,
|
|
56
|
+
baseUrl: 'https://cloud.langfuse.com', // or your self-hosted URL
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### 4. Run Explorbot
|
|
63
|
+
|
|
64
|
+
Once configured, Explorbot traces every AI call. No code changes needed.
|
|
65
|
+
|
|
66
|
+
## What Gets Traced
|
|
67
|
+
|
|
68
|
+
Explorbot uses the [Vercel AI SDK integration](https://langfuse.com/docs/integrations/vercel-ai-sdk) with Langfuse. Each session captures:
|
|
69
|
+
|
|
70
|
+
| Trace | Description |
|
|
71
|
+
|-------|-------------|
|
|
72
|
+
| `test: <scenario>` | Full test execution cycle |
|
|
73
|
+
| `researcher: <url>` | Page analysis by Researcher agent |
|
|
74
|
+
| `planner: <url>` | Test scenario generation |
|
|
75
|
+
| `driller: <url>` | Component drilling |
|
|
76
|
+
| `ai.generateText` | Text generation calls |
|
|
77
|
+
| `ai.generateObject` | Structured output calls |
|
|
78
|
+
| `codeceptjs.step` | Individual browser actions |
|
|
79
|
+
|
|
80
|
+
Navigator has no span of its own — its AI calls appear as `ai.*` spans under the parent trace.
|
|
81
|
+
|
|
82
|
+
## Analyzing Sessions
|
|
83
|
+
|
|
84
|
+
### In Langfuse Dashboard
|
|
85
|
+
|
|
86
|
+
1. Open your Langfuse project
|
|
87
|
+
2. Find the session by timestamp or name
|
|
88
|
+
3. Click to see the full trace tree
|
|
89
|
+
4. Inspect individual spans for:
|
|
90
|
+
- Input prompts
|
|
91
|
+
- Output responses
|
|
92
|
+
- Token counts
|
|
93
|
+
- Duration
|
|
94
|
+
- Errors
|
|
95
|
+
|
|
96
|
+
## Debugging with Claude Code
|
|
97
|
+
|
|
98
|
+
Explorbot includes a Claude Code skill that analyzes failed sessions.
|
|
99
|
+
|
|
100
|
+
### Using the Debug Skill
|
|
101
|
+
|
|
102
|
+
Find the failed `test: <scenario>` trace in Langfuse and copy its trace ID. Then, in Claude Code, run:
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
/explorbot-debug
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Give it the trace ID — the skill fetches the trace with all its observations via `bun .claude/skills/explorbot-debug/langfuse-export.ts <trace-id>`. The trace holds the full context: prompts, tool calls, page states, and AI decisions. Without a trace ID, the skill analyzes `output/explorbot.log` instead.
|
|
109
|
+
|
|
110
|
+
### What the Skill Analyzes
|
|
111
|
+
|
|
112
|
+
The skill looks for three failure patterns:
|
|
113
|
+
|
|
114
|
+
| Pattern | Symptoms | Solution |
|
|
115
|
+
|---------|----------|----------|
|
|
116
|
+
| **Missing Context** | Wrong element clicked, didn't understand UI | Add Knowledge file with disambiguation rules |
|
|
117
|
+
| **Wrong Prompts** | Incorrect assumptions, wrong flow | Add Knowledge with business context |
|
|
118
|
+
| **Wrong Tool Choice** | Used click when form needed, typing issues | Add Knowledge with CodeceptJS code examples |
|
|
119
|
+
|
|
120
|
+
### How It Helps
|
|
121
|
+
|
|
122
|
+
1. Extracts key data from the trace with jq:
|
|
123
|
+
- Failed tool calls
|
|
124
|
+
- URLs visited
|
|
125
|
+
- Prompts sent to the AI
|
|
126
|
+
|
|
127
|
+
2. Identifies the root cause of failures.
|
|
128
|
+
|
|
129
|
+
3. Suggests Knowledge files to fix the issue:
|
|
130
|
+
```markdown
|
|
131
|
+
---
|
|
132
|
+
url: /admin/users/*
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## User Table
|
|
136
|
+
Each row has same buttons. Use container:
|
|
137
|
+
I.click('Delete', '[data-user-id="123"]')
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
4. Can try interactions with browser tools, if available, and record working CodeceptJS code.
|
|
141
|
+
|
|
142
|
+
### Example Workflow
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
# 1. Test fails
|
|
146
|
+
./bin/explorbot-cli.ts explore /admin/users
|
|
147
|
+
|
|
148
|
+
# 2. Open Langfuse, find the failed "test: ..." trace, copy its trace ID
|
|
149
|
+
|
|
150
|
+
# 3. In Claude Code:
|
|
151
|
+
/explorbot-debug
|
|
152
|
+
# Provide the trace ID
|
|
153
|
+
|
|
154
|
+
# 4. Skill analyzes and suggests Knowledge fix
|
|
155
|
+
# 5. Create knowledge file
|
|
156
|
+
./bin/explorbot-cli.ts learn "/admin/users/*" "Use container context for table actions"
|
|
157
|
+
|
|
158
|
+
# 6. Re-run test
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Debugging Tips
|
|
162
|
+
|
|
163
|
+
### Enable Verbose Logging
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
./bin/explorbot-cli.ts explore /admin/users --verbose
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Or set the environment variable:
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
DEBUG=explorbot:* ./bin/explorbot-cli.ts explore /admin/users
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
This shows detailed logs:
|
|
176
|
+
|
|
177
|
+
- Prompts sent to the AI
|
|
178
|
+
- Tool calls and results
|
|
179
|
+
- State transitions
|
|
180
|
+
|
|
181
|
+
### Specific Debug Namespaces
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
# AI provider calls only
|
|
185
|
+
DEBUG=explorbot:provider ./bin/explorbot-cli.ts explore /admin/users
|
|
186
|
+
|
|
187
|
+
# Navigator agent only
|
|
188
|
+
DEBUG=explorbot:navigator ./bin/explorbot-cli.ts explore /admin/users
|
|
189
|
+
|
|
190
|
+
# Multiple namespaces
|
|
191
|
+
DEBUG=explorbot:tester,explorbot:navigator ./bin/explorbot-cli.ts explore /admin/users
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Available Namespaces
|
|
195
|
+
|
|
196
|
+
| Namespace | What it shows |
|
|
197
|
+
|-----------|---------------|
|
|
198
|
+
| `explorbot:provider` | AI API calls, responses |
|
|
199
|
+
| `explorbot:provider:out` | Outgoing prompts |
|
|
200
|
+
| `explorbot:provider:in` | Incoming responses |
|
|
201
|
+
| `explorbot:navigator` | Navigation decisions |
|
|
202
|
+
| `explorbot:researcher` | Page analysis |
|
|
203
|
+
| `explorbot:planner` | Test scenario generation |
|
|
204
|
+
| `explorbot:tester` | Test execution |
|
|
205
|
+
| `explorbot:historian` | Experience saving |
|
|
206
|
+
| `explorbot:quartermaster` | A11y analysis |
|
|
207
|
+
|
|
208
|
+
## Cost Tracking
|
|
209
|
+
|
|
210
|
+
Langfuse tracks token usage per call. Use it to:
|
|
211
|
+
|
|
212
|
+
- Monitor cost across sessions
|
|
213
|
+
- Compare model efficiency
|
|
214
|
+
- Find expensive operations
|
|
215
|
+
- Tune prompts to reduce tokens
|
|
216
|
+
|
|
217
|
+
## Self-Hosting Langfuse
|
|
218
|
+
|
|
219
|
+
For privacy or compliance, you can self-host Langfuse. Langfuse v3 requires docker compose with Postgres, ClickHouse, and Redis — follow the [self-hosting docs](https://langfuse.com/self-hosting).
|
|
220
|
+
|
|
221
|
+
Then set `baseUrl` in your config:
|
|
222
|
+
|
|
223
|
+
```javascript
|
|
224
|
+
langfuse: {
|
|
225
|
+
baseUrl: 'http://localhost:3000',
|
|
226
|
+
}
|
|
227
|
+
```
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# Self-Regression Tests
|
|
2
|
+
|
|
3
|
+
The regression harness runs Explorbot **end-to-end with real AI models** against a controlled local fixture app, then asserts on the artifacts Explorbot produces (research, plans, test results). Unlike the integration tests in `tests/integration/` — which mock the LLM — these runs use a live provider, so they are nondeterministic and gated behind owner approval in CI.
|
|
4
|
+
|
|
5
|
+
The harness lives in `tests/regression/` and is driven by `regression:*` commands in the repo `Bunoshfile.js`.
|
|
6
|
+
|
|
7
|
+
## Scenarios
|
|
8
|
+
|
|
9
|
+
### Scenario A — fresh explore (`regression:basic`)
|
|
10
|
+
|
|
11
|
+
Runs `explorbot explore /issues --headless` against the Trackly fixture and asserts:
|
|
12
|
+
|
|
13
|
+
- **Login evidence** — a plan targets a post-login route (`/issues`, `/settings`) and at least one research file describes a post-login page (proves the agent applied the seeded credentials and got past the gate).
|
|
14
|
+
- **Research** — at least one research file with a heading, a UI-map table, and enough domain keywords.
|
|
15
|
+
- **Scenarios identified** — the plan holds at least `MIN_PLANNED_TESTS` tests covering at least `MIN_FEATURE_GROUPS` feature areas.
|
|
16
|
+
- **Tests passed** — the `Results: N passed, N failed` stdout line shows no failures and at least `MIN_PASSED` passing tests, cross-checked against the reporter markdown.
|
|
17
|
+
|
|
18
|
+
Credentials are supplied through a seeded knowledge file (`tests/regression/seeds/knowledge/login.md`) matched to `/login`, so this scenario also exercises knowledge rules.
|
|
19
|
+
|
|
20
|
+
### Scenario B — experience reuse (`regression:experience`)
|
|
21
|
+
|
|
22
|
+
Proves Explorbot reuses prior context to pass a test it cannot pass cold. The Trackly Archive vault (`/vault`) is unlocked only by an access code that exists nowhere in the DOM — only in the server and in the seed files.
|
|
23
|
+
|
|
24
|
+
- **Control run** (always, once) — runs the seed plan with **empty** knowledge and experience dirs. It must NOT pass. A fully-passing control means the vault gate is broken and fails the harness.
|
|
25
|
+
- **Seeded run** (retried) — runs the same plan with the seed knowledge and experience dirs. It must pass.
|
|
26
|
+
|
|
27
|
+
The plan (`tests/regression/seeds/vault-plan.md`) describes *what* to do but never contains the code. The seeded context supplies it two ways: `seeds/knowledge/vault.md` carries the access **code** (data), and `seeds/experience/vault.md` carries the interaction **recipe** (fill field, click Unlock). Both are prior seeded context; the control has neither and fails.
|
|
28
|
+
|
|
29
|
+
> The code is carried in a knowledge file, not only experience, on purpose. Knowledge is Explorbot's prominent, deterministic channel for page-specific data — the same mechanism scenario A uses for login credentials. Empirically, cheap models followed an experience-only code recipe only occasionally, so an experience-only gate was a coin-flip; knowledge makes the gate reliable while the experience file still exercises recipe reuse.
|
|
30
|
+
|
|
31
|
+
## The fixture app — "Trackly"
|
|
32
|
+
|
|
33
|
+
A self-contained issue tracker served in-process by `tests/regression/fixture/server.ts` (`Bun.serve`, ephemeral port, fresh in-memory store per attempt). No external network, no database.
|
|
34
|
+
|
|
35
|
+
| Route | Auth | Contents |
|
|
36
|
+
|-------|------|----------|
|
|
37
|
+
| `/login` | no | credentials form (always native HTML) |
|
|
38
|
+
| `/issues` | yes | issue list, search, status filter, label menu (start page) |
|
|
39
|
+
| `/issues/new` | yes | create form: title, description, priority, labels + assignees multiselects |
|
|
40
|
+
| `/issues/:id` | yes | detail, change-status menu, comment form, delete modal |
|
|
41
|
+
| `/settings` | yes | Profile/Preferences tabs + an activity iframe |
|
|
42
|
+
| `/vault` | no | scenario B access-code gate |
|
|
43
|
+
| `/api/*` | cookie | REST API over the same store, `+ /api/openapi.json` |
|
|
44
|
+
|
|
45
|
+
The REST API mirrors the store and is served for a future API-testing scenario; the current scenarios do not exercise it.
|
|
46
|
+
|
|
47
|
+
### Component variants (ARIA on/off)
|
|
48
|
+
|
|
49
|
+
Every widget (button, text field, select, multiselect, dropdown menu, modal, tabs) renders in one of three variants, selectable per run:
|
|
50
|
+
|
|
51
|
+
- `native` — semantic HTML (`<button>`, `<select multiple>`, `<dialog>`, `<details>`).
|
|
52
|
+
- `aria` — custom `<div>` widgets with correct roles (`role="combobox"`, `aria-modal`, `role="menu"`, …).
|
|
53
|
+
- `plain` — bare `<div>` widgets with no roles or labels (the hostile case).
|
|
54
|
+
- `random` — a seeded RNG picks a variant per widget; the same `--seed` reproduces identical markup.
|
|
55
|
+
|
|
56
|
+
Pass `--variant` and `--seed` to any scenario. The login page is always native so variant runs don't fail at the door.
|
|
57
|
+
|
|
58
|
+
## Running locally
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
# No-AI sanity check: fixture routes, auth, API, vault gate, seed parsing, variant rendering
|
|
62
|
+
bunx bunosh regression:smoke
|
|
63
|
+
|
|
64
|
+
# Serve the fixture for manual inspection (append ?variant=plain&seed=7 to any page)
|
|
65
|
+
bunx bunosh regression:serve
|
|
66
|
+
|
|
67
|
+
# Real-AI runs (need a provider key)
|
|
68
|
+
export OPENROUTER_API_KEY=sk-...
|
|
69
|
+
bunx bunosh regression:experience --retries 0 # cheapest AI path
|
|
70
|
+
bunx bunosh regression:basic --retries 0
|
|
71
|
+
bunx bunosh regression:all # both scenarios, default retries
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Each attempt runs in an isolated throwaway directory under `tests/regression/.runs/` (gitignored). Inspect `tests/regression/.runs/<scenario>-<variant>-a<n>/output/` for the research, plans, and reporter markdown a run produced, and `tests/regression/.runs/report.md` for the summary.
|
|
75
|
+
|
|
76
|
+
### Variant matrix
|
|
77
|
+
|
|
78
|
+
`regression:variants` runs a scenario across variants and reports the outcome per variant **without gating** — a `plain`-variant failure is data about model robustness, not a regression. Only a crashed or timed-out run fails it.
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
bunx bunosh regression:variants --scenario basic --variants native,aria,plain
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## CI and the approval gate
|
|
85
|
+
|
|
86
|
+
`.github/workflows/regression.yml` runs on `pull_request` and `workflow_dispatch`. The job uses the `regression` GitHub environment, which holds `OPENROUTER_API_KEY` behind a **required reviewer**. Every run — including fork PRs — pauses at the environment gate before the secret is exposed. The job runs the PR's own code, so the reviewer must read the PR diff (workflow, Bunoshfile, fixture, lib) before approving; that review is the security boundary. The workflow never uses `pull_request_target`.
|
|
87
|
+
|
|
88
|
+
The report is posted as a sticky PR comment (on `pull_request`) or a `Regression Reports` GitHub Discussion (on `workflow_dispatch`). Fork PRs get a read-only token, so comment posting may fail; the report is also written to the job step summary and uploaded as the `regression-runs` artifact.
|
|
89
|
+
|
|
90
|
+
The report also embeds the **Session Analysis** from the fresh-explore run — Explorbot's Analyst agent writes a prose summary of what works, defects, UX issues, and execution issues, which the harness reads from `output/reports/<label>.md` and appends to the comment. The Analyst is enabled in the config template (`ai.agents.analyst.enabled: true`); it adds one AI call per basic run.
|
|
91
|
+
|
|
92
|
+
## Tuning
|
|
93
|
+
|
|
94
|
+
- **Thresholds** (`MIN_PLANNED_TESTS`, `MIN_PASSED`, `MIN_KEYWORD_HITS`, `MIN_FEATURE_GROUPS`) live at the top of `tests/regression/lib/assertions.ts`.
|
|
95
|
+
- **Models** live in `tests/regression/fixture/explorbot.config.js`. If cheap models are too flaky, promote a stronger model to `ai.model` or lower `MIN_PASSED`.
|
|
96
|
+
- **Run size** — adjust `--max-tests` in `runBasicScenario` and the per-CLI `timeout` values in `Bunoshfile.js`.
|
|
97
|
+
|
|
98
|
+
## Owner prerequisites (one-time)
|
|
99
|
+
|
|
100
|
+
1. Settings → Environments → create `regression`; add the repo owner as a **Required reviewer**; deployment branch policy "No restriction".
|
|
101
|
+
2. Add the environment secret `OPENROUTER_API_KEY` (a dedicated key with a low spend limit).
|
|
102
|
+
3. Create a Discussions category named exactly `Regression Reports`.
|
|
103
|
+
4. Ensure the OpenRouter account has credit for the models in the config template.
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Testing Guide
|
|
2
|
+
|
|
3
|
+
## Running Tests
|
|
4
|
+
|
|
5
|
+
### Unit Tests
|
|
6
|
+
```bash
|
|
7
|
+
# Run all unit tests
|
|
8
|
+
bun test tests/unit
|
|
9
|
+
|
|
10
|
+
# Run specific test file
|
|
11
|
+
bun test tests/unit/state-manager.test.ts
|
|
12
|
+
|
|
13
|
+
# Run tests with coverage
|
|
14
|
+
bun test tests/unit --coverage
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### Coverage Reports
|
|
18
|
+
|
|
19
|
+
#### Text Coverage Report
|
|
20
|
+
```bash
|
|
21
|
+
# Get coverage with text output
|
|
22
|
+
bun run test:coverage
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
#### Coverage Summary Only
|
|
26
|
+
```bash
|
|
27
|
+
# Get just the coverage summary
|
|
28
|
+
bun run test:coverage:summary
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
#### LCOV Coverage File
|
|
32
|
+
The `--coverage` flag writes coverage data to `coverage/lcov.info`.
|
|
33
|
+
|
|
34
|
+
## Coverage Configuration
|
|
35
|
+
|
|
36
|
+
Coverage is configured in `bunfig.toml`:
|
|
37
|
+
|
|
38
|
+
- **Coverage Directory**: `coverage/`
|
|
39
|
+
- **Coverage Threshold**: 80%
|
|
40
|
+
- **Included Files**: `src/**/*.{ts,tsx,js,jsx}`
|
|
41
|
+
- **Excluded Files**: Test files, TUI components, build artifacts
|
|
42
|
+
|
|
43
|
+
## Test Structure
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
tests/
|
|
47
|
+
├── unit/ # Unit tests (Bun)
|
|
48
|
+
│ ├── state-manager.test.ts
|
|
49
|
+
│ ├── experience-tracker.test.ts
|
|
50
|
+
│ └── ...
|
|
51
|
+
├── integration/ # AI agent tests with mocked LLM
|
|
52
|
+
├── node/ # Node.js build smoke tests
|
|
53
|
+
├── regression/ # End-to-end runs with real AI
|
|
54
|
+
└── mocks/ # Test mocks
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
This page covers unit tests. The other suites: integration tests exercise AI agents against a mocked LLM via aimock — see [AI integration tests](./ai-integration-tests.md). Node smoke tests in `tests/node/` verify the compiled npm build and run in CI (`bun run test:node`). Regression tests run Explorbot with real AI against a local fixture app — see [regression tests](./regression-tests.md).
|
|
58
|
+
|
|
59
|
+
## Writing Tests
|
|
60
|
+
|
|
61
|
+
### Best Practices
|
|
62
|
+
|
|
63
|
+
1. **Happy path focus**: Test successful scenarios and core functionality.
|
|
64
|
+
2. **Test isolation**: Make each test independent and clean up after itself.
|
|
65
|
+
3. **Descriptive names**: Name tests for what they check.
|
|
66
|
+
4. **Mock external dependencies**: Use `MockAIProvider` for AI-related tests.
|
|
67
|
+
5. **Temp directories**: Use `/tmp/` paths for file system tests.
|
|
68
|
+
|
|
69
|
+
### Mock AI Provider
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
import { MockAIProvider } from '../mocks/ai-provider.mock';
|
|
73
|
+
|
|
74
|
+
const mockAI = new MockAIProvider();
|
|
75
|
+
mockAI.setResponses([
|
|
76
|
+
{ text: 'Mock response 1' },
|
|
77
|
+
{ text: 'Mock response 2' }
|
|
78
|
+
]);
|
|
79
|
+
|
|
80
|
+
// Use mockAI.getModel() in your tests
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## CI/CD Integration
|
|
84
|
+
|
|
85
|
+
Generate coverage reports for your CI pipeline:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
# Generate coverage for CI
|
|
89
|
+
bun test tests/unit --coverage --coverage-reporter=lcov
|
|
90
|
+
|
|
91
|
+
# Check coverage threshold (exits with error if below 80%)
|
|
92
|
+
bun test tests/unit --coverage --coverage-reporter=text
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Upload the LCOV file (`coverage/lcov.info`) to a coverage service like Codecov or Coveralls.
|