explorbot 0.2.2 → 0.2.4
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 +59 -38
- package/boat/api-tester/src/apibot.ts +4 -2
- package/boat/api-tester/src/cli.ts +2 -2
- package/boat/api-tester/src/config.ts +43 -10
- 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 +1 -0
- package/boat/doc-collector/src/config.ts +4 -2
- package/boat/doc-collector/src/docs-renderer.ts +18 -4
- package/boat/doc-collector/src/state-diagram.ts +61 -14
- package/boat/prima/bin/prima-cli.ts +5 -0
- package/boat/prima/package.json +16 -0
- package/boat/prima/src/activity-line.ts +33 -0
- package/boat/prima/src/cli.ts +251 -0
- package/boat/prima/src/envelope.ts +169 -0
- package/boat/prima/src/prima.ts +1124 -0
- package/boat/prima/src/pw-parser.ts +27 -0
- package/boat/prima/src/pw-registry.ts +74 -0
- package/boat/prima/src/session-log.ts +126 -0
- package/dist/bin/explorbot-cli.js +51 -32
- package/dist/boat/api-tester/bin/apibot-cli.js +2 -0
- package/dist/boat/api-tester/src/apibot.js +3 -2
- package/dist/boat/api-tester/src/cli.js +2 -2
- package/dist/boat/api-tester/src/config.js +40 -10
- 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 +1 -0
- package/dist/boat/doc-collector/src/config.js +4 -2
- package/dist/boat/doc-collector/src/docs-renderer.js +17 -3
- package/dist/boat/doc-collector/src/state-diagram.js +57 -13
- package/dist/boat/prima/bin/prima-cli.js +4 -0
- package/dist/boat/prima/src/activity-line.js +30 -0
- package/dist/boat/prima/src/cli.js +220 -0
- package/dist/boat/prima/src/envelope.js +142 -0
- package/dist/boat/prima/src/prima.js +1031 -0
- package/dist/boat/prima/src/pw-parser.js +30 -0
- package/dist/boat/prima/src/pw-registry.js +65 -0
- package/dist/boat/prima/src/session-log.js +108 -0
- package/dist/models.json +3 -0
- package/dist/package.json +8 -3
- 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 +7 -2
- package/dist/src/action.js +41 -6
- package/dist/src/ai/captain/mixin.js +3 -4
- package/dist/src/ai/captain/web-mode.js +7 -4
- package/dist/src/ai/captain.js +2 -0
- package/dist/src/ai/navigator.d.ts +11 -0
- package/dist/src/ai/navigator.js +21 -12
- package/dist/src/ai/pilot.d.ts +4 -0
- package/dist/src/ai/pilot.js +48 -2
- package/dist/src/ai/planner.d.ts +1 -0
- package/dist/src/ai/planner.js +6 -0
- package/dist/src/ai/provider.js +2 -2
- package/dist/src/ai/rerunner.js +2 -1
- package/dist/src/ai/researcher.js +2 -2
- package/dist/src/ai/rules.js +17 -10
- package/dist/src/ai/task-agent.js +5 -2
- package/dist/src/ai/tester.d.ts +1 -0
- package/dist/src/ai/tester.js +33 -20
- package/dist/src/ai/tools.d.ts +14 -0
- package/dist/src/ai/tools.js +113 -36
- package/dist/src/application-spec-contract.d.ts +8 -0
- package/dist/src/application-spec-contract.js +8 -0
- package/dist/src/application-spec.d.ts +15 -0
- package/dist/src/application-spec.js +71 -0
- package/dist/src/browser-server.d.ts +12 -6
- package/dist/src/browser-server.js +74 -19
- package/dist/src/commands/clean-command.js +2 -7
- package/dist/src/commands/init-command.d.ts +5 -0
- package/dist/src/commands/init-command.js +119 -1
- package/dist/src/commands/navigate-command.js +1 -1
- package/dist/src/commands/research-command.js +1 -1
- package/dist/src/commands/sites-command.d.ts +6 -0
- package/dist/src/commands/sites-command.js +23 -0
- package/dist/src/components/InitWizard.d.ts +10 -0
- package/dist/src/components/InitWizard.js +133 -0
- package/dist/src/components/InputReadline.d.ts +1 -0
- package/dist/src/components/InputReadline.js +7 -4
- package/dist/src/config.d.ts +25 -5
- package/dist/src/config.js +158 -40
- package/dist/src/execution-controller.d.ts +2 -0
- package/dist/src/execution-controller.js +6 -0
- package/dist/src/explorbot.d.ts +11 -1
- package/dist/src/explorbot.js +27 -6
- package/dist/src/explorer.d.ts +4 -1
- package/dist/src/explorer.js +42 -9
- package/dist/src/global-config.d.ts +22 -0
- package/dist/src/global-config.js +117 -0
- package/dist/src/knowledge-tracker.d.ts +5 -1
- package/dist/src/knowledge-tracker.js +14 -1
- package/dist/src/playwright-recorder.js +30 -0
- package/dist/src/remote.d.ts +54 -0
- package/dist/src/remote.js +229 -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/stats.d.ts +1 -0
- package/dist/src/stats.js +1 -0
- package/dist/src/test-plan.d.ts +2 -0
- package/dist/src/test-plan.js +7 -0
- package/dist/src/utils/aria.d.ts +2 -8
- package/dist/src/utils/aria.js +69 -40
- package/dist/src/utils/cli-name.js +6 -2
- package/dist/src/utils/html.js +1 -0
- package/dist/src/utils/logger.d.ts +6 -0
- package/dist/src/utils/logger.js +24 -0
- package/dist/src/utils/page-readiness.js +18 -1
- package/dist/src/utils/test-files.js +1 -2
- package/dist/src/utils/url-matcher.d.ts +1 -0
- package/dist/src/utils/url-matcher.js +12 -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 +86 -0
- package/docs/reference/commands.md +994 -0
- package/docs/reference/configuration.md +569 -0
- package/docs/reference/scripting.md +303 -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/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/models.json +3 -0
- package/package.json +8 -3
- package/rules/navigator/verification-actions.md +20 -0
- package/src/action-result.ts +11 -0
- package/src/action.ts +47 -7
- package/src/ai/captain/mixin.ts +3 -3
- package/src/ai/captain/web-mode.ts +7 -4
- package/src/ai/captain.ts +3 -0
- package/src/ai/navigator.ts +26 -15
- package/src/ai/pilot.ts +53 -2
- package/src/ai/planner.ts +7 -0
- package/src/ai/provider.ts +2 -4
- package/src/ai/rerunner.ts +2 -1
- package/src/ai/researcher.ts +2 -2
- package/src/ai/rules.ts +17 -10
- package/src/ai/task-agent.ts +4 -2
- package/src/ai/tester.ts +32 -18
- package/src/ai/tools.ts +132 -36
- package/src/application-spec-contract.ts +10 -0
- package/src/application-spec.ts +87 -0
- package/src/browser-server.ts +74 -19
- package/src/commands/clean-command.ts +1 -6
- package/src/commands/init-command.ts +146 -1
- package/src/commands/navigate-command.ts +1 -1
- package/src/commands/research-command.ts +1 -1
- package/src/commands/sites-command.ts +27 -0
- package/src/components/InitWizard.tsx +166 -0
- package/src/components/InputReadline.tsx +8 -4
- package/src/config.ts +177 -43
- package/src/execution-controller.ts +8 -0
- package/src/explorbot.ts +34 -7
- package/src/explorer.ts +47 -9
- package/src/global-config.ts +148 -0
- package/src/knowledge-tracker.ts +17 -1
- package/src/playwright-recorder.ts +23 -0
- package/src/remote.ts +238 -0
- package/src/reporter.ts +7 -1
- package/src/state-manager.ts +2 -1
- package/src/stats.ts +1 -0
- package/src/test-plan.ts +9 -0
- package/src/utils/aria.ts +65 -45
- package/src/utils/cli-name.ts +5 -2
- package/src/utils/html.ts +1 -0
- package/src/utils/logger.ts +24 -1
- package/src/utils/page-readiness.ts +24 -1
- package/src/utils/test-files.ts +1 -2
- package/src/utils/url-matcher.ts +13 -0
- package/src/utils/web-element.ts +9 -0
- package/src/utils/web-sandbox.ts +3 -4
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
const EXPECTATION_LABELS = {
|
|
4
|
+
passed: 'PASSED ',
|
|
5
|
+
failed: 'FAILED ',
|
|
6
|
+
unverified: 'not verified',
|
|
7
|
+
};
|
|
8
|
+
export function renderEnvelope(data) {
|
|
9
|
+
const sections = [renderResult(data), renderPage(data), renderValue(data), renderChanges(data), renderSteps(data), renderExpectations(data), renderOutcome(data), ...renderFailure(data), renderInstance(data), renderArtifacts(data)];
|
|
10
|
+
return sections.filter((section) => section).join('\n\n');
|
|
11
|
+
}
|
|
12
|
+
export function writeArtifacts(dir, snapshot) {
|
|
13
|
+
mkdirSync(dir, { recursive: true });
|
|
14
|
+
const paths = {
|
|
15
|
+
aria: path.resolve(dir, 'aria.yml'),
|
|
16
|
+
html: path.resolve(dir, 'page.html'),
|
|
17
|
+
};
|
|
18
|
+
writeFileSync(paths.aria, snapshot.aria ?? '', 'utf-8');
|
|
19
|
+
writeFileSync(paths.html, snapshot.html ?? '', 'utf-8');
|
|
20
|
+
if (!snapshot.requests.length)
|
|
21
|
+
return paths;
|
|
22
|
+
paths.network = path.resolve(dir, 'network.jsonl');
|
|
23
|
+
writeFileSync(paths.network, snapshot.requests.map((request) => `${JSON.stringify(request)}\n`).join(''), 'utf-8');
|
|
24
|
+
return paths;
|
|
25
|
+
}
|
|
26
|
+
function renderResult(data) {
|
|
27
|
+
const lines = [`ok: ${data.ok}`, `command: ${data.command}`];
|
|
28
|
+
if (data.used?.length)
|
|
29
|
+
lines.push(`used: ${data.used.join('; ')}`);
|
|
30
|
+
return section('Result', lines.join('\n'));
|
|
31
|
+
}
|
|
32
|
+
function renderPage(data) {
|
|
33
|
+
const { url, previousUrl, title, state, visits } = data.page;
|
|
34
|
+
const urlLabel = `url: ${url}`;
|
|
35
|
+
const stateLabel = `state: ${state}`;
|
|
36
|
+
const width = Math.max(urlLabel.length, stateLabel.length) + 3;
|
|
37
|
+
let changedMarker = '';
|
|
38
|
+
if (previousUrl && previousUrl !== url)
|
|
39
|
+
changedMarker = `(changed: ${previousUrl} → ${url})`;
|
|
40
|
+
const lines = [align(urlLabel, changedMarker, width), `title: ${title}`, align(stateLabel, `(visit #${visits})`, width)];
|
|
41
|
+
return section('Page', lines.join('\n'));
|
|
42
|
+
}
|
|
43
|
+
function renderValue(data) {
|
|
44
|
+
if (data.value === undefined)
|
|
45
|
+
return null;
|
|
46
|
+
return section('Value', data.value);
|
|
47
|
+
}
|
|
48
|
+
function renderChanges(data) {
|
|
49
|
+
if (data.changes === undefined || data.changes === null)
|
|
50
|
+
return null;
|
|
51
|
+
return section('Changes', data.changes);
|
|
52
|
+
}
|
|
53
|
+
function renderSteps(data) {
|
|
54
|
+
if (!data.steps?.length)
|
|
55
|
+
return null;
|
|
56
|
+
const lines = [];
|
|
57
|
+
data.steps.forEach((step, index) => {
|
|
58
|
+
lines.push(`${index + 1}. ${step.ok ? 'ok ' : 'FAIL'} ${step.label}`);
|
|
59
|
+
for (const line of (step.proof || '').split('\n').filter(Boolean))
|
|
60
|
+
lines.push(` ${line}`);
|
|
61
|
+
});
|
|
62
|
+
if (data.stepFiles)
|
|
63
|
+
lines.push('', `page after each step: ${data.stepFiles}`);
|
|
64
|
+
return section('Steps', lines.join('\n'));
|
|
65
|
+
}
|
|
66
|
+
function renderExpectations(data) {
|
|
67
|
+
if (!data.expectations?.length)
|
|
68
|
+
return null;
|
|
69
|
+
const lines = data.expectations.map((expectation, index) => `${index + 1}. ${EXPECTATION_LABELS[expectation.status]} ${expectation.text}`);
|
|
70
|
+
return section('Expected outcomes', lines.join('\n'));
|
|
71
|
+
}
|
|
72
|
+
function renderOutcome(data) {
|
|
73
|
+
if (data.answer)
|
|
74
|
+
return section('Answer', data.answer);
|
|
75
|
+
if (data.research)
|
|
76
|
+
return section('Research', data.research);
|
|
77
|
+
if (!data.assertions)
|
|
78
|
+
return null;
|
|
79
|
+
if (!data.assertions.length)
|
|
80
|
+
return section('Assertions', 'none ran — no assertion could express this claim, so nothing was checked against the page');
|
|
81
|
+
const lines = data.assertions.map((assertion) => {
|
|
82
|
+
const code = assertion.code
|
|
83
|
+
.split('\n')
|
|
84
|
+
.map((line) => line.trim())
|
|
85
|
+
.filter((line) => line && !line.startsWith('//'))
|
|
86
|
+
.join(' ');
|
|
87
|
+
return `${code} => ${assertion.passed ? 'PASSED' : 'FAILED'}`;
|
|
88
|
+
});
|
|
89
|
+
const proof = data.assertions.flatMap((assertion) => assertion.proof);
|
|
90
|
+
if (proof.length)
|
|
91
|
+
lines.push('', 'playwright:', ...proof);
|
|
92
|
+
return section('Assertions', lines.join('\n'));
|
|
93
|
+
}
|
|
94
|
+
function renderFailure(data) {
|
|
95
|
+
if (!data.failure)
|
|
96
|
+
return [];
|
|
97
|
+
return [section('Failure', `error: ${data.failure.error}`), renderCompactAria(data.failure.compactAria)];
|
|
98
|
+
}
|
|
99
|
+
function renderCompactAria(compactAria) {
|
|
100
|
+
if (!compactAria)
|
|
101
|
+
return null;
|
|
102
|
+
return section('Current page (compact ARIA)', compactAria);
|
|
103
|
+
}
|
|
104
|
+
function renderInstance(data) {
|
|
105
|
+
const instance = data.instance;
|
|
106
|
+
const parts = [`${instance.name} (${tabsLabel(instance.tabs)})`, browserLine(instance)];
|
|
107
|
+
if (instance.others.length)
|
|
108
|
+
parts.push(`other instances: ${instance.others.map((other) => `${other.name} (${tabsLabel(other.tabs)})`).join(', ')}`);
|
|
109
|
+
if (data.status)
|
|
110
|
+
parts.push(`details: prima status ${data.status}`);
|
|
111
|
+
return section('Instance', parts.join(' | '));
|
|
112
|
+
}
|
|
113
|
+
function browserLine(instance) {
|
|
114
|
+
if (instance.attached)
|
|
115
|
+
return `attached to ${instance.attached}`;
|
|
116
|
+
if (instance.startedAgo)
|
|
117
|
+
return `running, started ${instance.startedAgo} ago`;
|
|
118
|
+
if (instance.tabs > 0)
|
|
119
|
+
return 'running';
|
|
120
|
+
return 'not running';
|
|
121
|
+
}
|
|
122
|
+
function tabsLabel(tabs) {
|
|
123
|
+
if (tabs === 1)
|
|
124
|
+
return '1 tab';
|
|
125
|
+
return `${tabs} tabs`;
|
|
126
|
+
}
|
|
127
|
+
export function renderArtifacts(data) {
|
|
128
|
+
if (!data.artifacts)
|
|
129
|
+
return null;
|
|
130
|
+
const lines = [`aria: ${data.artifacts.aria}`, `html: ${data.artifacts.html}`];
|
|
131
|
+
if (data.artifacts.network)
|
|
132
|
+
lines.push(`network: ${data.artifacts.network}`);
|
|
133
|
+
return section('Artifacts', lines.join('\n'));
|
|
134
|
+
}
|
|
135
|
+
function align(label, marker, width) {
|
|
136
|
+
if (!marker)
|
|
137
|
+
return label;
|
|
138
|
+
return `${label.padEnd(width)}${marker}`;
|
|
139
|
+
}
|
|
140
|
+
function section(title, body) {
|
|
141
|
+
return `### ${title}\n${body}`;
|
|
142
|
+
}
|