diff --git a/packages/cli/package.json b/packages/cli/package.json index 16490a47..fe652ccc 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@openrouter/spawn", - "version": "0.13.2", + "version": "0.13.3", "type": "module", "bin": { "spawn": "cli.js" diff --git a/packages/cli/src/commands/help.ts b/packages/cli/src/commands/help.ts index 38666b2a..81af0963 100644 --- a/packages/cli/src/commands/help.ts +++ b/packages/cli/src/commands/help.ts @@ -6,6 +6,8 @@ function getHelpUsageSection(): string { spawn Interactive agent + cloud picker spawn Launch agent on cloud directly spawn --dry-run Preview what would be provisioned (or -n) + spawn --zone Set zone/region (works for all clouds) + spawn --size Set instance size/type (works for all clouds) spawn --custom Show interactive size/region pickers spawn --headless Provision and exit (no interactive session) spawn --output json @@ -44,6 +46,9 @@ function getHelpExamplesSection(): string { spawn codex sprite -p "Add tests" ${pc.dim("# Short form of --prompt")} spawn openclaw aws -f instructions.txt ${pc.dim("# Read prompt from file (short for --prompt-file)")} + spawn claude gcp --zone us-east1-b ${pc.dim("# Use a specific GCP zone")} + spawn claude gcp --size e2-standard-4 + ${pc.dim("# Use a specific machine type")} spawn opencode gcp --dry-run ${pc.dim("# Preview without provisioning")} spawn claude hetzner --headless ${pc.dim("# Provision, print connection info, exit")} spawn claude hetzner --output json ${pc.dim("# Structured JSON output on stdout")} diff --git a/packages/cli/src/flags.ts b/packages/cli/src/flags.ts index e619e573..9c992d66 100644 --- a/packages/cli/src/flags.ts +++ b/packages/cli/src/flags.ts @@ -24,6 +24,10 @@ export const KNOWN_FLAGS = new Set([ "--clear", "--custom", "--reauth", + "--zone", + "--region", + "--machine-type", + "--size", ]); /** Return the first unknown flag in args, or null if all are known/positional */ diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index 6c1ef461..62de03f8 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -93,6 +93,8 @@ function checkUnknownFlags(args: string[]): void { console.error(` ${pc.cyan("--headless")} Non-interactive mode (no prompts, no SSH session)`); console.error(` ${pc.cyan("--output json")} Output structured JSON to stdout`); console.error(` ${pc.cyan("--custom")} Show interactive size/region pickers`); + console.error(` ${pc.cyan("--zone, --region")} Set zone/region (e.g. us-east1-b, nyc3)`); + console.error(` ${pc.cyan("--size, --machine-type")} Set instance size (e.g. e2-standard-4, s-2vcpu-4gb)`); console.error(` ${pc.cyan("--name")} Set the spawn/resource name`); console.error(` ${pc.cyan("--reauth")} Force re-prompting for cloud credentials`); console.error(` ${pc.cyan("--help, -h")} Show help information`); @@ -767,6 +769,42 @@ async function main(): Promise { process.env.SPAWN_NAME = nameFlag; } + // Extract --zone / --region flag (maps to cloud-specific env vars) + const [zoneFlag, zoneFilteredArgs] = extractFlagValue( + filteredArgs, + [ + "--zone", + "--region", + ], + "zone/region", + "spawn gcp --zone us-east1-b", + ); + filteredArgs.splice(0, filteredArgs.length, ...zoneFilteredArgs); + if (zoneFlag) { + process.env.GCP_ZONE = zoneFlag; + process.env.DO_REGION = zoneFlag; + process.env.HETZNER_LOCATION = zoneFlag; + process.env.AWS_DEFAULT_REGION = zoneFlag; + } + + // Extract --machine-type / --size flag (maps to cloud-specific env vars) + const [sizeFlag, sizeFilteredArgs] = extractFlagValue( + filteredArgs, + [ + "--machine-type", + "--size", + ], + "machine type/size", + "spawn gcp --machine-type e2-standard-4", + ); + filteredArgs.splice(0, filteredArgs.length, ...sizeFilteredArgs); + if (sizeFlag) { + process.env.GCP_MACHINE_TYPE = sizeFlag; + process.env.DO_DROPLET_SIZE = sizeFlag; + process.env.HETZNER_SERVER_TYPE = sizeFlag; + process.env.LIGHTSAIL_BUNDLE = sizeFlag; + } + // --output implies --headless const effectiveHeadless = headless || !!outputFormat;