@@ -11,7 +11,7 @@ import { promisify } from "node:util";
1111import { randomUUID } from "node:crypto" ;
1212import { createServer } from "node:net" ;
1313import { constants as fsConstants } from "node:fs" ;
14- import { access } from "node:fs/promises" ;
14+ import { access , readdir } from "node:fs/promises" ;
1515import { dirname , resolve } from "node:path" ;
1616import { fileURLToPath } from "node:url" ;
1717
@@ -409,33 +409,98 @@ async function isDockerImageAvailable(image: string): Promise<boolean> {
409409 }
410410}
411411
412- async function resolveSandboxAgentCli ( ) : Promise < string > {
412+ interface SandboxAgentCommand {
413+ command : string ;
414+ args ?: string [ ] ;
415+ }
416+
417+ async function findPnpmPackageDir (
418+ pnpmDir : string ,
419+ prefix : string ,
420+ ) : Promise < string | null > {
421+ try {
422+ const entries = await readdir ( pnpmDir ) ;
423+ const match = entries . find ( ( entry ) => entry . startsWith ( prefix ) ) ;
424+ return match ? resolve ( pnpmDir , match ) : null ;
425+ } catch {
426+ return null ;
427+ }
428+ }
429+
430+ async function resolveSandboxAgentCommand ( ) : Promise < SandboxAgentCommand > {
413431 const packageDir = dirname (
414432 fileURLToPath ( new URL ( "../../package.json" , import . meta. url ) ) ,
415433 ) ;
416- const candidates = [
417- resolve (
418- packageDir ,
419- "node_modules" ,
420- "sandbox-agent" ,
421- "node_modules" ,
422- ".bin" ,
423- "sandbox-agent" ,
424- ) ,
434+ const workspaceRoot = resolve ( packageDir , ".." , ".." ) ;
435+ const pnpmDir = resolve ( workspaceRoot , "node_modules" , ".pnpm" ) ;
436+ const platformPackage = ( ( ) => {
437+ if ( process . platform === "linux" && process . arch === "x64" ) {
438+ return "@sandbox-agent+cli-linux-x64@" ;
439+ }
440+ if ( process . platform === "linux" && process . arch === "arm64" ) {
441+ return "@sandbox-agent+cli-linux-arm64@" ;
442+ }
443+ if ( process . platform === "darwin" && process . arch === "arm64" ) {
444+ return "@sandbox-agent+cli-darwin-arm64@" ;
445+ }
446+ if ( process . platform === "darwin" && process . arch === "x64" ) {
447+ return "@sandbox-agent+cli-darwin-x64@" ;
448+ }
449+ if ( process . platform === "win32" && process . arch === "x64" ) {
450+ return "@sandbox-agent+cli-win32-x64@" ;
451+ }
452+ return null ;
453+ } ) ( ) ;
454+
455+ if ( platformPackage ) {
456+ const platformDir = await findPnpmPackageDir ( pnpmDir , platformPackage ) ;
457+ if ( platformDir ) {
458+ const binName = process . platform === "win32" ? "sandbox-agent.exe" : "sandbox-agent" ;
459+ const candidate = resolve (
460+ platformDir ,
461+ "node_modules" ,
462+ platformPackage . slice ( 0 , - 1 ) . replace ( "+" , "/" ) ,
463+ "bin" ,
464+ binName ,
465+ ) ;
466+ try {
467+ await access ( candidate , fsConstants . X_OK ) ;
468+ return { command : candidate } ;
469+ } catch {
470+ // Fall through to the JS launcher.
471+ }
472+ }
473+ }
474+
475+ const cliPackageDir = await findPnpmPackageDir ( pnpmDir , "@sandbox-agent+cli@" ) ;
476+ const scriptCandidates = cliPackageDir
477+ ? [
478+ resolve (
479+ cliPackageDir ,
480+ "node_modules" ,
481+ "@sandbox-agent" ,
482+ "cli" ,
483+ "bin" ,
484+ "sandbox-agent" ,
485+ ) ,
486+ ]
487+ : [ ] ;
488+ const fallbackCandidates = [
425489 resolve (
426490 packageDir ,
427- ".." ,
428- ".." ,
429491 "node_modules" ,
430492 ".bin" ,
431493 "sandbox-agent" ,
432494 ) ,
433495 ] ;
434496
435- for ( const candidate of candidates ) {
497+ for ( const candidate of [ ... scriptCandidates , ... fallbackCandidates ] ) {
436498 try {
437499 await access ( candidate , fsConstants . X_OK ) ;
438- return candidate ;
500+ if ( candidate . endsWith ( ".bin/sandbox-agent" ) ) {
501+ return { command : candidate } ;
502+ }
503+ return { command : process . execPath , args : [ candidate ] } ;
439504 } catch {
440505 // Try the next candidate.
441506 }
@@ -473,13 +538,14 @@ async function startLocalSandboxAgent(
473538 port : number ,
474539 timeout : number ,
475540) : Promise < ContainerHandle > {
476- const cliPath = await resolveSandboxAgentCli ( ) ;
541+ const cli = await resolveSandboxAgentCommand ( ) ;
477542 const name = `sandbox-agent-local-${ randomUUID ( ) . slice ( 0 , 8 ) } ` ;
478543 const stdoutChunks : string [ ] = [ ] ;
479544 const stderrChunks : string [ ] = [ ] ;
480545 const child = spawn (
481- cliPath ,
546+ cli . command ,
482547 [
548+ ...( cli . args ?? [ ] ) ,
483549 "server" ,
484550 "--host" ,
485551 "127.0.0.1" ,
0 commit comments