Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@openrouter/spawn",
"version": "0.27.5",
"version": "0.27.6",
"type": "module",
"bin": {
"spawn": "cli.js"
Expand Down
5 changes: 3 additions & 2 deletions packages/cli/src/local/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ async function main() {

const agent = resolveAgent(agentName);

// Warn about security implications of installing agents locally
if (process.env.SPAWN_NON_INTERACTIVE !== "1") {
// Warn about security implications of installing OpenClaw locally
// (OpenClaw has browser access and broader system control than other agents)
if (agentName === "openclaw" && process.env.SPAWN_NON_INTERACTIVE !== "1") {
process.stderr.write("\n");
logWarn("⚠ Local installation warning");
logWarn(` This will install ${agent.name} directly on your machine.`);
Expand Down
36 changes: 17 additions & 19 deletions packages/cli/src/shared/spawn-skill.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,37 +24,35 @@ const SKILL_BODY = `# Spawn — Create Child VMs

You have the \`spawn\` CLI installed. Use it to provision cloud VMs with AI agents.

## Usage
## Provision a Child VM

\`\`\`bash
spawn <agent> <cloud> --headless --output json --prompt "task description"
\`\`\`

## Agents: claude, codex, openclaw, zeroclaw, opencode, kilocode, hermes, junie
## Clouds: hetzner, digitalocean, aws, gcp, sprite

## Example

\`\`\`bash
spawn claude hetzner --headless --output json --prompt "Implement the auth module"
\`\`\`
**Agents:** claude, codex, openclaw, zeroclaw, opencode, kilocode, hermes, junie
**Clouds:** hetzner, digitalocean, aws, gcp, sprite

Returns JSON: \`{"status":"success","ip_address":"...","ssh_user":"root","server_id":"..."}\`

## Running a prompt on a child VM
## Running Prompts on Child VMs

**--headless only provisions the VM — it does NOT run the prompt on it.**
To actually execute work on the child, SSH in and run the agent:
\`--headless\` only provisions — to run work on the child, SSH in with \`bash -lc\`:

\`\`\`bash
ssh -o StrictHostKeyChecking=accept-new root@<ip_address> '~/.local/bin/claude --print "your prompt"'
# Claude Code (use -p, NOT --print or --headless)
ssh -o StrictHostKeyChecking=accept-new root@<ip> "bash -lc 'claude -p --dangerously-skip-permissions \\"your prompt\\"'"

# Codex CLI
ssh -o StrictHostKeyChecking=accept-new root@<ip> "bash -lc 'codex --quiet \\"your prompt\\"'"
\`\`\`

### Known gotchas — do NOT waste time rediscovering these:
- Agent binaries are at \`~/.local/bin/\`, NOT on the default PATH. Always use the full path: \`~/.local/bin/claude\`, \`~/.local/bin/codex\`, etc.
- Claude Code blocks \`--dangerously-skip-permissions\` as root. Use \`--print\` for one-shot prompts instead — it works as root and returns the response directly.
- Do NOT try to create a non-root user to work around root restrictions — it requires copying config files (\`.claude.json\`, \`.claude/settings.json\`, env vars) and is fragile. Just use \`--print\`.
- For long-running tasks, use \`spawn delete --name <name> --yes\` to clean up when done.
### IMPORTANT — do NOT waste tokens rediscovering these:
- **Always use \`bash -lc\`** — agent binaries are in \`~/.local/bin/\` which is only on PATH in login shells
- **Claude uses \`-p\`** for non-interactive output (NOT \`--print\`, NOT \`--headless\`)
- **Add \`--dangerously-skip-permissions\`** to skip approval prompts on child VMs
- **Never try \`which claude\` or \`find\`** to locate binaries — they are always at \`~/.local/bin/<agent>\`
- **Never create non-root users** to work around permission issues — just use \`-p\`

## Managing Children

Expand All @@ -78,7 +76,7 @@ You have the \`spawn\` CLI for creating child cloud VMs with AI agents.
Use \`spawn <agent> <cloud> --headless --output json --prompt "task"\` to delegate work.
Available agents: claude, codex, openclaw, zeroclaw, opencode, kilocode, hermes, junie.
Cloud credentials are pre-configured. Run \`spawn list --json\` to see children.
Note: --headless only provisions the VM. To run a prompt, SSH in: \`ssh root@<ip> '~/.local/bin/<agent> --print "prompt"'\`.
\`--headless\` only provisions. To run a prompt on the child: \`ssh root@<ip> "bash -lc 'claude -p --dangerously-skip-permissions \\"prompt\\"'"\`. Always use \`bash -lc\` (binaries are in ~/.local/bin/).
`;

// ─── Agent config ───────────────────────────────────────────────────────────
Expand Down
27 changes: 20 additions & 7 deletions skills/claude/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,40 @@ allowed-tools: Bash

You have the `spawn` CLI installed. Use it to provision cloud VMs with AI agents.

## Usage
## Provision a Child VM

```bash
spawn <agent> <cloud> --headless --output json --prompt "task description"
```

## Agents: claude, codex, openclaw, zeroclaw, opencode, kilocode, hermes, junie
## Clouds: hetzner, digitalocean, aws, gcp, sprite
**Agents:** claude, codex, openclaw, zeroclaw, opencode, kilocode, hermes, junie
**Clouds:** hetzner, digitalocean, aws, gcp, sprite

## Example
Returns JSON: `{"status":"success","ip_address":"...","ssh_user":"root","server_id":"..."}`

## Running Prompts on Child VMs

`--headless` only provisions — to run work on the child, SSH in with `bash -lc`:

```bash
spawn claude hetzner --headless --output json --prompt "Implement the auth module"
# Claude Code (use -p, NOT --print or --headless)
ssh -o StrictHostKeyChecking=accept-new root@<ip> "bash -lc 'claude -p --dangerously-skip-permissions \"your prompt\"'"

# Codex CLI
ssh -o StrictHostKeyChecking=accept-new root@<ip> "bash -lc 'codex --quiet \"your prompt\"'"
```

Returns JSON: `{"status":"success","ip_address":"...","ssh_user":"root","server_id":"..."}`
### IMPORTANT — do NOT waste tokens rediscovering these:
- **Always use `bash -lc`** — agent binaries are in `~/.local/bin/` which is only on PATH in login shells
- **Claude uses `-p`** for non-interactive output (NOT `--print`, NOT `--headless`)
- **Add `--dangerously-skip-permissions`** to skip approval prompts on child VMs
- **Never try `which claude` or `find`** to locate binaries — they are always at `~/.local/bin/<agent>`
- **Never create non-root users** to work around permission issues — just use `-p`

## Managing Children

- `spawn list --json` — see running children
- `spawn delete --name <name> --yes` — tear down a child VM
- `spawn delete --name <name> --yes` — tear down a child VM (headless)
- `spawn tree` — see the full spawn tree

## Context
Expand Down
27 changes: 20 additions & 7 deletions skills/codex/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,40 @@ allowed-tools: Bash

You have the `spawn` CLI installed. Use it to provision cloud VMs with AI agents.

## Usage
## Provision a Child VM

```bash
spawn <agent> <cloud> --headless --output json --prompt "task description"
```

## Agents: claude, codex, openclaw, zeroclaw, opencode, kilocode, hermes, junie
## Clouds: hetzner, digitalocean, aws, gcp, sprite
**Agents:** claude, codex, openclaw, zeroclaw, opencode, kilocode, hermes, junie
**Clouds:** hetzner, digitalocean, aws, gcp, sprite

## Example
Returns JSON: `{"status":"success","ip_address":"...","ssh_user":"root","server_id":"..."}`

## Running Prompts on Child VMs

`--headless` only provisions — to run work on the child, SSH in with `bash -lc`:

```bash
spawn claude hetzner --headless --output json --prompt "Implement the auth module"
# Claude Code (use -p, NOT --print or --headless)
ssh -o StrictHostKeyChecking=accept-new root@<ip> "bash -lc 'claude -p --dangerously-skip-permissions \"your prompt\"'"

# Codex CLI
ssh -o StrictHostKeyChecking=accept-new root@<ip> "bash -lc 'codex --quiet \"your prompt\"'"
```

Returns JSON: `{"status":"success","ip_address":"...","ssh_user":"root","server_id":"..."}`
### IMPORTANT — do NOT waste tokens rediscovering these:
- **Always use `bash -lc`** — agent binaries are in `~/.local/bin/` which is only on PATH in login shells
- **Claude uses `-p`** for non-interactive output (NOT `--print`, NOT `--headless`)
- **Add `--dangerously-skip-permissions`** to skip approval prompts on child VMs
- **Never try `which claude` or `find`** to locate binaries — they are always at `~/.local/bin/<agent>`
- **Never create non-root users** to work around permission issues — just use `-p`

## Managing Children

- `spawn list --json` — see running children
- `spawn delete --name <name> --yes` — tear down a child VM
- `spawn delete --name <name> --yes` — tear down a child VM (headless)
- `spawn tree` — see the full spawn tree

## Context
Expand Down
1 change: 1 addition & 0 deletions skills/hermes/SOUL.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ You have the `spawn` CLI for creating child cloud VMs with AI agents.
Use `spawn <agent> <cloud> --headless --output json --prompt "task"` to delegate work.
Available agents: claude, codex, openclaw, zeroclaw, opencode, kilocode, hermes, junie.
Cloud credentials are pre-configured. Run `spawn list --json` to see children.
`--headless` only provisions. To run a prompt on the child: `ssh root@<ip> "bash -lc 'claude -p --dangerously-skip-permissions \"prompt\"'"`. Always use `bash -lc` (binaries are in ~/.local/bin/).
28 changes: 21 additions & 7 deletions skills/junie/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,45 @@

You have the `spawn` CLI installed. Use it to provision cloud VMs with AI agents.

## Usage
## Provision a Child VM

```bash
spawn <agent> <cloud> --headless --output json --prompt "task description"
```

## Agents: claude, codex, openclaw, zeroclaw, opencode, kilocode, hermes, junie
## Clouds: hetzner, digitalocean, aws, gcp, sprite
**Agents:** claude, codex, openclaw, zeroclaw, opencode, kilocode, hermes, junie
**Clouds:** hetzner, digitalocean, aws, gcp, sprite

## Example
Returns JSON: `{"status":"success","ip_address":"...","ssh_user":"root","server_id":"..."}`

## Running Prompts on Child VMs

`--headless` only provisions — to run work on the child, SSH in with `bash -lc`:

```bash
spawn claude hetzner --headless --output json --prompt "Implement the auth module"
# Claude Code (use -p, NOT --print or --headless)
ssh -o StrictHostKeyChecking=accept-new root@<ip> "bash -lc 'claude -p --dangerously-skip-permissions \"your prompt\"'"

# Codex CLI
ssh -o StrictHostKeyChecking=accept-new root@<ip> "bash -lc 'codex --quiet \"your prompt\"'"
```

Returns JSON: `{"status":"success","ip_address":"...","ssh_user":"root","server_id":"..."}`
### IMPORTANT — do NOT waste tokens rediscovering these:
- **Always use `bash -lc`** — agent binaries are in `~/.local/bin/` which is only on PATH in login shells
- **Claude uses `-p`** for non-interactive output (NOT `--print`, NOT `--headless`)
- **Add `--dangerously-skip-permissions`** to skip approval prompts on child VMs
- **Never try `which claude` or `find`** to locate binaries — they are always at `~/.local/bin/<agent>`
- **Never create non-root users** to work around permission issues — just use `-p`

## Managing Children

- `spawn list --json` — see running children
- `spawn delete --name <name> --yes` — tear down a child VM
- `spawn delete --name <name> --yes` — tear down a child VM (headless)
- `spawn tree` — see the full spawn tree

## Context

- You are running inside a spawned VM (SPAWN_DEPTH is set)
- Cloud credentials are pre-configured — no auth prompts
- OpenRouter billing is shared with the parent

28 changes: 21 additions & 7 deletions skills/kilocode/spawn.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,45 @@

You have the `spawn` CLI installed. Use it to provision cloud VMs with AI agents.

## Usage
## Provision a Child VM

```bash
spawn <agent> <cloud> --headless --output json --prompt "task description"
```

## Agents: claude, codex, openclaw, zeroclaw, opencode, kilocode, hermes, junie
## Clouds: hetzner, digitalocean, aws, gcp, sprite
**Agents:** claude, codex, openclaw, zeroclaw, opencode, kilocode, hermes, junie
**Clouds:** hetzner, digitalocean, aws, gcp, sprite

## Example
Returns JSON: `{"status":"success","ip_address":"...","ssh_user":"root","server_id":"..."}`

## Running Prompts on Child VMs

`--headless` only provisions — to run work on the child, SSH in with `bash -lc`:

```bash
spawn claude hetzner --headless --output json --prompt "Implement the auth module"
# Claude Code (use -p, NOT --print or --headless)
ssh -o StrictHostKeyChecking=accept-new root@<ip> "bash -lc 'claude -p --dangerously-skip-permissions \"your prompt\"'"

# Codex CLI
ssh -o StrictHostKeyChecking=accept-new root@<ip> "bash -lc 'codex --quiet \"your prompt\"'"
```

Returns JSON: `{"status":"success","ip_address":"...","ssh_user":"root","server_id":"..."}`
### IMPORTANT — do NOT waste tokens rediscovering these:
- **Always use `bash -lc`** — agent binaries are in `~/.local/bin/` which is only on PATH in login shells
- **Claude uses `-p`** for non-interactive output (NOT `--print`, NOT `--headless`)
- **Add `--dangerously-skip-permissions`** to skip approval prompts on child VMs
- **Never try `which claude` or `find`** to locate binaries — they are always at `~/.local/bin/<agent>`
- **Never create non-root users** to work around permission issues — just use `-p`

## Managing Children

- `spawn list --json` — see running children
- `spawn delete --name <name> --yes` — tear down a child VM
- `spawn delete --name <name> --yes` — tear down a child VM (headless)
- `spawn tree` — see the full spawn tree

## Context

- You are running inside a spawned VM (SPAWN_DEPTH is set)
- Cloud credentials are pre-configured — no auth prompts
- OpenRouter billing is shared with the parent

27 changes: 20 additions & 7 deletions skills/openclaw/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,40 @@ allowed-tools: Bash

You have the `spawn` CLI installed. Use it to provision cloud VMs with AI agents.

## Usage
## Provision a Child VM

```bash
spawn <agent> <cloud> --headless --output json --prompt "task description"
```

## Agents: claude, codex, openclaw, zeroclaw, opencode, kilocode, hermes, junie
## Clouds: hetzner, digitalocean, aws, gcp, sprite
**Agents:** claude, codex, openclaw, zeroclaw, opencode, kilocode, hermes, junie
**Clouds:** hetzner, digitalocean, aws, gcp, sprite

## Example
Returns JSON: `{"status":"success","ip_address":"...","ssh_user":"root","server_id":"..."}`

## Running Prompts on Child VMs

`--headless` only provisions — to run work on the child, SSH in with `bash -lc`:

```bash
spawn claude hetzner --headless --output json --prompt "Implement the auth module"
# Claude Code (use -p, NOT --print or --headless)
ssh -o StrictHostKeyChecking=accept-new root@<ip> "bash -lc 'claude -p --dangerously-skip-permissions \"your prompt\"'"

# Codex CLI
ssh -o StrictHostKeyChecking=accept-new root@<ip> "bash -lc 'codex --quiet \"your prompt\"'"
```

Returns JSON: `{"status":"success","ip_address":"...","ssh_user":"root","server_id":"..."}`
### IMPORTANT — do NOT waste tokens rediscovering these:
- **Always use `bash -lc`** — agent binaries are in `~/.local/bin/` which is only on PATH in login shells
- **Claude uses `-p`** for non-interactive output (NOT `--print`, NOT `--headless`)
- **Add `--dangerously-skip-permissions`** to skip approval prompts on child VMs
- **Never try `which claude` or `find`** to locate binaries — they are always at `~/.local/bin/<agent>`
- **Never create non-root users** to work around permission issues — just use `-p`

## Managing Children

- `spawn list --json` — see running children
- `spawn delete --name <name> --yes` — tear down a child VM
- `spawn delete --name <name> --yes` — tear down a child VM (headless)
- `spawn tree` — see the full spawn tree

## Context
Expand Down
28 changes: 21 additions & 7 deletions skills/opencode/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,45 @@

You have the `spawn` CLI installed. Use it to provision cloud VMs with AI agents.

## Usage
## Provision a Child VM

```bash
spawn <agent> <cloud> --headless --output json --prompt "task description"
```

## Agents: claude, codex, openclaw, zeroclaw, opencode, kilocode, hermes, junie
## Clouds: hetzner, digitalocean, aws, gcp, sprite
**Agents:** claude, codex, openclaw, zeroclaw, opencode, kilocode, hermes, junie
**Clouds:** hetzner, digitalocean, aws, gcp, sprite

## Example
Returns JSON: `{"status":"success","ip_address":"...","ssh_user":"root","server_id":"..."}`

## Running Prompts on Child VMs

`--headless` only provisions — to run work on the child, SSH in with `bash -lc`:

```bash
spawn claude hetzner --headless --output json --prompt "Implement the auth module"
# Claude Code (use -p, NOT --print or --headless)
ssh -o StrictHostKeyChecking=accept-new root@<ip> "bash -lc 'claude -p --dangerously-skip-permissions \"your prompt\"'"

# Codex CLI
ssh -o StrictHostKeyChecking=accept-new root@<ip> "bash -lc 'codex --quiet \"your prompt\"'"
```

Returns JSON: `{"status":"success","ip_address":"...","ssh_user":"root","server_id":"..."}`
### IMPORTANT — do NOT waste tokens rediscovering these:
- **Always use `bash -lc`** — agent binaries are in `~/.local/bin/` which is only on PATH in login shells
- **Claude uses `-p`** for non-interactive output (NOT `--print`, NOT `--headless`)
- **Add `--dangerously-skip-permissions`** to skip approval prompts on child VMs
- **Never try `which claude` or `find`** to locate binaries — they are always at `~/.local/bin/<agent>`
- **Never create non-root users** to work around permission issues — just use `-p`

## Managing Children

- `spawn list --json` — see running children
- `spawn delete --name <name> --yes` — tear down a child VM
- `spawn delete --name <name> --yes` — tear down a child VM (headless)
- `spawn tree` — see the full spawn tree

## Context

- You are running inside a spawned VM (SPAWN_DEPTH is set)
- Cloud credentials are pre-configured — no auth prompts
- OpenRouter billing is shared with the parent

Loading
Loading