Setting the file. One moment.
Bb Finalize · Browser Trace · browserbase/skills · Skills Docs
ContentsBack to the top of the page (opens in a new tab)
scripts/ bb-finalize.mjs
JavaScript · 100 lines · 3 KB
;
14
15 import { runDir, readJson, ensureDir, runCmd } from './lib.mjs' ;
16
17 if ( ! process.env. BROWSERBASE_API_KEY ) {
18 console. error ( 'BROWSERBASE_API_KEY must be set' );
19 process. exit ( 1 );
20 }
21
22 const [ runId , ... rest ] = process.argv. slice ( 2 );
23 if ( ! runId) {
24 console. error ( 'usage: bb-finalize.mjs <run-id> [--release]' );
25 process. exit ( 2 );
26 }
27 const release = rest. includes ( '--release' );
28
29 const RD = runDir (runId);
30 const manifestPath = path. join ( RD , 'manifest.json' );
31 const manifest = readJson (manifestPath);
32 if ( ! manifest) {
33 console. error ( `manifest not found at ${ RD }` );
34 process. exit ( 1 );
35 }
36
37 const sessionId = manifest?.browserbase?.session_id;
38 if ( ! sessionId) {
39 console. error ( 'manifest has no .browserbase.session_id — was this run captured via bb-capture.mjs?' );
40 process. exit ( 1 );
41 }
42
43 const bbDir = path. join ( RD , 'browserbase' );
44 ensureDir (bbDir);
45
46 // Final session metadata — proxyBytes, status, ended_at all settle here.
47 {
48 const r = runCmd ( 'browse' , [ 'cloud' , 'sessions' , 'get' , sessionId]);
49 if (r.ok) {
50 fs. writeFileSync (path. join (bbDir, 'session.json' ), r.stdout);
51 console. log ( 'wrote session.json' );
52 } else {
53 console. error ( 'warn: browse cloud sessions get failed' );
54 }
55 }
56
57 // Server-side logs. Often empty — the firehose in cdp/raw.ndjson is the source of truth.
58 {
59 const r = runCmd ( 'browse' , [ 'cloud' , 'sessions' , 'logs' , sessionId]);
60 if (r.ok) {
61 fs. writeFileSync (path. join (bbDir, 'logs.json' ), r.stdout);
62 let n = '?' ;
63 try { n = String ( JSON . parse (r.stdout). length ?? '?' ); } catch {}
64 console. log ( `wrote logs.json (${ n } entries)` );
65 }
66 }
67
68 // Downloads. An empty session yields a 22-byte EOCD-only zip; any real
69 // content is always larger.
70 {
71 const out = path. join (bbDir, 'downloads.zip' );
72 const r = runCmd ( 'browse' , [ 'cloud' , 'sessions' , 'downloads' , 'get' , sessionId, '--output' , out]);
73 if (r.ok && fs. existsSync (out)) {
74 const size = fs. statSync (out).size;
75 if (size <= 22 ) {
76 fs. unlinkSync (out);
77 console. log ( 'no downloads' );
78 } else {
79 console. log ( `wrote downloads.zip (${ size } bytes)` );
80 }
81 } else if (fs. existsSync (out)) {
82 fs. unlinkSync (out);
83 }
84 }
85
86 if (release) {
87 const r = runCmd ( 'browse' , [ 'cloud' , 'sessions' , 'update' , sessionId, '--status' , 'REQUEST_RELEASE' ]);
88 if (r.ok) console. log ( `released session ${ sessionId }` );
89
90 // Re-snapshot session.json so it reflects the final COMPLETED state with
91 // settled proxyBytes and endedAt instead of the pre-release values.
92 const r2 = runCmd ( 'browse' , [ 'cloud' , 'sessions' , 'get' , sessionId]);
93 if (r2.ok) {
94 fs. writeFileSync (path. join (bbDir, 'session.json' ), r2.stdout);
95 console. log ( 'refreshed session.json (post-release)' );
96 }
97 }
98
99 console. log ( `finalized: ${ bbDir }` );
100 for ( const f of fs. readdirSync (bbDir)) console. log (f);