Setting the file. One moment. Bb Capture · Browser Trace · browserbase/skills · Skills DocsRaw file
scripts/bb-capture.mjs
JavaScript·95 lines·4 KB
{ spawnSync }
from
'node:child_process'
;
15import { fileURLToPath } from 'node:url';
16
17import { runDir, readJson, writeJson, runCmd } from './lib.mjs';
18
19const __dirname = path.dirname(fileURLToPath(import.meta.url));
20
21if (!process.env.BROWSERBASE_API_KEY) {
22 console.error('BROWSERBASE_API_KEY must be set');
23 process.exit(1);
24}
25
26const [target, runIdArg, intervalArg] = process.argv.slice(2);
27if (!target) {
28 console.error('usage: bb-capture.mjs --new|<session-id> [run-id] [interval-seconds]');
29 process.exit(2);
30}
31
32let sessionJson;
33if (target === '--new') {
34 const timeout = String(process.env.BB_SESSION_TIMEOUT || '600');
35 const r = runCmd('browse', ['cloud', 'sessions', 'create', '--keep-alive', '--timeout', timeout]);
36 if (!r.ok) { console.error(r.stderr || 'browse cloud sessions create failed'); process.exit(1); }
37 sessionJson = JSON.parse(r.stdout);
38 console.log(`Created Browserbase session: ${sessionJson.id}`);
39} else {
40 const r = runCmd('browse', ['cloud', 'sessions', 'get', target]);
41 if (!r.ok) { console.error(r.stderr || 'browse cloud sessions get failed'); process.exit(1); }
42 sessionJson = JSON.parse(r.stdout);
43 if (sessionJson.status !== 'RUNNING') {
44 console.error(`Session ${target} is not RUNNING (status=${sessionJson.status}). Recreate with --keep-alive.`);
45 process.exit(1);
46 }
47}
48
49const sessionId = sessionJson.id;
50const connectUrl = sessionJson.connectUrl;
51
52let debugJson = null;
53const dbg = runCmd('browse', ['cloud', 'sessions', 'debug', sessionId]);
54if (dbg.ok) {
55 try { debugJson = JSON.parse(dbg.stdout); } catch {}
56}
57
58// Hand off to start-capture.mjs as a child process so it owns its own
59// detached background processes (cdp + snapshot loop).
60const startScript = path.join(__dirname, 'start-capture.mjs');
61const startArgs = [startScript, connectUrl];
62if (runIdArg) startArgs.push(runIdArg);
63if (intervalArg) startArgs.push(intervalArg);
64
65const start = spawnSync(process.execPath, startArgs, { stdio: ['ignore', 'pipe', 'inherit'] });
66if (start.status !== 0) process.exit(start.status ?? 1);
67
68// start-capture writes a status block to stdout; surface it minus the noisy
69// signed connectUrl, then add the BB-specific lines.
70const lines = start.stdout.toString().split('\n').filter(l => l && !l.startsWith('target='));
71for (const l of lines) console.log(l);
72
73// Patch the manifest with Browserbase metadata so traversal queries can later
74// join CDP events back to platform info (region, debugger URL, project, etc.).
75const runId = (lines.find(l => l.startsWith('run_id=')) || '').slice('run_id='.length);
76if (!runId) { console.error('could not parse run_id from start-capture output'); process.exit(1); }
77
78const manifestPath = path.join(runDir(runId), 'manifest.json');
79const manifest = readJson(manifestPath, {});
80const debuggerUrl = debugJson?.debuggerFullscreenUrl ?? debugJson?.debuggerUrl ?? null;
81
82manifest.browserbase = {
83 session_id: sessionJson.id,
84 project_id: sessionJson.projectId,
85 region: sessionJson.region,
86 started_at: sessionJson.startedAt,
87 expires_at: sessionJson.expiresAt,
88 keep_alive: sessionJson.keepAlive,
89 debugger_url: debuggerUrl,
90};
91writeJson(manifestPath, manifest);
92
93if (debuggerUrl) console.log(`Live debugger: ${debuggerUrl}`);
94console.log(`session_id=${sessionId}`);
95console.log(`connect_url=${(connectUrl || '').slice(0, 60)}…`);