@browserbasehq/sdk-functions 0.0.1 → 0.0.2

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/dist/cli.js CHANGED
@@ -1,45 +1,53 @@
1
1
  #!/usr/bin/env node
2
- import d from 'chalk';
3
- import * as j from 'fs';
4
- import { existsSync, readdirSync, readFileSync } from 'fs';
5
- import * as O from 'path';
6
- import { join } from 'path';
2
+ import a from 'chalk';
3
+ import * as L from 'fs';
4
+ import { existsSync, mkdirSync, copyFileSync, readFileSync, writeFileSync, readdirSync } from 'fs';
5
+ import * as z from 'path';
6
+ import { dirname, resolve, join } from 'path';
7
7
  import 'dotenv/config';
8
- import Se from 'archiver';
8
+ import Ke from 'archiver';
9
9
  import { Command } from 'commander';
10
10
  import { createServer } from 'http';
11
11
  import { randomUUID } from 'crypto';
12
- import ge from '@browserbasehq/sdk';
13
- import b, { z } from 'zod';
14
- import { spawn } from 'child_process';
12
+ import xe from '@browserbasehq/sdk';
13
+ import I, { z as z$1 } from 'zod';
14
+ import { execSync, spawn } from 'child_process';
15
+ import { createRequire } from 'module';
16
+ import { fileURLToPath } from 'url';
15
17
 
16
- var H=Object.defineProperty;var ue=(o,e,n)=>e in o?H(o,e,{enumerable:true,configurable:true,writable:true,value:n}):o[e]=n;var B=(o,e)=>()=>(o&&(e=o(o=0)),e);var de=(o,e)=>{for(var n in e)H(o,n,{get:e[n],enumerable:true});};var l=(o,e,n)=>ue(o,typeof e!="symbol"?e+"":e,n);function Z(o){let e=process.env.BB_API_KEY;e||(console.error(d.red("Error: BB_API_KEY not found in environment variables.")),console.log(d.gray("Please set BB_API_KEY in your .env file or environment.")),process.exit(1));let n=process.env.BB_PROJECT_ID;n||(console.error(d.red("Error: BB_PROJECT_ID not found in environment variables.")),console.log(d.gray("Please set BB_PROJECT_ID in your .env file or environment.")),process.exit(1));let r=o.apiUrl||process.env.BB_API_URL||"https://api.browserbase.com",t=o.entrypoint||"main.ts",s=O.resolve(t);j.existsSync(s)||(console.error(d.red(`Error: Entrypoint file not found: ${s}`)),process.exit(1));let i=O.extname(t).toLowerCase();return [".ts",".js",".mjs",".mts"].includes(i)||(console.error(d.red(`Error: Invalid entrypoint extension: ${i}. Must be .ts, .js, .mjs, or .mts`)),process.exit(1)),{apiKey:e,projectId:n,apiUrl:r,entrypoint:t,workingDirectory:process.cwd()}}function Q(o){o.apiKey.startsWith("bb_")||console.warn(d.yellow("Warning: API key doesn't start with 'bb_'. Make sure you're using a valid Browserbase API key."));}var X=B(()=>{});function Re(o){let e=O.join(o,".gitignore"),n=["node_modules/**",".git/**",".env",".env.*","*.log",".DS_Store","dist/**","build/**","*.zip","*.tar","*.tar.gz",".vscode/**",".idea/**"];if(!j.existsSync(e))return n;try{let t=j.readFileSync(e,"utf-8").split(`
17
- `).map(s=>s.trim()).filter(s=>s&&!s.startsWith("#")).map(s=>s.endsWith("/")?`${s}**`:s);return [...n,...t]}catch(r){return console.warn(d.yellow(r,"Warning: Could not read .gitignore file, using defaults")),n}}async function ee(o,e){return new Promise((n,r)=>{console.log(d.cyan("Creating archive..."));let t=Se("tar",{gzip:true,gzipOptions:{level:9}}),s=[],i=0;t.on("data",a=>{s.push(a);}),t.on("entry",a=>{if(!a.stats?.isDirectory()&&(i++,e?.dryRun)){let u=O.relative(o,a.name);console.log(d.gray(` + ${u}`));}}),t.on("end",()=>{let a=Buffer.concat(s),u=(a.length/(1024*1024)).toFixed(2);console.log(d.green(`\u2713 Archive created: ${i} files, ${u} MB`)),n({buffer:a,size:a.length,fileCount:i});}),t.on("error",a=>{console.error(d.red(`Archive error: ${a.message}`)),r(a);}),t.on("warning",a=>{a.code==="ENOENT"?console.warn(d.yellow(`Warning: ${a.message}`)):r(a);});let c=Re(o);e?.dryRun&&(console.log(d.gray(`
18
- Ignoring patterns:`)),c.forEach(a=>{console.log(d.gray(` - ${a}`));}),console.log(d.gray(`
19
- Including files:`))),t.glob("**/*",{cwd:o,ignore:c,dot:true,follow:false}),t.finalize();})}function ne(o,e=50){let n=o/1048576;n>e&&(console.error(d.red(`Error: Archive size (${n.toFixed(2)} MB) exceeds maximum allowed size (${e} MB)`)),console.log(d.gray("Consider adding more patterns to .gitignore to reduce archive size")),process.exit(1));}var oe=B(()=>{});async function re(o,e,n){if(n?.dryRun)return console.log(d.cyan(`
20
- [Dry run] Would upload to:`)),console.log(d.gray(` URL: ${o.apiUrl}/v1/functions/builds`)),console.log(d.gray(` Project ID: ${o.projectId}`)),console.log(d.gray(` Entrypoint: ${o.entrypoint}`)),console.log(d.gray(` Archive size: ${(e.length/(1024*1024)).toFixed(2)} MB`)),{success:true,message:"Dry run completed successfully"};console.log(d.cyan(`
21
- Uploading build...`));try{let r=new FormData,t={entrypoint:o.entrypoint,projectId:o.projectId};r.append("metadata",JSON.stringify(t));let s=new Blob([e],{type:"application/gzip"});r.append("archive",s,"archive.tar.gz");let i=`${o.apiUrl}/v1/functions/builds`;console.log(d.gray(`Uploading to: ${i}`));let c=await fetch(i,{method:"POST",headers:{"x-bb-api-key":o.apiKey},body:r});if(!c.ok){let u=`HTTP ${c.status}: ${c.statusText}`;try{let p=await c.json();if(typeof p=="object"&&p!==null&&("message"in p||"error"in p)){let f=p;u=f.message||f.error||u;}}catch{try{let p=await c.text();p&&(u=p);}catch{}}return console.error(d.red(`Upload failed: ${u}`)),{success:!1,message:u}}let a={};try{let u=await c.json();typeof u=="object"&&u!==null&&(a=u);}catch{}return a.id?(console.log(d.green("\u2713 Build uploaded successfully")),console.log(d.gray(`Build ID: ${a.id}`)),{success:!0,buildId:a.id,message:"Build uploaded successfully"}):(console.error(d.red("Upload failed: No build ID received in response")),{success:!1,message:"No build ID received in response"})}catch(r){let t=r instanceof Error?r.message:"Unknown error occurred";return console.error(d.red(`Upload error: ${t}`)),r&&typeof r=="object"&&"code"in r&&r.code==="ECONNREFUSED"&&console.log(d.yellow(`
22
- Cannot connect to ${o.apiUrl}. Make sure the API server is running.`)),{success:false,message:t}}}async function xe(o,e){try{let n=`${o.apiUrl}/v1/functions/builds/${e}`,r=await fetch(n,{method:"GET",headers:{"x-bb-api-key":o.apiKey}});return r.ok?await r.json():(console.error(d.red(`Failed to get build status: HTTP ${r.status}`)),null)}catch(n){return console.error(d.red(`Error fetching build status: ${n instanceof Error?n.message:"Unknown error"}`)),null}}async function te(o,e,n){let r=2e3,t=60;console.log(d.cyan(`
23
- Waiting for build to complete...`));for(let s=0;s<t;s++){let i=await xe(o,e);if(!i)return console.error(d.red("Failed to get build status")),null;if(process.stdout.write(`\r${d.gray(`Status: ${i.status}... (${s+1}/${t})`)}`),i.status!=="RUNNING")return process.stdout.write("\r"+" ".repeat(50)+"\r"),i.status==="COMPLETED"?console.log(d.green("\u2713 Build completed successfully")):i.status==="FAILED"&&console.error(d.red("\u2717 Build failed")),i;await new Promise(c=>setTimeout(c,r));}return process.stdout.write("\r"+" ".repeat(50)+"\r"),console.error(d.yellow("Build is still running after maximum wait time")),null}var se=B(()=>{});var ie={};de(ie,{publishFunction:()=>Ce});async function Ce(o){console.log(d.bold.cyan(`
18
+ var Z=Object.defineProperty;var Ie=(o,e,n)=>e in o?Z(o,e,{enumerable:true,configurable:true,writable:true,value:n}):o[e]=n;var j=(o,e)=>()=>(o&&(e=o(o=0)),e);var Se=(o,e)=>{for(var n in e)Z(o,n,{get:e[n],enumerable:true});};var p=(o,e,n)=>Ie(o,typeof e!="symbol"?e+"":e,n);function ae(o){let e=process.env.BB_API_KEY;e||(console.error(a.red("Error: BB_API_KEY not found in environment variables.")),console.log(a.gray("Please set BB_API_KEY in your .env file or environment.")),process.exit(1));let n=process.env.BB_PROJECT_ID;n||(console.error(a.red("Error: BB_PROJECT_ID not found in environment variables.")),console.log(a.gray("Please set BB_PROJECT_ID in your .env file or environment.")),process.exit(1));let r=o.apiUrl||process.env.BB_API_URL||"https://api.browserbase.com",t=o.entrypoint||"main.ts",i=z.resolve(t);L.existsSync(i)||(console.error(a.red(`Error: Entrypoint file not found: ${i}`)),process.exit(1));let s=z.extname(t).toLowerCase();return [".ts",".js",".mjs",".mts"].includes(s)||(console.error(a.red(`Error: Invalid entrypoint extension: ${s}. Must be .ts, .js, .mjs, or .mts`)),process.exit(1)),{apiKey:e,projectId:n,apiUrl:r,entrypoint:t,workingDirectory:process.cwd()}}function ce(o){o.apiKey.startsWith("bb_")||console.warn(a.yellow("Warning: API key doesn't start with 'bb_'. Make sure you're using a valid Browserbase API key."));}var le=j(()=>{});function Ge(o){let e=z.join(o,".gitignore"),n=["node_modules/**",".git/**",".env",".env.*","*.log",".DS_Store","dist/**","build/**","*.zip","*.tar","*.tar.gz",".vscode/**",".idea/**"];if(!L.existsSync(e))return n;try{let t=L.readFileSync(e,"utf-8").split(`
19
+ `).map(i=>i.trim()).filter(i=>i&&!i.startsWith("#")).map(i=>i.endsWith("/")?`${i}**`:i);return [...n,...t]}catch(r){return console.warn(a.yellow(r,"Warning: Could not read .gitignore file, using defaults")),n}}async function de(o,e){return new Promise((n,r)=>{console.log(a.cyan("Creating archive..."));let t=Ke("tar",{gzip:true,gzipOptions:{level:9}}),i=[],s=0;t.on("data",c=>{i.push(c);}),t.on("entry",c=>{if(!c.stats?.isDirectory()&&(s++,e?.dryRun)){let u=z.relative(o,c.name);console.log(a.gray(` + ${u}`));}}),t.on("end",()=>{let c=Buffer.concat(i),u=(c.length/(1024*1024)).toFixed(2);console.log(a.green(`\u2713 Archive created: ${s} files, ${u} MB`)),n({buffer:c,size:c.length,fileCount:s});}),t.on("error",c=>{console.error(a.red(`Archive error: ${c.message}`)),r(c);}),t.on("warning",c=>{c.code==="ENOENT"?console.warn(a.yellow(`Warning: ${c.message}`)):r(c);});let d=Ge(o);e?.dryRun&&(console.log(a.gray(`
20
+ Ignoring patterns:`)),d.forEach(c=>{console.log(a.gray(` - ${c}`));}),console.log(a.gray(`
21
+ Including files:`))),t.glob("**/*",{cwd:o,ignore:d,dot:true,follow:false}),t.finalize();})}function pe(o,e=50){let n=o/1048576;n>e&&(console.error(a.red(`Error: Archive size (${n.toFixed(2)} MB) exceeds maximum allowed size (${e} MB)`)),console.log(a.gray("Consider adding more patterns to .gitignore to reduce archive size")),process.exit(1));}var ue=j(()=>{});async function ge(o,e,n){if(n?.dryRun)return console.log(a.cyan(`
22
+ [Dry run] Would upload to:`)),console.log(a.gray(` URL: ${o.apiUrl}/v1/functions/builds`)),console.log(a.gray(` Project ID: ${o.projectId}`)),console.log(a.gray(` Entrypoint: ${o.entrypoint}`)),console.log(a.gray(` Archive size: ${(e.length/(1024*1024)).toFixed(2)} MB`)),{success:true,message:"Dry run completed successfully"};console.log(a.cyan(`
23
+ Uploading build...`));try{let r=new FormData,t={entrypoint:o.entrypoint,projectId:o.projectId};r.append("metadata",JSON.stringify(t));let i=new Blob([e],{type:"application/gzip"});r.append("archive",i,"archive.tar.gz");let s=`${o.apiUrl}/v1/functions/builds`;console.log(a.gray(`Uploading to: ${s}`));let d=await fetch(s,{method:"POST",headers:{"x-bb-api-key":o.apiKey},body:r});if(!d.ok){let u=`HTTP ${d.status}: ${d.statusText}`;try{let m=await d.json();if(typeof m=="object"&&m!==null&&("message"in m||"error"in m)){let h=m;u=h.message||h.error||u;}}catch{try{let m=await d.text();m&&(u=m);}catch{}}return console.error(a.red(`Upload failed: ${u}`)),{success:!1,message:u}}let c={};try{let u=await d.json();typeof u=="object"&&u!==null&&(c=u);}catch{}return c.id?(console.log(a.green("\u2713 Build uploaded successfully")),console.log(a.gray(`Build ID: ${c.id}`)),{success:!0,buildId:c.id,message:"Build uploaded successfully"}):(console.error(a.red("Upload failed: No build ID received in response")),{success:!1,message:"No build ID received in response"})}catch(r){let t=r instanceof Error?r.message:"Unknown error occurred";return console.error(a.red(`Upload error: ${t}`)),r&&typeof r=="object"&&"code"in r&&r.code==="ECONNREFUSED"&&console.log(a.yellow(`
24
+ Cannot connect to ${o.apiUrl}. Make sure the API server is running.`)),{success:false,message:t}}}async function Ye(o,e){try{let n=`${o.apiUrl}/v1/functions/builds/${e}`,r=await fetch(n,{method:"GET",headers:{"x-bb-api-key":o.apiKey}});return r.ok?await r.json():(console.error(a.red(`Failed to get build status: HTTP ${r.status}`)),null)}catch(n){return console.error(a.red(`Error fetching build status: ${n instanceof Error?n.message:"Unknown error"}`)),null}}async function me(o,e,n){let r=2e3,t=100;console.log(a.cyan(`
25
+ Waiting for build to complete...`)),console.log(a.gray("(Builds typically take around 1 minute to complete)"));for(let i=0;i<t;i++){let s=await Ye(o,e);if(!s)return console.error(a.red("Failed to get build status")),null;if(process.stdout.write(`\r${a.gray(`Status: ${s.status}... (polling ${i+1}/${t})`)}`),s.status!=="RUNNING")return process.stdout.write("\r"+" ".repeat(60)+"\r"),s.status==="COMPLETED"?console.log(a.green("\u2713 Build completed successfully")):s.status==="FAILED"&&console.error(a.red("\u2717 Build failed")),s;await new Promise(d=>setTimeout(d,r));}return process.stdout.write("\r"+" ".repeat(60)+"\r"),console.error(a.yellow("Build is still running after maximum wait time (~3 minutes)")),console.error(a.yellow("Please check the dashboard for the current build status.")),null}var fe=j(()=>{});var ye={};Se(ye,{publishFunction:()=>Ze});function he(o){if(console.log(a.bold.cyan(`
26
+ \u{1F4E6} Build Details`)),console.log(a.gray("\u2500".repeat(50))),console.log(a.white(`Build ID: ${a.cyan(o.id)}`)),console.log(a.white(`Project ID: ${a.cyan(o.projectId)}`)),console.log(a.white(`Status: ${a.green(o.status)}`)),o.request?.entrypoint&&console.log(a.white(`Entrypoint: ${a.cyan(o.request.entrypoint)}`)),o.startedAt&&console.log(a.white(`Started: ${a.gray(new Date(o.startedAt).toLocaleString())}`)),o.endedAt&&(console.log(a.white(`Completed: ${a.gray(new Date(o.endedAt).toLocaleString())}`)),o.startedAt)){let e=new Date(o.endedAt).getTime()-new Date(o.startedAt).getTime(),n=Math.floor(e/1e3);console.log(a.white(`Duration: ${a.cyan(`${n} seconds`)}`));}o.expiresAt&&console.log(a.white(`Expires: ${a.gray(new Date(o.expiresAt).toLocaleString())}`)),o.builtFunctions&&o.builtFunctions.length>0?(console.log(a.bold.cyan(`
27
+ \u{1F680} Built Functions`)),console.log(a.gray("\u2500".repeat(50))),o.builtFunctions.forEach((e,n)=>{if(console.log(a.bold.white(`
28
+ ${n+1}. ${e.name}`)),console.log(a.white(` Function ID: ${a.cyan(e.id)}`)),e.createdVersion&&(console.log(a.white(` Version ID: ${a.cyan(e.createdVersion.id)}`)),e.createdVersion.sessionCreateParams)){let r=e.createdVersion.sessionCreateParams;Object.keys(r).length>0&&(console.log(a.white(" Browser Settings:")),Object.entries(r).forEach(([i,s])=>{console.log(a.gray(` - ${i}: ${JSON.stringify(s)}`));}));}}),console.log(a.bold.cyan(`
29
+ \u2728 Next Steps`)),console.log(a.gray("\u2500".repeat(50))),console.log(a.white("Your functions are ready to be invoked! Invoke using cURL:")),o.builtFunctions.forEach(e=>{console.log(a.gray(`
30
+ curl --request POST \\`)),console.log(a.gray(` --url ${e.projectId?"https":"http"}://api.browserbase.com/v1/functions/${e.id}/invoke \\`)),console.log(a.gray(" --header 'Content-Type: application/json' \\")),console.log(a.gray(" --header 'x-bb-api-key: YOUR_API_KEY' \\")),console.log(a.gray(` --data '{"params": {}}'`));})):console.log(a.yellow(`
31
+ No functions were built. Please check your entrypoint and function exports.`));}async function Ze(o){console.log(a.bold.cyan(`
24
32
  Browserbase Functions - Publish
25
- `));try{let e={};o.entrypoint!==void 0&&(e.entrypoint=o.entrypoint),o.apiUrl!==void 0&&(e.apiUrl=o.apiUrl);let n=Z(e);Q(n),console.log(d.gray(`Working directory: ${n.workingDirectory}`)),console.log(d.gray(`Entrypoint: ${n.entrypoint}`)),console.log(d.gray(`API URL: ${n.apiUrl}`)),console.log(d.gray(`Project ID: ${n.projectId}`)),o.dryRun&&console.log(d.yellow(`
33
+ `));try{let e={};o.entrypoint!==void 0&&(e.entrypoint=o.entrypoint),o.apiUrl!==void 0&&(e.apiUrl=o.apiUrl);let n=ae(e);ce(n),console.log(a.gray(`Working directory: ${n.workingDirectory}`)),console.log(a.gray(`Entrypoint: ${n.entrypoint}`)),console.log(a.gray(`API URL: ${n.apiUrl}`)),console.log(a.gray(`Project ID: ${n.projectId}`)),o.dryRun&&console.log(a.yellow(`
26
34
  [Dry run mode - no files will be uploaded]
27
- `));let r={};o.dryRun!==void 0&&(r.dryRun=o.dryRun);let t=await ee(n.workingDirectory,r);ne(t.size);let s={};o.dryRun!==void 0&&(s.dryRun=o.dryRun);let i=await re(n,t.buffer,s);if(i.success||(console.error(d.red(`
28
- \u2717 Publish failed`)),process.exit(1)),o.dryRun)console.log(d.bold.green(`
29
- \u2713 Dry run completed successfully!`)),console.log(d.cyan(`
30
- Your function would have been published. Run without --dry-run to publish.`));else if(console.log(d.bold.green(`
31
- \u2713 Function uploaded successfully!`)),i.buildId){console.log(d.gray(`
32
- Build ID: ${i.buildId}`));let c=await te(n,i.buildId);c?.status==="COMPLETED"?console.log(d.bold.green(`
33
- \u{1F389} Your function has been deployed and is ready for invocation!`)):c?.status==="FAILED"?(console.error(d.red(`
34
- \u2717 Build failed during processing`)),process.exit(1)):console.log(d.yellow(`
35
- Build status could not be determined. Check the dashboard for updates.`));}else console.log(d.cyan(`
36
- Your function will be available for invocation once the build is processed.`));}catch(e){console.error(d.red(`
37
- \u2717 Publish failed: ${e.message??"unknown error"}`)),process.exit(1);}}var ae=B(()=>{X();oe();se();});var k=class{constructor(e=false){l(this,"nextConnection",null);l(this,"invokeConnection",null);l(this,"currentRequestId",null);l(this,"currentFunctionName",null);l(this,"currentSessionId",null);l(this,"sessionCleanupCallback",null);l(this,"verbose");l(this,"runtimeConnectedOnce",false);this.verbose=e;}setSessionCleanupCallback(e){this.sessionCleanupCallback=e;}holdNextConnection(e){this.nextConnection&&(this.nextConnection.response.writeHead(503,{"Content-Type":"application/json"}),this.nextConnection.response.end(JSON.stringify({error:"Another runtime connected"}))),this.nextConnection={response:e,timestamp:Date.now()},this.runtimeConnectedOnce=true,this.verbose&&console.log(d.cyan("\u{1F50C} Function runtime connected, ready for invocations"));}triggerInvocation(e,n,r,t){if(!this.nextConnection)return this.verbose&&console.log(d.yellow("\u26A0\uFE0F No runtime connected to handle invocation")),false;if(this.invokeConnection)return this.verbose&&console.log(d.yellow("\u26A0\uFE0F Another invocation is already in progress")),false;let s=randomUUID();this.currentRequestId=s,this.currentFunctionName=e,this.currentSessionId=r.session.id,this.invokeConnection={response:t,timestamp:Date.now()};let i={functionName:e,params:n,context:r};return this.nextConnection.response.writeHead(200,{"Content-Type":"application/json","Lambda-Runtime-Aws-Request-Id":s,"Lambda-Runtime-Deadline-Ms":String(Date.now()+3e5),"Lambda-Runtime-Invoked-Function-Arn":`arn:aws:lambda:us-east-1:000000000000:function:${e}`}),this.nextConnection.response.end(JSON.stringify(i)),this.nextConnection=null,console.log(d.blue(`\u{1F680} Invoking function '${e}' (request-id: ${s})`)),true}completeWithSuccess(e,n){return e!==this.currentRequestId?(this.verbose&&console.log(d.yellow(`\u26A0\uFE0F Request ID mismatch: expected ${this.currentRequestId}, got ${e}`)),false):this.invokeConnection?(this.invokeConnection.response.writeHead(200,{"Content-Type":"application/json"}),this.invokeConnection.response.end(JSON.stringify(n??{})),console.log(d.green(`\u2713 Function '${this.currentFunctionName}' completed successfully`)),this.sessionCleanupCallback&&this.currentSessionId&&this.sessionCleanupCallback(this.currentSessionId).catch(r=>{console.error(d.red("Failed to cleanup session:"),r);}),this.invokeConnection=null,this.currentRequestId=null,this.currentFunctionName=null,this.currentSessionId=null,true):(this.verbose&&console.log(d.yellow("\u26A0\uFE0F No active invocation to complete")),false)}completeWithError(e,n){return e!==this.currentRequestId?(this.verbose&&console.log(d.yellow(`\u26A0\uFE0F Request ID mismatch: expected ${this.currentRequestId}, got ${e}`)),false):this.invokeConnection?(this.invokeConnection.response.writeHead(500,{"Content-Type":"application/json"}),this.invokeConnection.response.end(JSON.stringify({error:{message:n.errorMessage,type:n.errorType,stackTrace:n.stackTrace}})),console.log(d.red(`\u2717 Function '${this.currentFunctionName}' failed: ${n.errorMessage}`)),this.sessionCleanupCallback&&this.currentSessionId&&this.sessionCleanupCallback(this.currentSessionId).catch(r=>{console.error(d.red("Failed to cleanup session:"),r);}),this.invokeConnection=null,this.currentRequestId=null,this.currentFunctionName=null,this.currentSessionId=null,true):(this.verbose&&console.log(d.yellow("\u26A0\uFE0F No active invocation to complete")),false)}isReady(){return this.nextConnection!==null&&this.invokeConnection===null}hasActiveInvocation(){return this.invokeConnection!==null}getCurrentRequestId(){return this.currentRequestId}isRuntimeConnected(){return this.runtimeConnectedOnce&&this.nextConnection!==null}};var M=class{constructor(){l(this,"browserbaseClient",null);l(this,"projectId");l(this,"apiKey");l(this,"initialized",false);let e=process.env.BB_PROJECT_ID,n=process.env.BB_API_KEY;if(!e||!n)throw console.error(d.red(`\u2717 Browserbase credentials not found.
38
- `)+d.red(` Please set BB_PROJECT_ID and BB_API_KEY in your .env file.
39
- `)+d.gray(" Copy .env.example to .env and fill in your credentials.")),new Error("Missing Browserbase credentials");this.projectId=e,this.apiKey=n;}async initialize(){this.initialized||(this.browserbaseClient=new ge({apiKey:this.apiKey}),this.initialized=true,console.log(d.green("\u2713 Browserbase client initialized")));}async createSession(e){if(!this.browserbaseClient)throw new Error("Browser manager not initialized");console.log(d.cyan("Creating browser session..."));let n=await this.browserbaseClient.sessions.create({projectId:this.projectId,...e}),r={id:n.id,connectUrl:n.connectUrl};return console.log(d.green(`\u2713 Browser session created: ${r.id}`)),r}async closeSession(e){if(!this.browserbaseClient)throw new Error("Browser manager not initialized");try{console.log(d.cyan(`Closing browser session: ${e}...`)),await this.browserbaseClient.sessions.update(e,{projectId:this.projectId,status:"REQUEST_RELEASE"}),console.log(d.green(`\u2713 Browser session closed: ${e}`));}catch(n){console.warn(d.yellow(`\u26A0\uFE0F Could not close session ${e}:`),n instanceof Error?n.message:String(n));}}getProjectId(){return this.projectId}isInitialized(){return this.initialized}};var N=class{constructor(e){l(this,"manifests",new Map);l(this,"manifestsPath");this.manifestsPath=e||join(process.cwd(),".browserbase","functions","manifests");}loadManifests(){if(!existsSync(this.manifestsPath)){console.log(d.yellow(`\u26A0\uFE0F No ${this.manifestsPath} directory found`)),console.log(d.gray(" Run your entrypoint file first to generate manifests"));return}try{let n=readdirSync(this.manifestsPath).filter(r=>r.endsWith(".json"));for(let r of n){let t=join(this.manifestsPath,r),s=readFileSync(t,"utf-8"),i=JSON.parse(s);this.manifests.set(i.name,i),console.log(d.gray(` Loaded manifest for function: ${i.name}`));}this.manifests.size>0?console.log(d.green(`\u2713 Loaded ${this.manifests.size} function manifest(s)`)):console.log(d.yellow("\u26A0\uFE0F No function manifests found in .browserbase directory"));}catch(e){console.error(d.red("Failed to load function manifests:"),e);}}getManifest(e){return this.manifests.get(e)}getSize(){return this.manifests.size}hasManifest(e){return this.manifests.has(e)}getManifestNames(){return Array.from(this.manifests.keys())}};var $={async parseJsonBody(o){return new Promise((e,n)=>{let r="";o.on("data",t=>{r+=t.toString();}),o.on("end",()=>{try{let t=r?JSON.parse(r):{};e(t);}catch(t){n(new Error("Invalid JSON body",{cause:t}));}}),o.on("error",n);})},async parseAndValidate(o,e){let n=await this.parseJsonBody(o);return e.parse(n)}};var h={sendJson(o,e,n){o.writeHead(e,{"Content-Type":"application/json"}),o.end(JSON.stringify(n));},sendSuccess(o,e,n=200){let r={status:"success",...e!==void 0&&{data:e}};this.sendJson(o,n,r);},sendError(o,e,n=500,r,t){let s={error:e};r&&(s.message=r),t&&(s.details=t),this.sendJson(o,n,s);},sendBadRequest(o,e,n){this.sendError(o,"Bad Request",400,e,n);},sendNotFound(o,e){this.sendError(o,"Not Found",404,e);},sendInternalError(o,e="An internal error occurred",n){this.sendError(o,"Internal Server Error",500,e,n);},sendServiceUnavailable(o,e){this.sendError(o,"Service Unavailable",503,e);},sendAccepted(o,e){let n=e||{status:"accepted"};this.sendJson(o,202,n);}};var ve=b.object({id:b.string(),connectUrl:b.string()}),F=b.object({session:ve});var ye=b.object({functionName:b.string().min(1),params:b.looseObject({}),context:F});b.object({requestId:b.string().min(1),event:ye});var W=b.object({errorMessage:b.string().min(1),errorType:b.string().min(1),stackTrace:b.array(b.string().min(1))});var A=class{constructor(e){l(this,"bridge");l(this,"browserManager");l(this,"manifestStore");this.bridge=e.bridge,this.browserManager=e.browserManager,this.manifestStore=e.manifestStore,this.bridge.setSessionCleanupCallback(async n=>{await this.cleanupSession(n);});}async handleInvocationNext(e,n){this.bridge.holdNextConnection(n);}async handleFunctionInvoke(e,n,r){try{let t=z.object({functionName:z.string().optional(),params:z.unknown().default({}),context:F.optional()}),s=await $.parseAndValidate(e,t),i=r||s.functionName;if(!i){h.sendBadRequest(n,"Function name is required");return}let c=this.manifestStore.getManifest(i);if(!c){console.error(d.red(`\u2717 Function "${i}" not found in registry`)),console.error(d.gray(" Make sure the function is defined in your entrypoint file")),h.sendNotFound(n,`Function "${i}" not found in registry. Make sure it is defined with defineFn() in your entrypoint file.`);return}let a;try{console.log(d.cyan(`Creating browser session for ${i}...`));let f=c?.config?.sessionConfig||{};a=await this.browserManager.createSession(f);}catch(f){console.error(d.red("Failed to create browser session:"),f),h.sendInternalError(n,"Failed to create browser session",f instanceof Error?f.message:String(f));return}let u=s.context||{invocation:{id:crypto.randomUUID(),region:"local"},session:a};if(u.session=a,!this.bridge.triggerInvocation(i,s.params,u,n)){await this.cleanupSession(a.id),h.sendServiceUnavailable(n,this.bridge.hasActiveInvocation()?"Another invocation is in progress":"No runtime connected");return}}catch(t){t instanceof z.ZodError?h.sendBadRequest(n,"Invalid request body",t):(console.error(d.red("Error handling invoke:"),t),h.sendInternalError(n));}}async handleInvocationResponse(e,n,r){try{let t=await $.parseJsonBody(e);if(!this.bridge.completeWithSuccess(r,t)){h.sendBadRequest(n,"No matching invocation or request ID mismatch");return}h.sendAccepted(n);}catch(t){console.error(d.red("Error handling response:"),t),h.sendInternalError(n);}}async handleInvocationError(e,n,r){try{let t=await $.parseAndValidate(e,W);if(!this.bridge.completeWithError(r,t)){h.sendBadRequest(n,"No matching invocation or request ID mismatch");return}h.sendAccepted(n);}catch(t){t instanceof z.ZodError?h.sendBadRequest(n,"Invalid error format",t):(console.error(d.red("Error handling error report:"),t),h.sendInternalError(n));}}async cleanupSession(e){try{await this.browserManager.closeSession(e);}catch(n){console.error(d.red(`Failed to cleanup session ${e}:`),n);}}};async function we(o,e,n){let{handlers:r}=n,t=new URL(o.url||"",`http://${o.headers.host}`),s=o.method||"GET",i=t.pathname;if(console.log(d.gray(`[${s}] ${i}`)),e.setHeader("Access-Control-Allow-Origin","*"),e.setHeader("Access-Control-Allow-Methods","GET, POST, OPTIONS"),e.setHeader("Access-Control-Allow-Headers","Content-Type"),s==="OPTIONS"){e.writeHead(200),e.end();return}try{if(s==="GET"&&i==="/"){e.writeHead(200,{"Content-Type":"application/json"}),e.end(JSON.stringify({ok:!0}));return}if(s==="GET"&&i==="/2018-06-01/runtime/invocation/next"){await r.handleInvocationNext(o,e);return}let c=i.match(/^\/v1\/functions\/([^/]+)\/invoke$/);if(s==="POST"&&c&&c[1]){let p=c[1];await r.handleFunctionInvoke(o,e,p);return}let a=i.match(/^\/2018-06-01\/runtime\/invocation\/([^/]+)\/response$/);if(s==="POST"&&a&&a[1]){let p=a[1];await r.handleInvocationResponse(o,e,p);return}let u=i.match(/^\/2018-06-01\/runtime\/invocation\/([^/]+)\/error$/);if(s==="POST"&&u&&u[1]){let p=u[1];await r.handleInvocationError(o,e,p);return}e.writeHead(404,{"Content-Type":"application/json"}),e.end(JSON.stringify({error:"Not found"}));}catch(c){console.error(d.red("Server error:"),c),e.writeHead(500,{"Content-Type":"application/json"}),e.end(JSON.stringify({error:"Internal server error"}));}}async function G(o){let{port:e,host:n,handlers:s}=o,i=createServer(async(c,a)=>{await we(c,a,{handlers:s});});return new Promise((c,a)=>{i.listen(e,n,()=>{c(i);}),i.on("error",u=>{u.code==="EADDRINUSE"?a(new Error(`Port ${e} is already in use`)):u.code==="EACCES"?a(new Error(`Permission denied to bind to port ${e}`)):a(u);});})}var D=class{constructor(e){l(this,"process",null);l(this,"entrypoint");l(this,"runtimeApiUrl");l(this,"verbose");l(this,"isShuttingDown",false);this.entrypoint=e.entrypoint,this.runtimeApiUrl=e.runtimeApiUrl,this.verbose=e.verbose;}async start(){if(this.process)throw new Error("Process is already running");if(this.verbose&&(console.log(d.gray("Starting runtime process...")),console.log(d.gray(` Command: tsx watch --clear-screen=false ${this.entrypoint}`)),console.log(d.gray(` Working directory: ${process.cwd()}`)),console.log(d.gray(` Runtime API: ${this.runtimeApiUrl}`))),this.process=spawn("tsx",["watch","--clear-screen=false",this.entrypoint],{cwd:process.cwd(),env:{...process.env,AWS_LAMBDA_RUNTIME_API:this.runtimeApiUrl,BB_FUNCTIONS_PHASE:"runtime",NODE_ENV:"local"},stdio:["ignore","pipe","pipe"]}),this.process.stdout?.on("data",e=>{e.toString().trim().split(`
40
- `).forEach(r=>{r.trim()&&console.log(d.blue("[Runtime]"),r);});}),this.process.stderr?.on("data",e=>{e.toString().trim().split(`
41
- `).forEach(r=>{r.trim()&&(r.includes("Watching for file changes")?console.log(d.green("\u2713 Runtime watching for file changes")):r.includes("Restarting")?console.log(d.yellow("\u21BB Runtime restarting due to file change...")):console.error(d.red("[Runtime Error]"),r));});}),this.process.on("exit",(e,n)=>{this.isShuttingDown||(e!==0?(console.error(d.red(`\u2717 Runtime process exited unexpectedly with code ${e}`)),n&&console.error(d.red(` Signal: ${n}`))):console.log(d.gray("Runtime process exited")),this.process=null);}),this.process.on("error",e=>{e.code==="ENOENT"?console.error(d.red("\u2717 Failed to start runtime: tsx not found"),d.yellow(`
42
- Make sure tsx is installed: npm install -g tsx or pnpm add tsx`)):console.error(d.red("\u2717 Failed to start runtime process:"),e),this.process=null;}),await new Promise(e=>setTimeout(e,100)),!this.process||this.process.exitCode!==null)throw new Error("Failed to start runtime process");console.log(d.green("\u2713 Runtime process started"));}async stop(){if(this.process)return this.isShuttingDown=true,this.verbose&&console.log(d.gray("Stopping runtime process...")),new Promise(e=>{if(!this.process){e();return}let n=setTimeout(()=>{this.process&&(console.log(d.yellow("\u26A0\uFE0F Force killing runtime process")),this.process.kill("SIGKILL"));},5e3);this.process.on("exit",()=>{clearTimeout(n),this.process=null,console.log(d.green("\u2713 Runtime process stopped")),e();}),this.process.kill("SIGTERM");})}isRunning(){return this.process!==null&&this.process.exitCode===null}};async function V(o){let{entrypoint:e,port:n,host:r,verbose:t}=o;process.env.NODE_ENV==="production"&&console.warn(d.yellow("\u26A0\uFE0F Warning: Running dev server in production mode. This is not recommended."));let s=`${r}:${n}`;t&&console.log(d.gray(`Runtime API URL: ${s}`));let i=new k(t),c=new M;await c.initialize();let a=new N;a.loadManifests();let u=new A({bridge:i,browserManager:c,manifestStore:a}),p=new D({entrypoint:e,runtimeApiUrl:s,verbose:t}),f=null;try{f=await G({port:n,host:r,bridge:i,browserManager:c,handlers:u}),console.log(d.green(`\u2713 Development server listening on http://${r}:${n}`)),console.log(d.cyan("Starting runtime process...")),await p.start();let E=1e4,ce=200,le=Date.now(),_=!1;for(;Date.now()-le<E;){if(i.isRuntimeConnected()){_=!0,console.log(d.green("\u2713 Runtime connected and ready")),a.loadManifests();break}await new Promise(z=>setTimeout(z,ce));}_||(console.log(d.yellow("\u26A0\uFE0F Runtime is taking longer than expected to connect...")),a.loadManifests());let J=async()=>(console.log(d.cyan(`
43
- \u{1F4E6} Shutting down...`)),await p.stop(),new Promise(z=>{f?.close(()=>{console.log(d.green("\u2713 Server closed")),z();});}));process.on("SIGINT",async()=>{await J(),process.exit(0);}),process.on("SIGTERM",async()=>{await J(),process.exit(0);});}catch(E){throw console.error(d.red("Failed to start:"),E),p.isRunning()&&await p.stop(),f&&f.close(),E}}var q=new Command;q.name("bb").description("Browserbase Functions CLI").version("0.0.1");q.command("dev").description("Start a local development server for testing Browserbase Functions").argument("<entrypoint>","Path to the TypeScript/JavaScript file that imports all your functions").option("-p, --port <number>","Port to listen on","14113").option("-h, --host <string>","Host to bind to","127.0.0.1").action(async(o,e)=>{try{let n=await import('fs'),r=await import('path'),t=r.resolve(o);n.existsSync(t)||(console.error(d.red(`Error: Entrypoint file not found: ${t}`)),process.exit(1));let s=r.extname(t);[".ts",".tsx",".js",".jsx",".mjs",".cjs"].includes(s)||(console.error(d.red("Error: Invalid file extension. Expected .ts, .tsx, .js, .jsx, .mjs, or .cjs")),process.exit(1));let i=parseInt(e.port,10);(isNaN(i)||i<1||i>65535)&&(console.error(d.red("Error: Invalid port number. Must be between 1 and 65535.")),process.exit(1)),console.log(d.cyan("Starting Browserbase Functions development server...")),console.log(d.gray(`Entrypoint: ${t}`)),await V({entrypoint:t,port:i,host:e.host,verbose:e.verbose});}catch(n){console.error(d.red("Failed to start development server:"),n),process.exit(1);}});q.command("publish").description("Publish your Browserbase Function to the cloud").argument("<entrypoint>","Path to the TypeScript/JavaScript file that imports all your functions").option("-u, --api-url <url>","API endpoint URL").option("--dry-run","Show what would be published without uploading").action(async(o,e)=>{try{let{publishFunction:n}=await Promise.resolve().then(()=>(ae(),ie));await n({entrypoint:o,apiUrl:e.apiUrl,dryRun:e.dryRun});}catch(n){console.error(d.red("Publish failed:"),n),process.exit(1);}});q.parse();
35
+ `));let r={};o.dryRun!==void 0&&(r.dryRun=o.dryRun);let t=await de(n.workingDirectory,r);pe(t.size);let i={};o.dryRun!==void 0&&(i.dryRun=o.dryRun);let s=await ge(n,t.buffer,i);if(s.success||(console.error(a.red(`
36
+ \u2717 Publish failed`)),process.exit(1)),o.dryRun)console.log(a.bold.green(`
37
+ \u2713 Dry run completed successfully!`)),console.log(a.cyan(`
38
+ Your function would have been published. Run without --dry-run to publish.`));else if(console.log(a.bold.green(`
39
+ \u2713 Function uploaded successfully!`)),s.buildId){console.log(a.gray(`
40
+ Build ID: ${s.buildId}`));let d=await me(n,s.buildId);d?.status==="COMPLETED"?(console.log(a.bold.green(`
41
+ \u{1F389} Your function has been deployed and is ready for invocation!`)),he(d)):d?.status==="FAILED"?(console.error(a.red(`
42
+ \u2717 Build failed during processing`)),d&&he(d),process.exit(1)):console.log(a.yellow(`
43
+ Build status could not be determined. Check the dashboard for updates.`));}else console.log(a.cyan(`
44
+ Your function will be available for invocation once the build is processed.`));}catch(e){console.error(a.red(`
45
+ \u2717 Publish failed: ${e.message??"unknown error"}`)),process.exit(1);}}var ve=j(()=>{le();ue();fe();});var A=class{constructor(e=false){p(this,"nextConnection",null);p(this,"invokeConnection",null);p(this,"currentRequestId",null);p(this,"currentFunctionName",null);p(this,"currentSessionId",null);p(this,"sessionCleanupCallback",null);p(this,"verbose");p(this,"runtimeConnectedOnce",false);this.verbose=e;}setSessionCleanupCallback(e){this.sessionCleanupCallback=e;}holdNextConnection(e){this.nextConnection&&(this.nextConnection.response.writeHead(503,{"Content-Type":"application/json"}),this.nextConnection.response.end(JSON.stringify({error:"Another runtime connected"}))),this.nextConnection={response:e,timestamp:Date.now()},this.runtimeConnectedOnce=true,this.verbose&&console.log(a.cyan("\u{1F50C} Function runtime connected, ready for invocations"));}triggerInvocation(e,n,r,t){if(!this.nextConnection)return this.verbose&&console.log(a.yellow("\u26A0\uFE0F No runtime connected to handle invocation")),false;if(this.invokeConnection)return this.verbose&&console.log(a.yellow("\u26A0\uFE0F Another invocation is already in progress")),false;let i=randomUUID();this.currentRequestId=i,this.currentFunctionName=e,this.currentSessionId=r.session.id,this.invokeConnection={response:t,timestamp:Date.now()};let s={functionName:e,params:n,context:r};return this.nextConnection.response.writeHead(200,{"Content-Type":"application/json","Lambda-Runtime-Aws-Request-Id":i,"Lambda-Runtime-Deadline-Ms":String(Date.now()+3e5),"Lambda-Runtime-Invoked-Function-Arn":`arn:aws:lambda:us-east-1:000000000000:function:${e}`}),this.nextConnection.response.end(JSON.stringify(s)),this.nextConnection=null,console.log(a.blue(`\u{1F680} Invoking function '${e}' (request-id: ${i})`)),true}completeWithSuccess(e,n){return e!==this.currentRequestId?(this.verbose&&console.log(a.yellow(`\u26A0\uFE0F Request ID mismatch: expected ${this.currentRequestId}, got ${e}`)),false):this.invokeConnection?(this.invokeConnection.response.writeHead(200,{"Content-Type":"application/json"}),this.invokeConnection.response.end(JSON.stringify(n??{})),console.log(a.green(`\u2713 Function '${this.currentFunctionName}' completed successfully`)),this.sessionCleanupCallback&&this.currentSessionId&&this.sessionCleanupCallback(this.currentSessionId).catch(r=>{console.error(a.red("Failed to cleanup session:"),r);}),this.invokeConnection=null,this.currentRequestId=null,this.currentFunctionName=null,this.currentSessionId=null,true):(this.verbose&&console.log(a.yellow("\u26A0\uFE0F No active invocation to complete")),false)}completeWithError(e,n){return e!==this.currentRequestId?(this.verbose&&console.log(a.yellow(`\u26A0\uFE0F Request ID mismatch: expected ${this.currentRequestId}, got ${e}`)),false):this.invokeConnection?(this.invokeConnection.response.writeHead(500,{"Content-Type":"application/json"}),this.invokeConnection.response.end(JSON.stringify({error:{message:n.errorMessage,type:n.errorType,stackTrace:n.stackTrace}})),console.log(a.red(`\u2717 Function '${this.currentFunctionName}' failed: ${n.errorMessage}`)),this.sessionCleanupCallback&&this.currentSessionId&&this.sessionCleanupCallback(this.currentSessionId).catch(r=>{console.error(a.red("Failed to cleanup session:"),r);}),this.invokeConnection=null,this.currentRequestId=null,this.currentFunctionName=null,this.currentSessionId=null,true):(this.verbose&&console.log(a.yellow("\u26A0\uFE0F No active invocation to complete")),false)}isReady(){return this.nextConnection!==null&&this.invokeConnection===null}hasActiveInvocation(){return this.invokeConnection!==null}getCurrentRequestId(){return this.currentRequestId}isRuntimeConnected(){return this.runtimeConnectedOnce&&this.nextConnection!==null}};var F=class{constructor(){p(this,"browserbaseClient",null);p(this,"projectId");p(this,"apiKey");p(this,"initialized",false);let e=process.env.BB_PROJECT_ID,n=process.env.BB_API_KEY;if(!e||!n)throw console.error(a.red(`\u2717 Browserbase credentials not found.
46
+ `)+a.red(` Please set BB_PROJECT_ID and BB_API_KEY in your .env file.
47
+ `)+a.gray(" Copy .env.example to .env and fill in your credentials.")),new Error("Missing Browserbase credentials");this.projectId=e,this.apiKey=n;}async initialize(){this.initialized||(this.browserbaseClient=new xe({apiKey:this.apiKey}),this.initialized=true,console.log(a.green("\u2713 Browserbase client initialized")));}async createSession(e){if(!this.browserbaseClient)throw new Error("Browser manager not initialized");console.log(a.cyan("Creating browser session..."));let n=await this.browserbaseClient.sessions.create({projectId:this.projectId,...e}),r={id:n.id,connectUrl:n.connectUrl};return console.log(a.green(`\u2713 Browser session created: ${r.id}`)),r}async closeSession(e){if(!this.browserbaseClient)throw new Error("Browser manager not initialized");try{console.log(a.cyan(`Closing browser session: ${e}...`)),await this.browserbaseClient.sessions.update(e,{projectId:this.projectId,status:"REQUEST_RELEASE"}),console.log(a.green(`\u2713 Browser session closed: ${e}`));}catch(n){console.warn(a.yellow(`\u26A0\uFE0F Could not close session ${e}:`),n instanceof Error?n.message:String(n));}}getProjectId(){return this.projectId}isInitialized(){return this.initialized}};var T=class{constructor(e){p(this,"manifests",new Map);p(this,"manifestsPath");this.manifestsPath=e||join(process.cwd(),".browserbase","functions","manifests");}loadManifests(){if(!existsSync(this.manifestsPath)){console.log(a.yellow(`\u26A0\uFE0F No ${this.manifestsPath} directory found`)),console.log(a.gray(" Run your entrypoint file first to generate manifests"));return}try{let n=readdirSync(this.manifestsPath).filter(r=>r.endsWith(".json"));for(let r of n){let t=join(this.manifestsPath,r),i=readFileSync(t,"utf-8"),s=JSON.parse(i);this.manifests.set(s.name,s),console.log(a.gray(` Loaded manifest for function: ${s.name}`));}this.manifests.size>0?console.log(a.green(`\u2713 Loaded ${this.manifests.size} function manifest(s)`)):console.log(a.yellow("\u26A0\uFE0F No function manifests found in .browserbase directory"));}catch(e){console.error(a.red("Failed to load function manifests:"),e);}}getManifest(e){return this.manifests.get(e)}getSize(){return this.manifests.size}hasManifest(e){return this.manifests.has(e)}getManifestNames(){return Array.from(this.manifests.keys())}};var D={async parseJsonBody(o){return new Promise((e,n)=>{let r="";o.on("data",t=>{r+=t.toString();}),o.on("end",()=>{try{let t=r?JSON.parse(r):{};e(t);}catch(t){n(new Error("Invalid JSON body",{cause:t}));}}),o.on("error",n);})},async parseAndValidate(o,e){let n=await this.parseJsonBody(o);return e.parse(n)}};var y={sendJson(o,e,n){o.writeHead(e,{"Content-Type":"application/json"}),o.end(JSON.stringify(n));},sendSuccess(o,e,n=200){let r={status:"success",...e!==void 0&&{data:e}};this.sendJson(o,n,r);},sendError(o,e,n=500,r,t){let i={error:e};r&&(i.message=r),t&&(i.details=t),this.sendJson(o,n,i);},sendBadRequest(o,e,n){this.sendError(o,"Bad Request",400,e,n);},sendNotFound(o,e){this.sendError(o,"Not Found",404,e);},sendInternalError(o,e="An internal error occurred",n){this.sendError(o,"Internal Server Error",500,e,n);},sendServiceUnavailable(o,e){this.sendError(o,"Service Unavailable",503,e);},sendAccepted(o,e){let n=e||{status:"accepted"};this.sendJson(o,202,n);}};var Ee=I.object({id:I.string(),connectUrl:I.string()}),U=I.object({session:Ee});var Be=I.object({functionName:I.string().min(1),params:I.looseObject({}),context:U});I.object({requestId:I.string().min(1),event:Be});var X=I.object({errorMessage:I.string().min(1),errorType:I.string().min(1),stackTrace:I.array(I.string().min(1))});var q=class{constructor(e){p(this,"bridge");p(this,"browserManager");p(this,"manifestStore");this.bridge=e.bridge,this.browserManager=e.browserManager,this.manifestStore=e.manifestStore,this.bridge.setSessionCleanupCallback(async n=>{await this.cleanupSession(n);});}async handleInvocationNext(e,n){this.bridge.holdNextConnection(n);}async handleFunctionInvoke(e,n,r){try{let t=z$1.object({functionName:z$1.string().optional(),params:z$1.unknown().default({}),context:U.optional()}),i=await D.parseAndValidate(e,t),s=r||i.functionName;if(!s){y.sendBadRequest(n,"Function name is required");return}let d=this.manifestStore.getManifest(s);if(!d){console.error(a.red(`\u2717 Function "${s}" not found in registry`)),console.error(a.gray(" Make sure the function is defined in your entrypoint file")),y.sendNotFound(n,`Function "${s}" not found in registry. Make sure it is defined with defineFn() in your entrypoint file.`);return}let c;try{console.log(a.cyan(`Creating browser session for ${s}...`));let h=d?.config?.sessionConfig||{};c=await this.browserManager.createSession(h);}catch(h){console.error(a.red("Failed to create browser session:"),h),y.sendInternalError(n,"Failed to create browser session",h instanceof Error?h.message:String(h));return}let u=i.context||{invocation:{id:crypto.randomUUID(),region:"local"},session:c};if(u.session=c,!this.bridge.triggerInvocation(s,i.params,u,n)){await this.cleanupSession(c.id),y.sendServiceUnavailable(n,this.bridge.hasActiveInvocation()?"Another invocation is in progress":"No runtime connected");return}}catch(t){t instanceof z$1.ZodError?y.sendBadRequest(n,"Invalid request body",t):(console.error(a.red("Error handling invoke:"),t),y.sendInternalError(n));}}async handleInvocationResponse(e,n,r){try{let t=await D.parseJsonBody(e);if(!this.bridge.completeWithSuccess(r,t)){y.sendBadRequest(n,"No matching invocation or request ID mismatch");return}y.sendAccepted(n);}catch(t){console.error(a.red("Error handling response:"),t),y.sendInternalError(n);}}async handleInvocationError(e,n,r){try{let t=await D.parseAndValidate(e,X);if(!this.bridge.completeWithError(r,t)){y.sendBadRequest(n,"No matching invocation or request ID mismatch");return}y.sendAccepted(n);}catch(t){t instanceof z$1.ZodError?y.sendBadRequest(n,"Invalid error format",t):(console.error(a.red("Error handling error report:"),t),y.sendInternalError(n));}}async cleanupSession(e){try{await this.browserManager.closeSession(e);}catch(n){console.error(a.red(`Failed to cleanup session ${e}:`),n);}}};async function $e(o,e,n){let{handlers:r}=n,t=new URL(o.url||"",`http://${o.headers.host}`),i=o.method||"GET",s=t.pathname;if(console.log(a.gray(`[${i}] ${s}`)),e.setHeader("Access-Control-Allow-Origin","*"),e.setHeader("Access-Control-Allow-Methods","GET, POST, OPTIONS"),e.setHeader("Access-Control-Allow-Headers","Content-Type"),i==="OPTIONS"){e.writeHead(200),e.end();return}try{if(i==="GET"&&s==="/"){e.writeHead(200,{"Content-Type":"application/json"}),e.end(JSON.stringify({ok:!0}));return}if(i==="GET"&&s==="/2018-06-01/runtime/invocation/next"){await r.handleInvocationNext(o,e);return}let d=s.match(/^\/v1\/functions\/([^/]+)\/invoke$/);if(i==="POST"&&d&&d[1]){let m=d[1];await r.handleFunctionInvoke(o,e,m);return}let c=s.match(/^\/2018-06-01\/runtime\/invocation\/([^/]+)\/response$/);if(i==="POST"&&c&&c[1]){let m=c[1];await r.handleInvocationResponse(o,e,m);return}let u=s.match(/^\/2018-06-01\/runtime\/invocation\/([^/]+)\/error$/);if(i==="POST"&&u&&u[1]){let m=u[1];await r.handleInvocationError(o,e,m);return}e.writeHead(404,{"Content-Type":"application/json"}),e.end(JSON.stringify({error:"Not found"}));}catch(d){console.error(a.red("Server error:"),d),e.writeHead(500,{"Content-Type":"application/json"}),e.end(JSON.stringify({error:"Internal server error"}));}}async function ne(o){let{port:e,host:n,handlers:i}=o,s=createServer(async(d,c)=>{await $e(d,c,{handlers:i});});return new Promise((d,c)=>{s.listen(e,n,()=>{d(s);}),s.on("error",u=>{u.code==="EADDRINUSE"?c(new Error(`Port ${e} is already in use`)):u.code==="EACCES"?c(new Error(`Permission denied to bind to port ${e}`)):c(u);});})}var _=class{constructor(e){p(this,"process",null);p(this,"entrypoint");p(this,"runtimeApiUrl");p(this,"verbose");p(this,"isShuttingDown",false);this.entrypoint=e.entrypoint,this.runtimeApiUrl=e.runtimeApiUrl,this.verbose=e.verbose;}async start(){if(this.process)throw new Error("Process is already running");this.verbose&&(console.log(a.gray("Starting runtime process...")),console.log(a.gray(` Command: tsx watch --clear-screen=false ${this.entrypoint}`)),console.log(a.gray(` Working directory: ${process.cwd()}`)),console.log(a.gray(` Runtime API: ${this.runtimeApiUrl}`)));let n=createRequire(import.meta.url).resolve("tsx/cli"),r=["watch","--clear-screen=false",this.entrypoint];if(this.process=spawn(process.execPath,[n,...r],{cwd:process.cwd(),env:{...process.env,AWS_LAMBDA_RUNTIME_API:this.runtimeApiUrl,BB_FUNCTIONS_PHASE:"runtime",NODE_ENV:"local"},stdio:["ignore","pipe","pipe"]}),this.process.stdout?.on("data",t=>{t.toString().trim().split(`
48
+ `).forEach(s=>{s.trim()&&console.log(a.blue("[Runtime]"),s);});}),this.process.stderr?.on("data",t=>{t.toString().trim().split(`
49
+ `).forEach(s=>{s.trim()&&(s.includes("Watching for file changes")?console.log(a.green("\u2713 Runtime watching for file changes")):s.includes("Restarting")?console.log(a.yellow("\u21BB Runtime restarting due to file change...")):console.error(a.red("[Runtime Error]"),s));});}),this.process.on("exit",(t,i)=>{this.isShuttingDown||(t!==0?(console.error(a.red(`\u2717 Runtime process exited unexpectedly with code ${t}`)),i&&console.error(a.red(` Signal: ${i}`))):console.log(a.gray("Runtime process exited")),this.process=null);}),this.process.on("error",t=>{t.code==="ENOENT"?console.error(a.red("\u2717 Failed to start runtime: tsx not found"),a.yellow(`
50
+ Make sure tsx is installed: npm install -g tsx or pnpm add tsx`)):console.error(a.red("\u2717 Failed to start runtime process:"),t),this.process=null;}),await new Promise(t=>setTimeout(t,100)),!this.process||this.process.exitCode!==null)throw new Error("Failed to start runtime process");console.log(a.green("\u2713 Runtime process started"));}async stop(){if(this.process)return this.isShuttingDown=true,this.verbose&&console.log(a.gray("Stopping runtime process...")),new Promise(e=>{if(!this.process){e();return}let n=setTimeout(()=>{this.process&&(console.log(a.yellow("\u26A0\uFE0F Force killing runtime process")),this.process.kill("SIGKILL"));},5e3);this.process.on("exit",()=>{clearTimeout(n),this.process=null,console.log(a.green("\u2713 Runtime process stopped")),e();}),this.process.kill("SIGTERM");})}isRunning(){return this.process!==null&&this.process.exitCode===null}};async function oe(o){let{entrypoint:e,port:n,host:r,verbose:t}=o;process.env.NODE_ENV==="production"&&console.warn(a.yellow("\u26A0\uFE0F Warning: Running dev server in production mode. This is not recommended."));let i=`${r}:${n}`;t&&console.log(a.gray(`Runtime API URL: ${i}`));let s=new A(t),d=new F;await d.initialize();let c=new T;c.loadManifests();let u=new q({bridge:s,browserManager:d,manifestStore:c}),m=new _({entrypoint:e,runtimeApiUrl:i,verbose:t}),h=null;try{h=await ne({port:n,host:r,bridge:s,browserManager:d,handlers:u}),console.log(a.green(`\u2713 Development server listening on http://${r}:${n}`)),console.log(a.cyan("Starting runtime process...")),await m.start();let N=1e4,we=200,be=Date.now(),G=!1;for(;Date.now()-be<N;){if(s.isRuntimeConnected()){G=!0,console.log(a.green("\u2713 Runtime connected and ready")),c.loadManifests();break}await new Promise(H=>setTimeout(H,we));}G||(console.log(a.yellow("\u26A0\uFE0F Runtime is taking longer than expected to connect...")),c.loadManifests());let Y=async()=>(console.log(a.cyan(`
51
+ \u{1F4E6} Shutting down...`)),await m.stop(),new Promise(H=>{h?.close(()=>{console.log(a.green("\u2713 Server closed")),H();});}));process.on("SIGINT",async()=>{await Y(),process.exit(0);}),process.on("SIGTERM",async()=>{await Y(),process.exit(0);});}catch(N){throw console.error(a.red("Failed to start:"),N),m.isRunning()&&await m.stop(),h&&h.close(),N}}var Oe=fileURLToPath(import.meta.url),V=dirname(Oe);async function se(o){if(!Ve(o.projectName))throw new Error(`Invalid project name "${o.projectName}". Project names must start with a letter and contain only letters, numbers, hyphens, and underscores.`);let e=resolve(process.cwd(),o.projectName);if(existsSync(e))throw new Error(`Directory "${o.projectName}" already exists. Please choose a different name or delete the existing directory.`);console.log(a.cyan(`\u{1F680} Creating new Browserbase Functions project: ${a.bold(o.projectName)}`)),mkdirSync(e,{recursive:true});try{Ue(),existsSync(join(e,".git"))?console.log(a.yellow("\u2713 Git repository already exists")):(console.log(a.gray("Initializing git repository...")),execSync("git init",{cwd:e,stdio:"pipe"}),console.log(a.green("\u2713 Git repository initialized"))),Le(e),existsSync(join(e,"package.json"))?console.log(a.yellow("\u2713 package.json already exists")):(console.log(a.gray("Creating package.json...")),execSync("pnpm init",{cwd:e,stdio:"pipe"}),console.log(a.green("\u2713 package.json created")));let n=qe(o.packageManager);_e(e,n),console.log(a.gray("Installing dependencies...")),ze(e,n),console.log(a.green("\u2713 Dependencies installed")),Je(e),existsSync(join(e,"tsconfig.json"))?console.log(a.yellow("\u2713 TypeScript configuration already exists")):(console.log(a.gray("Initializing TypeScript configuration...")),execSync(`${n==="pnpm"?"pnpm":"npx"} tsc --init`,{cwd:e,stdio:"pipe"}),We(e),console.log(a.green("\u2713 TypeScript configuration created"))),He(e),console.log(""),console.log(a.green.bold("\u2728 Project initialized successfully!")),console.log(""),console.log(a.cyan("Next steps:")),console.log(a.gray("1. Navigate to your project:")),console.log(a.white(` cd ${o.projectName}`)),console.log(a.gray("2. Add your Browserbase API key and project ID to .env")),console.log(a.gray("3. Run your function locally:")),console.log(a.white(` ${n==="pnpm"?"pnpm":"npx"} bb dev index.ts`)),console.log(a.gray("4. When ready, publish your function:")),console.log(a.white(` ${n==="pnpm"?"pnpm":"npx"} bb publish index.ts`)),console.log(""),console.log(a.gray("Learn more at https://browserbase.com/docs"));}catch(n){console.error(a.red("\u274C Initialization failed:"),n instanceof Error?n.message:n),process.exit(1);}}function Ue(){let o=[{command:"node --version",name:"Node.js"},{command:"pnpm --version",name:"pnpm"},{command:"git --version",name:"git"}];for(let{command:e,name:n}of o)try{execSync(e,{stdio:"pipe"});}catch{throw new Error(`${n} is not installed. Please install ${n} and try again.`)}}function qe(o){if(o)return o;let e=process.env.npm_config_user_agent;return e&&e.includes("pnpm"),"pnpm"}function _e(o,e){let n=join(o,"package.json"),r=JSON.parse(readFileSync(n,"utf-8")),t;try{e==="pnpm"?(t=execSync("pnpm --version",{stdio:"pipe"}).toString().trim(),r.packageManager=`pnpm@${t}`):(t=execSync("npm --version",{stdio:"pipe"}).toString().trim(),r.packageManager=`npm@${t}`);}catch{r.packageManager=e==="pnpm"?"pnpm@9.0.0":"npm@10.0.0";}writeFileSync(n,JSON.stringify(r,null,2)),console.log(a.green(`\u2713 Package manager set to ${r.packageManager}`));}function ze(o,e){let n=e==="pnpm"?"pnpm add":"npm install",r=e==="pnpm"?"pnpm add -D":"npm install --save-dev";console.log(a.gray(" Installing @browserbasehq/sdk-functions...")),execSync(`${n} @browserbasehq/sdk-functions`,{cwd:o,stdio:"pipe"}),console.log(a.gray(" Installing playwright-core...")),execSync(`${n} playwright-core`,{cwd:o,stdio:"pipe"}),console.log(a.gray(" Installing TypeScript and type definitions...")),execSync(`${r} typescript @types/node`,{cwd:o,stdio:"pipe"});}function Je(o){let e=join(o,".env");if(existsSync(e))console.log(a.yellow("\u2713 .env file already exists"));else {let n=join(V,"templates",".env.template");copyFileSync(n,e),console.log(a.green("\u2713 .env file created"));}}function Le(o){let e=join(o,".gitignore");if(existsSync(e))console.log(a.yellow("\u2713 .gitignore file already exists"));else {let n=join(V,"templates",".gitignore.template");copyFileSync(n,e),console.log(a.green("\u2713 .gitignore file created"));}}function He(o){let e=join(o,"index.ts");if(existsSync(e))console.log(a.yellow("\u2713 index.ts already exists"));else {let n=join(V,"templates","starter-function.ts.template");copyFileSync(n,e),console.log(a.green("\u2713 Starter function created (index.ts)"));}}function We(o){let e=join(o,"tsconfig.json");try{let n=JSON.parse(readFileSync(e,"utf-8"));n.compilerOptions={...n.compilerOptions,target:"ES2022",module:"NodeNext",moduleResolution:"NodeNext",esModuleInterop:!0,forceConsistentCasingInFileNames:!0,strict:!0,skipLibCheck:!0,resolveJsonModule:!0},writeFileSync(e,JSON.stringify(n,null,2));}catch{console.log(a.yellow(" Using default TypeScript configuration"));}}function Ve(o){return /^[a-zA-Z][a-zA-Z0-9_-]*$/.test(o)}var $=new Command;$.name("bb").description("Browserbase Functions CLI").version("0.0.2");var K=["npm","pnpm"];$.command("init <project-name>").description("Initialize a new Browserbase Functions project").option("-p, --package-manager <manager>",`Package manager to use (${K.join(" or ")})`,"pnpm").action(async(o,e)=>{try{let n=e.packageManager.toLowerCase();K.includes(n)||(console.error(a.red(`Error: Invalid package manager "${e.packageManager}"`)),console.error(a.gray(`Valid options are: ${K.join(", ")}`)),process.exit(1)),await se({projectName:o,packageManager:n});}catch(n){console.error(a.red("Initialization failed:"),n),process.exit(1);}});$.command("dev").description("Start a local development server for testing Browserbase Functions").argument("<entrypoint>","Path to the TypeScript/JavaScript file that imports all your functions").option("-p, --port <number>","Port to listen on","14113").option("-h, --host <string>","Host to bind to","127.0.0.1").action(async(o,e)=>{try{let n=await import('fs'),r=await import('path'),t=r.resolve(o);n.existsSync(t)||(console.error(a.red(`Error: Entrypoint file not found: ${t}`)),process.exit(1));let i=r.extname(t);[".ts",".tsx",".js",".jsx",".mjs",".cjs"].includes(i)||(console.error(a.red("Error: Invalid file extension. Expected .ts, .tsx, .js, .jsx, .mjs, or .cjs")),process.exit(1));let s=parseInt(e.port,10);(isNaN(s)||s<1||s>65535)&&(console.error(a.red("Error: Invalid port number. Must be between 1 and 65535.")),process.exit(1)),console.log(a.cyan("Starting Browserbase Functions development server...")),console.log(a.gray(`Entrypoint: ${t}`)),await oe({entrypoint:t,port:s,host:e.host,verbose:e.verbose});}catch(n){console.error(a.red("Failed to start development server:"),n),process.exit(1);}});$.command("publish").description("Publish your Browserbase Function to the cloud").argument("<entrypoint>","Path to the TypeScript/JavaScript file that imports all your functions").option("-u, --api-url <url>","API endpoint URL").option("--dry-run","Show what would be published without uploading").action(async(o,e)=>{try{let{publishFunction:n}=await Promise.resolve().then(()=>(ve(),ye));await n({entrypoint:o,apiUrl:e.apiUrl,dryRun:e.dryRun});}catch(n){console.error(a.red("Publish failed:"),n),process.exit(1);}});$.parse();
44
52
  //# sourceMappingURL=cli.js.map
45
53
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli/publish/config.ts","../src/cli/publish/archiver.ts","../src/cli/publish/api-client.ts","../src/cli/publish/index.ts","../src/cli/dev/bridge.ts","../src/cli/dev/browser-manager.ts","../src/cli/dev/handlers/manifest-store.ts","../src/cli/dev/handlers/request-parser.ts","../src/cli/dev/handlers/response-builder.ts","../src/schemas/invocation.ts","../src/schemas/events.ts","../src/cli/dev/handlers/index.ts","../src/cli/dev/server.ts","../src/cli/dev/process.ts","../src/cli/dev/index.ts","../src/cli/main.ts"],"names":["loadConfig","options","apiKey","chalk","projectId","apiUrl","entrypoint","entrypointPath","Y","ext","validateConfig","config","init_config","__esmMin","loadGitignorePatterns","workingDirectory","gitignorePath","U","defaultPatterns","patterns","line","pattern","error","createArchive","resolve","reject","archive","archiver","chunks","fileCount","chunk","entry","relativePath","buffer","sizeInMB","err","ignorePatterns","validateArchiveSize","size","maxSizeMB","init_archiver","uploadBuild","archiveBuffer","formData","metadata","blob","url","response","errorMessage","errorBody","typedErrorBody","textBody","responseData","jsonResponse","getBuildStatus","buildId","pollBuildStatus","intervalMs","maxAttempts","attempt","status","init_api_client","publish_exports","__export","publishFunction","configOptions","archiveOptions","uploadOptions","result","buildStatus","init_publish","InvocationBridge","verbose","__publicField","callback","functionName","params","context","invokeResponse","requestId","randomUUID","payload","RemoteBrowserManager","foundProjectId","foundApiKey","Browserbase","sessionConfig","createdSession","session","sessionId","ManifestStore","manifestsPath","join","existsSync","jsonFiles","readdirSync","f","file","filePath","content","readFileSync","manifest","requestParser","req","body","parsed","schema","responseBuilder","res","statusCode","data","message","details","FunctionInvocationContextSessionDetails","z","FunctionInvocationContext","RuntimeEventPayload","RuntimeError","DevServerHandlers","deps","_req","invokeSchema","validatedData","finalFunctionName","validatedError","handleRequest","handlers","method","path","invokeMatch","responseMatch","errorMatch","startServer","port","host","server","createServer","ProcessManager","spawn","code","signal","killTimeout","startDevServer","runtimeApiUrl","bridge","browserManager","manifestStore","processManager","maxWaitTime","pollInterval","startTime","runtimeConnected","shutdown","program","Command","fs"],"mappings":"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","file":"cli.js","sourcesContent":["import chalk from \"chalk\";\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport \"dotenv/config\";\n\nexport interface PublishConfig {\n apiKey: string;\n projectId: string;\n apiUrl: string;\n entrypoint: string;\n workingDirectory: string;\n}\n\nexport function loadConfig(options: {\n entrypoint?: string;\n apiUrl?: string;\n}): PublishConfig {\n // Get API key from environment\n const apiKey = process.env[\"BB_API_KEY\"];\n if (!apiKey) {\n console.error(\n chalk.red(\"Error: BB_API_KEY not found in environment variables.\"),\n );\n console.log(\n chalk.gray(\"Please set BB_API_KEY in your .env file or environment.\"),\n );\n process.exit(1);\n }\n\n // Get project ID from environment\n const projectId = process.env[\"BB_PROJECT_ID\"];\n if (!projectId) {\n console.error(\n chalk.red(\"Error: BB_PROJECT_ID not found in environment variables.\"),\n );\n console.log(\n chalk.gray(\"Please set BB_PROJECT_ID in your .env file or environment.\"),\n );\n process.exit(1);\n }\n\n // Use provided API URL or default\n const apiUrl =\n options.apiUrl ||\n process.env[\"BB_API_URL\"] ||\n \"https://api.browserbase.com\";\n\n // Use provided entrypoint or default to main.ts\n const entrypoint = options.entrypoint || \"main.ts\";\n\n // Validate entrypoint exists\n const entrypointPath = path.resolve(entrypoint);\n if (!fs.existsSync(entrypointPath)) {\n console.error(\n chalk.red(`Error: Entrypoint file not found: ${entrypointPath}`),\n );\n process.exit(1);\n }\n\n // Validate entrypoint has valid extension\n const ext = path.extname(entrypoint).toLowerCase();\n if (![\".ts\", \".js\", \".mjs\", \".mts\"].includes(ext)) {\n console.error(\n chalk.red(\n `Error: Invalid entrypoint extension: ${ext}. Must be .ts, .js, .mjs, or .mts`,\n ),\n );\n process.exit(1);\n }\n\n return {\n apiKey,\n projectId,\n apiUrl,\n entrypoint,\n workingDirectory: process.cwd(),\n };\n}\n\nexport function validateConfig(config: PublishConfig): void {\n // Additional validation if needed\n if (!config.apiKey.startsWith(\"bb_\")) {\n console.warn(\n chalk.yellow(\n \"Warning: API key doesn't start with 'bb_'. Make sure you're using a valid Browserbase API key.\",\n ),\n );\n }\n}\n","import archiver from \"archiver\";\nimport chalk from \"chalk\";\nimport * as path from \"node:path\";\nimport * as fs from \"node:fs\";\n\ninterface ArchiveResult {\n buffer: Buffer;\n size: number;\n fileCount: number;\n}\n\nfunction loadGitignorePatterns(workingDirectory: string): string[] {\n const gitignorePath = path.join(workingDirectory, \".gitignore\");\n const defaultPatterns = [\n \"node_modules/**\",\n \".git/**\",\n \".env\",\n \".env.*\",\n \"*.log\",\n \".DS_Store\",\n \"dist/**\",\n \"build/**\",\n \"*.zip\",\n \"*.tar\",\n \"*.tar.gz\",\n \".vscode/**\",\n \".idea/**\",\n ];\n\n if (!fs.existsSync(gitignorePath)) {\n return defaultPatterns;\n }\n\n try {\n const gitignoreContent = fs.readFileSync(gitignorePath, \"utf-8\");\n const patterns = gitignoreContent\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line && !line.startsWith(\"#\"))\n .map((pattern) => {\n // Convert gitignore patterns to glob patterns for archiver\n if (pattern.endsWith(\"/\")) {\n return `${pattern}**`;\n }\n return pattern;\n });\n\n return [...defaultPatterns, ...patterns];\n } catch (error: unknown) {\n console.warn(\n chalk.yellow(\n error,\n \"Warning: Could not read .gitignore file, using defaults\",\n ),\n );\n return defaultPatterns;\n }\n}\n\nexport async function createArchive(\n workingDirectory: string,\n options?: {\n dryRun?: boolean;\n },\n): Promise<ArchiveResult> {\n return new Promise((resolve, reject) => {\n console.log(chalk.cyan(\"Creating archive...\"));\n\n const archive = archiver(\"tar\", {\n gzip: true,\n gzipOptions: { level: 9 }, // Maximum compression\n });\n\n const chunks: Buffer[] = [];\n let fileCount = 0;\n\n // Collect archive data in memory\n archive.on(\"data\", (chunk) => {\n chunks.push(chunk);\n });\n\n // Track files being added\n archive.on(\"entry\", (entry) => {\n if (!entry.stats?.isDirectory()) {\n fileCount++;\n if (options?.dryRun) {\n const relativePath = path.relative(workingDirectory, entry.name);\n console.log(chalk.gray(` + ${relativePath}`));\n }\n }\n });\n\n archive.on(\"end\", () => {\n const buffer = Buffer.concat(chunks);\n const sizeInMB = (buffer.length / (1024 * 1024)).toFixed(2);\n\n console.log(\n chalk.green(`✓ Archive created: ${fileCount} files, ${sizeInMB} MB`),\n );\n\n resolve({\n buffer,\n size: buffer.length,\n fileCount,\n });\n });\n\n archive.on(\"error\", (err) => {\n console.error(chalk.red(`Archive error: ${err.message}`));\n reject(err);\n });\n\n archive.on(\"warning\", (err) => {\n if (err.code === \"ENOENT\") {\n console.warn(chalk.yellow(`Warning: ${err.message}`));\n } else {\n reject(err);\n }\n });\n\n // Get ignore patterns\n const ignorePatterns = loadGitignorePatterns(workingDirectory);\n\n if (options?.dryRun) {\n console.log(chalk.gray(\"\\nIgnoring patterns:\"));\n ignorePatterns.forEach((pattern) => {\n console.log(chalk.gray(` - ${pattern}`));\n });\n console.log(chalk.gray(\"\\nIncluding files:\"));\n }\n\n // Add directory contents with ignore patterns\n archive.glob(\"**/*\", {\n cwd: workingDirectory,\n ignore: ignorePatterns,\n dot: true, // Include dotfiles (except those in ignore patterns)\n follow: false, // Don't follow symlinks\n });\n\n // Finalize the archive\n archive.finalize();\n });\n}\n\nexport function validateArchiveSize(\n size: number,\n maxSizeMB: number = 50,\n): void {\n const sizeInMB = size / (1024 * 1024);\n if (sizeInMB > maxSizeMB) {\n console.error(\n chalk.red(\n `Error: Archive size (${sizeInMB.toFixed(\n 2,\n )} MB) exceeds maximum allowed size (${maxSizeMB} MB)`,\n ),\n );\n console.log(\n chalk.gray(\n \"Consider adding more patterns to .gitignore to reduce archive size\",\n ),\n );\n process.exit(1);\n }\n}\n","import chalk from \"chalk\";\n\nimport { type PublishConfig } from \"./config.js\";\n\nexport interface BuildMetadata {\n entrypoint: string;\n projectId?: string;\n}\n\nexport interface UploadResult {\n buildId?: string;\n success: boolean;\n message?: string;\n}\n\nexport type BuildStatus = \"RUNNING\" | \"COMPLETED\" | \"FAILED\";\n\nexport interface BuildStatusResponse {\n id: string;\n status: BuildStatus;\n}\n\nexport async function uploadBuild(\n config: PublishConfig,\n archiveBuffer: Buffer,\n options?: {\n dryRun?: boolean;\n },\n): Promise<UploadResult> {\n if (options?.dryRun) {\n console.log(chalk.cyan(\"\\n[Dry run] Would upload to:\"));\n console.log(chalk.gray(` URL: ${config.apiUrl}/v1/functions/builds`));\n console.log(chalk.gray(` Project ID: ${config.projectId}`));\n console.log(chalk.gray(` Entrypoint: ${config.entrypoint}`));\n console.log(\n chalk.gray(\n ` Archive size: ${(archiveBuffer.length / (1024 * 1024)).toFixed(2)} MB`,\n ),\n );\n return {\n success: true,\n message: \"Dry run completed successfully\",\n };\n }\n\n console.log(chalk.cyan(\"\\nUploading build...\"));\n\n try {\n // Create form data\n const formData = new FormData();\n\n // Add metadata\n const metadata: BuildMetadata = {\n entrypoint: config.entrypoint,\n projectId: config.projectId,\n };\n formData.append(\"metadata\", JSON.stringify(metadata));\n\n // Add archive file as a blob\n const blob = new Blob([archiveBuffer], { type: \"application/gzip\" });\n formData.append(\"archive\", blob, \"archive.tar.gz\");\n\n // Make the request\n const url = `${config.apiUrl}/v1/functions/builds`;\n console.log(chalk.gray(`Uploading to: ${url}`));\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"x-bb-api-key\": config.apiKey,\n },\n body: formData,\n });\n\n // Handle response\n if (!response.ok) {\n let errorMessage = `HTTP ${response.status}: ${response.statusText}`;\n\n try {\n const errorBody = await response.json();\n if (\n typeof errorBody === \"object\" &&\n errorBody !== null &&\n (\"message\" in errorBody || \"error\" in errorBody)\n ) {\n const typedErrorBody = errorBody as {\n message?: string;\n error?: string;\n };\n errorMessage =\n typedErrorBody.message || typedErrorBody.error || errorMessage;\n }\n } catch {\n // If response is not JSON, try text\n try {\n const textBody = await response.text();\n if (textBody) {\n errorMessage = textBody;\n }\n } catch {\n // Keep default error message\n }\n }\n\n console.error(chalk.red(`Upload failed: ${errorMessage}`));\n return {\n success: false,\n message: errorMessage,\n };\n }\n\n // Parse successful response\n let responseData: { id?: string } = {};\n try {\n const jsonResponse = await response.json();\n if (typeof jsonResponse === \"object\" && jsonResponse !== null) {\n responseData = jsonResponse as { id?: string };\n }\n } catch {\n // Response might not be JSON\n }\n\n if (!responseData.id) {\n console.error(\n chalk.red(\"Upload failed: No build ID received in response\"),\n );\n return {\n success: false,\n message: \"No build ID received in response\",\n };\n }\n\n console.log(chalk.green(\"✓ Build uploaded successfully\"));\n console.log(chalk.gray(`Build ID: ${responseData.id}`));\n\n return {\n success: true,\n buildId: responseData.id,\n message: \"Build uploaded successfully\",\n };\n } catch (error: unknown) {\n const errorMessage =\n error instanceof Error ? error.message : \"Unknown error occurred\";\n console.error(chalk.red(`Upload error: ${errorMessage}`));\n\n if (\n error &&\n typeof error === \"object\" &&\n \"code\" in error &&\n error.code === \"ECONNREFUSED\"\n ) {\n console.log(\n chalk.yellow(\n `\\nCannot connect to ${config.apiUrl}. Make sure the API server is running.`,\n ),\n );\n }\n\n return {\n success: false,\n message: errorMessage,\n };\n }\n}\n\nasync function getBuildStatus(\n config: PublishConfig,\n buildId: string,\n): Promise<BuildStatusResponse | null> {\n try {\n const url = `${config.apiUrl}/v1/functions/builds/${buildId}`;\n const response = await fetch(url, {\n method: \"GET\",\n headers: {\n \"x-bb-api-key\": config.apiKey,\n },\n });\n\n if (!response.ok) {\n console.error(\n chalk.red(`Failed to get build status: HTTP ${response.status}`),\n );\n return null;\n }\n\n const data = await response.json();\n return data as BuildStatusResponse;\n } catch (error) {\n console.error(\n chalk.red(\n `Error fetching build status: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n ),\n );\n return null;\n }\n}\n\nexport async function pollBuildStatus(\n config: PublishConfig,\n buildId: string,\n options?: {\n intervalMs?: number;\n maxAttempts?: number;\n },\n): Promise<BuildStatusResponse | null> {\n const intervalMs = options?.intervalMs ?? 2000; // Default 2 seconds\n const maxAttempts = options?.maxAttempts ?? 60; // Default 2 minutes max (60 * 2s)\n\n console.log(chalk.cyan(\"\\nWaiting for build to complete...\"));\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n const status = await getBuildStatus(config, buildId);\n\n if (!status) {\n console.error(chalk.red(\"Failed to get build status\"));\n return null;\n }\n\n // Show progress indicator\n process.stdout.write(\n `\\r${chalk.gray(`Status: ${status.status}... (${attempt + 1}/${maxAttempts})`)}`,\n );\n\n if (status.status !== \"RUNNING\") {\n process.stdout.write(\"\\r\" + \" \".repeat(50) + \"\\r\"); // Clear the progress line\n\n if (status.status === \"COMPLETED\") {\n console.log(chalk.green(\"✓ Build completed successfully\"));\n } else if (status.status === \"FAILED\") {\n console.error(chalk.red(\"✗ Build failed\"));\n }\n\n return status;\n }\n\n // Wait before next poll\n await new Promise((resolve) => setTimeout(resolve, intervalMs));\n }\n\n process.stdout.write(\"\\r\" + \" \".repeat(50) + \"\\r\"); // Clear the progress line\n console.error(chalk.yellow(\"Build is still running after maximum wait time\"));\n return null;\n}\n","import chalk from \"chalk\";\n\nimport { loadConfig, validateConfig } from \"./config.js\";\nimport { createArchive, validateArchiveSize } from \"./archiver.js\";\nimport { uploadBuild, pollBuildStatus } from \"./api-client.js\";\n\nexport interface PublishOptions {\n entrypoint?: string;\n apiUrl?: string;\n dryRun?: boolean;\n}\n\nexport async function publishFunction(options: PublishOptions): Promise<void> {\n console.log(chalk.bold.cyan(\"\\nBrowserbase Functions - Publish\\n\"));\n\n try {\n // Load and validate configuration\n const configOptions: { entrypoint?: string; apiUrl?: string } = {};\n if (options.entrypoint !== undefined) {\n configOptions.entrypoint = options.entrypoint;\n }\n if (options.apiUrl !== undefined) {\n configOptions.apiUrl = options.apiUrl;\n }\n const config = loadConfig(configOptions);\n\n validateConfig(config);\n\n console.log(chalk.gray(`Working directory: ${config.workingDirectory}`));\n console.log(chalk.gray(`Entrypoint: ${config.entrypoint}`));\n console.log(chalk.gray(`API URL: ${config.apiUrl}`));\n console.log(chalk.gray(`Project ID: ${config.projectId}`));\n\n if (options.dryRun) {\n console.log(\n chalk.yellow(\"\\n[Dry run mode - no files will be uploaded]\\n\"),\n );\n }\n\n // Create archive\n const archiveOptions: { dryRun?: boolean } = {};\n if (options.dryRun !== undefined) {\n archiveOptions.dryRun = options.dryRun;\n }\n const archive = await createArchive(\n config.workingDirectory,\n archiveOptions,\n );\n\n // Validate archive size\n validateArchiveSize(archive.size);\n\n // Upload build\n const uploadOptions: { dryRun?: boolean } = {};\n if (options.dryRun !== undefined) {\n uploadOptions.dryRun = options.dryRun;\n }\n const result = await uploadBuild(config, archive.buffer, uploadOptions);\n\n if (!result.success) {\n console.error(chalk.red(\"\\n✗ Publish failed\"));\n process.exit(1);\n }\n\n // Success!\n if (options.dryRun) {\n console.log(chalk.bold.green(\"\\n✓ Dry run completed successfully!\"));\n console.log(\n chalk.cyan(\n \"\\nYour function would have been published. Run without --dry-run to publish.\",\n ),\n );\n } else {\n console.log(chalk.bold.green(\"\\n✓ Function uploaded successfully!\"));\n\n if (result.buildId) {\n console.log(chalk.gray(`\\nBuild ID: ${result.buildId}`));\n\n // Poll for build status\n const buildStatus = await pollBuildStatus(config, result.buildId);\n\n if (buildStatus?.status === \"COMPLETED\") {\n console.log(\n chalk.bold.green(\n \"\\n🎉 Your function has been deployed and is ready for invocation!\",\n ),\n );\n } else if (buildStatus?.status === \"FAILED\") {\n console.error(chalk.red(\"\\n✗ Build failed during processing\"));\n process.exit(1);\n } else {\n console.log(\n chalk.yellow(\n \"\\nBuild status could not be determined. Check the dashboard for updates.\",\n ),\n );\n }\n } else {\n console.log(\n chalk.cyan(\n \"\\nYour function will be available for invocation once the build is processed.\",\n ),\n );\n }\n }\n } catch (error: unknown) {\n console.error(\n chalk.red(\n `\\n✗ Publish failed: ${(error as { message?: string }).message ?? \"unknown error\"}`,\n ),\n );\n\n // if (error.stack && process.env.DEBUG) {\n // console.error(chalk.gray(error.stack));\n // }\n\n process.exit(1);\n }\n}\n","import { ServerResponse } from \"http\";\nimport { randomUUID } from \"crypto\";\nimport chalk from \"chalk\";\nimport type { FunctionInvocationContext } from \"../../schemas/invocation.js\";\n\ninterface HeldConnection {\n response: ServerResponse;\n timestamp: number;\n}\n\nexport interface InvocationPayload {\n functionName: string;\n params: unknown;\n context: FunctionInvocationContext;\n}\n\nexport interface RuntimeError {\n errorMessage: string;\n errorType: string;\n stackTrace: string[];\n}\n\n/**\n * Interface for managing the lifecycle of invocations, bridging between external invoke requests\n * and the function runtime's polling mechanism.\n */\nexport interface IInvocationBridge {\n /**\n * Set a callback to be called when a session should be cleaned up.\n */\n setSessionCleanupCallback(\n callback: (sessionId: string) => Promise<void>,\n ): void;\n\n /**\n * Hold a connection from the runtime waiting for the next invocation.\n * This corresponds to the SDK calling GET /invocation/next.\n */\n holdNextConnection(response: ServerResponse): void;\n\n /**\n * Trigger an invocation by completing the held /next connection with invoke data\n * and holding the invoke connection until the function completes.\n */\n triggerInvocation(\n functionName: string,\n params: unknown,\n context: FunctionInvocationContext,\n invokeResponse: ServerResponse,\n ): boolean;\n\n /**\n * Complete the held invoke connection with a successful response.\n */\n completeWithSuccess(requestId: string, result: unknown): boolean;\n\n /**\n * Complete the held invoke connection with an error response.\n */\n completeWithError(requestId: string, error: RuntimeError): boolean;\n\n /**\n * Check if the bridge is ready to accept invocations.\n */\n isReady(): boolean;\n\n /**\n * Check if there's an active invocation.\n */\n hasActiveInvocation(): boolean;\n\n /**\n * Get the current request ID if there's an active invocation.\n */\n getCurrentRequestId(): string | null;\n\n /**\n * Check if the runtime has connected at least once.\n */\n isRuntimeConnected(): boolean;\n}\n\n/**\n * Manages the lifecycle of invocations, bridging between external invoke requests\n * and the function runtime's polling mechanism.\n */\nexport class InvocationBridge implements IInvocationBridge {\n private nextConnection: HeldConnection | null = null;\n private invokeConnection: HeldConnection | null = null;\n private currentRequestId: string | null = null;\n private currentFunctionName: string | null = null;\n private currentSessionId: string | null = null;\n private sessionCleanupCallback:\n | ((sessionId: string) => Promise<void>)\n | null = null;\n private verbose: boolean;\n private runtimeConnectedOnce: boolean = false;\n\n constructor(verbose: boolean = false) {\n this.verbose = verbose;\n }\n\n /**\n * Set a callback to be called when a session should be cleaned up.\n */\n public setSessionCleanupCallback(\n callback: (sessionId: string) => Promise<void>,\n ): void {\n this.sessionCleanupCallback = callback;\n }\n\n /**\n * Hold a connection from the runtime waiting for the next invocation.\n * This corresponds to the SDK calling GET /invocation/next.\n */\n public holdNextConnection(response: ServerResponse): void {\n if (this.nextConnection) {\n // If there's already a held connection, close the old one\n this.nextConnection.response.writeHead(503, {\n \"Content-Type\": \"application/json\",\n });\n this.nextConnection.response.end(\n JSON.stringify({ error: \"Another runtime connected\" }),\n );\n }\n\n this.nextConnection = {\n response,\n timestamp: Date.now(),\n };\n\n // Mark that runtime has connected at least once\n this.runtimeConnectedOnce = true;\n\n if (this.verbose) {\n console.log(\n chalk.cyan(\"🔌 Function runtime connected, ready for invocations\"),\n );\n }\n }\n\n /**\n * Trigger an invocation by completing the held /next connection with invoke data\n * and holding the invoke connection until the function completes.\n */\n public triggerInvocation(\n functionName: string,\n params: unknown,\n context: FunctionInvocationContext,\n invokeResponse: ServerResponse,\n ): boolean {\n // Check if runtime is ready (has a held /next connection)\n if (!this.nextConnection) {\n if (this.verbose) {\n console.log(\n chalk.yellow(\"⚠️ No runtime connected to handle invocation\"),\n );\n }\n return false;\n }\n\n // Check if there's already an active invocation\n if (this.invokeConnection) {\n if (this.verbose) {\n console.log(\n chalk.yellow(\"⚠️ Another invocation is already in progress\"),\n );\n }\n return false;\n }\n\n // Generate a request ID for this invocation\n const requestId = randomUUID();\n this.currentRequestId = requestId;\n this.currentFunctionName = functionName;\n this.currentSessionId = context.session.id;\n\n // Hold the invoke connection\n this.invokeConnection = {\n response: invokeResponse,\n timestamp: Date.now(),\n };\n\n // Complete the held /next connection with the invocation payload\n const payload: InvocationPayload = {\n functionName,\n params,\n context,\n };\n\n // Set Lambda runtime headers\n this.nextConnection.response.writeHead(200, {\n \"Content-Type\": \"application/json\",\n \"Lambda-Runtime-Aws-Request-Id\": requestId,\n \"Lambda-Runtime-Deadline-Ms\": String(Date.now() + 300000), // 5 minutes from now\n \"Lambda-Runtime-Invoked-Function-Arn\": `arn:aws:lambda:us-east-1:000000000000:function:${functionName}`,\n });\n\n this.nextConnection.response.end(JSON.stringify(payload));\n this.nextConnection = null;\n\n console.log(\n chalk.blue(\n `🚀 Invoking function '${functionName}' (request-id: ${requestId})`,\n ),\n );\n\n return true;\n }\n\n /**\n * Complete the held invoke connection with a successful response.\n */\n public completeWithSuccess(requestId: string, result: unknown): boolean {\n // Validate request ID matches\n if (requestId !== this.currentRequestId) {\n if (this.verbose) {\n console.log(\n chalk.yellow(\n `⚠️ Request ID mismatch: expected ${this.currentRequestId}, got ${requestId}`,\n ),\n );\n }\n return false;\n }\n\n // Check if there's an active invocation\n if (!this.invokeConnection) {\n if (this.verbose) {\n console.log(chalk.yellow(\"⚠️ No active invocation to complete\"));\n }\n return false;\n }\n\n // Complete the held invoke connection\n this.invokeConnection.response.writeHead(200, {\n \"Content-Type\": \"application/json\",\n });\n this.invokeConnection.response.end(JSON.stringify(result ?? {}));\n\n console.log(\n chalk.green(\n `✓ Function '${this.currentFunctionName}' completed successfully`,\n ),\n );\n\n // Clean up session if callback is set\n if (this.sessionCleanupCallback && this.currentSessionId) {\n this.sessionCleanupCallback(this.currentSessionId).catch((error) => {\n console.error(chalk.red(\"Failed to cleanup session:\"), error);\n });\n }\n\n // Clean up state\n this.invokeConnection = null;\n this.currentRequestId = null;\n this.currentFunctionName = null;\n this.currentSessionId = null;\n\n return true;\n }\n\n /**\n * Complete the held invoke connection with an error response.\n */\n public completeWithError(requestId: string, error: RuntimeError): boolean {\n // Validate request ID matches\n if (requestId !== this.currentRequestId) {\n if (this.verbose) {\n console.log(\n chalk.yellow(\n `⚠️ Request ID mismatch: expected ${this.currentRequestId}, got ${requestId}`,\n ),\n );\n }\n return false;\n }\n\n // Check if there's an active invocation\n if (!this.invokeConnection) {\n if (this.verbose) {\n console.log(chalk.yellow(\"⚠️ No active invocation to complete\"));\n }\n return false;\n }\n\n // Complete the held invoke connection with error\n this.invokeConnection.response.writeHead(500, {\n \"Content-Type\": \"application/json\",\n });\n this.invokeConnection.response.end(\n JSON.stringify({\n error: {\n message: error.errorMessage,\n type: error.errorType,\n stackTrace: error.stackTrace,\n },\n }),\n );\n\n console.log(\n chalk.red(\n `✗ Function '${this.currentFunctionName}' failed: ${error.errorMessage}`,\n ),\n );\n\n // Clean up session if callback is set\n if (this.sessionCleanupCallback && this.currentSessionId) {\n this.sessionCleanupCallback(this.currentSessionId).catch((error) => {\n console.error(chalk.red(\"Failed to cleanup session:\"), error);\n });\n }\n\n // Clean up state\n this.invokeConnection = null;\n this.currentRequestId = null;\n this.currentFunctionName = null;\n this.currentSessionId = null;\n\n return true;\n }\n\n /**\n * Check if the bridge is ready to accept invocations.\n */\n public isReady(): boolean {\n return this.nextConnection !== null && this.invokeConnection === null;\n }\n\n /**\n * Check if there's an active invocation.\n */\n public hasActiveInvocation(): boolean {\n return this.invokeConnection !== null;\n }\n\n /**\n * Get the current request ID if there's an active invocation.\n */\n public getCurrentRequestId(): string | null {\n return this.currentRequestId;\n }\n\n /**\n * Check if the runtime has connected at least once.\n */\n public isRuntimeConnected(): boolean {\n return this.runtimeConnectedOnce && this.nextConnection !== null;\n }\n}\n","import Browserbase from \"@browserbasehq/sdk\";\nimport chalk from \"chalk\";\n\nexport interface SessionConfig {\n [key: string]: unknown;\n}\n\nexport interface Session {\n id: string;\n connectUrl: string;\n}\n\n/**\n * Interface for managing remote browser sessions\n */\nexport interface IRemoteBrowserManager {\n /**\n * Initialize the browser manager and check credentials\n */\n initialize(): Promise<void>;\n\n /**\n * Create a new browser session\n */\n createSession(sessionConfig?: SessionConfig): Promise<Session>;\n\n /**\n * Close a browser session\n */\n closeSession(sessionId: string): Promise<void>;\n\n /**\n * Get the project ID\n */\n getProjectId(): string;\n\n /**\n * Check if the manager is initialized\n */\n isInitialized(): boolean;\n}\n\n/**\n * Manages remote browser sessions using Browserbase\n */\nexport class RemoteBrowserManager implements IRemoteBrowserManager {\n private browserbaseClient: Browserbase | null = null;\n private projectId: string;\n private apiKey: string;\n private initialized: boolean = false;\n\n constructor() {\n const foundProjectId = process.env[\"BB_PROJECT_ID\"];\n const foundApiKey = process.env[\"BB_API_KEY\"];\n\n if (!foundProjectId || !foundApiKey) {\n console.error(\n chalk.red(\"✗ Browserbase credentials not found.\\n\") +\n chalk.red(\n \" Please set BB_PROJECT_ID and BB_API_KEY in your .env file.\\n\",\n ) +\n chalk.gray(\n \" Copy .env.example to .env and fill in your credentials.\",\n ),\n );\n throw new Error(\"Missing Browserbase credentials\");\n }\n\n this.projectId = foundProjectId;\n this.apiKey = foundApiKey;\n }\n\n /**\n * Initialize the browser manager and check credentials\n */\n public async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n // Creating a new Browserbase client is sufficient to assume connection\n this.browserbaseClient = new Browserbase({\n apiKey: this.apiKey,\n });\n\n this.initialized = true;\n console.log(chalk.green(\"✓ Browserbase client initialized\"));\n }\n\n /**\n * Create a new browser session\n */\n public async createSession(sessionConfig?: SessionConfig): Promise<Session> {\n if (!this.browserbaseClient) {\n throw new Error(\"Browser manager not initialized\");\n }\n\n console.log(chalk.cyan(`Creating browser session...`));\n\n const createdSession = await this.browserbaseClient.sessions.create({\n projectId: this.projectId,\n ...sessionConfig,\n });\n\n const session: Session = {\n id: createdSession.id,\n connectUrl: createdSession.connectUrl,\n };\n\n console.log(chalk.green(`✓ Browser session created: ${session.id}`));\n return session;\n }\n\n /**\n * Close a browser session\n */\n public async closeSession(sessionId: string): Promise<void> {\n if (!this.browserbaseClient) {\n throw new Error(\"Browser manager not initialized\");\n }\n\n try {\n console.log(chalk.cyan(`Closing browser session: ${sessionId}...`));\n await this.browserbaseClient.sessions.update(sessionId, {\n projectId: this.projectId,\n status: \"REQUEST_RELEASE\",\n });\n console.log(chalk.green(`✓ Browser session closed: ${sessionId}`));\n } catch (error) {\n // Session might already be closed or expired, log but don't throw\n console.warn(\n chalk.yellow(`⚠️ Could not close session ${sessionId}:`),\n error instanceof Error ? error.message : String(error),\n );\n }\n }\n\n /**\n * Get the project ID\n */\n public getProjectId(): string {\n return this.projectId;\n }\n\n /**\n * Check if the manager is initialized\n */\n public isInitialized(): boolean {\n return this.initialized;\n }\n}\n","import { readFileSync, existsSync, readdirSync } from \"fs\";\nimport { join } from \"path\";\nimport chalk from \"chalk\";\nimport type { PersistedFunctionManifest } from \"../../../types/definition.js\";\nimport type { JSONSchemaInput } from \"../../../types/schema.js\";\n\n/**\n * Interface for managing function manifests\n */\nexport interface IManifestStore {\n /**\n * Load manifests from the filesystem\n */\n loadManifests(): void;\n\n /**\n * Get a manifest by function name\n */\n getManifest(\n functionName: string,\n ): PersistedFunctionManifest<JSONSchemaInput> | undefined;\n\n /**\n * Get the total number of loaded manifests\n */\n getSize(): number;\n\n /**\n * Check if a manifest exists for the given function name\n */\n hasManifest(functionName: string): boolean;\n\n /**\n * Get all loaded manifest names\n */\n getManifestNames(): string[];\n}\n\n/**\n * Implementation of manifest store for managing function manifests\n */\nexport class ManifestStore implements IManifestStore {\n private manifests = new Map<\n string,\n PersistedFunctionManifest<JSONSchemaInput>\n >();\n private manifestsPath: string;\n\n constructor(manifestsPath?: string) {\n this.manifestsPath =\n manifestsPath ||\n join(process.cwd(), \".browserbase\", \"functions\", \"manifests\");\n }\n\n /**\n * Load function manifests from the filesystem\n */\n public loadManifests(): void {\n if (!existsSync(this.manifestsPath)) {\n console.log(chalk.yellow(`⚠️ No ${this.manifestsPath} directory found`));\n console.log(\n chalk.gray(\" Run your entrypoint file first to generate manifests\"),\n );\n return;\n }\n\n try {\n const files = readdirSync(this.manifestsPath);\n const jsonFiles = files.filter((f) => f.endsWith(\".json\"));\n\n for (const file of jsonFiles) {\n const filePath = join(this.manifestsPath, file);\n const content = readFileSync(filePath, \"utf-8\");\n const manifest = JSON.parse(\n content,\n ) as PersistedFunctionManifest<JSONSchemaInput>;\n\n this.manifests.set(manifest.name, manifest);\n console.log(\n chalk.gray(` Loaded manifest for function: ${manifest.name}`),\n );\n }\n\n if (this.manifests.size > 0) {\n console.log(\n chalk.green(`✓ Loaded ${this.manifests.size} function manifest(s)`),\n );\n } else {\n console.log(\n chalk.yellow(\n \"⚠️ No function manifests found in .browserbase directory\",\n ),\n );\n }\n } catch (error) {\n console.error(chalk.red(\"Failed to load function manifests:\"), error);\n }\n }\n\n /**\n * Get a manifest by function name\n */\n public getManifest(\n functionName: string,\n ): PersistedFunctionManifest<JSONSchemaInput> | undefined {\n return this.manifests.get(functionName);\n }\n\n /**\n * Get the total number of loaded manifests\n */\n public getSize(): number {\n return this.manifests.size;\n }\n\n /**\n * Check if a manifest exists for the given function name\n */\n public hasManifest(functionName: string): boolean {\n return this.manifests.has(functionName);\n }\n\n /**\n * Get all loaded manifest names\n */\n public getManifestNames(): string[] {\n return Array.from(this.manifests.keys());\n }\n}\n","import { IncomingMessage } from \"http\";\nimport { z } from \"zod\";\n\n/**\n * Interface for request parsing operations\n */\nexport interface IRequestParser {\n /**\n * Parse JSON body from an incoming request\n */\n parseJsonBody(req: IncomingMessage): Promise<unknown>;\n\n /**\n * Parse and validate JSON body with a Zod schema\n */\n parseAndValidate<T>(req: IncomingMessage, schema: z.ZodType<T>): Promise<T>;\n}\n\n/**\n * Request parser implementation\n */\nexport const requestParser: IRequestParser = {\n async parseJsonBody(req: IncomingMessage): Promise<unknown> {\n return new Promise((resolve, reject) => {\n let body = \"\";\n\n req.on(\"data\", (chunk) => {\n body += chunk.toString();\n });\n\n req.on(\"end\", () => {\n try {\n const parsed = body ? JSON.parse(body) : {};\n resolve(parsed);\n } catch (error: unknown) {\n reject(new Error(\"Invalid JSON body\", { cause: error }));\n }\n });\n\n req.on(\"error\", reject);\n });\n },\n\n async parseAndValidate<T>(\n req: IncomingMessage,\n schema: z.ZodType<T>,\n ): Promise<T> {\n const body = await this.parseJsonBody(req);\n return schema.parse(body);\n },\n};\n","import { ServerResponse } from \"http\";\n\n/**\n * Standard response format for errors\n */\nexport interface ErrorResponse {\n error: string;\n message?: string;\n details?: unknown;\n}\n\n/**\n * Standard response format for success\n */\nexport interface SuccessResponse<T = unknown> {\n status: string;\n data?: T;\n}\n\n/**\n * Interface for response building operations\n */\nexport interface IResponseBuilder {\n /**\n * Send a JSON response with the given status code\n */\n sendJson(res: ServerResponse, statusCode: number, data: unknown): void;\n\n /**\n * Send a success response\n */\n sendSuccess<T = unknown>(\n res: ServerResponse,\n data?: T,\n statusCode?: number,\n ): void;\n\n /**\n * Send an error response\n */\n sendError(\n res: ServerResponse,\n error: string,\n statusCode?: number,\n message?: string,\n details?: unknown,\n ): void;\n\n /**\n * Send a 400 Bad Request error\n */\n sendBadRequest(res: ServerResponse, message: string, details?: unknown): void;\n\n /**\n * Send a 404 Not Found error\n */\n sendNotFound(res: ServerResponse, message: string): void;\n\n /**\n * Send a 500 Internal Server Error\n */\n sendInternalError(\n res: ServerResponse,\n message?: string,\n details?: unknown,\n ): void;\n\n /**\n * Send a 503 Service Unavailable error\n */\n sendServiceUnavailable(res: ServerResponse, message: string): void;\n\n /**\n * Send a 202 Accepted response\n */\n sendAccepted(res: ServerResponse, data?: unknown): void;\n}\n\n/**\n * Response builder implementation\n */\nexport const responseBuilder: IResponseBuilder = {\n sendJson(res: ServerResponse, statusCode: number, data: unknown): void {\n res.writeHead(statusCode, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(data));\n },\n\n sendSuccess<T = unknown>(\n res: ServerResponse,\n data?: T,\n statusCode: number = 200,\n ): void {\n const response: SuccessResponse<T> = {\n status: \"success\",\n ...(data !== undefined && { data }),\n };\n this.sendJson(res, statusCode, response);\n },\n\n sendError(\n res: ServerResponse,\n error: string,\n statusCode: number = 500,\n message?: string,\n details?: unknown,\n ): void {\n const response: ErrorResponse = {\n error,\n };\n if (message) {\n response.message = message;\n }\n if (details) {\n response.details = details;\n }\n this.sendJson(res, statusCode, response);\n },\n\n sendBadRequest(\n res: ServerResponse,\n message: string,\n details?: unknown,\n ): void {\n this.sendError(res, \"Bad Request\", 400, message, details);\n },\n\n sendNotFound(res: ServerResponse, message: string): void {\n this.sendError(res, \"Not Found\", 404, message);\n },\n\n sendInternalError(\n res: ServerResponse,\n message: string = \"An internal error occurred\",\n details?: unknown,\n ): void {\n this.sendError(res, \"Internal Server Error\", 500, message, details);\n },\n\n sendServiceUnavailable(res: ServerResponse, message: string): void {\n this.sendError(res, \"Service Unavailable\", 503, message);\n },\n\n sendAccepted(res: ServerResponse, data?: unknown): void {\n const response = data || { status: \"accepted\" };\n this.sendJson(res, 202, response);\n },\n};\n","import z from \"zod\";\n\nexport const FunctionInvocationContextSessionDetails = z.object({\n id: z.string(),\n connectUrl: z.string(),\n});\n\nexport type FunctionInvocationContextSessionDetails = z.infer<\n typeof FunctionInvocationContextSessionDetails\n>;\n\nexport const FunctionInvocationContext = z.object({\n session: FunctionInvocationContextSessionDetails,\n});\n\nexport type FunctionInvocationContext = z.infer<\n typeof FunctionInvocationContext\n>;\n","import z from \"zod\";\nimport { FunctionInvocationContext } from \"./invocation.js\";\n\nexport const RuntimeEventPayload = z.object({\n functionName: z.string().min(1),\n params: z.looseObject({}), // Allow passthrough of unknown (all) keys\n context: FunctionInvocationContext,\n});\n\nexport type RuntimeEventPayload = z.infer<typeof RuntimeEventPayload>;\n\nexport const RuntimeEvent = z.object({\n requestId: z.string().min(1),\n event: RuntimeEventPayload,\n});\n\nexport type RuntimeEvent = z.infer<typeof RuntimeEvent>;\n\nexport const RuntimeError = z.object({\n errorMessage: z.string().min(1),\n errorType: z.string().min(1),\n stackTrace: z.array(z.string().min(1)),\n});\n\nexport type RuntimeError = z.infer<typeof RuntimeError>;\n","import { IncomingMessage, ServerResponse } from \"http\";\nimport { z } from \"zod\";\nimport chalk from \"chalk\";\nimport { type IInvocationBridge } from \"../bridge.js\";\nimport { type IRemoteBrowserManager } from \"../browser-manager.js\";\nimport { type IManifestStore } from \"./manifest-store.js\";\nimport { requestParser } from \"./request-parser.js\";\nimport { responseBuilder } from \"./response-builder.js\";\nimport { RuntimeError } from \"../../../schemas/events.js\";\nimport { FunctionInvocationContext } from \"../../../schemas/invocation.js\";\n\n/**\n * Dependencies required by the request handlers\n */\nexport interface RequestHandlerDependencies {\n bridge: IInvocationBridge;\n browserManager: IRemoteBrowserManager;\n manifestStore: IManifestStore;\n}\n\n/**\n * Interface for request handlers\n */\nexport interface IRequestHandlers {\n /**\n * Handle GET /2018-06-01/runtime/invocation/next\n * This endpoint is called by the runtime to get the next invocation.\n * We hold the connection until an invocation arrives.\n */\n handleInvocationNext(\n req: IncomingMessage,\n res: ServerResponse,\n ): Promise<void>;\n\n /**\n * Handle POST /v1/functions/:name/invoke\n * This endpoint is called by external clients to invoke a function.\n */\n handleFunctionInvoke(\n req: IncomingMessage,\n res: ServerResponse,\n functionName: string,\n ): Promise<void>;\n\n /**\n * Handle POST /2018-06-01/runtime/invocation/:requestId/response\n * This endpoint is called by the runtime when a function completes successfully.\n */\n handleInvocationResponse(\n req: IncomingMessage,\n res: ServerResponse,\n requestId: string,\n ): Promise<void>;\n\n /**\n * Handle POST /2018-06-01/runtime/invocation/:requestId/error\n * This endpoint is called by the runtime when a function fails.\n */\n handleInvocationError(\n req: IncomingMessage,\n res: ServerResponse,\n requestId: string,\n ): Promise<void>;\n}\n\n/**\n * Implementation of request handlers for the dev server\n */\nexport class DevServerHandlers implements IRequestHandlers {\n private readonly bridge: IInvocationBridge;\n private readonly browserManager: IRemoteBrowserManager;\n private readonly manifestStore: IManifestStore;\n\n constructor(deps: RequestHandlerDependencies) {\n this.bridge = deps.bridge;\n this.browserManager = deps.browserManager;\n this.manifestStore = deps.manifestStore;\n\n // Set up the session cleanup callback in the bridge\n this.bridge.setSessionCleanupCallback(async (sessionId: string) => {\n await this.cleanupSession(sessionId);\n });\n }\n\n /**\n * Handle GET /2018-06-01/runtime/invocation/next\n */\n public async handleInvocationNext(\n _req: IncomingMessage,\n res: ServerResponse,\n ): Promise<void> {\n // Hold the connection in the bridge\n this.bridge.holdNextConnection(res);\n\n // The response will be completed later when an invocation arrives\n // via triggerInvocation in the bridge\n }\n\n /**\n * Handle POST /v1/functions/:name/invoke\n */\n public async handleFunctionInvoke(\n req: IncomingMessage,\n res: ServerResponse,\n functionName: string,\n ): Promise<void> {\n try {\n // Define the invoke request schema\n const invokeSchema = z.object({\n functionName: z.string().optional(),\n params: z.unknown().default({}),\n context: FunctionInvocationContext.optional(),\n });\n\n // Parse and validate the request body\n const validatedData = await requestParser.parseAndValidate(\n req,\n invokeSchema,\n );\n\n // Use function name from URL path\n const finalFunctionName = functionName || validatedData.functionName;\n\n if (!finalFunctionName) {\n responseBuilder.sendBadRequest(res, \"Function name is required\");\n return;\n }\n\n // Look up function manifest to get sessionConfig\n const manifest = this.manifestStore.getManifest(finalFunctionName);\n\n if (!manifest) {\n console.error(\n chalk.red(`✗ Function \"${finalFunctionName}\" not found in registry`),\n );\n console.error(\n chalk.gray(\n \" Make sure the function is defined in your entrypoint file\",\n ),\n );\n responseBuilder.sendNotFound(\n res,\n `Function \"${finalFunctionName}\" not found in registry. Make sure it is defined with defineFn() in your entrypoint file.`,\n );\n return;\n }\n\n // Always create a browser session\n let session: { id: string; connectUrl: string };\n\n try {\n console.log(\n chalk.cyan(`Creating browser session for ${finalFunctionName}...`),\n );\n\n // Create session with function's sessionConfig if available\n const sessionConfig = manifest?.config?.sessionConfig || {};\n session = await this.browserManager.createSession(sessionConfig);\n } catch (error) {\n console.error(chalk.red(\"Failed to create browser session:\"), error);\n responseBuilder.sendInternalError(\n res,\n \"Failed to create browser session\",\n error instanceof Error ? error.message : String(error),\n );\n return;\n }\n\n // Build context with the created session\n const context = validatedData.context || {\n invocation: {\n id: crypto.randomUUID(),\n region: \"local\",\n },\n session: session,\n };\n\n // Always use the created session\n context.session = session;\n\n // Try to trigger the invocation\n const success = this.bridge.triggerInvocation(\n finalFunctionName,\n validatedData.params,\n context,\n res,\n );\n\n if (!success) {\n // Runtime not ready or another invocation in progress\n // Clean up the session we just created since we won't use it\n await this.cleanupSession(session.id);\n\n responseBuilder.sendServiceUnavailable(\n res,\n this.bridge.hasActiveInvocation()\n ? \"Another invocation is in progress\"\n : \"No runtime connected\",\n );\n return;\n }\n\n // The response will be completed later when the function completes\n // via completeWithSuccess or completeWithError in the bridge\n } catch (error) {\n if (error instanceof z.ZodError) {\n responseBuilder.sendBadRequest(res, \"Invalid request body\", error);\n } else {\n console.error(chalk.red(\"Error handling invoke:\"), error);\n responseBuilder.sendInternalError(res);\n }\n }\n }\n\n /**\n * Handle POST /2018-06-01/runtime/invocation/:requestId/response\n */\n public async handleInvocationResponse(\n req: IncomingMessage,\n res: ServerResponse,\n requestId: string,\n ): Promise<void> {\n try {\n // Parse the response body\n const body = await requestParser.parseJsonBody(req);\n\n // Complete the invocation with success\n const success = this.bridge.completeWithSuccess(requestId, body);\n\n if (!success) {\n responseBuilder.sendBadRequest(\n res,\n \"No matching invocation or request ID mismatch\",\n );\n return;\n }\n\n // Send acknowledgment to the runtime\n responseBuilder.sendAccepted(res);\n } catch (error) {\n console.error(chalk.red(\"Error handling response:\"), error);\n responseBuilder.sendInternalError(res);\n }\n }\n\n /**\n * Handle POST /2018-06-01/runtime/invocation/:requestId/error\n */\n public async handleInvocationError(\n req: IncomingMessage,\n res: ServerResponse,\n requestId: string,\n ): Promise<void> {\n try {\n // Parse and validate the error body using SDK schema\n const validatedError = await requestParser.parseAndValidate(\n req,\n RuntimeError,\n );\n\n // Complete the invocation with error\n const success = this.bridge.completeWithError(requestId, validatedError);\n\n if (!success) {\n responseBuilder.sendBadRequest(\n res,\n \"No matching invocation or request ID mismatch\",\n );\n return;\n }\n\n // Send acknowledgment to the runtime\n responseBuilder.sendAccepted(res);\n } catch (error) {\n if (error instanceof z.ZodError) {\n responseBuilder.sendBadRequest(res, \"Invalid error format\", error);\n } else {\n console.error(chalk.red(\"Error handling error report:\"), error);\n responseBuilder.sendInternalError(res);\n }\n }\n }\n\n /**\n * Private method to cleanup a browser session\n */\n private async cleanupSession(sessionId: string): Promise<void> {\n try {\n await this.browserManager.closeSession(sessionId);\n } catch (error) {\n console.error(\n chalk.red(`Failed to cleanup session ${sessionId}:`),\n error,\n );\n }\n }\n}\n","import { createServer, Server, IncomingMessage, ServerResponse } from \"http\";\nimport chalk from \"chalk\";\nimport { type IInvocationBridge } from \"./bridge.js\";\nimport { type IRemoteBrowserManager } from \"./browser-manager.js\";\nimport { type IRequestHandlers } from \"./handlers/index.js\";\n\nexport interface ServerOptions {\n port: number;\n host: string;\n bridge: IInvocationBridge;\n browserManager: IRemoteBrowserManager;\n handlers: IRequestHandlers;\n}\n\nexport interface RequestHandlerDeps {\n bridge: IInvocationBridge;\n browserManager: IRemoteBrowserManager;\n handlers: IRequestHandlers;\n}\n\n/**\n * Main request handler for the dev server\n * Extracted for testability\n */\nexport async function handleRequest(\n req: IncomingMessage,\n res: ServerResponse,\n deps: RequestHandlerDeps,\n): Promise<void> {\n const { handlers } = deps;\n const url = new URL(req.url || \"\", `http://${req.headers.host}`);\n const method = req.method || \"GET\";\n const path = url.pathname;\n\n console.log(chalk.gray(`[${method}] ${path}`));\n\n // Set CORS headers for local development\n res.setHeader(\"Access-Control-Allow-Origin\", \"*\");\n res.setHeader(\"Access-Control-Allow-Methods\", \"GET, POST, OPTIONS\");\n res.setHeader(\"Access-Control-Allow-Headers\", \"Content-Type\");\n\n // Handle preflight requests\n if (method === \"OPTIONS\") {\n res.writeHead(200);\n res.end();\n return;\n }\n\n try {\n // Route: GET / (healthcheck)\n if (method === \"GET\" && path === \"/\") {\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ ok: true }));\n return;\n }\n\n // Route: GET /2018-06-01/runtime/invocation/next\n if (method === \"GET\" && path === \"/2018-06-01/runtime/invocation/next\") {\n await handlers.handleInvocationNext(req, res);\n return;\n }\n\n // Route: POST /v1/functions/:name/invoke\n const invokeMatch = path.match(/^\\/v1\\/functions\\/([^/]+)\\/invoke$/);\n if (method === \"POST\" && invokeMatch && invokeMatch[1]) {\n const functionName = invokeMatch[1];\n await handlers.handleFunctionInvoke(req, res, functionName);\n return;\n }\n\n // Route: POST /2018-06-01/runtime/invocation/:requestId/response\n const responseMatch = path.match(\n /^\\/2018-06-01\\/runtime\\/invocation\\/([^/]+)\\/response$/,\n );\n if (method === \"POST\" && responseMatch && responseMatch[1]) {\n const requestId = responseMatch[1];\n await handlers.handleInvocationResponse(req, res, requestId);\n return;\n }\n\n // Route: POST /2018-06-01/runtime/invocation/:requestId/error\n const errorMatch = path.match(\n /^\\/2018-06-01\\/runtime\\/invocation\\/([^/]+)\\/error$/,\n );\n if (method === \"POST\" && errorMatch && errorMatch[1]) {\n const requestId = errorMatch[1];\n await handlers.handleInvocationError(req, res, requestId);\n return;\n }\n\n // 404 for unknown routes\n res.writeHead(404, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Not found\" }));\n } catch (error) {\n console.error(chalk.red(\"Server error:\"), error);\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Internal server error\" }));\n }\n}\n\nexport async function startServer(options: ServerOptions): Promise<Server> {\n const { port, host, bridge, browserManager, handlers } = options;\n\n const server = createServer(\n async (req: IncomingMessage, res: ServerResponse) => {\n await handleRequest(req, res, { bridge, browserManager, handlers });\n },\n );\n\n return new Promise((resolve, reject) => {\n server.listen(port, host, () => {\n resolve(server);\n });\n\n server.on(\"error\", (error: NodeJS.ErrnoException) => {\n if (error.code === \"EADDRINUSE\") {\n reject(new Error(`Port ${port} is already in use`));\n } else if (error.code === \"EACCES\") {\n reject(new Error(`Permission denied to bind to port ${port}`));\n } else {\n reject(error);\n }\n });\n });\n}\n","import { spawn, ChildProcess } from \"child_process\";\nimport chalk from \"chalk\";\n\nexport interface ProcessManagerOptions {\n entrypoint: string;\n runtimeApiUrl: string;\n verbose: boolean;\n}\n\n/**\n * Interface for managing the lifecycle of the user's function process.\n * Spawns tsx watch to enable hot reloading during development.\n */\nexport interface IProcessManager {\n /**\n * Start the user's function process using tsx watch.\n */\n start(): Promise<void>;\n\n /**\n * Stop the user's function process.\n */\n stop(): Promise<void>;\n\n /**\n * Check if the process is currently running.\n */\n isRunning(): boolean;\n}\n\n/**\n * Manages the lifecycle of the user's function process.\n * Spawns tsx watch to enable hot reloading during development.\n */\nexport class ProcessManager implements IProcessManager {\n private process: ChildProcess | null = null;\n private entrypoint: string;\n private runtimeApiUrl: string;\n private verbose: boolean;\n private isShuttingDown = false;\n\n constructor(options: ProcessManagerOptions) {\n this.entrypoint = options.entrypoint;\n this.runtimeApiUrl = options.runtimeApiUrl;\n this.verbose = options.verbose;\n }\n\n /**\n * Start the user's function process using tsx watch.\n */\n public async start(): Promise<void> {\n if (this.process) {\n throw new Error(\"Process is already running\");\n }\n\n if (this.verbose) {\n console.log(chalk.gray(`Starting runtime process...`));\n console.log(\n chalk.gray(\n ` Command: tsx watch --clear-screen=false ${this.entrypoint}`,\n ),\n );\n console.log(chalk.gray(` Working directory: ${process.cwd()}`));\n console.log(chalk.gray(` Runtime API: ${this.runtimeApiUrl}`));\n }\n\n // Spawn tsx watch with the user's entrypoint\n this.process = spawn(\n \"tsx\",\n [\"watch\", \"--clear-screen=false\", this.entrypoint],\n {\n cwd: process.cwd(),\n env: {\n ...process.env,\n AWS_LAMBDA_RUNTIME_API: this.runtimeApiUrl,\n BB_FUNCTIONS_PHASE: \"runtime\",\n NODE_ENV: \"local\",\n },\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n },\n );\n\n // Handle stdout\n this.process.stdout?.on(\"data\", (data) => {\n const lines = data.toString().trim().split(\"\\n\");\n lines.forEach((line: string) => {\n if (line.trim()) {\n console.log(chalk.blue(\"[Runtime]\"), line);\n }\n });\n });\n\n // Handle stderr\n this.process.stderr?.on(\"data\", (data) => {\n const lines = data.toString().trim().split(\"\\n\");\n lines.forEach((line: string) => {\n if (line.trim()) {\n // Check if it's a tsx watch message\n if (line.includes(\"Watching for file changes\")) {\n console.log(chalk.green(\"✓ Runtime watching for file changes\"));\n } else if (line.includes(\"Restarting\")) {\n console.log(\n chalk.yellow(\"↻ Runtime restarting due to file change...\"),\n );\n } else {\n console.error(chalk.red(\"[Runtime Error]\"), line);\n }\n }\n });\n });\n\n // Handle process exit\n this.process.on(\"exit\", (code, signal) => {\n if (!this.isShuttingDown) {\n if (code !== 0) {\n console.error(\n chalk.red(\n `✗ Runtime process exited unexpectedly with code ${code}`,\n ),\n );\n if (signal) {\n console.error(chalk.red(` Signal: ${signal}`));\n }\n } else {\n console.log(chalk.gray(\"Runtime process exited\"));\n }\n this.process = null;\n }\n });\n\n // Handle process errors\n this.process.on(\"error\", (error) => {\n if ((error as Error & { code: string }).code === \"ENOENT\") {\n console.error(\n chalk.red(\"✗ Failed to start runtime: tsx not found\"),\n chalk.yellow(\n \"\\n Make sure tsx is installed: npm install -g tsx or pnpm add tsx\",\n ),\n );\n } else {\n console.error(chalk.red(\"✗ Failed to start runtime process:\"), error);\n }\n this.process = null;\n });\n\n // Give the process a moment to start\n await new Promise((resolve) => setTimeout(resolve, 100));\n\n if (!this.process || this.process.exitCode !== null) {\n throw new Error(\"Failed to start runtime process\");\n }\n\n console.log(chalk.green(\"✓ Runtime process started\"));\n }\n\n /**\n * Stop the user's function process.\n */\n public async stop(): Promise<void> {\n if (!this.process) {\n return;\n }\n\n this.isShuttingDown = true;\n\n if (this.verbose) {\n console.log(chalk.gray(\"Stopping runtime process...\"));\n }\n\n return new Promise((resolve) => {\n if (!this.process) {\n resolve();\n return;\n }\n\n // Set a timeout to force kill if graceful shutdown fails\n const killTimeout = setTimeout(() => {\n if (this.process) {\n console.log(chalk.yellow(\"⚠️ Force killing runtime process\"));\n this.process.kill(\"SIGKILL\");\n }\n }, 5000);\n\n this.process.on(\"exit\", () => {\n clearTimeout(killTimeout);\n this.process = null;\n console.log(chalk.green(\"✓ Runtime process stopped\"));\n resolve();\n });\n\n // Try graceful shutdown first\n this.process.kill(\"SIGTERM\");\n });\n }\n\n /**\n * Check if the process is currently running.\n */\n public isRunning(): boolean {\n return this.process !== null && this.process.exitCode === null;\n }\n}\n","import chalk from \"chalk\";\nimport { startServer } from \"./server.js\";\nimport { InvocationBridge } from \"./bridge.js\";\nimport { ProcessManager } from \"./process.js\";\nimport { RemoteBrowserManager } from \"./browser-manager.js\";\nimport { DevServerHandlers } from \"./handlers/index.js\";\nimport \"dotenv/config\";\nimport { ManifestStore } from \"./handlers/manifest-store.js\";\nimport type { Server } from \"node:http\";\n\nexport interface DevServerOptions {\n entrypoint: string;\n port: number;\n host: string;\n verbose: boolean;\n}\n\nexport async function startDevServer(options: DevServerOptions): Promise<void> {\n const { entrypoint, port, host, verbose } = options;\n\n // Check if we're in production mode\n if (process.env[\"NODE_ENV\"] === \"production\") {\n console.warn(\n chalk.yellow(\n \"⚠️ Warning: Running dev server in production mode. This is not recommended.\",\n ),\n );\n }\n\n // Set the runtime API URL\n const runtimeApiUrl = `${host}:${port}`;\n\n if (verbose) {\n console.log(chalk.gray(`Runtime API URL: ${runtimeApiUrl}`));\n }\n\n // Create the invocation bridge\n const bridge = new InvocationBridge(verbose);\n\n // Create the browser manager\n const browserManager = new RemoteBrowserManager();\n await browserManager.initialize();\n\n // Create and initialize the manifest store\n const manifestStore = new ManifestStore();\n manifestStore.loadManifests();\n\n // Create the handlers with all dependencies\n const handlers = new DevServerHandlers({\n bridge,\n browserManager,\n manifestStore,\n });\n\n // Create the process manager\n const processManager = new ProcessManager({\n entrypoint,\n runtimeApiUrl,\n verbose,\n });\n\n // Start the server\n let server: Server | null = null;\n\n try {\n // Start the server first\n server = await startServer({\n port,\n host,\n bridge,\n browserManager,\n handlers,\n });\n\n console.log(\n chalk.green(`✓ Development server listening on http://${host}:${port}`),\n );\n\n // Then start the user's function process\n console.log(chalk.cyan(\"Starting runtime process...\"));\n await processManager.start();\n\n // Wait for runtime to connect with retry logic\n const maxWaitTime = 10000; // 10 seconds max\n const pollInterval = 200; // Check every 200ms\n const startTime = Date.now();\n let runtimeConnected = false;\n\n while (Date.now() - startTime < maxWaitTime) {\n if (bridge.isRuntimeConnected()) {\n runtimeConnected = true;\n console.log(chalk.green(\"✓ Runtime connected and ready\"));\n // Reload manifests after runtime starts as it may have created them\n manifestStore.loadManifests();\n break;\n }\n await new Promise((resolve) => setTimeout(resolve, pollInterval));\n }\n\n if (!runtimeConnected) {\n console.log(\n chalk.yellow(\n \"⚠️ Runtime is taking longer than expected to connect...\",\n ),\n );\n // Still try to reload manifests in case they were written\n manifestStore.loadManifests();\n }\n\n // Handle graceful shutdown\n const shutdown = async () => {\n console.log(chalk.cyan(\"\\n📦 Shutting down...\"));\n\n // Stop the user process first\n await processManager.stop();\n\n // Then close the server\n return new Promise<void>((resolve) => {\n server?.close(() => {\n console.log(chalk.green(\"✓ Server closed\"));\n resolve();\n });\n });\n };\n\n // Handle process termination\n process.on(\"SIGINT\", async () => {\n await shutdown();\n process.exit(0);\n });\n\n process.on(\"SIGTERM\", async () => {\n await shutdown();\n process.exit(0);\n });\n } catch (error) {\n console.error(chalk.red(\"Failed to start:\"), error);\n\n // Clean up on error\n if (processManager.isRunning()) {\n await processManager.stop();\n }\n if (server) {\n server.close();\n }\n\n throw error;\n }\n}\n","#!/usr/bin/env node\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { startDevServer } from \"./dev/index.js\";\n\n// Version is injected at build time\ndeclare const __CLI_VERSION__: string;\n\nconst program = new Command();\n\nprogram\n .name(\"bb\")\n .description(\"Browserbase Functions CLI\")\n .version(__CLI_VERSION__);\n\nprogram\n .command(\"dev\")\n .description(\n \"Start a local development server for testing Browserbase Functions\",\n )\n .argument(\n \"<entrypoint>\",\n \"Path to the TypeScript/JavaScript file that imports all your functions\",\n )\n .option(\"-p, --port <number>\", \"Port to listen on\", \"14113\")\n .option(\"-h, --host <string>\", \"Host to bind to\", \"127.0.0.1\")\n .action(async (entrypoint, options) => {\n try {\n // Validate entrypoint file exists\n const fs = await import(\"fs\");\n const path = await import(\"path\");\n\n const entrypointPath = path.resolve(entrypoint);\n if (!fs.existsSync(entrypointPath)) {\n console.error(\n chalk.red(`Error: Entrypoint file not found: ${entrypointPath}`),\n );\n process.exit(1);\n }\n\n // Validate file extension\n const ext = path.extname(entrypointPath);\n if (![\".ts\", \".tsx\", \".js\", \".jsx\", \".mjs\", \".cjs\"].includes(ext)) {\n console.error(\n chalk.red(\n `Error: Invalid file extension. Expected .ts, .tsx, .js, .jsx, .mjs, or .cjs`,\n ),\n );\n process.exit(1);\n }\n\n const port = parseInt(options.port, 10);\n if (isNaN(port) || port < 1 || port > 65535) {\n console.error(\n chalk.red(\"Error: Invalid port number. Must be between 1 and 65535.\"),\n );\n process.exit(1);\n }\n\n console.log(\n chalk.cyan(\"Starting Browserbase Functions development server...\"),\n );\n console.log(chalk.gray(`Entrypoint: ${entrypointPath}`));\n\n await startDevServer({\n entrypoint: entrypointPath,\n port,\n host: options.host,\n verbose: options.verbose,\n });\n } catch (error) {\n console.error(chalk.red(\"Failed to start development server:\"), error);\n process.exit(1);\n }\n });\n\nprogram\n .command(\"publish\")\n .description(\"Publish your Browserbase Function to the cloud\")\n .argument(\n \"<entrypoint>\",\n \"Path to the TypeScript/JavaScript file that imports all your functions\",\n )\n .option(\"-u, --api-url <url>\", \"API endpoint URL\")\n .option(\"--dry-run\", \"Show what would be published without uploading\")\n .action(async (entrypoint, options) => {\n try {\n const { publishFunction } = await import(\"./publish/index.js\");\n await publishFunction({\n entrypoint: entrypoint,\n apiUrl: options.apiUrl,\n dryRun: options.dryRun,\n });\n } catch (error) {\n console.error(chalk.red(\"Publish failed:\"), error);\n process.exit(1);\n }\n });\n\nprogram.parse();\n"]}
1
+ {"version":3,"sources":["../src/cli/publish/config.ts","../src/cli/publish/archiver.ts","../src/cli/publish/api-client.ts","../src/cli/publish/index.ts","../src/cli/dev/bridge.ts","../src/cli/dev/browser-manager.ts","../src/cli/dev/handlers/manifest-store.ts","../src/cli/dev/handlers/request-parser.ts","../src/cli/dev/handlers/response-builder.ts","../src/schemas/invocation.ts","../src/schemas/events.ts","../src/cli/dev/handlers/index.ts","../src/cli/dev/server.ts","../src/cli/dev/process.ts","../src/cli/dev/index.ts","../src/cli/init/index.ts","../src/cli/main.ts"],"names":["loadConfig","options","apiKey","chalk","projectId","apiUrl","entrypoint","entrypointPath","ie","ext","validateConfig","config","init_config","__esmMin","loadGitignorePatterns","workingDirectory","gitignorePath","J","defaultPatterns","patterns","line","pattern","error","createArchive","resolve","reject","archive","archiver","chunks","fileCount","chunk","entry","relativePath","buffer","sizeInMB","err","ignorePatterns","validateArchiveSize","size","maxSizeMB","init_archiver","uploadBuild","archiveBuffer","formData","metadata","blob","url","response","errorMessage","errorBody","typedErrorBody","textBody","responseData","jsonResponse","getBuildStatus","buildId","pollBuildStatus","intervalMs","maxAttempts","attempt","status","init_api_client","publish_exports","__export","publishFunction","displayBuildDetails","build","duration","seconds","func","index","params","key","value","configOptions","archiveOptions","uploadOptions","result","buildStatus","init_publish","InvocationBridge","verbose","__publicField","callback","functionName","context","invokeResponse","requestId","randomUUID","payload","RemoteBrowserManager","foundProjectId","foundApiKey","Browserbase","sessionConfig","createdSession","session","sessionId","ManifestStore","manifestsPath","join","existsSync","jsonFiles","readdirSync","f","file","filePath","content","readFileSync","manifest","requestParser","req","body","parsed","schema","responseBuilder","res","statusCode","data","message","details","FunctionInvocationContextSessionDetails","z","FunctionInvocationContext","RuntimeEventPayload","RuntimeError","DevServerHandlers","deps","_req","invokeSchema","validatedData","finalFunctionName","validatedError","handleRequest","handlers","method","path","invokeMatch","responseMatch","errorMatch","startServer","port","host","server","createServer","ProcessManager","tsxCli","createRequire","args","spawn","code","signal","killTimeout","startDevServer","runtimeApiUrl","bridge","browserManager","manifestStore","processManager","maxWaitTime","pollInterval","startTime","runtimeConnected","shutdown","__filename","fileURLToPath","__dirname","dirname","init","isValidProjectName","targetDir","mkdirSync","checkPrerequisites","execSync","createGitignoreFile","packageManager","detectPackageManager","updatePackageManager","installDependencies","createEnvFile","updateTsConfig","createStarterFunction","requiredCommands","command","name","preferred","userAgent","packageJsonPath","packageJson","version","writeFileSync","installCmd","installDevCmd","envPath","templatePath","copyFileSync","indexPath","tsConfigPath","tsConfig","program","Command","validPackageManagers","projectName","fs"],"mappings":"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","file":"cli.js","sourcesContent":["import chalk from \"chalk\";\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport \"dotenv/config\";\n\nexport interface PublishConfig {\n apiKey: string;\n projectId: string;\n apiUrl: string;\n entrypoint: string;\n workingDirectory: string;\n}\n\nexport function loadConfig(options: {\n entrypoint?: string;\n apiUrl?: string;\n}): PublishConfig {\n // Get API key from environment\n const apiKey = process.env[\"BB_API_KEY\"];\n if (!apiKey) {\n console.error(\n chalk.red(\"Error: BB_API_KEY not found in environment variables.\"),\n );\n console.log(\n chalk.gray(\"Please set BB_API_KEY in your .env file or environment.\"),\n );\n process.exit(1);\n }\n\n // Get project ID from environment\n const projectId = process.env[\"BB_PROJECT_ID\"];\n if (!projectId) {\n console.error(\n chalk.red(\"Error: BB_PROJECT_ID not found in environment variables.\"),\n );\n console.log(\n chalk.gray(\"Please set BB_PROJECT_ID in your .env file or environment.\"),\n );\n process.exit(1);\n }\n\n // Use provided API URL or default\n const apiUrl =\n options.apiUrl ||\n process.env[\"BB_API_URL\"] ||\n \"https://api.browserbase.com\";\n\n // Use provided entrypoint or default to main.ts\n const entrypoint = options.entrypoint || \"main.ts\";\n\n // Validate entrypoint exists\n const entrypointPath = path.resolve(entrypoint);\n if (!fs.existsSync(entrypointPath)) {\n console.error(\n chalk.red(`Error: Entrypoint file not found: ${entrypointPath}`),\n );\n process.exit(1);\n }\n\n // Validate entrypoint has valid extension\n const ext = path.extname(entrypoint).toLowerCase();\n if (![\".ts\", \".js\", \".mjs\", \".mts\"].includes(ext)) {\n console.error(\n chalk.red(\n `Error: Invalid entrypoint extension: ${ext}. Must be .ts, .js, .mjs, or .mts`,\n ),\n );\n process.exit(1);\n }\n\n return {\n apiKey,\n projectId,\n apiUrl,\n entrypoint,\n workingDirectory: process.cwd(),\n };\n}\n\nexport function validateConfig(config: PublishConfig): void {\n // Additional validation if needed\n if (!config.apiKey.startsWith(\"bb_\")) {\n console.warn(\n chalk.yellow(\n \"Warning: API key doesn't start with 'bb_'. Make sure you're using a valid Browserbase API key.\",\n ),\n );\n }\n}\n","import archiver from \"archiver\";\nimport chalk from \"chalk\";\nimport * as path from \"node:path\";\nimport * as fs from \"node:fs\";\n\ninterface ArchiveResult {\n buffer: Buffer;\n size: number;\n fileCount: number;\n}\n\nfunction loadGitignorePatterns(workingDirectory: string): string[] {\n const gitignorePath = path.join(workingDirectory, \".gitignore\");\n const defaultPatterns = [\n \"node_modules/**\",\n \".git/**\",\n \".env\",\n \".env.*\",\n \"*.log\",\n \".DS_Store\",\n \"dist/**\",\n \"build/**\",\n \"*.zip\",\n \"*.tar\",\n \"*.tar.gz\",\n \".vscode/**\",\n \".idea/**\",\n ];\n\n if (!fs.existsSync(gitignorePath)) {\n return defaultPatterns;\n }\n\n try {\n const gitignoreContent = fs.readFileSync(gitignorePath, \"utf-8\");\n const patterns = gitignoreContent\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line && !line.startsWith(\"#\"))\n .map((pattern) => {\n // Convert gitignore patterns to glob patterns for archiver\n if (pattern.endsWith(\"/\")) {\n return `${pattern}**`;\n }\n return pattern;\n });\n\n return [...defaultPatterns, ...patterns];\n } catch (error: unknown) {\n console.warn(\n chalk.yellow(\n error,\n \"Warning: Could not read .gitignore file, using defaults\",\n ),\n );\n return defaultPatterns;\n }\n}\n\nexport async function createArchive(\n workingDirectory: string,\n options?: {\n dryRun?: boolean;\n },\n): Promise<ArchiveResult> {\n return new Promise((resolve, reject) => {\n console.log(chalk.cyan(\"Creating archive...\"));\n\n const archive = archiver(\"tar\", {\n gzip: true,\n gzipOptions: { level: 9 }, // Maximum compression\n });\n\n const chunks: Buffer[] = [];\n let fileCount = 0;\n\n // Collect archive data in memory\n archive.on(\"data\", (chunk) => {\n chunks.push(chunk);\n });\n\n // Track files being added\n archive.on(\"entry\", (entry) => {\n if (!entry.stats?.isDirectory()) {\n fileCount++;\n if (options?.dryRun) {\n const relativePath = path.relative(workingDirectory, entry.name);\n console.log(chalk.gray(` + ${relativePath}`));\n }\n }\n });\n\n archive.on(\"end\", () => {\n const buffer = Buffer.concat(chunks);\n const sizeInMB = (buffer.length / (1024 * 1024)).toFixed(2);\n\n console.log(\n chalk.green(`✓ Archive created: ${fileCount} files, ${sizeInMB} MB`),\n );\n\n resolve({\n buffer,\n size: buffer.length,\n fileCount,\n });\n });\n\n archive.on(\"error\", (err) => {\n console.error(chalk.red(`Archive error: ${err.message}`));\n reject(err);\n });\n\n archive.on(\"warning\", (err) => {\n if (err.code === \"ENOENT\") {\n console.warn(chalk.yellow(`Warning: ${err.message}`));\n } else {\n reject(err);\n }\n });\n\n // Get ignore patterns\n const ignorePatterns = loadGitignorePatterns(workingDirectory);\n\n if (options?.dryRun) {\n console.log(chalk.gray(\"\\nIgnoring patterns:\"));\n ignorePatterns.forEach((pattern) => {\n console.log(chalk.gray(` - ${pattern}`));\n });\n console.log(chalk.gray(\"\\nIncluding files:\"));\n }\n\n // Add directory contents with ignore patterns\n archive.glob(\"**/*\", {\n cwd: workingDirectory,\n ignore: ignorePatterns,\n dot: true, // Include dotfiles (except those in ignore patterns)\n follow: false, // Don't follow symlinks\n });\n\n // Finalize the archive\n archive.finalize();\n });\n}\n\nexport function validateArchiveSize(\n size: number,\n maxSizeMB: number = 50,\n): void {\n const sizeInMB = size / (1024 * 1024);\n if (sizeInMB > maxSizeMB) {\n console.error(\n chalk.red(\n `Error: Archive size (${sizeInMB.toFixed(\n 2,\n )} MB) exceeds maximum allowed size (${maxSizeMB} MB)`,\n ),\n );\n console.log(\n chalk.gray(\n \"Consider adding more patterns to .gitignore to reduce archive size\",\n ),\n );\n process.exit(1);\n }\n}\n","import chalk from \"chalk\";\n\nimport { type PublishConfig } from \"./config.js\";\n\nexport interface BuildMetadata {\n entrypoint: string;\n projectId?: string;\n}\n\nexport interface UploadResult {\n buildId?: string;\n success: boolean;\n message?: string;\n}\n\nexport type BuildStatus = \"RUNNING\" | \"COMPLETED\" | \"FAILED\";\n\nexport interface FunctionCreatedVersion {\n id: string;\n projectId: string;\n functionId: string;\n functionBuildId: string;\n sessionCreateParams?: Record<string, unknown>;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface BuiltFunction {\n id: string;\n projectId: string;\n name: string;\n createdVersion: FunctionCreatedVersion;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface BuildStatusResponse {\n id: string;\n projectId: string;\n status: BuildStatus;\n request: {\n entrypoint: string;\n };\n createdAt: string;\n updatedAt: string;\n startedAt: string;\n endedAt?: string;\n expiresAt: string;\n builtFunctions?: BuiltFunction[];\n}\n\nexport async function uploadBuild(\n config: PublishConfig,\n archiveBuffer: Buffer,\n options?: {\n dryRun?: boolean;\n },\n): Promise<UploadResult> {\n if (options?.dryRun) {\n console.log(chalk.cyan(\"\\n[Dry run] Would upload to:\"));\n console.log(chalk.gray(` URL: ${config.apiUrl}/v1/functions/builds`));\n console.log(chalk.gray(` Project ID: ${config.projectId}`));\n console.log(chalk.gray(` Entrypoint: ${config.entrypoint}`));\n console.log(\n chalk.gray(\n ` Archive size: ${(archiveBuffer.length / (1024 * 1024)).toFixed(2)} MB`,\n ),\n );\n return {\n success: true,\n message: \"Dry run completed successfully\",\n };\n }\n\n console.log(chalk.cyan(\"\\nUploading build...\"));\n\n try {\n // Create form data\n const formData = new FormData();\n\n // Add metadata\n const metadata: BuildMetadata = {\n entrypoint: config.entrypoint,\n projectId: config.projectId,\n };\n formData.append(\"metadata\", JSON.stringify(metadata));\n\n // Add archive file as a blob\n const blob = new Blob([archiveBuffer], { type: \"application/gzip\" });\n formData.append(\"archive\", blob, \"archive.tar.gz\");\n\n // Make the request\n const url = `${config.apiUrl}/v1/functions/builds`;\n console.log(chalk.gray(`Uploading to: ${url}`));\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"x-bb-api-key\": config.apiKey,\n },\n body: formData,\n });\n\n // Handle response\n if (!response.ok) {\n let errorMessage = `HTTP ${response.status}: ${response.statusText}`;\n\n try {\n const errorBody = await response.json();\n if (\n typeof errorBody === \"object\" &&\n errorBody !== null &&\n (\"message\" in errorBody || \"error\" in errorBody)\n ) {\n const typedErrorBody = errorBody as {\n message?: string;\n error?: string;\n };\n errorMessage =\n typedErrorBody.message || typedErrorBody.error || errorMessage;\n }\n } catch {\n // If response is not JSON, try text\n try {\n const textBody = await response.text();\n if (textBody) {\n errorMessage = textBody;\n }\n } catch {\n // Keep default error message\n }\n }\n\n console.error(chalk.red(`Upload failed: ${errorMessage}`));\n return {\n success: false,\n message: errorMessage,\n };\n }\n\n // Parse successful response\n let responseData: { id?: string } = {};\n try {\n const jsonResponse = await response.json();\n if (typeof jsonResponse === \"object\" && jsonResponse !== null) {\n responseData = jsonResponse as { id?: string };\n }\n } catch {\n // Response might not be JSON\n }\n\n if (!responseData.id) {\n console.error(\n chalk.red(\"Upload failed: No build ID received in response\"),\n );\n return {\n success: false,\n message: \"No build ID received in response\",\n };\n }\n\n console.log(chalk.green(\"✓ Build uploaded successfully\"));\n console.log(chalk.gray(`Build ID: ${responseData.id}`));\n\n return {\n success: true,\n buildId: responseData.id,\n message: \"Build uploaded successfully\",\n };\n } catch (error: unknown) {\n const errorMessage =\n error instanceof Error ? error.message : \"Unknown error occurred\";\n console.error(chalk.red(`Upload error: ${errorMessage}`));\n\n if (\n error &&\n typeof error === \"object\" &&\n \"code\" in error &&\n error.code === \"ECONNREFUSED\"\n ) {\n console.log(\n chalk.yellow(\n `\\nCannot connect to ${config.apiUrl}. Make sure the API server is running.`,\n ),\n );\n }\n\n return {\n success: false,\n message: errorMessage,\n };\n }\n}\n\nasync function getBuildStatus(\n config: PublishConfig,\n buildId: string,\n): Promise<BuildStatusResponse | null> {\n try {\n const url = `${config.apiUrl}/v1/functions/builds/${buildId}`;\n const response = await fetch(url, {\n method: \"GET\",\n headers: {\n \"x-bb-api-key\": config.apiKey,\n },\n });\n\n if (!response.ok) {\n console.error(\n chalk.red(`Failed to get build status: HTTP ${response.status}`),\n );\n return null;\n }\n\n const data = await response.json();\n return data as BuildStatusResponse;\n } catch (error) {\n console.error(\n chalk.red(\n `Error fetching build status: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n ),\n );\n return null;\n }\n}\n\nexport async function pollBuildStatus(\n config: PublishConfig,\n buildId: string,\n options?: {\n intervalMs?: number;\n maxAttempts?: number;\n },\n): Promise<BuildStatusResponse | null> {\n const intervalMs = options?.intervalMs ?? 2000; // Default 2 seconds\n const maxAttempts = options?.maxAttempts ?? 100; // Default ~3 minutes max (100 * 2s)\n\n console.log(chalk.cyan(\"\\nWaiting for build to complete...\"));\n console.log(\n chalk.gray(\"(Builds typically take around 1 minute to complete)\"),\n );\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n const status = await getBuildStatus(config, buildId);\n\n if (!status) {\n console.error(chalk.red(\"Failed to get build status\"));\n return null;\n }\n\n // Show progress indicator with clearer polling information\n process.stdout.write(\n `\\r${chalk.gray(`Status: ${status.status}... (polling ${attempt + 1}/${maxAttempts})`)}`,\n );\n\n if (status.status !== \"RUNNING\") {\n process.stdout.write(\"\\r\" + \" \".repeat(60) + \"\\r\"); // Clear the progress line\n\n if (status.status === \"COMPLETED\") {\n console.log(chalk.green(\"✓ Build completed successfully\"));\n } else if (status.status === \"FAILED\") {\n console.error(chalk.red(\"✗ Build failed\"));\n }\n\n return status;\n }\n\n // Wait before next poll\n await new Promise((resolve) => setTimeout(resolve, intervalMs));\n }\n\n process.stdout.write(\"\\r\" + \" \".repeat(60) + \"\\r\"); // Clear the progress line\n console.error(\n chalk.yellow(\"Build is still running after maximum wait time (~3 minutes)\"),\n );\n console.error(\n chalk.yellow(\"Please check the dashboard for the current build status.\"),\n );\n return null;\n}\n","import chalk from \"chalk\";\n\nimport { loadConfig, validateConfig } from \"./config.js\";\nimport { createArchive, validateArchiveSize } from \"./archiver.js\";\nimport {\n uploadBuild,\n pollBuildStatus,\n type BuildStatusResponse,\n} from \"./api-client.js\";\n\nexport interface PublishOptions {\n entrypoint?: string;\n apiUrl?: string;\n dryRun?: boolean;\n}\n\nfunction displayBuildDetails(build: BuildStatusResponse): void {\n console.log(chalk.bold.cyan(\"\\n📦 Build Details\"));\n console.log(chalk.gray(\"─\".repeat(50)));\n\n // Display basic build information\n console.log(chalk.white(`Build ID: ${chalk.cyan(build.id)}`));\n console.log(chalk.white(`Project ID: ${chalk.cyan(build.projectId)}`));\n console.log(chalk.white(`Status: ${chalk.green(build.status)}`));\n\n if (build.request?.entrypoint) {\n console.log(\n chalk.white(`Entrypoint: ${chalk.cyan(build.request.entrypoint)}`),\n );\n }\n\n // Display timing information if available\n if (build.startedAt) {\n console.log(\n chalk.white(\n `Started: ${chalk.gray(new Date(build.startedAt).toLocaleString())}`,\n ),\n );\n }\n if (build.endedAt) {\n console.log(\n chalk.white(\n `Completed: ${chalk.gray(new Date(build.endedAt).toLocaleString())}`,\n ),\n );\n if (build.startedAt) {\n const duration =\n new Date(build.endedAt).getTime() - new Date(build.startedAt).getTime();\n const seconds = Math.floor(duration / 1000);\n console.log(chalk.white(`Duration: ${chalk.cyan(`${seconds} seconds`)}`));\n }\n }\n if (build.expiresAt) {\n console.log(\n chalk.white(\n `Expires: ${chalk.gray(new Date(build.expiresAt).toLocaleString())}`,\n ),\n );\n }\n\n // Display built functions\n if (build.builtFunctions && build.builtFunctions.length > 0) {\n console.log(chalk.bold.cyan(\"\\n🚀 Built Functions\"));\n console.log(chalk.gray(\"─\".repeat(50)));\n\n build.builtFunctions.forEach((func, index) => {\n console.log(chalk.bold.white(`\\n${index + 1}. ${func.name}`));\n console.log(chalk.white(` Function ID: ${chalk.cyan(func.id)}`));\n\n if (func.createdVersion) {\n console.log(\n chalk.white(` Version ID: ${chalk.cyan(func.createdVersion.id)}`),\n );\n\n // Display browser settings if available\n if (func.createdVersion.sessionCreateParams) {\n const params = func.createdVersion.sessionCreateParams;\n const hasSettings = Object.keys(params).length > 0;\n\n if (hasSettings) {\n console.log(chalk.white(` Browser Settings:`));\n Object.entries(params).forEach(([key, value]) => {\n console.log(\n chalk.gray(` - ${key}: ${JSON.stringify(value)}`),\n );\n });\n }\n }\n }\n });\n\n console.log(chalk.bold.cyan(\"\\n✨ Next Steps\"));\n console.log(chalk.gray(\"─\".repeat(50)));\n console.log(\n chalk.white(\"Your functions are ready to be invoked! Invoke using cURL:\"),\n );\n\n build.builtFunctions.forEach((func) => {\n console.log(chalk.gray(\"\\n curl --request POST \\\\\"));\n console.log(\n chalk.gray(\n ` --url ${func.projectId ? \"https\" : \"http\"}://api.browserbase.com/v1/functions/${func.id}/invoke \\\\`,\n ),\n );\n console.log(\n chalk.gray(\" --header 'Content-Type: application/json' \\\\\"),\n );\n console.log(chalk.gray(\" --header 'x-bb-api-key: YOUR_API_KEY' \\\\\"));\n console.log(chalk.gray(\" --data '{\\\"params\\\": {}}'\"));\n });\n } else {\n console.log(\n chalk.yellow(\n \"\\nNo functions were built. Please check your entrypoint and function exports.\",\n ),\n );\n }\n}\n\nexport async function publishFunction(options: PublishOptions): Promise<void> {\n console.log(chalk.bold.cyan(\"\\nBrowserbase Functions - Publish\\n\"));\n\n try {\n // Load and validate configuration\n const configOptions: { entrypoint?: string; apiUrl?: string } = {};\n if (options.entrypoint !== undefined) {\n configOptions.entrypoint = options.entrypoint;\n }\n if (options.apiUrl !== undefined) {\n configOptions.apiUrl = options.apiUrl;\n }\n const config = loadConfig(configOptions);\n\n validateConfig(config);\n\n console.log(chalk.gray(`Working directory: ${config.workingDirectory}`));\n console.log(chalk.gray(`Entrypoint: ${config.entrypoint}`));\n console.log(chalk.gray(`API URL: ${config.apiUrl}`));\n console.log(chalk.gray(`Project ID: ${config.projectId}`));\n\n if (options.dryRun) {\n console.log(\n chalk.yellow(\"\\n[Dry run mode - no files will be uploaded]\\n\"),\n );\n }\n\n // Create archive\n const archiveOptions: { dryRun?: boolean } = {};\n if (options.dryRun !== undefined) {\n archiveOptions.dryRun = options.dryRun;\n }\n const archive = await createArchive(\n config.workingDirectory,\n archiveOptions,\n );\n\n // Validate archive size\n validateArchiveSize(archive.size);\n\n // Upload build\n const uploadOptions: { dryRun?: boolean } = {};\n if (options.dryRun !== undefined) {\n uploadOptions.dryRun = options.dryRun;\n }\n const result = await uploadBuild(config, archive.buffer, uploadOptions);\n\n if (!result.success) {\n console.error(chalk.red(\"\\n✗ Publish failed\"));\n process.exit(1);\n }\n\n // Success!\n if (options.dryRun) {\n console.log(chalk.bold.green(\"\\n✓ Dry run completed successfully!\"));\n console.log(\n chalk.cyan(\n \"\\nYour function would have been published. Run without --dry-run to publish.\",\n ),\n );\n } else {\n console.log(chalk.bold.green(\"\\n✓ Function uploaded successfully!\"));\n\n if (result.buildId) {\n console.log(chalk.gray(`\\nBuild ID: ${result.buildId}`));\n\n // Poll for build status\n const buildStatus = await pollBuildStatus(config, result.buildId);\n\n if (buildStatus?.status === \"COMPLETED\") {\n console.log(\n chalk.bold.green(\n \"\\n🎉 Your function has been deployed and is ready for invocation!\",\n ),\n );\n\n // Display detailed build information and next steps\n displayBuildDetails(buildStatus);\n } else if (buildStatus?.status === \"FAILED\") {\n console.error(chalk.red(\"\\n✗ Build failed during processing\"));\n\n // Still display build details for failed builds to help with debugging\n if (buildStatus) {\n displayBuildDetails(buildStatus);\n }\n\n process.exit(1);\n } else {\n console.log(\n chalk.yellow(\n \"\\nBuild status could not be determined. Check the dashboard for updates.\",\n ),\n );\n }\n } else {\n console.log(\n chalk.cyan(\n \"\\nYour function will be available for invocation once the build is processed.\",\n ),\n );\n }\n }\n } catch (error: unknown) {\n console.error(\n chalk.red(\n `\\n✗ Publish failed: ${(error as { message?: string }).message ?? \"unknown error\"}`,\n ),\n );\n\n // if (error.stack && process.env.DEBUG) {\n // console.error(chalk.gray(error.stack));\n // }\n\n process.exit(1);\n }\n}\n","import { ServerResponse } from \"http\";\nimport { randomUUID } from \"crypto\";\nimport chalk from \"chalk\";\nimport type { FunctionInvocationContext } from \"../../schemas/invocation.js\";\n\ninterface HeldConnection {\n response: ServerResponse;\n timestamp: number;\n}\n\nexport interface InvocationPayload {\n functionName: string;\n params: unknown;\n context: FunctionInvocationContext;\n}\n\nexport interface RuntimeError {\n errorMessage: string;\n errorType: string;\n stackTrace: string[];\n}\n\n/**\n * Interface for managing the lifecycle of invocations, bridging between external invoke requests\n * and the function runtime's polling mechanism.\n */\nexport interface IInvocationBridge {\n /**\n * Set a callback to be called when a session should be cleaned up.\n */\n setSessionCleanupCallback(\n callback: (sessionId: string) => Promise<void>,\n ): void;\n\n /**\n * Hold a connection from the runtime waiting for the next invocation.\n * This corresponds to the SDK calling GET /invocation/next.\n */\n holdNextConnection(response: ServerResponse): void;\n\n /**\n * Trigger an invocation by completing the held /next connection with invoke data\n * and holding the invoke connection until the function completes.\n */\n triggerInvocation(\n functionName: string,\n params: unknown,\n context: FunctionInvocationContext,\n invokeResponse: ServerResponse,\n ): boolean;\n\n /**\n * Complete the held invoke connection with a successful response.\n */\n completeWithSuccess(requestId: string, result: unknown): boolean;\n\n /**\n * Complete the held invoke connection with an error response.\n */\n completeWithError(requestId: string, error: RuntimeError): boolean;\n\n /**\n * Check if the bridge is ready to accept invocations.\n */\n isReady(): boolean;\n\n /**\n * Check if there's an active invocation.\n */\n hasActiveInvocation(): boolean;\n\n /**\n * Get the current request ID if there's an active invocation.\n */\n getCurrentRequestId(): string | null;\n\n /**\n * Check if the runtime has connected at least once.\n */\n isRuntimeConnected(): boolean;\n}\n\n/**\n * Manages the lifecycle of invocations, bridging between external invoke requests\n * and the function runtime's polling mechanism.\n */\nexport class InvocationBridge implements IInvocationBridge {\n private nextConnection: HeldConnection | null = null;\n private invokeConnection: HeldConnection | null = null;\n private currentRequestId: string | null = null;\n private currentFunctionName: string | null = null;\n private currentSessionId: string | null = null;\n private sessionCleanupCallback:\n | ((sessionId: string) => Promise<void>)\n | null = null;\n private verbose: boolean;\n private runtimeConnectedOnce: boolean = false;\n\n constructor(verbose: boolean = false) {\n this.verbose = verbose;\n }\n\n /**\n * Set a callback to be called when a session should be cleaned up.\n */\n public setSessionCleanupCallback(\n callback: (sessionId: string) => Promise<void>,\n ): void {\n this.sessionCleanupCallback = callback;\n }\n\n /**\n * Hold a connection from the runtime waiting for the next invocation.\n * This corresponds to the SDK calling GET /invocation/next.\n */\n public holdNextConnection(response: ServerResponse): void {\n if (this.nextConnection) {\n // If there's already a held connection, close the old one\n this.nextConnection.response.writeHead(503, {\n \"Content-Type\": \"application/json\",\n });\n this.nextConnection.response.end(\n JSON.stringify({ error: \"Another runtime connected\" }),\n );\n }\n\n this.nextConnection = {\n response,\n timestamp: Date.now(),\n };\n\n // Mark that runtime has connected at least once\n this.runtimeConnectedOnce = true;\n\n if (this.verbose) {\n console.log(\n chalk.cyan(\"🔌 Function runtime connected, ready for invocations\"),\n );\n }\n }\n\n /**\n * Trigger an invocation by completing the held /next connection with invoke data\n * and holding the invoke connection until the function completes.\n */\n public triggerInvocation(\n functionName: string,\n params: unknown,\n context: FunctionInvocationContext,\n invokeResponse: ServerResponse,\n ): boolean {\n // Check if runtime is ready (has a held /next connection)\n if (!this.nextConnection) {\n if (this.verbose) {\n console.log(\n chalk.yellow(\"⚠️ No runtime connected to handle invocation\"),\n );\n }\n return false;\n }\n\n // Check if there's already an active invocation\n if (this.invokeConnection) {\n if (this.verbose) {\n console.log(\n chalk.yellow(\"⚠️ Another invocation is already in progress\"),\n );\n }\n return false;\n }\n\n // Generate a request ID for this invocation\n const requestId = randomUUID();\n this.currentRequestId = requestId;\n this.currentFunctionName = functionName;\n this.currentSessionId = context.session.id;\n\n // Hold the invoke connection\n this.invokeConnection = {\n response: invokeResponse,\n timestamp: Date.now(),\n };\n\n // Complete the held /next connection with the invocation payload\n const payload: InvocationPayload = {\n functionName,\n params,\n context,\n };\n\n // Set Lambda runtime headers\n this.nextConnection.response.writeHead(200, {\n \"Content-Type\": \"application/json\",\n \"Lambda-Runtime-Aws-Request-Id\": requestId,\n \"Lambda-Runtime-Deadline-Ms\": String(Date.now() + 300000), // 5 minutes from now\n \"Lambda-Runtime-Invoked-Function-Arn\": `arn:aws:lambda:us-east-1:000000000000:function:${functionName}`,\n });\n\n this.nextConnection.response.end(JSON.stringify(payload));\n this.nextConnection = null;\n\n console.log(\n chalk.blue(\n `🚀 Invoking function '${functionName}' (request-id: ${requestId})`,\n ),\n );\n\n return true;\n }\n\n /**\n * Complete the held invoke connection with a successful response.\n */\n public completeWithSuccess(requestId: string, result: unknown): boolean {\n // Validate request ID matches\n if (requestId !== this.currentRequestId) {\n if (this.verbose) {\n console.log(\n chalk.yellow(\n `⚠️ Request ID mismatch: expected ${this.currentRequestId}, got ${requestId}`,\n ),\n );\n }\n return false;\n }\n\n // Check if there's an active invocation\n if (!this.invokeConnection) {\n if (this.verbose) {\n console.log(chalk.yellow(\"⚠️ No active invocation to complete\"));\n }\n return false;\n }\n\n // Complete the held invoke connection\n this.invokeConnection.response.writeHead(200, {\n \"Content-Type\": \"application/json\",\n });\n this.invokeConnection.response.end(JSON.stringify(result ?? {}));\n\n console.log(\n chalk.green(\n `✓ Function '${this.currentFunctionName}' completed successfully`,\n ),\n );\n\n // Clean up session if callback is set\n if (this.sessionCleanupCallback && this.currentSessionId) {\n this.sessionCleanupCallback(this.currentSessionId).catch((error) => {\n console.error(chalk.red(\"Failed to cleanup session:\"), error);\n });\n }\n\n // Clean up state\n this.invokeConnection = null;\n this.currentRequestId = null;\n this.currentFunctionName = null;\n this.currentSessionId = null;\n\n return true;\n }\n\n /**\n * Complete the held invoke connection with an error response.\n */\n public completeWithError(requestId: string, error: RuntimeError): boolean {\n // Validate request ID matches\n if (requestId !== this.currentRequestId) {\n if (this.verbose) {\n console.log(\n chalk.yellow(\n `⚠️ Request ID mismatch: expected ${this.currentRequestId}, got ${requestId}`,\n ),\n );\n }\n return false;\n }\n\n // Check if there's an active invocation\n if (!this.invokeConnection) {\n if (this.verbose) {\n console.log(chalk.yellow(\"⚠️ No active invocation to complete\"));\n }\n return false;\n }\n\n // Complete the held invoke connection with error\n this.invokeConnection.response.writeHead(500, {\n \"Content-Type\": \"application/json\",\n });\n this.invokeConnection.response.end(\n JSON.stringify({\n error: {\n message: error.errorMessage,\n type: error.errorType,\n stackTrace: error.stackTrace,\n },\n }),\n );\n\n console.log(\n chalk.red(\n `✗ Function '${this.currentFunctionName}' failed: ${error.errorMessage}`,\n ),\n );\n\n // Clean up session if callback is set\n if (this.sessionCleanupCallback && this.currentSessionId) {\n this.sessionCleanupCallback(this.currentSessionId).catch((error) => {\n console.error(chalk.red(\"Failed to cleanup session:\"), error);\n });\n }\n\n // Clean up state\n this.invokeConnection = null;\n this.currentRequestId = null;\n this.currentFunctionName = null;\n this.currentSessionId = null;\n\n return true;\n }\n\n /**\n * Check if the bridge is ready to accept invocations.\n */\n public isReady(): boolean {\n return this.nextConnection !== null && this.invokeConnection === null;\n }\n\n /**\n * Check if there's an active invocation.\n */\n public hasActiveInvocation(): boolean {\n return this.invokeConnection !== null;\n }\n\n /**\n * Get the current request ID if there's an active invocation.\n */\n public getCurrentRequestId(): string | null {\n return this.currentRequestId;\n }\n\n /**\n * Check if the runtime has connected at least once.\n */\n public isRuntimeConnected(): boolean {\n return this.runtimeConnectedOnce && this.nextConnection !== null;\n }\n}\n","import Browserbase from \"@browserbasehq/sdk\";\nimport chalk from \"chalk\";\n\nexport interface SessionConfig {\n [key: string]: unknown;\n}\n\nexport interface Session {\n id: string;\n connectUrl: string;\n}\n\n/**\n * Interface for managing remote browser sessions\n */\nexport interface IRemoteBrowserManager {\n /**\n * Initialize the browser manager and check credentials\n */\n initialize(): Promise<void>;\n\n /**\n * Create a new browser session\n */\n createSession(sessionConfig?: SessionConfig): Promise<Session>;\n\n /**\n * Close a browser session\n */\n closeSession(sessionId: string): Promise<void>;\n\n /**\n * Get the project ID\n */\n getProjectId(): string;\n\n /**\n * Check if the manager is initialized\n */\n isInitialized(): boolean;\n}\n\n/**\n * Manages remote browser sessions using Browserbase\n */\nexport class RemoteBrowserManager implements IRemoteBrowserManager {\n private browserbaseClient: Browserbase | null = null;\n private projectId: string;\n private apiKey: string;\n private initialized: boolean = false;\n\n constructor() {\n const foundProjectId = process.env[\"BB_PROJECT_ID\"];\n const foundApiKey = process.env[\"BB_API_KEY\"];\n\n if (!foundProjectId || !foundApiKey) {\n console.error(\n chalk.red(\"✗ Browserbase credentials not found.\\n\") +\n chalk.red(\n \" Please set BB_PROJECT_ID and BB_API_KEY in your .env file.\\n\",\n ) +\n chalk.gray(\n \" Copy .env.example to .env and fill in your credentials.\",\n ),\n );\n throw new Error(\"Missing Browserbase credentials\");\n }\n\n this.projectId = foundProjectId;\n this.apiKey = foundApiKey;\n }\n\n /**\n * Initialize the browser manager and check credentials\n */\n public async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n // Creating a new Browserbase client is sufficient to assume connection\n this.browserbaseClient = new Browserbase({\n apiKey: this.apiKey,\n });\n\n this.initialized = true;\n console.log(chalk.green(\"✓ Browserbase client initialized\"));\n }\n\n /**\n * Create a new browser session\n */\n public async createSession(sessionConfig?: SessionConfig): Promise<Session> {\n if (!this.browserbaseClient) {\n throw new Error(\"Browser manager not initialized\");\n }\n\n console.log(chalk.cyan(`Creating browser session...`));\n\n const createdSession = await this.browserbaseClient.sessions.create({\n projectId: this.projectId,\n ...sessionConfig,\n });\n\n const session: Session = {\n id: createdSession.id,\n connectUrl: createdSession.connectUrl,\n };\n\n console.log(chalk.green(`✓ Browser session created: ${session.id}`));\n return session;\n }\n\n /**\n * Close a browser session\n */\n public async closeSession(sessionId: string): Promise<void> {\n if (!this.browserbaseClient) {\n throw new Error(\"Browser manager not initialized\");\n }\n\n try {\n console.log(chalk.cyan(`Closing browser session: ${sessionId}...`));\n await this.browserbaseClient.sessions.update(sessionId, {\n projectId: this.projectId,\n status: \"REQUEST_RELEASE\",\n });\n console.log(chalk.green(`✓ Browser session closed: ${sessionId}`));\n } catch (error) {\n // Session might already be closed or expired, log but don't throw\n console.warn(\n chalk.yellow(`⚠️ Could not close session ${sessionId}:`),\n error instanceof Error ? error.message : String(error),\n );\n }\n }\n\n /**\n * Get the project ID\n */\n public getProjectId(): string {\n return this.projectId;\n }\n\n /**\n * Check if the manager is initialized\n */\n public isInitialized(): boolean {\n return this.initialized;\n }\n}\n","import { readFileSync, existsSync, readdirSync } from \"fs\";\nimport { join } from \"path\";\nimport chalk from \"chalk\";\nimport type { PersistedFunctionManifest } from \"../../../types/definition.js\";\nimport type { JSONSchemaInput } from \"../../../types/schema.js\";\n\n/**\n * Interface for managing function manifests\n */\nexport interface IManifestStore {\n /**\n * Load manifests from the filesystem\n */\n loadManifests(): void;\n\n /**\n * Get a manifest by function name\n */\n getManifest(\n functionName: string,\n ): PersistedFunctionManifest<JSONSchemaInput> | undefined;\n\n /**\n * Get the total number of loaded manifests\n */\n getSize(): number;\n\n /**\n * Check if a manifest exists for the given function name\n */\n hasManifest(functionName: string): boolean;\n\n /**\n * Get all loaded manifest names\n */\n getManifestNames(): string[];\n}\n\n/**\n * Implementation of manifest store for managing function manifests\n */\nexport class ManifestStore implements IManifestStore {\n private manifests = new Map<\n string,\n PersistedFunctionManifest<JSONSchemaInput>\n >();\n private manifestsPath: string;\n\n constructor(manifestsPath?: string) {\n this.manifestsPath =\n manifestsPath ||\n join(process.cwd(), \".browserbase\", \"functions\", \"manifests\");\n }\n\n /**\n * Load function manifests from the filesystem\n */\n public loadManifests(): void {\n if (!existsSync(this.manifestsPath)) {\n console.log(chalk.yellow(`⚠️ No ${this.manifestsPath} directory found`));\n console.log(\n chalk.gray(\" Run your entrypoint file first to generate manifests\"),\n );\n return;\n }\n\n try {\n const files = readdirSync(this.manifestsPath);\n const jsonFiles = files.filter((f) => f.endsWith(\".json\"));\n\n for (const file of jsonFiles) {\n const filePath = join(this.manifestsPath, file);\n const content = readFileSync(filePath, \"utf-8\");\n const manifest = JSON.parse(\n content,\n ) as PersistedFunctionManifest<JSONSchemaInput>;\n\n this.manifests.set(manifest.name, manifest);\n console.log(\n chalk.gray(` Loaded manifest for function: ${manifest.name}`),\n );\n }\n\n if (this.manifests.size > 0) {\n console.log(\n chalk.green(`✓ Loaded ${this.manifests.size} function manifest(s)`),\n );\n } else {\n console.log(\n chalk.yellow(\n \"⚠️ No function manifests found in .browserbase directory\",\n ),\n );\n }\n } catch (error) {\n console.error(chalk.red(\"Failed to load function manifests:\"), error);\n }\n }\n\n /**\n * Get a manifest by function name\n */\n public getManifest(\n functionName: string,\n ): PersistedFunctionManifest<JSONSchemaInput> | undefined {\n return this.manifests.get(functionName);\n }\n\n /**\n * Get the total number of loaded manifests\n */\n public getSize(): number {\n return this.manifests.size;\n }\n\n /**\n * Check if a manifest exists for the given function name\n */\n public hasManifest(functionName: string): boolean {\n return this.manifests.has(functionName);\n }\n\n /**\n * Get all loaded manifest names\n */\n public getManifestNames(): string[] {\n return Array.from(this.manifests.keys());\n }\n}\n","import { IncomingMessage } from \"http\";\nimport { z } from \"zod\";\n\n/**\n * Interface for request parsing operations\n */\nexport interface IRequestParser {\n /**\n * Parse JSON body from an incoming request\n */\n parseJsonBody(req: IncomingMessage): Promise<unknown>;\n\n /**\n * Parse and validate JSON body with a Zod schema\n */\n parseAndValidate<T>(req: IncomingMessage, schema: z.ZodType<T>): Promise<T>;\n}\n\n/**\n * Request parser implementation\n */\nexport const requestParser: IRequestParser = {\n async parseJsonBody(req: IncomingMessage): Promise<unknown> {\n return new Promise((resolve, reject) => {\n let body = \"\";\n\n req.on(\"data\", (chunk) => {\n body += chunk.toString();\n });\n\n req.on(\"end\", () => {\n try {\n const parsed = body ? JSON.parse(body) : {};\n resolve(parsed);\n } catch (error: unknown) {\n reject(new Error(\"Invalid JSON body\", { cause: error }));\n }\n });\n\n req.on(\"error\", reject);\n });\n },\n\n async parseAndValidate<T>(\n req: IncomingMessage,\n schema: z.ZodType<T>,\n ): Promise<T> {\n const body = await this.parseJsonBody(req);\n return schema.parse(body);\n },\n};\n","import { ServerResponse } from \"http\";\n\n/**\n * Standard response format for errors\n */\nexport interface ErrorResponse {\n error: string;\n message?: string;\n details?: unknown;\n}\n\n/**\n * Standard response format for success\n */\nexport interface SuccessResponse<T = unknown> {\n status: string;\n data?: T;\n}\n\n/**\n * Interface for response building operations\n */\nexport interface IResponseBuilder {\n /**\n * Send a JSON response with the given status code\n */\n sendJson(res: ServerResponse, statusCode: number, data: unknown): void;\n\n /**\n * Send a success response\n */\n sendSuccess<T = unknown>(\n res: ServerResponse,\n data?: T,\n statusCode?: number,\n ): void;\n\n /**\n * Send an error response\n */\n sendError(\n res: ServerResponse,\n error: string,\n statusCode?: number,\n message?: string,\n details?: unknown,\n ): void;\n\n /**\n * Send a 400 Bad Request error\n */\n sendBadRequest(res: ServerResponse, message: string, details?: unknown): void;\n\n /**\n * Send a 404 Not Found error\n */\n sendNotFound(res: ServerResponse, message: string): void;\n\n /**\n * Send a 500 Internal Server Error\n */\n sendInternalError(\n res: ServerResponse,\n message?: string,\n details?: unknown,\n ): void;\n\n /**\n * Send a 503 Service Unavailable error\n */\n sendServiceUnavailable(res: ServerResponse, message: string): void;\n\n /**\n * Send a 202 Accepted response\n */\n sendAccepted(res: ServerResponse, data?: unknown): void;\n}\n\n/**\n * Response builder implementation\n */\nexport const responseBuilder: IResponseBuilder = {\n sendJson(res: ServerResponse, statusCode: number, data: unknown): void {\n res.writeHead(statusCode, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(data));\n },\n\n sendSuccess<T = unknown>(\n res: ServerResponse,\n data?: T,\n statusCode: number = 200,\n ): void {\n const response: SuccessResponse<T> = {\n status: \"success\",\n ...(data !== undefined && { data }),\n };\n this.sendJson(res, statusCode, response);\n },\n\n sendError(\n res: ServerResponse,\n error: string,\n statusCode: number = 500,\n message?: string,\n details?: unknown,\n ): void {\n const response: ErrorResponse = {\n error,\n };\n if (message) {\n response.message = message;\n }\n if (details) {\n response.details = details;\n }\n this.sendJson(res, statusCode, response);\n },\n\n sendBadRequest(\n res: ServerResponse,\n message: string,\n details?: unknown,\n ): void {\n this.sendError(res, \"Bad Request\", 400, message, details);\n },\n\n sendNotFound(res: ServerResponse, message: string): void {\n this.sendError(res, \"Not Found\", 404, message);\n },\n\n sendInternalError(\n res: ServerResponse,\n message: string = \"An internal error occurred\",\n details?: unknown,\n ): void {\n this.sendError(res, \"Internal Server Error\", 500, message, details);\n },\n\n sendServiceUnavailable(res: ServerResponse, message: string): void {\n this.sendError(res, \"Service Unavailable\", 503, message);\n },\n\n sendAccepted(res: ServerResponse, data?: unknown): void {\n const response = data || { status: \"accepted\" };\n this.sendJson(res, 202, response);\n },\n};\n","import z from \"zod\";\n\nexport const FunctionInvocationContextSessionDetails = z.object({\n id: z.string(),\n connectUrl: z.string(),\n});\n\nexport type FunctionInvocationContextSessionDetails = z.infer<\n typeof FunctionInvocationContextSessionDetails\n>;\n\nexport const FunctionInvocationContext = z.object({\n session: FunctionInvocationContextSessionDetails,\n});\n\nexport type FunctionInvocationContext = z.infer<\n typeof FunctionInvocationContext\n>;\n","import z from \"zod\";\nimport { FunctionInvocationContext } from \"./invocation.js\";\n\nexport const RuntimeEventPayload = z.object({\n functionName: z.string().min(1),\n params: z.looseObject({}), // Allow passthrough of unknown (all) keys\n context: FunctionInvocationContext,\n});\n\nexport type RuntimeEventPayload = z.infer<typeof RuntimeEventPayload>;\n\nexport const RuntimeEvent = z.object({\n requestId: z.string().min(1),\n event: RuntimeEventPayload,\n});\n\nexport type RuntimeEvent = z.infer<typeof RuntimeEvent>;\n\nexport const RuntimeError = z.object({\n errorMessage: z.string().min(1),\n errorType: z.string().min(1),\n stackTrace: z.array(z.string().min(1)),\n});\n\nexport type RuntimeError = z.infer<typeof RuntimeError>;\n","import { IncomingMessage, ServerResponse } from \"http\";\nimport { z } from \"zod\";\nimport chalk from \"chalk\";\nimport { type IInvocationBridge } from \"../bridge.js\";\nimport { type IRemoteBrowserManager } from \"../browser-manager.js\";\nimport { type IManifestStore } from \"./manifest-store.js\";\nimport { requestParser } from \"./request-parser.js\";\nimport { responseBuilder } from \"./response-builder.js\";\nimport { RuntimeError } from \"../../../schemas/events.js\";\nimport { FunctionInvocationContext } from \"../../../schemas/invocation.js\";\n\n/**\n * Dependencies required by the request handlers\n */\nexport interface RequestHandlerDependencies {\n bridge: IInvocationBridge;\n browserManager: IRemoteBrowserManager;\n manifestStore: IManifestStore;\n}\n\n/**\n * Interface for request handlers\n */\nexport interface IRequestHandlers {\n /**\n * Handle GET /2018-06-01/runtime/invocation/next\n * This endpoint is called by the runtime to get the next invocation.\n * We hold the connection until an invocation arrives.\n */\n handleInvocationNext(\n req: IncomingMessage,\n res: ServerResponse,\n ): Promise<void>;\n\n /**\n * Handle POST /v1/functions/:name/invoke\n * This endpoint is called by external clients to invoke a function.\n */\n handleFunctionInvoke(\n req: IncomingMessage,\n res: ServerResponse,\n functionName: string,\n ): Promise<void>;\n\n /**\n * Handle POST /2018-06-01/runtime/invocation/:requestId/response\n * This endpoint is called by the runtime when a function completes successfully.\n */\n handleInvocationResponse(\n req: IncomingMessage,\n res: ServerResponse,\n requestId: string,\n ): Promise<void>;\n\n /**\n * Handle POST /2018-06-01/runtime/invocation/:requestId/error\n * This endpoint is called by the runtime when a function fails.\n */\n handleInvocationError(\n req: IncomingMessage,\n res: ServerResponse,\n requestId: string,\n ): Promise<void>;\n}\n\n/**\n * Implementation of request handlers for the dev server\n */\nexport class DevServerHandlers implements IRequestHandlers {\n private readonly bridge: IInvocationBridge;\n private readonly browserManager: IRemoteBrowserManager;\n private readonly manifestStore: IManifestStore;\n\n constructor(deps: RequestHandlerDependencies) {\n this.bridge = deps.bridge;\n this.browserManager = deps.browserManager;\n this.manifestStore = deps.manifestStore;\n\n // Set up the session cleanup callback in the bridge\n this.bridge.setSessionCleanupCallback(async (sessionId: string) => {\n await this.cleanupSession(sessionId);\n });\n }\n\n /**\n * Handle GET /2018-06-01/runtime/invocation/next\n */\n public async handleInvocationNext(\n _req: IncomingMessage,\n res: ServerResponse,\n ): Promise<void> {\n // Hold the connection in the bridge\n this.bridge.holdNextConnection(res);\n\n // The response will be completed later when an invocation arrives\n // via triggerInvocation in the bridge\n }\n\n /**\n * Handle POST /v1/functions/:name/invoke\n */\n public async handleFunctionInvoke(\n req: IncomingMessage,\n res: ServerResponse,\n functionName: string,\n ): Promise<void> {\n try {\n // Define the invoke request schema\n const invokeSchema = z.object({\n functionName: z.string().optional(),\n params: z.unknown().default({}),\n context: FunctionInvocationContext.optional(),\n });\n\n // Parse and validate the request body\n const validatedData = await requestParser.parseAndValidate(\n req,\n invokeSchema,\n );\n\n // Use function name from URL path\n const finalFunctionName = functionName || validatedData.functionName;\n\n if (!finalFunctionName) {\n responseBuilder.sendBadRequest(res, \"Function name is required\");\n return;\n }\n\n // Look up function manifest to get sessionConfig\n const manifest = this.manifestStore.getManifest(finalFunctionName);\n\n if (!manifest) {\n console.error(\n chalk.red(`✗ Function \"${finalFunctionName}\" not found in registry`),\n );\n console.error(\n chalk.gray(\n \" Make sure the function is defined in your entrypoint file\",\n ),\n );\n responseBuilder.sendNotFound(\n res,\n `Function \"${finalFunctionName}\" not found in registry. Make sure it is defined with defineFn() in your entrypoint file.`,\n );\n return;\n }\n\n // Always create a browser session\n let session: { id: string; connectUrl: string };\n\n try {\n console.log(\n chalk.cyan(`Creating browser session for ${finalFunctionName}...`),\n );\n\n // Create session with function's sessionConfig if available\n const sessionConfig = manifest?.config?.sessionConfig || {};\n session = await this.browserManager.createSession(sessionConfig);\n } catch (error) {\n console.error(chalk.red(\"Failed to create browser session:\"), error);\n responseBuilder.sendInternalError(\n res,\n \"Failed to create browser session\",\n error instanceof Error ? error.message : String(error),\n );\n return;\n }\n\n // Build context with the created session\n const context = validatedData.context || {\n invocation: {\n id: crypto.randomUUID(),\n region: \"local\",\n },\n session: session,\n };\n\n // Always use the created session\n context.session = session;\n\n // Try to trigger the invocation\n const success = this.bridge.triggerInvocation(\n finalFunctionName,\n validatedData.params,\n context,\n res,\n );\n\n if (!success) {\n // Runtime not ready or another invocation in progress\n // Clean up the session we just created since we won't use it\n await this.cleanupSession(session.id);\n\n responseBuilder.sendServiceUnavailable(\n res,\n this.bridge.hasActiveInvocation()\n ? \"Another invocation is in progress\"\n : \"No runtime connected\",\n );\n return;\n }\n\n // The response will be completed later when the function completes\n // via completeWithSuccess or completeWithError in the bridge\n } catch (error) {\n if (error instanceof z.ZodError) {\n responseBuilder.sendBadRequest(res, \"Invalid request body\", error);\n } else {\n console.error(chalk.red(\"Error handling invoke:\"), error);\n responseBuilder.sendInternalError(res);\n }\n }\n }\n\n /**\n * Handle POST /2018-06-01/runtime/invocation/:requestId/response\n */\n public async handleInvocationResponse(\n req: IncomingMessage,\n res: ServerResponse,\n requestId: string,\n ): Promise<void> {\n try {\n // Parse the response body\n const body = await requestParser.parseJsonBody(req);\n\n // Complete the invocation with success\n const success = this.bridge.completeWithSuccess(requestId, body);\n\n if (!success) {\n responseBuilder.sendBadRequest(\n res,\n \"No matching invocation or request ID mismatch\",\n );\n return;\n }\n\n // Send acknowledgment to the runtime\n responseBuilder.sendAccepted(res);\n } catch (error) {\n console.error(chalk.red(\"Error handling response:\"), error);\n responseBuilder.sendInternalError(res);\n }\n }\n\n /**\n * Handle POST /2018-06-01/runtime/invocation/:requestId/error\n */\n public async handleInvocationError(\n req: IncomingMessage,\n res: ServerResponse,\n requestId: string,\n ): Promise<void> {\n try {\n // Parse and validate the error body using SDK schema\n const validatedError = await requestParser.parseAndValidate(\n req,\n RuntimeError,\n );\n\n // Complete the invocation with error\n const success = this.bridge.completeWithError(requestId, validatedError);\n\n if (!success) {\n responseBuilder.sendBadRequest(\n res,\n \"No matching invocation or request ID mismatch\",\n );\n return;\n }\n\n // Send acknowledgment to the runtime\n responseBuilder.sendAccepted(res);\n } catch (error) {\n if (error instanceof z.ZodError) {\n responseBuilder.sendBadRequest(res, \"Invalid error format\", error);\n } else {\n console.error(chalk.red(\"Error handling error report:\"), error);\n responseBuilder.sendInternalError(res);\n }\n }\n }\n\n /**\n * Private method to cleanup a browser session\n */\n private async cleanupSession(sessionId: string): Promise<void> {\n try {\n await this.browserManager.closeSession(sessionId);\n } catch (error) {\n console.error(\n chalk.red(`Failed to cleanup session ${sessionId}:`),\n error,\n );\n }\n }\n}\n","import { createServer, Server, IncomingMessage, ServerResponse } from \"http\";\nimport chalk from \"chalk\";\nimport { type IInvocationBridge } from \"./bridge.js\";\nimport { type IRemoteBrowserManager } from \"./browser-manager.js\";\nimport { type IRequestHandlers } from \"./handlers/index.js\";\n\nexport interface ServerOptions {\n port: number;\n host: string;\n bridge: IInvocationBridge;\n browserManager: IRemoteBrowserManager;\n handlers: IRequestHandlers;\n}\n\nexport interface RequestHandlerDeps {\n bridge: IInvocationBridge;\n browserManager: IRemoteBrowserManager;\n handlers: IRequestHandlers;\n}\n\n/**\n * Main request handler for the dev server\n * Extracted for testability\n */\nexport async function handleRequest(\n req: IncomingMessage,\n res: ServerResponse,\n deps: RequestHandlerDeps,\n): Promise<void> {\n const { handlers } = deps;\n const url = new URL(req.url || \"\", `http://${req.headers.host}`);\n const method = req.method || \"GET\";\n const path = url.pathname;\n\n console.log(chalk.gray(`[${method}] ${path}`));\n\n // Set CORS headers for local development\n res.setHeader(\"Access-Control-Allow-Origin\", \"*\");\n res.setHeader(\"Access-Control-Allow-Methods\", \"GET, POST, OPTIONS\");\n res.setHeader(\"Access-Control-Allow-Headers\", \"Content-Type\");\n\n // Handle preflight requests\n if (method === \"OPTIONS\") {\n res.writeHead(200);\n res.end();\n return;\n }\n\n try {\n // Route: GET / (healthcheck)\n if (method === \"GET\" && path === \"/\") {\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ ok: true }));\n return;\n }\n\n // Route: GET /2018-06-01/runtime/invocation/next\n if (method === \"GET\" && path === \"/2018-06-01/runtime/invocation/next\") {\n await handlers.handleInvocationNext(req, res);\n return;\n }\n\n // Route: POST /v1/functions/:name/invoke\n const invokeMatch = path.match(/^\\/v1\\/functions\\/([^/]+)\\/invoke$/);\n if (method === \"POST\" && invokeMatch && invokeMatch[1]) {\n const functionName = invokeMatch[1];\n await handlers.handleFunctionInvoke(req, res, functionName);\n return;\n }\n\n // Route: POST /2018-06-01/runtime/invocation/:requestId/response\n const responseMatch = path.match(\n /^\\/2018-06-01\\/runtime\\/invocation\\/([^/]+)\\/response$/,\n );\n if (method === \"POST\" && responseMatch && responseMatch[1]) {\n const requestId = responseMatch[1];\n await handlers.handleInvocationResponse(req, res, requestId);\n return;\n }\n\n // Route: POST /2018-06-01/runtime/invocation/:requestId/error\n const errorMatch = path.match(\n /^\\/2018-06-01\\/runtime\\/invocation\\/([^/]+)\\/error$/,\n );\n if (method === \"POST\" && errorMatch && errorMatch[1]) {\n const requestId = errorMatch[1];\n await handlers.handleInvocationError(req, res, requestId);\n return;\n }\n\n // 404 for unknown routes\n res.writeHead(404, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Not found\" }));\n } catch (error) {\n console.error(chalk.red(\"Server error:\"), error);\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Internal server error\" }));\n }\n}\n\nexport async function startServer(options: ServerOptions): Promise<Server> {\n const { port, host, bridge, browserManager, handlers } = options;\n\n const server = createServer(\n async (req: IncomingMessage, res: ServerResponse) => {\n await handleRequest(req, res, { bridge, browserManager, handlers });\n },\n );\n\n return new Promise((resolve, reject) => {\n server.listen(port, host, () => {\n resolve(server);\n });\n\n server.on(\"error\", (error: NodeJS.ErrnoException) => {\n if (error.code === \"EADDRINUSE\") {\n reject(new Error(`Port ${port} is already in use`));\n } else if (error.code === \"EACCES\") {\n reject(new Error(`Permission denied to bind to port ${port}`));\n } else {\n reject(error);\n }\n });\n });\n}\n","import { spawn, ChildProcess } from \"node:child_process\";\nimport { createRequire } from \"node:module\";\nimport chalk from \"chalk\";\n\nexport interface ProcessManagerOptions {\n entrypoint: string;\n runtimeApiUrl: string;\n verbose: boolean;\n}\n\n/**\n * Interface for managing the lifecycle of the user's function process.\n * Spawns tsx watch to enable hot reloading during development.\n */\nexport interface IProcessManager {\n /**\n * Start the user's function process using tsx watch.\n */\n start(): Promise<void>;\n\n /**\n * Stop the user's function process.\n */\n stop(): Promise<void>;\n\n /**\n * Check if the process is currently running.\n */\n isRunning(): boolean;\n}\n\n/**\n * Manages the lifecycle of the user's function process.\n * Spawns tsx watch to enable hot reloading during development.\n */\nexport class ProcessManager implements IProcessManager {\n private process: ChildProcess | null = null;\n private entrypoint: string;\n private runtimeApiUrl: string;\n private verbose: boolean;\n private isShuttingDown = false;\n\n constructor(options: ProcessManagerOptions) {\n this.entrypoint = options.entrypoint;\n this.runtimeApiUrl = options.runtimeApiUrl;\n this.verbose = options.verbose;\n }\n\n /**\n * Start the user's function process using tsx watch.\n */\n public async start(): Promise<void> {\n if (this.process) {\n throw new Error(\"Process is already running\");\n }\n\n if (this.verbose) {\n console.log(chalk.gray(`Starting runtime process...`));\n console.log(\n chalk.gray(\n ` Command: tsx watch --clear-screen=false ${this.entrypoint}`,\n ),\n );\n console.log(chalk.gray(` Working directory: ${process.cwd()}`));\n console.log(chalk.gray(` Runtime API: ${this.runtimeApiUrl}`));\n }\n\n const createdRequire = createRequire(import.meta.url);\n const tsxCli = createdRequire.resolve(\"tsx/cli\");\n\n const args = [\"watch\", \"--clear-screen=false\", this.entrypoint];\n\n // Spawn tsx watch with the user's entrypoint\n this.process = spawn(process.execPath, [tsxCli, ...args], {\n cwd: process.cwd(),\n env: {\n ...process.env,\n AWS_LAMBDA_RUNTIME_API: this.runtimeApiUrl,\n BB_FUNCTIONS_PHASE: \"runtime\",\n NODE_ENV: \"local\",\n },\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n\n // Handle stdout\n this.process.stdout?.on(\"data\", (data) => {\n const lines = data.toString().trim().split(\"\\n\");\n lines.forEach((line: string) => {\n if (line.trim()) {\n console.log(chalk.blue(\"[Runtime]\"), line);\n }\n });\n });\n\n // Handle stderr\n this.process.stderr?.on(\"data\", (data) => {\n const lines = data.toString().trim().split(\"\\n\");\n lines.forEach((line: string) => {\n if (line.trim()) {\n // Check if it's a tsx watch message\n if (line.includes(\"Watching for file changes\")) {\n console.log(chalk.green(\"✓ Runtime watching for file changes\"));\n } else if (line.includes(\"Restarting\")) {\n console.log(\n chalk.yellow(\"↻ Runtime restarting due to file change...\"),\n );\n } else {\n console.error(chalk.red(\"[Runtime Error]\"), line);\n }\n }\n });\n });\n\n // Handle process exit\n this.process.on(\"exit\", (code, signal) => {\n if (!this.isShuttingDown) {\n if (code !== 0) {\n console.error(\n chalk.red(\n `✗ Runtime process exited unexpectedly with code ${code}`,\n ),\n );\n if (signal) {\n console.error(chalk.red(` Signal: ${signal}`));\n }\n } else {\n console.log(chalk.gray(\"Runtime process exited\"));\n }\n this.process = null;\n }\n });\n\n // Handle process errors\n this.process.on(\"error\", (error) => {\n if ((error as Error & { code: string }).code === \"ENOENT\") {\n console.error(\n chalk.red(\"✗ Failed to start runtime: tsx not found\"),\n chalk.yellow(\n \"\\n Make sure tsx is installed: npm install -g tsx or pnpm add tsx\",\n ),\n );\n } else {\n console.error(chalk.red(\"✗ Failed to start runtime process:\"), error);\n }\n this.process = null;\n });\n\n // Give the process a moment to start\n await new Promise((resolve) => setTimeout(resolve, 100));\n\n if (!this.process || this.process.exitCode !== null) {\n throw new Error(\"Failed to start runtime process\");\n }\n\n console.log(chalk.green(\"✓ Runtime process started\"));\n }\n\n /**\n * Stop the user's function process.\n */\n public async stop(): Promise<void> {\n if (!this.process) {\n return;\n }\n\n this.isShuttingDown = true;\n\n if (this.verbose) {\n console.log(chalk.gray(\"Stopping runtime process...\"));\n }\n\n return new Promise((resolve) => {\n if (!this.process) {\n resolve();\n return;\n }\n\n // Set a timeout to force kill if graceful shutdown fails\n const killTimeout = setTimeout(() => {\n if (this.process) {\n console.log(chalk.yellow(\"⚠️ Force killing runtime process\"));\n this.process.kill(\"SIGKILL\");\n }\n }, 5000);\n\n this.process.on(\"exit\", () => {\n clearTimeout(killTimeout);\n this.process = null;\n console.log(chalk.green(\"✓ Runtime process stopped\"));\n resolve();\n });\n\n // Try graceful shutdown first\n this.process.kill(\"SIGTERM\");\n });\n }\n\n /**\n * Check if the process is currently running.\n */\n public isRunning(): boolean {\n return this.process !== null && this.process.exitCode === null;\n }\n}\n","import chalk from \"chalk\";\nimport { startServer } from \"./server.js\";\nimport { InvocationBridge } from \"./bridge.js\";\nimport { ProcessManager } from \"./process.js\";\nimport { RemoteBrowserManager } from \"./browser-manager.js\";\nimport { DevServerHandlers } from \"./handlers/index.js\";\nimport \"dotenv/config\";\nimport { ManifestStore } from \"./handlers/manifest-store.js\";\nimport type { Server } from \"node:http\";\n\nexport interface DevServerOptions {\n entrypoint: string;\n port: number;\n host: string;\n verbose: boolean;\n}\n\nexport async function startDevServer(options: DevServerOptions): Promise<void> {\n const { entrypoint, port, host, verbose } = options;\n\n // Check if we're in production mode\n if (process.env[\"NODE_ENV\"] === \"production\") {\n console.warn(\n chalk.yellow(\n \"⚠️ Warning: Running dev server in production mode. This is not recommended.\",\n ),\n );\n }\n\n // Set the runtime API URL\n const runtimeApiUrl = `${host}:${port}`;\n\n if (verbose) {\n console.log(chalk.gray(`Runtime API URL: ${runtimeApiUrl}`));\n }\n\n // Create the invocation bridge\n const bridge = new InvocationBridge(verbose);\n\n // Create the browser manager\n const browserManager = new RemoteBrowserManager();\n await browserManager.initialize();\n\n // Create and initialize the manifest store\n const manifestStore = new ManifestStore();\n manifestStore.loadManifests();\n\n // Create the handlers with all dependencies\n const handlers = new DevServerHandlers({\n bridge,\n browserManager,\n manifestStore,\n });\n\n // Create the process manager\n const processManager = new ProcessManager({\n entrypoint,\n runtimeApiUrl,\n verbose,\n });\n\n // Start the server\n let server: Server | null = null;\n\n try {\n // Start the server first\n server = await startServer({\n port,\n host,\n bridge,\n browserManager,\n handlers,\n });\n\n console.log(\n chalk.green(`✓ Development server listening on http://${host}:${port}`),\n );\n\n // Then start the user's function process\n console.log(chalk.cyan(\"Starting runtime process...\"));\n await processManager.start();\n\n // Wait for runtime to connect with retry logic\n const maxWaitTime = 10000; // 10 seconds max\n const pollInterval = 200; // Check every 200ms\n const startTime = Date.now();\n let runtimeConnected = false;\n\n while (Date.now() - startTime < maxWaitTime) {\n if (bridge.isRuntimeConnected()) {\n runtimeConnected = true;\n console.log(chalk.green(\"✓ Runtime connected and ready\"));\n // Reload manifests after runtime starts as it may have created them\n manifestStore.loadManifests();\n break;\n }\n await new Promise((resolve) => setTimeout(resolve, pollInterval));\n }\n\n if (!runtimeConnected) {\n console.log(\n chalk.yellow(\n \"⚠️ Runtime is taking longer than expected to connect...\",\n ),\n );\n // Still try to reload manifests in case they were written\n manifestStore.loadManifests();\n }\n\n // Handle graceful shutdown\n const shutdown = async () => {\n console.log(chalk.cyan(\"\\n📦 Shutting down...\"));\n\n // Stop the user process first\n await processManager.stop();\n\n // Then close the server\n return new Promise<void>((resolve) => {\n server?.close(() => {\n console.log(chalk.green(\"✓ Server closed\"));\n resolve();\n });\n });\n };\n\n // Handle process termination\n process.on(\"SIGINT\", async () => {\n await shutdown();\n process.exit(0);\n });\n\n process.on(\"SIGTERM\", async () => {\n await shutdown();\n process.exit(0);\n });\n } catch (error) {\n console.error(chalk.red(\"Failed to start:\"), error);\n\n // Clean up on error\n if (processManager.isRunning()) {\n await processManager.stop();\n }\n if (server) {\n server.close();\n }\n\n throw error;\n }\n}\n","import { execSync } from \"child_process\";\nimport {\n existsSync,\n readFileSync,\n writeFileSync,\n copyFileSync,\n mkdirSync,\n} from \"fs\";\nimport { join, resolve } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { dirname } from \"path\";\nimport chalk from \"chalk\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\ninterface InitOptions {\n projectName: string;\n packageManager?: \"npm\" | \"pnpm\";\n}\n\nexport async function init(options: InitOptions) {\n // Validate project name\n if (!isValidProjectName(options.projectName)) {\n throw new Error(\n `Invalid project name \"${options.projectName}\". Project names must start with a letter and contain only letters, numbers, hyphens, and underscores.`,\n );\n }\n\n const targetDir = resolve(process.cwd(), options.projectName);\n\n // Check if directory already exists\n if (existsSync(targetDir)) {\n throw new Error(\n `Directory \"${options.projectName}\" already exists. Please choose a different name or delete the existing directory.`,\n );\n }\n\n console.log(\n chalk.cyan(\n `🚀 Creating new Browserbase Functions project: ${chalk.bold(options.projectName)}`,\n ),\n );\n\n // Create the project directory\n mkdirSync(targetDir, { recursive: true });\n\n try {\n // Step 1: Check prerequisites\n checkPrerequisites();\n\n // Step 2: Initialize git repository\n if (!existsSync(join(targetDir, \".git\"))) {\n console.log(chalk.gray(\"Initializing git repository...\"));\n execSync(\"git init\", { cwd: targetDir, stdio: \"pipe\" });\n console.log(chalk.green(\"✓ Git repository initialized\"));\n } else {\n console.log(chalk.yellow(\"✓ Git repository already exists\"));\n }\n\n // Step 3: Create .gitignore file\n createGitignoreFile(targetDir);\n\n // Step 4: Initialize package.json\n if (!existsSync(join(targetDir, \"package.json\"))) {\n console.log(chalk.gray(\"Creating package.json...\"));\n execSync(\"pnpm init\", { cwd: targetDir, stdio: \"pipe\" });\n console.log(chalk.green(\"✓ package.json created\"));\n } else {\n console.log(chalk.yellow(\"✓ package.json already exists\"));\n }\n\n // Step 5: Detect and update package manager\n const packageManager = detectPackageManager(options.packageManager);\n updatePackageManager(targetDir, packageManager);\n\n // Step 6: Install dependencies\n console.log(chalk.gray(\"Installing dependencies...\"));\n installDependencies(targetDir, packageManager);\n console.log(chalk.green(\"✓ Dependencies installed\"));\n\n // Step 7: Create .env file\n createEnvFile(targetDir);\n\n // Step 8: Initialize TypeScript configuration\n if (!existsSync(join(targetDir, \"tsconfig.json\"))) {\n console.log(chalk.gray(\"Initializing TypeScript configuration...\"));\n execSync(`${packageManager === \"pnpm\" ? \"pnpm\" : \"npx\"} tsc --init`, {\n cwd: targetDir,\n stdio: \"pipe\",\n });\n\n // Update tsconfig.json with recommended settings\n updateTsConfig(targetDir);\n console.log(chalk.green(\"✓ TypeScript configuration created\"));\n } else {\n console.log(chalk.yellow(\"✓ TypeScript configuration already exists\"));\n }\n\n // Step 9: Create starter function\n createStarterFunction(targetDir);\n\n // Success message\n console.log(\"\");\n console.log(chalk.green.bold(\"✨ Project initialized successfully!\"));\n console.log(\"\");\n console.log(chalk.cyan(\"Next steps:\"));\n console.log(chalk.gray(\"1. Navigate to your project:\"));\n console.log(chalk.white(` cd ${options.projectName}`));\n console.log(\n chalk.gray(\"2. Add your Browserbase API key and project ID to .env\"),\n );\n console.log(chalk.gray(\"3. Run your function locally:\"));\n console.log(\n chalk.white(\n ` ${packageManager === \"pnpm\" ? \"pnpm\" : \"npx\"} bb dev index.ts`,\n ),\n );\n console.log(chalk.gray(\"4. When ready, publish your function:\"));\n console.log(\n chalk.white(\n ` ${packageManager === \"pnpm\" ? \"pnpm\" : \"npx\"} bb publish index.ts`,\n ),\n );\n console.log(\"\");\n console.log(chalk.gray(\"Learn more at https://browserbase.com/docs\"));\n } catch (error) {\n console.error(\n chalk.red(\"❌ Initialization failed:\"),\n error instanceof Error ? error.message : error,\n );\n process.exit(1);\n }\n}\n\nfunction checkPrerequisites() {\n const requiredCommands = [\n { command: \"node --version\", name: \"Node.js\" },\n { command: \"pnpm --version\", name: \"pnpm\" },\n { command: \"git --version\", name: \"git\" },\n ];\n\n for (const { command, name } of requiredCommands) {\n try {\n execSync(command, { stdio: \"pipe\" });\n } catch {\n throw new Error(\n `${name} is not installed. Please install ${name} and try again.`,\n );\n }\n }\n}\n\nfunction detectPackageManager(preferred?: \"npm\" | \"pnpm\"): \"npm\" | \"pnpm\" {\n if (preferred) {\n return preferred;\n }\n\n // Check if running via pnpm dlx\n const userAgent = process.env[\"npm_config_user_agent\"];\n if (userAgent && userAgent.includes(\"pnpm\")) {\n return \"pnpm\";\n }\n\n // Default to pnpm since it's required anyway\n return \"pnpm\";\n}\n\nfunction updatePackageManager(\n targetDir: string,\n packageManager: \"npm\" | \"pnpm\",\n) {\n const packageJsonPath = join(targetDir, \"package.json\");\n const packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\n\n // Get the version of the package manager\n let version: string;\n try {\n if (packageManager === \"pnpm\") {\n version = execSync(\"pnpm --version\", { stdio: \"pipe\" }).toString().trim();\n packageJson.packageManager = `pnpm@${version}`;\n } else {\n version = execSync(\"npm --version\", { stdio: \"pipe\" }).toString().trim();\n packageJson.packageManager = `npm@${version}`;\n }\n } catch {\n // If we can't get the version, use a recent stable version\n packageJson.packageManager =\n packageManager === \"pnpm\" ? \"pnpm@9.0.0\" : \"npm@10.0.0\";\n }\n\n writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));\n console.log(\n chalk.green(`✓ Package manager set to ${packageJson.packageManager}`),\n );\n}\n\nfunction installDependencies(\n targetDir: string,\n packageManager: \"npm\" | \"pnpm\",\n) {\n const installCmd = packageManager === \"pnpm\" ? \"pnpm add\" : \"npm install\";\n const installDevCmd =\n packageManager === \"pnpm\" ? \"pnpm add -D\" : \"npm install --save-dev\";\n\n // Install regular dependencies\n console.log(chalk.gray(\" Installing @browserbasehq/sdk-functions...\"));\n execSync(`${installCmd} @browserbasehq/sdk-functions`, {\n cwd: targetDir,\n stdio: \"pipe\",\n });\n\n console.log(chalk.gray(\" Installing playwright-core...\"));\n execSync(`${installCmd} playwright-core`, {\n cwd: targetDir,\n stdio: \"pipe\",\n });\n\n // Install dev dependencies\n console.log(chalk.gray(\" Installing TypeScript and type definitions...\"));\n execSync(`${installDevCmd} typescript @types/node`, {\n cwd: targetDir,\n stdio: \"pipe\",\n });\n}\n\nfunction createEnvFile(targetDir: string) {\n const envPath = join(targetDir, \".env\");\n if (!existsSync(envPath)) {\n const templatePath = join(__dirname, \"templates\", \".env.template\");\n copyFileSync(templatePath, envPath);\n console.log(chalk.green(\"✓ .env file created\"));\n } else {\n console.log(chalk.yellow(\"✓ .env file already exists\"));\n }\n}\n\nfunction createGitignoreFile(targetDir: string) {\n const gitignorePath = join(targetDir, \".gitignore\");\n if (!existsSync(gitignorePath)) {\n const templatePath = join(__dirname, \"templates\", \".gitignore.template\");\n copyFileSync(templatePath, gitignorePath);\n console.log(chalk.green(\"✓ .gitignore file created\"));\n } else {\n console.log(chalk.yellow(\"✓ .gitignore file already exists\"));\n }\n}\n\nfunction createStarterFunction(targetDir: string) {\n const indexPath = join(targetDir, \"index.ts\");\n if (!existsSync(indexPath)) {\n const templatePath = join(\n __dirname,\n \"templates\",\n \"starter-function.ts.template\",\n );\n copyFileSync(templatePath, indexPath);\n console.log(chalk.green(\"✓ Starter function created (index.ts)\"));\n } else {\n console.log(chalk.yellow(\"✓ index.ts already exists\"));\n }\n}\n\nfunction updateTsConfig(targetDir: string) {\n const tsConfigPath = join(targetDir, \"tsconfig.json\");\n\n try {\n const tsConfig = JSON.parse(readFileSync(tsConfigPath, \"utf-8\"));\n\n // Update with recommended settings for Browserbase functions\n tsConfig.compilerOptions = {\n ...tsConfig.compilerOptions,\n target: \"ES2022\",\n module: \"NodeNext\",\n moduleResolution: \"NodeNext\",\n esModuleInterop: true,\n forceConsistentCasingInFileNames: true,\n strict: true,\n skipLibCheck: true,\n resolveJsonModule: true,\n };\n\n writeFileSync(tsConfigPath, JSON.stringify(tsConfig, null, 2));\n } catch {\n // If we can't parse/update, that's okay - the default tsc --init output will work\n console.log(chalk.yellow(\" Using default TypeScript configuration\"));\n }\n}\n\nfunction isValidProjectName(name: string): boolean {\n // Project name must start with a letter and contain only letters, numbers, hyphens, and underscores\n const validNameRegex = /^[a-zA-Z][a-zA-Z0-9_-]*$/;\n return validNameRegex.test(name);\n}\n","#!/usr/bin/env node\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { startDevServer } from \"./dev/index.js\";\nimport { init } from \"./init/index.js\";\n\n// Version is injected at build time\ndeclare const __CLI_VERSION__: string;\n\nconst program = new Command();\n\nprogram\n .name(\"bb\")\n .description(\"Browserbase Functions CLI\")\n .version(__CLI_VERSION__);\n\nconst validPackageManagers = [\"npm\", \"pnpm\"];\n\nprogram\n .command(\"init <project-name>\")\n .description(\"Initialize a new Browserbase Functions project\")\n .option(\n \"-p, --package-manager <manager>\",\n `Package manager to use (${validPackageManagers.join(\" or \")})`,\n \"pnpm\",\n )\n .action(async (projectName, options) => {\n try {\n const packageManager = options.packageManager.toLowerCase();\n\n if (!validPackageManagers.includes(packageManager)) {\n console.error(\n chalk.red(\n `Error: Invalid package manager \"${options.packageManager}\"`,\n ),\n );\n console.error(\n chalk.gray(`Valid options are: ${validPackageManagers.join(\", \")}`),\n );\n process.exit(1);\n }\n\n await init({\n projectName: projectName,\n packageManager: packageManager as \"npm\" | \"pnpm\",\n });\n } catch (error) {\n console.error(chalk.red(\"Initialization failed:\"), error);\n process.exit(1);\n }\n });\n\nprogram\n .command(\"dev\")\n .description(\n \"Start a local development server for testing Browserbase Functions\",\n )\n .argument(\n \"<entrypoint>\",\n \"Path to the TypeScript/JavaScript file that imports all your functions\",\n )\n .option(\"-p, --port <number>\", \"Port to listen on\", \"14113\")\n .option(\"-h, --host <string>\", \"Host to bind to\", \"127.0.0.1\")\n .action(async (entrypoint, options) => {\n try {\n // Validate entrypoint file exists\n const fs = await import(\"fs\");\n const path = await import(\"path\");\n\n const entrypointPath = path.resolve(entrypoint);\n if (!fs.existsSync(entrypointPath)) {\n console.error(\n chalk.red(`Error: Entrypoint file not found: ${entrypointPath}`),\n );\n process.exit(1);\n }\n\n // Validate file extension\n const ext = path.extname(entrypointPath);\n if (![\".ts\", \".tsx\", \".js\", \".jsx\", \".mjs\", \".cjs\"].includes(ext)) {\n console.error(\n chalk.red(\n `Error: Invalid file extension. Expected .ts, .tsx, .js, .jsx, .mjs, or .cjs`,\n ),\n );\n process.exit(1);\n }\n\n const port = parseInt(options.port, 10);\n if (isNaN(port) || port < 1 || port > 65535) {\n console.error(\n chalk.red(\"Error: Invalid port number. Must be between 1 and 65535.\"),\n );\n process.exit(1);\n }\n\n console.log(\n chalk.cyan(\"Starting Browserbase Functions development server...\"),\n );\n console.log(chalk.gray(`Entrypoint: ${entrypointPath}`));\n\n await startDevServer({\n entrypoint: entrypointPath,\n port,\n host: options.host,\n verbose: options.verbose,\n });\n } catch (error) {\n console.error(chalk.red(\"Failed to start development server:\"), error);\n process.exit(1);\n }\n });\n\nprogram\n .command(\"publish\")\n .description(\"Publish your Browserbase Function to the cloud\")\n .argument(\n \"<entrypoint>\",\n \"Path to the TypeScript/JavaScript file that imports all your functions\",\n )\n .option(\"-u, --api-url <url>\", \"API endpoint URL\")\n .option(\"--dry-run\", \"Show what would be published without uploading\")\n .action(async (entrypoint, options) => {\n try {\n const { publishFunction } = await import(\"./publish/index.js\");\n await publishFunction({\n entrypoint: entrypoint,\n apiUrl: options.apiUrl,\n dryRun: options.dryRun,\n });\n } catch (error) {\n console.error(chalk.red(\"Publish failed:\"), error);\n process.exit(1);\n }\n });\n\nprogram.parse();\n"]}
@@ -0,0 +1,8 @@
1
+ # Browserbase Configuration
2
+ # Get your API key and project ID from https://browserbase.com
3
+
4
+ # Your Browserbase API key
5
+ BB_API_KEY=your_api_key_here
6
+
7
+ # Your Browserbase project ID
8
+ BB_PROJECT_ID=your_project_id_here
@@ -0,0 +1,18 @@
1
+ # Dependencies
2
+ node_modules/
3
+
4
+ # Environment variables
5
+ .env
6
+ .env.local
7
+
8
+ # TypeScript build info
9
+ *.tsbuildinfo
10
+
11
+ # OS files
12
+ .DS_Store
13
+ Thumbs.db
14
+
15
+ # Logs
16
+ *.log
17
+ npm-debug.log*
18
+ pnpm-debug.log*
@@ -0,0 +1,61 @@
1
+ import { defineFn } from "@browserbasehq/sdk-functions";
2
+ import { chromium } from "playwright-core";
3
+
4
+ // This is your first Browserbase function!
5
+ // You can run it locally with: bb dev index.ts
6
+ // Once ready, publish it with: bb publish index.ts
7
+
8
+ type HNSubmission = {
9
+ title: string | null;
10
+ url: string | null;
11
+ rank: number;
12
+ };
13
+
14
+ defineFn("my-function", async (context) => {
15
+ const { session } = context;
16
+
17
+ console.log("Connecting to browser session:", session.id);
18
+
19
+ // Connect to the browser instance
20
+ const browser = await chromium.connectOverCDP(session.connectUrl);
21
+ const browserContext = browser.contexts()[0]!;
22
+ const page = browserContext.pages()[0]!;
23
+
24
+ // Navigate to Hacker News
25
+ console.log("Navigating to Hacker News...");
26
+ await page.goto("https://news.ycombinator.com");
27
+
28
+ // Wait for the content to load
29
+ await page.waitForSelector(".athing", { timeout: 30000 });
30
+
31
+ // Extract the first three submission titles
32
+ const titles = await page.evaluate(() => {
33
+ const results: HNSubmission[] = [];
34
+
35
+ document.querySelectorAll(".athing").forEach((submission, idx) => {
36
+ if (idx >= 3) return; // only return 3
37
+
38
+ const titleElement = submission.querySelector(".titleline > a");
39
+
40
+ if (titleElement) {
41
+ results.push({
42
+ title: titleElement.textContent ?? null,
43
+ url: titleElement.getAttribute("href"),
44
+ rank: idx + 1,
45
+ });
46
+ }
47
+ });
48
+
49
+ return results;
50
+ });
51
+
52
+ console.log(`Successfully extracted ${titles.length} titles`);
53
+
54
+ // Return the results
55
+ return {
56
+ message: "Successfully fetched top Hacker News stories",
57
+ timestamp: new Date().toISOString(),
58
+ results: titles,
59
+ };
60
+ });
61
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@browserbasehq/sdk-functions",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "exports": {