@browserflow-ai/cli 0.0.6
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/bin/bf.js +3 -0
- package/dist/commands/baseline.d.ts +77 -0
- package/dist/commands/baseline.d.ts.map +1 -0
- package/dist/commands/baseline.js +429 -0
- package/dist/commands/baseline.js.map +1 -0
- package/dist/commands/doctor.d.ts +39 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +230 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/explore.d.ts +12 -0
- package/dist/commands/explore.d.ts.map +1 -0
- package/dist/commands/explore.js +114 -0
- package/dist/commands/explore.js.map +1 -0
- package/dist/commands/init.d.ts +15 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +160 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/lint.d.ts +37 -0
- package/dist/commands/lint.d.ts.map +1 -0
- package/dist/commands/lint.js +248 -0
- package/dist/commands/lint.js.map +1 -0
- package/dist/commands/repair.d.ts +72 -0
- package/dist/commands/repair.d.ts.map +1 -0
- package/dist/commands/repair.js +271 -0
- package/dist/commands/repair.js.map +1 -0
- package/dist/commands/review.d.ts +26 -0
- package/dist/commands/review.d.ts.map +1 -0
- package/dist/commands/review.js +371 -0
- package/dist/commands/review.js.map +1 -0
- package/dist/commands/run.d.ts +5 -0
- package/dist/commands/run.d.ts.map +1 -0
- package/dist/commands/run.js +66 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -0
- package/dist/run/executor.d.ts +10 -0
- package/dist/run/executor.d.ts.map +1 -0
- package/dist/run/executor.js +95 -0
- package/dist/run/executor.js.map +1 -0
- package/dist/run/failure-bundle.d.ts +65 -0
- package/dist/run/failure-bundle.d.ts.map +1 -0
- package/dist/run/failure-bundle.js +253 -0
- package/dist/run/failure-bundle.js.map +1 -0
- package/dist/run/index.d.ts +6 -0
- package/dist/run/index.d.ts.map +1 -0
- package/dist/run/index.js +6 -0
- package/dist/run/index.js.map +1 -0
- package/dist/run/output.d.ts +5 -0
- package/dist/run/output.d.ts.map +1 -0
- package/dist/run/output.js +62 -0
- package/dist/run/output.js.map +1 -0
- package/dist/run/results.d.ts +5 -0
- package/dist/run/results.d.ts.map +1 -0
- package/dist/run/results.js +124 -0
- package/dist/run/results.js.map +1 -0
- package/dist/run/types.d.ts +44 -0
- package/dist/run/types.d.ts.map +1 -0
- package/dist/run/types.js +2 -0
- package/dist/run/types.js.map +1 -0
- package/dist/ui/box.d.ts +13 -0
- package/dist/ui/box.d.ts.map +1 -0
- package/dist/ui/box.js +32 -0
- package/dist/ui/box.js.map +1 -0
- package/dist/ui/colors.d.ts +28 -0
- package/dist/ui/colors.d.ts.map +1 -0
- package/dist/ui/colors.js +34 -0
- package/dist/ui/colors.js.map +1 -0
- package/dist/ui/env.d.ts +31 -0
- package/dist/ui/env.d.ts.map +1 -0
- package/dist/ui/env.js +77 -0
- package/dist/ui/env.js.map +1 -0
- package/dist/ui/index.d.ts +7 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +7 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/output.d.ts +18 -0
- package/dist/ui/output.d.ts.map +1 -0
- package/dist/ui/output.js +33 -0
- package/dist/ui/output.js.map +1 -0
- package/dist/ui/prompts.d.ts +12 -0
- package/dist/ui/prompts.d.ts.map +1 -0
- package/dist/ui/prompts.js +37 -0
- package/dist/ui/prompts.js.map +1 -0
- package/dist/ui/spinner.d.ts +9 -0
- package/dist/ui/spinner.d.ts.map +1 -0
- package/dist/ui/spinner.js +27 -0
- package/dist/ui/spinner.js.map +1 -0
- package/package.json +78 -0
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { exec as execCallback } from 'node:child_process';
|
|
3
|
+
import { promisify } from 'node:util';
|
|
4
|
+
import { access, readFile } from 'node:fs/promises';
|
|
5
|
+
import { join } from 'node:path';
|
|
6
|
+
import { createServer } from 'node:net';
|
|
7
|
+
import { parse as parseYaml } from 'yaml';
|
|
8
|
+
import { logSuccess, logError, logWarning, logHeader, logNewline } from '../ui/prompts.js';
|
|
9
|
+
import { colors } from '../ui/colors.js';
|
|
10
|
+
const exec = promisify(execCallback);
|
|
11
|
+
async function fileExists(path) {
|
|
12
|
+
try {
|
|
13
|
+
await access(path);
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
async function isPortAvailable(port) {
|
|
21
|
+
return new Promise((resolve) => {
|
|
22
|
+
const server = createServer();
|
|
23
|
+
server.once('error', () => resolve(false));
|
|
24
|
+
server.once('listening', () => {
|
|
25
|
+
server.close();
|
|
26
|
+
resolve(true);
|
|
27
|
+
});
|
|
28
|
+
server.listen(port, '127.0.0.1');
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
export async function checkNodeVersion() {
|
|
32
|
+
const version = process.version;
|
|
33
|
+
const major = parseInt(version.slice(1));
|
|
34
|
+
if (major >= 18) {
|
|
35
|
+
return { status: 'pass', message: `Node.js ${version}` };
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
status: 'fail',
|
|
39
|
+
message: `Node.js ${version} (need >=18)`,
|
|
40
|
+
fixHint: 'Install Node.js 18+ from https://nodejs.org',
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export async function checkAgentBrowser() {
|
|
44
|
+
try {
|
|
45
|
+
const { stdout } = await exec('agent-browser --version');
|
|
46
|
+
const version = stdout.trim();
|
|
47
|
+
// Handle version with or without 'v' prefix
|
|
48
|
+
const displayVersion = version.startsWith('v') ? version : `v${version}`;
|
|
49
|
+
return { status: 'pass', message: displayVersion };
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return {
|
|
53
|
+
status: 'fail',
|
|
54
|
+
message: 'Not installed',
|
|
55
|
+
fixHint: 'Run: bun add -g agent-browser',
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
export async function checkPlaywrightBrowsers() {
|
|
60
|
+
try {
|
|
61
|
+
// Get playwright version
|
|
62
|
+
const { stdout: versionOutput } = await exec('bunx playwright --version');
|
|
63
|
+
const version = versionOutput.trim();
|
|
64
|
+
// Check if chromium is installed using --list
|
|
65
|
+
try {
|
|
66
|
+
const { stdout: listOutput } = await exec('bunx playwright install --list');
|
|
67
|
+
// Check if chromium is listed in the browsers section
|
|
68
|
+
if (listOutput.includes('chromium-')) {
|
|
69
|
+
return { status: 'pass', message: `Installed (Playwright ${version})` };
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
status: 'warn',
|
|
73
|
+
message: `Playwright ${version} (chromium not installed)`,
|
|
74
|
+
fixHint: 'Run: bunx playwright install chromium',
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return {
|
|
79
|
+
status: 'warn',
|
|
80
|
+
message: `Playwright ${version} (browsers may need install)`,
|
|
81
|
+
fixHint: 'Run: bunx playwright install chromium',
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
return {
|
|
87
|
+
status: 'fail',
|
|
88
|
+
message: 'Not installed',
|
|
89
|
+
fixHint: 'Run: bunx playwright install chromium',
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
async function loadConfig() {
|
|
94
|
+
const configPath = join(process.cwd(), 'browserflow.yaml');
|
|
95
|
+
if (!(await fileExists(configPath))) {
|
|
96
|
+
return { config: null, error: 'No browserflow.yaml' };
|
|
97
|
+
}
|
|
98
|
+
try {
|
|
99
|
+
const content = await readFile(configPath, 'utf-8');
|
|
100
|
+
const config = parseYaml(content);
|
|
101
|
+
return { config };
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
return { config: null, error: `Invalid YAML: ${err.message}` };
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
export async function checkConfiguration() {
|
|
108
|
+
const { config, error } = await loadConfig();
|
|
109
|
+
if (!config) {
|
|
110
|
+
return {
|
|
111
|
+
status: 'fail',
|
|
112
|
+
message: error ?? 'No browserflow.yaml',
|
|
113
|
+
fixHint: 'Run: bf init',
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
return { status: 'pass', message: 'Valid' };
|
|
117
|
+
}
|
|
118
|
+
export async function checkReviewPort() {
|
|
119
|
+
const { config } = await loadConfig();
|
|
120
|
+
const port = config?.review?.port ?? 8190;
|
|
121
|
+
if (await isPortAvailable(port)) {
|
|
122
|
+
return { status: 'pass', message: `Port ${port} available` };
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
status: 'warn',
|
|
126
|
+
message: `Port ${port} in use`,
|
|
127
|
+
fixHint: 'Change review.port in browserflow.yaml',
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
function createDefaultChecks() {
|
|
131
|
+
return [
|
|
132
|
+
{ name: 'Node.js version', check: checkNodeVersion },
|
|
133
|
+
{ name: 'agent-browser', check: checkAgentBrowser },
|
|
134
|
+
{ name: 'Playwright browsers', check: checkPlaywrightBrowsers },
|
|
135
|
+
{ name: 'Configuration', check: checkConfiguration },
|
|
136
|
+
{ name: 'Review port', check: checkReviewPort },
|
|
137
|
+
];
|
|
138
|
+
}
|
|
139
|
+
export function createMockChecks(options = {}) {
|
|
140
|
+
if (options.allPass) {
|
|
141
|
+
return [
|
|
142
|
+
{ name: 'Node.js version', check: async () => ({ status: 'pass', message: 'v20.0.0' }) },
|
|
143
|
+
{ name: 'agent-browser', check: async () => ({ status: 'pass', message: 'v0.5.0' }) },
|
|
144
|
+
{ name: 'Playwright browsers', check: async () => ({ status: 'pass', message: 'Installed' }) },
|
|
145
|
+
{ name: 'Configuration', check: async () => ({ status: 'pass', message: 'Valid' }) },
|
|
146
|
+
{ name: 'Review port', check: async () => ({ status: 'pass', message: 'Port 8190 available' }) },
|
|
147
|
+
];
|
|
148
|
+
}
|
|
149
|
+
return createDefaultChecks();
|
|
150
|
+
}
|
|
151
|
+
export async function runDoctor(options, checks = createDefaultChecks()) {
|
|
152
|
+
const checkOutputs = [];
|
|
153
|
+
for (const check of checks) {
|
|
154
|
+
const result = await check.check();
|
|
155
|
+
checkOutputs.push({ name: check.name, result });
|
|
156
|
+
// Attempt fix if requested and available
|
|
157
|
+
if (options.fix && result.status === 'fail' && check.fix) {
|
|
158
|
+
try {
|
|
159
|
+
await check.fix();
|
|
160
|
+
// Re-run check after fix
|
|
161
|
+
const newResult = await check.check();
|
|
162
|
+
checkOutputs[checkOutputs.length - 1].result = newResult;
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
// Fix failed, keep original result
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
const summary = {
|
|
170
|
+
passed: checkOutputs.filter(c => c.result.status === 'pass').length,
|
|
171
|
+
warnings: checkOutputs.filter(c => c.result.status === 'warn').length,
|
|
172
|
+
failed: checkOutputs.filter(c => c.result.status === 'fail').length,
|
|
173
|
+
};
|
|
174
|
+
// Exit code: 0 for all pass, 0 for warnings only, 1 for any failures
|
|
175
|
+
const exitCode = summary.failed > 0 ? 1 : 0;
|
|
176
|
+
return { checks: checkOutputs, summary, exitCode };
|
|
177
|
+
}
|
|
178
|
+
function formatCheckOutput(check) {
|
|
179
|
+
const { name, result } = check;
|
|
180
|
+
const paddedName = name.padEnd(20);
|
|
181
|
+
switch (result.status) {
|
|
182
|
+
case 'pass':
|
|
183
|
+
logSuccess(`${paddedName} ${result.message}`);
|
|
184
|
+
break;
|
|
185
|
+
case 'warn':
|
|
186
|
+
logWarning(`${paddedName} ${result.message}`);
|
|
187
|
+
if (result.fixHint) {
|
|
188
|
+
console.log(` ${colors.dim('→')} ${result.fixHint}`);
|
|
189
|
+
}
|
|
190
|
+
break;
|
|
191
|
+
case 'fail':
|
|
192
|
+
logError(`${paddedName} ${result.message}`);
|
|
193
|
+
if (result.fixHint) {
|
|
194
|
+
console.log(` ${colors.dim('→')} ${result.fixHint}`);
|
|
195
|
+
}
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
export function doctorCommand() {
|
|
200
|
+
const cmd = new Command('doctor');
|
|
201
|
+
cmd
|
|
202
|
+
.description('Check environment and dependencies')
|
|
203
|
+
.option('-v, --verbose', 'Show detailed output')
|
|
204
|
+
.option('--fix', 'Attempt to fix issues automatically')
|
|
205
|
+
.action(async (options) => {
|
|
206
|
+
logHeader('BrowserFlow Doctor');
|
|
207
|
+
logNewline();
|
|
208
|
+
const result = await runDoctor(options);
|
|
209
|
+
for (const check of result.checks) {
|
|
210
|
+
formatCheckOutput(check);
|
|
211
|
+
}
|
|
212
|
+
logNewline();
|
|
213
|
+
const { passed, warnings, failed } = result.summary;
|
|
214
|
+
const parts = [];
|
|
215
|
+
if (passed > 0)
|
|
216
|
+
parts.push(colors.pass(`${passed} passed`));
|
|
217
|
+
if (warnings > 0)
|
|
218
|
+
parts.push(colors.warning(`${warnings} warning${warnings > 1 ? 's' : ''}`));
|
|
219
|
+
if (failed > 0)
|
|
220
|
+
parts.push(colors.fail(`${failed} failed`));
|
|
221
|
+
console.log(parts.join(', '));
|
|
222
|
+
if (failed > 0 && !options.fix) {
|
|
223
|
+
logNewline();
|
|
224
|
+
console.log(colors.dim('Run bf doctor --fix to attempt automatic fixes.'));
|
|
225
|
+
}
|
|
226
|
+
process.exitCode = result.exitCode;
|
|
227
|
+
});
|
|
228
|
+
return cmd;
|
|
229
|
+
}
|
|
230
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* bf explore command - runs AI exploration for a spec
|
|
3
|
+
* @see bf-x9t
|
|
4
|
+
*/
|
|
5
|
+
import { Command } from 'commander';
|
|
6
|
+
import type { BrowserFlowSpec } from '@browserflow-ai/core';
|
|
7
|
+
/**
|
|
8
|
+
* Load and validate a spec file
|
|
9
|
+
*/
|
|
10
|
+
export declare function loadAndValidateSpec(specName: string, cwd?: string): Promise<BrowserFlowSpec>;
|
|
11
|
+
export declare function exploreCommand(): Command;
|
|
12
|
+
//# sourceMappingURL=explore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"explore.d.ts","sourceRoot":"","sources":["../../src/commands/explore.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAK5D;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,eAAe,CAAC,CAmCjH;AA4BD,wBAAgB,cAAc,IAAI,OAAO,CAkDxC"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* bf explore command - runs AI exploration for a spec
|
|
3
|
+
* @see bf-x9t
|
|
4
|
+
*/
|
|
5
|
+
import { Command } from 'commander';
|
|
6
|
+
import { readFile, mkdir, writeFile } from 'node:fs/promises';
|
|
7
|
+
import { join } from 'node:path';
|
|
8
|
+
import { parse as parseYaml } from 'yaml';
|
|
9
|
+
import { specSchema } from '@browserflow-ai/core';
|
|
10
|
+
import { Explorer, ClaudeAdapter, ClaudeCliAdapter, createBrowserSession } from '@browserflow-ai/exploration';
|
|
11
|
+
import { colors } from '../ui/colors.js';
|
|
12
|
+
/**
|
|
13
|
+
* Load and validate a spec file
|
|
14
|
+
*/
|
|
15
|
+
export async function loadAndValidateSpec(specName, cwd = process.cwd()) {
|
|
16
|
+
const specPath = join(cwd, 'specs', `${specName}.yaml`);
|
|
17
|
+
// Read file
|
|
18
|
+
let content;
|
|
19
|
+
try {
|
|
20
|
+
content = await readFile(specPath, 'utf-8');
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
const err = error;
|
|
24
|
+
if (err.code === 'ENOENT') {
|
|
25
|
+
throw new Error(`Spec file not found: ${specPath}`);
|
|
26
|
+
}
|
|
27
|
+
throw error;
|
|
28
|
+
}
|
|
29
|
+
// Parse YAML
|
|
30
|
+
let parsed;
|
|
31
|
+
try {
|
|
32
|
+
parsed = parseYaml(content);
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
const err = error;
|
|
36
|
+
throw new Error(`YAML syntax error: ${err.message}`);
|
|
37
|
+
}
|
|
38
|
+
// Validate against schema
|
|
39
|
+
const validation = specSchema.safeParse(parsed);
|
|
40
|
+
if (!validation.success) {
|
|
41
|
+
const issues = validation.error.issues.map((issue) => {
|
|
42
|
+
const path = issue.path.join('.');
|
|
43
|
+
return ` - ${path}: ${issue.message}`;
|
|
44
|
+
}).join('\n');
|
|
45
|
+
throw new Error(`Spec validation failed:\n${issues}`);
|
|
46
|
+
}
|
|
47
|
+
return validation.data;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Write exploration output to disk
|
|
51
|
+
*/
|
|
52
|
+
async function writeExplorationOutput(result) {
|
|
53
|
+
const outputDir = join('.browserflow', 'explorations', result.explorationId);
|
|
54
|
+
await mkdir(outputDir, { recursive: true });
|
|
55
|
+
await writeFile(join(outputDir, 'exploration.json'), JSON.stringify(result, null, 2));
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Create an AI adapter based on the adapter name
|
|
59
|
+
*/
|
|
60
|
+
function createAdapter(adapterName) {
|
|
61
|
+
switch (adapterName) {
|
|
62
|
+
case 'claude':
|
|
63
|
+
return new ClaudeAdapter();
|
|
64
|
+
case 'claude-cli':
|
|
65
|
+
return new ClaudeCliAdapter();
|
|
66
|
+
default:
|
|
67
|
+
throw new Error(`Unknown adapter: ${adapterName}. Available: claude, claude-cli`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
export function exploreCommand() {
|
|
71
|
+
const cmd = new Command('explore');
|
|
72
|
+
cmd
|
|
73
|
+
.description('Run AI exploration for a spec')
|
|
74
|
+
.requiredOption('--spec <name>', 'Spec name to explore')
|
|
75
|
+
.option('--url <url>', 'Base URL (overrides config)')
|
|
76
|
+
.option('--headed', 'Run browser in headed mode')
|
|
77
|
+
.option('--adapter <name>', 'AI adapter: claude (SDK), claude-cli (CLI)', 'claude')
|
|
78
|
+
.action(async (options) => {
|
|
79
|
+
try {
|
|
80
|
+
// 1. Load and validate spec
|
|
81
|
+
const spec = await loadAndValidateSpec(options.spec);
|
|
82
|
+
// 2. Determine base URL
|
|
83
|
+
const baseUrl = options.url || 'http://localhost:3000';
|
|
84
|
+
// 3. Create browser session and AI adapter
|
|
85
|
+
const browser = createBrowserSession();
|
|
86
|
+
const adapter = createAdapter(options.adapter);
|
|
87
|
+
// 4. Create explorer
|
|
88
|
+
const explorer = new Explorer({
|
|
89
|
+
adapter,
|
|
90
|
+
browser,
|
|
91
|
+
headless: !options.headed,
|
|
92
|
+
outputDir: '.browserflow/explorations',
|
|
93
|
+
});
|
|
94
|
+
// 5. Run exploration
|
|
95
|
+
console.log(colors.dim(`Running exploration for ${spec.name}...`));
|
|
96
|
+
const result = await explorer.runExploration(spec, baseUrl, {
|
|
97
|
+
specPath: `specs/${options.spec}.yaml`,
|
|
98
|
+
headless: !options.headed,
|
|
99
|
+
});
|
|
100
|
+
// 6. Write exploration output
|
|
101
|
+
await writeExplorationOutput(result);
|
|
102
|
+
// 7. Print summary
|
|
103
|
+
console.log(colors.success(`Exploration complete: ${result.explorationId}`));
|
|
104
|
+
console.log(`Run \`bf review --exploration ${result.explorationId}\` to review`);
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
const err = error;
|
|
108
|
+
console.error(colors.fail(err.message));
|
|
109
|
+
process.exitCode = 1;
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
return cmd;
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=explore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"explore.js","sourceRoot":"","sources":["../../src/commands/explore.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
export declare const DEFAULT_CONFIG = "project:\n name: my-project\n base_url: http://localhost:3000\n\nruntime:\n browser: chromium\n headless: true\n viewport:\n width: 1280\n height: 720\n timeout: 30s\n\nlocators:\n prefer_testid: true\n testid_attributes:\n - data-testid\n - data-test\n\nexploration:\n adapter: claude\n max_retries: 3\n\nreview:\n port: 8190\n auto_open: true\n\noutput:\n tests_dir: e2e/tests\n baselines_dir: baselines\n";
|
|
3
|
+
export declare const EXAMPLE_SPEC = "version: 2\nname: example\ndescription: Example spec - customize for your app\n\nsteps:\n - id: visit_home\n action: navigate\n url: /\n\n - id: homepage_screenshot\n action: screenshot\n name: homepage\n\ntags:\n - example\n - smoke\n";
|
|
4
|
+
export interface InitOptions {
|
|
5
|
+
force?: boolean;
|
|
6
|
+
example?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface InitResult {
|
|
9
|
+
created: string[];
|
|
10
|
+
updated: string[];
|
|
11
|
+
skipped: string[];
|
|
12
|
+
}
|
|
13
|
+
export declare function runInit(options: InitOptions): Promise<InitResult>;
|
|
14
|
+
export declare function initCommand(): Command;
|
|
15
|
+
//# sourceMappingURL=init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,eAAO,MAAM,cAAc,sbA6B1B,CAAC;AAEF,eAAO,MAAM,YAAY,gQAgBxB,CAAC;AAIF,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AA2CD,wBAAsB,OAAO,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAyCvE;AAED,wBAAgB,WAAW,IAAI,OAAO,CAuCrC"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { mkdir, writeFile, readFile, access } from 'node:fs/promises';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { logSuccess, logWarning, logHeader, logNewline, logInfo } from '../ui/prompts.js';
|
|
5
|
+
import { colors } from '../ui/colors.js';
|
|
6
|
+
export const DEFAULT_CONFIG = `project:
|
|
7
|
+
name: my-project
|
|
8
|
+
base_url: http://localhost:3000
|
|
9
|
+
|
|
10
|
+
runtime:
|
|
11
|
+
browser: chromium
|
|
12
|
+
headless: true
|
|
13
|
+
viewport:
|
|
14
|
+
width: 1280
|
|
15
|
+
height: 720
|
|
16
|
+
timeout: 30s
|
|
17
|
+
|
|
18
|
+
locators:
|
|
19
|
+
prefer_testid: true
|
|
20
|
+
testid_attributes:
|
|
21
|
+
- data-testid
|
|
22
|
+
- data-test
|
|
23
|
+
|
|
24
|
+
exploration:
|
|
25
|
+
adapter: claude
|
|
26
|
+
max_retries: 3
|
|
27
|
+
|
|
28
|
+
review:
|
|
29
|
+
port: 8190
|
|
30
|
+
auto_open: true
|
|
31
|
+
|
|
32
|
+
output:
|
|
33
|
+
tests_dir: e2e/tests
|
|
34
|
+
baselines_dir: baselines
|
|
35
|
+
`;
|
|
36
|
+
export const EXAMPLE_SPEC = `version: 2
|
|
37
|
+
name: example
|
|
38
|
+
description: Example spec - customize for your app
|
|
39
|
+
|
|
40
|
+
steps:
|
|
41
|
+
- id: visit_home
|
|
42
|
+
action: navigate
|
|
43
|
+
url: /
|
|
44
|
+
|
|
45
|
+
- id: homepage_screenshot
|
|
46
|
+
action: screenshot
|
|
47
|
+
name: homepage
|
|
48
|
+
|
|
49
|
+
tags:
|
|
50
|
+
- example
|
|
51
|
+
- smoke
|
|
52
|
+
`;
|
|
53
|
+
const GITIGNORE_ENTRIES = ['.browserflow/', 'node_modules/'];
|
|
54
|
+
async function fileExists(path) {
|
|
55
|
+
try {
|
|
56
|
+
await access(path);
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
async function appendToGitignore(entries) {
|
|
64
|
+
const gitignorePath = join(process.cwd(), '.gitignore');
|
|
65
|
+
let existingContent = '';
|
|
66
|
+
const added = [];
|
|
67
|
+
try {
|
|
68
|
+
existingContent = await readFile(gitignorePath, 'utf-8');
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
// File doesn't exist yet
|
|
72
|
+
}
|
|
73
|
+
const existingLines = new Set(existingContent.split('\n').map(l => l.trim()));
|
|
74
|
+
const toAdd = [];
|
|
75
|
+
for (const entry of entries) {
|
|
76
|
+
if (!existingLines.has(entry)) {
|
|
77
|
+
toAdd.push(entry);
|
|
78
|
+
added.push(entry);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if (toAdd.length > 0) {
|
|
82
|
+
const newContent = existingContent
|
|
83
|
+
? existingContent.trimEnd() + '\n' + toAdd.join('\n') + '\n'
|
|
84
|
+
: toAdd.join('\n') + '\n';
|
|
85
|
+
await writeFile(gitignorePath, newContent);
|
|
86
|
+
return { updated: true, added };
|
|
87
|
+
}
|
|
88
|
+
return { updated: false, added: [] };
|
|
89
|
+
}
|
|
90
|
+
export async function runInit(options) {
|
|
91
|
+
const result = {
|
|
92
|
+
created: [],
|
|
93
|
+
updated: [],
|
|
94
|
+
skipped: [],
|
|
95
|
+
};
|
|
96
|
+
// 1. Create browserflow.yaml
|
|
97
|
+
const configPath = join(process.cwd(), 'browserflow.yaml');
|
|
98
|
+
const configExists = await fileExists(configPath);
|
|
99
|
+
if (!configExists || options.force) {
|
|
100
|
+
await writeFile(configPath, DEFAULT_CONFIG);
|
|
101
|
+
result.created.push('browserflow.yaml');
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
result.skipped.push('browserflow.yaml');
|
|
105
|
+
}
|
|
106
|
+
// 2. Create specs/ directory
|
|
107
|
+
const specsDir = join(process.cwd(), 'specs');
|
|
108
|
+
const specsDirExists = await fileExists(specsDir);
|
|
109
|
+
if (!specsDirExists) {
|
|
110
|
+
await mkdir(specsDir, { recursive: true });
|
|
111
|
+
result.created.push('specs/');
|
|
112
|
+
}
|
|
113
|
+
// 3. Update .gitignore
|
|
114
|
+
const gitignoreResult = await appendToGitignore(GITIGNORE_ENTRIES);
|
|
115
|
+
if (gitignoreResult.updated) {
|
|
116
|
+
result.updated.push('.gitignore');
|
|
117
|
+
}
|
|
118
|
+
// 4. Create example spec (if --example)
|
|
119
|
+
if (options.example) {
|
|
120
|
+
const examplePath = join(specsDir, 'example.yaml');
|
|
121
|
+
await writeFile(examplePath, EXAMPLE_SPEC);
|
|
122
|
+
result.created.push('specs/example.yaml');
|
|
123
|
+
}
|
|
124
|
+
return result;
|
|
125
|
+
}
|
|
126
|
+
export function initCommand() {
|
|
127
|
+
const cmd = new Command('init');
|
|
128
|
+
cmd
|
|
129
|
+
.description('Initialize BrowserFlow in the current project')
|
|
130
|
+
.option('-f, --force', 'Overwrite existing configuration')
|
|
131
|
+
.option('--example', 'Create an example spec file')
|
|
132
|
+
.action(async (options) => {
|
|
133
|
+
logHeader('BrowserFlow Initialized!');
|
|
134
|
+
logNewline();
|
|
135
|
+
const result = await runInit(options);
|
|
136
|
+
if (result.created.length > 0 || result.updated.length > 0) {
|
|
137
|
+
console.log(colors.bold('Created:'));
|
|
138
|
+
for (const file of result.created) {
|
|
139
|
+
logSuccess(file);
|
|
140
|
+
}
|
|
141
|
+
for (const file of result.updated) {
|
|
142
|
+
logSuccess(`${file} (updated)`);
|
|
143
|
+
}
|
|
144
|
+
logNewline();
|
|
145
|
+
}
|
|
146
|
+
if (result.skipped.length > 0) {
|
|
147
|
+
console.log(colors.bold('Skipped (already exists):'));
|
|
148
|
+
for (const file of result.skipped) {
|
|
149
|
+
logWarning(`${file} - use --force to overwrite`);
|
|
150
|
+
}
|
|
151
|
+
logNewline();
|
|
152
|
+
}
|
|
153
|
+
console.log(colors.bold('Next steps:'));
|
|
154
|
+
logInfo('Edit browserflow.yaml with your project settings');
|
|
155
|
+
logInfo('Write specs in specs/ directory');
|
|
156
|
+
logInfo(`Run: ${colors.code('bf explore --spec <name>')}`);
|
|
157
|
+
});
|
|
158
|
+
return cmd;
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* bf lint command - validates spec files against v2 schema
|
|
3
|
+
* @see bf-eq4
|
|
4
|
+
*/
|
|
5
|
+
import { Command } from 'commander';
|
|
6
|
+
export interface LintError {
|
|
7
|
+
path: string;
|
|
8
|
+
message: string;
|
|
9
|
+
line: number;
|
|
10
|
+
value?: unknown;
|
|
11
|
+
}
|
|
12
|
+
export interface LintResult {
|
|
13
|
+
file: string;
|
|
14
|
+
errors: LintError[];
|
|
15
|
+
}
|
|
16
|
+
export interface LintOptions {
|
|
17
|
+
fix?: boolean;
|
|
18
|
+
cwd?: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Get line number for a path in YAML content
|
|
22
|
+
*/
|
|
23
|
+
export declare function getLineNumber(content: string, path: (string | number)[]): number;
|
|
24
|
+
/**
|
|
25
|
+
* Format lint error with actionable message
|
|
26
|
+
*/
|
|
27
|
+
export declare function formatLintError(error: LintError): LintError;
|
|
28
|
+
/**
|
|
29
|
+
* Lint a single spec file content
|
|
30
|
+
*/
|
|
31
|
+
export declare function lintSpec(content: string, filename: string): LintResult;
|
|
32
|
+
/**
|
|
33
|
+
* Lint multiple spec files
|
|
34
|
+
*/
|
|
35
|
+
export declare function lintFiles(files: string[], options?: LintOptions): Promise<LintResult[]>;
|
|
36
|
+
export declare function lintCommand(): Command;
|
|
37
|
+
//# sourceMappingURL=lint.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lint.d.ts","sourceRoot":"","sources":["../../src/commands/lint.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,GAAG,MAAM,CA4ChF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,CA2B3D;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,CAmDtE;AAED;;GAEG;AACH,wBAAsB,SAAS,CAC7B,KAAK,EAAE,MAAM,EAAE,EACf,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,UAAU,EAAE,CAAC,CA6CvB;AAqCD,wBAAgB,WAAW,IAAI,OAAO,CAkCrC"}
|