Skip to content

Commit ccd8600

Browse files
AhmedTMMclaude
andauthored
fix: scope local warning to openclaw-only + improve spawn skill docs (#3074)
- Revert local security warning to openclaw-only (was blocking all agents) - Update spawn skill to document how to run prompts on child VMs: - Always use `bash -lc` (binaries in ~/.local/bin/ need login shell) - Claude uses `-p` not `--print` or `--headless` - Add `--dangerously-skip-permissions` for unattended child VMs - Don't waste tokens with `which`/`find` or creating non-root users - Sync all on-disk skill files with embedded version Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent a29d0d8 commit ccd8600

11 files changed

Lines changed: 166 additions & 71 deletions

File tree

packages/cli/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@openrouter/spawn",
3-
"version": "0.27.5",
3+
"version": "0.27.6",
44
"type": "module",
55
"bin": {
66
"spawn": "cli.js"

packages/cli/src/local/main.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@ async function main() {
2121

2222
const agent = resolveAgent(agentName);
2323

24-
// Warn about security implications of installing agents locally
25-
if (process.env.SPAWN_NON_INTERACTIVE !== "1") {
24+
// Warn about security implications of installing OpenClaw locally
25+
// (OpenClaw has browser access and broader system control than other agents)
26+
if (agentName === "openclaw" && process.env.SPAWN_NON_INTERACTIVE !== "1") {
2627
process.stderr.write("\n");
2728
logWarn("⚠ Local installation warning");
2829
logWarn(` This will install ${agent.name} directly on your machine.`);

packages/cli/src/shared/spawn-skill.ts

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,37 +24,35 @@ const SKILL_BODY = `# Spawn — Create Child VMs
2424
2525
You have the \`spawn\` CLI installed. Use it to provision cloud VMs with AI agents.
2626
27-
## Usage
27+
## Provision a Child VM
2828
2929
\`\`\`bash
3030
spawn <agent> <cloud> --headless --output json --prompt "task description"
3131
\`\`\`
3232
33-
## Agents: claude, codex, openclaw, zeroclaw, opencode, kilocode, hermes, junie
34-
## Clouds: hetzner, digitalocean, aws, gcp, sprite
35-
36-
## Example
37-
38-
\`\`\`bash
39-
spawn claude hetzner --headless --output json --prompt "Implement the auth module"
40-
\`\`\`
33+
**Agents:** claude, codex, openclaw, zeroclaw, opencode, kilocode, hermes, junie
34+
**Clouds:** hetzner, digitalocean, aws, gcp, sprite
4135
4236
Returns JSON: \`{"status":"success","ip_address":"...","ssh_user":"root","server_id":"..."}\`
4337
44-
## Running a prompt on a child VM
38+
## Running Prompts on Child VMs
4539
46-
**--headless only provisions the VM — it does NOT run the prompt on it.**
47-
To actually execute work on the child, SSH in and run the agent:
40+
\`--headless\` only provisions — to run work on the child, SSH in with \`bash -lc\`:
4841
4942
\`\`\`bash
50-
ssh -o StrictHostKeyChecking=accept-new root@<ip_address> '~/.local/bin/claude --print "your prompt"'
43+
# Claude Code (use -p, NOT --print or --headless)
44+
ssh -o StrictHostKeyChecking=accept-new root@<ip> "bash -lc 'claude -p --dangerously-skip-permissions \\"your prompt\\"'"
45+
46+
# Codex CLI
47+
ssh -o StrictHostKeyChecking=accept-new root@<ip> "bash -lc 'codex --quiet \\"your prompt\\"'"
5148
\`\`\`
5249
53-
### Known gotchas — do NOT waste time rediscovering these:
54-
- Agent binaries are at \`~/.local/bin/\`, NOT on the default PATH. Always use the full path: \`~/.local/bin/claude\`, \`~/.local/bin/codex\`, etc.
55-
- Claude Code blocks \`--dangerously-skip-permissions\` as root. Use \`--print\` for one-shot prompts instead — it works as root and returns the response directly.
56-
- 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\`.
57-
- For long-running tasks, use \`spawn delete --name <name> --yes\` to clean up when done.
50+
### IMPORTANT — do NOT waste tokens rediscovering these:
51+
- **Always use \`bash -lc\`** — agent binaries are in \`~/.local/bin/\` which is only on PATH in login shells
52+
- **Claude uses \`-p\`** for non-interactive output (NOT \`--print\`, NOT \`--headless\`)
53+
- **Add \`--dangerously-skip-permissions\`** to skip approval prompts on child VMs
54+
- **Never try \`which claude\` or \`find\`** to locate binaries — they are always at \`~/.local/bin/<agent>\`
55+
- **Never create non-root users** to work around permission issues — just use \`-p\`
5856
5957
## Managing Children
6058
@@ -78,7 +76,7 @@ You have the \`spawn\` CLI for creating child cloud VMs with AI agents.
7876
Use \`spawn <agent> <cloud> --headless --output json --prompt "task"\` to delegate work.
7977
Available agents: claude, codex, openclaw, zeroclaw, opencode, kilocode, hermes, junie.
8078
Cloud credentials are pre-configured. Run \`spawn list --json\` to see children.
81-
Note: --headless only provisions the VM. To run a prompt, SSH in: \`ssh root@<ip> '~/.local/bin/<agent> --print "prompt"'\`.
79+
\`--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/).
8280
`;
8381

8482
// ─── Agent config ───────────────────────────────────────────────────────────

skills/claude/SKILL.md

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,40 @@ allowed-tools: Bash
88

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

11-
## Usage
11+
## Provision a Child VM
1212

1313
```bash
1414
spawn <agent> <cloud> --headless --output json --prompt "task description"
1515
```
1616

17-
## Agents: claude, codex, openclaw, zeroclaw, opencode, kilocode, hermes, junie
18-
## Clouds: hetzner, digitalocean, aws, gcp, sprite
17+
**Agents:** claude, codex, openclaw, zeroclaw, opencode, kilocode, hermes, junie
18+
**Clouds:** hetzner, digitalocean, aws, gcp, sprite
1919

20-
## Example
20+
Returns JSON: `{"status":"success","ip_address":"...","ssh_user":"root","server_id":"..."}`
21+
22+
## Running Prompts on Child VMs
23+
24+
`--headless` only provisions — to run work on the child, SSH in with `bash -lc`:
2125

2226
```bash
23-
spawn claude hetzner --headless --output json --prompt "Implement the auth module"
27+
# Claude Code (use -p, NOT --print or --headless)
28+
ssh -o StrictHostKeyChecking=accept-new root@<ip> "bash -lc 'claude -p --dangerously-skip-permissions \"your prompt\"'"
29+
30+
# Codex CLI
31+
ssh -o StrictHostKeyChecking=accept-new root@<ip> "bash -lc 'codex --quiet \"your prompt\"'"
2432
```
2533

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

2841
## Managing Children
2942

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

3447
## Context

skills/codex/SKILL.md

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,40 @@ allowed-tools: Bash
88

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

11-
## Usage
11+
## Provision a Child VM
1212

1313
```bash
1414
spawn <agent> <cloud> --headless --output json --prompt "task description"
1515
```
1616

17-
## Agents: claude, codex, openclaw, zeroclaw, opencode, kilocode, hermes, junie
18-
## Clouds: hetzner, digitalocean, aws, gcp, sprite
17+
**Agents:** claude, codex, openclaw, zeroclaw, opencode, kilocode, hermes, junie
18+
**Clouds:** hetzner, digitalocean, aws, gcp, sprite
1919

20-
## Example
20+
Returns JSON: `{"status":"success","ip_address":"...","ssh_user":"root","server_id":"..."}`
21+
22+
## Running Prompts on Child VMs
23+
24+
`--headless` only provisions — to run work on the child, SSH in with `bash -lc`:
2125

2226
```bash
23-
spawn claude hetzner --headless --output json --prompt "Implement the auth module"
27+
# Claude Code (use -p, NOT --print or --headless)
28+
ssh -o StrictHostKeyChecking=accept-new root@<ip> "bash -lc 'claude -p --dangerously-skip-permissions \"your prompt\"'"
29+
30+
# Codex CLI
31+
ssh -o StrictHostKeyChecking=accept-new root@<ip> "bash -lc 'codex --quiet \"your prompt\"'"
2432
```
2533

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

2841
## Managing Children
2942

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

3447
## Context

skills/hermes/SOUL.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ You have the `spawn` CLI for creating child cloud VMs with AI agents.
66
Use `spawn <agent> <cloud> --headless --output json --prompt "task"` to delegate work.
77
Available agents: claude, codex, openclaw, zeroclaw, opencode, kilocode, hermes, junie.
88
Cloud credentials are pre-configured. Run `spawn list --json` to see children.
9+
`--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/).

skills/junie/AGENTS.md

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,45 @@
22

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

5-
## Usage
5+
## Provision a Child VM
66

77
```bash
88
spawn <agent> <cloud> --headless --output json --prompt "task description"
99
```
1010

11-
## Agents: claude, codex, openclaw, zeroclaw, opencode, kilocode, hermes, junie
12-
## Clouds: hetzner, digitalocean, aws, gcp, sprite
11+
**Agents:** claude, codex, openclaw, zeroclaw, opencode, kilocode, hermes, junie
12+
**Clouds:** hetzner, digitalocean, aws, gcp, sprite
1313

14-
## Example
14+
Returns JSON: `{"status":"success","ip_address":"...","ssh_user":"root","server_id":"..."}`
15+
16+
## Running Prompts on Child VMs
17+
18+
`--headless` only provisions — to run work on the child, SSH in with `bash -lc`:
1519

1620
```bash
17-
spawn claude hetzner --headless --output json --prompt "Implement the auth module"
21+
# Claude Code (use -p, NOT --print or --headless)
22+
ssh -o StrictHostKeyChecking=accept-new root@<ip> "bash -lc 'claude -p --dangerously-skip-permissions \"your prompt\"'"
23+
24+
# Codex CLI
25+
ssh -o StrictHostKeyChecking=accept-new root@<ip> "bash -lc 'codex --quiet \"your prompt\"'"
1826
```
1927

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

2235
## Managing Children
2336

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

2841
## Context
2942

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

skills/kilocode/spawn.md

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,45 @@
22

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

5-
## Usage
5+
## Provision a Child VM
66

77
```bash
88
spawn <agent> <cloud> --headless --output json --prompt "task description"
99
```
1010

11-
## Agents: claude, codex, openclaw, zeroclaw, opencode, kilocode, hermes, junie
12-
## Clouds: hetzner, digitalocean, aws, gcp, sprite
11+
**Agents:** claude, codex, openclaw, zeroclaw, opencode, kilocode, hermes, junie
12+
**Clouds:** hetzner, digitalocean, aws, gcp, sprite
1313

14-
## Example
14+
Returns JSON: `{"status":"success","ip_address":"...","ssh_user":"root","server_id":"..."}`
15+
16+
## Running Prompts on Child VMs
17+
18+
`--headless` only provisions — to run work on the child, SSH in with `bash -lc`:
1519

1620
```bash
17-
spawn claude hetzner --headless --output json --prompt "Implement the auth module"
21+
# Claude Code (use -p, NOT --print or --headless)
22+
ssh -o StrictHostKeyChecking=accept-new root@<ip> "bash -lc 'claude -p --dangerously-skip-permissions \"your prompt\"'"
23+
24+
# Codex CLI
25+
ssh -o StrictHostKeyChecking=accept-new root@<ip> "bash -lc 'codex --quiet \"your prompt\"'"
1826
```
1927

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

2235
## Managing Children
2336

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

2841
## Context
2942

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

skills/openclaw/SKILL.md

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,40 @@ allowed-tools: Bash
88

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

11-
## Usage
11+
## Provision a Child VM
1212

1313
```bash
1414
spawn <agent> <cloud> --headless --output json --prompt "task description"
1515
```
1616

17-
## Agents: claude, codex, openclaw, zeroclaw, opencode, kilocode, hermes, junie
18-
## Clouds: hetzner, digitalocean, aws, gcp, sprite
17+
**Agents:** claude, codex, openclaw, zeroclaw, opencode, kilocode, hermes, junie
18+
**Clouds:** hetzner, digitalocean, aws, gcp, sprite
1919

20-
## Example
20+
Returns JSON: `{"status":"success","ip_address":"...","ssh_user":"root","server_id":"..."}`
21+
22+
## Running Prompts on Child VMs
23+
24+
`--headless` only provisions — to run work on the child, SSH in with `bash -lc`:
2125

2226
```bash
23-
spawn claude hetzner --headless --output json --prompt "Implement the auth module"
27+
# Claude Code (use -p, NOT --print or --headless)
28+
ssh -o StrictHostKeyChecking=accept-new root@<ip> "bash -lc 'claude -p --dangerously-skip-permissions \"your prompt\"'"
29+
30+
# Codex CLI
31+
ssh -o StrictHostKeyChecking=accept-new root@<ip> "bash -lc 'codex --quiet \"your prompt\"'"
2432
```
2533

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

2841
## Managing Children
2942

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

3447
## Context

skills/opencode/AGENTS.md

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,45 @@
22

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

5-
## Usage
5+
## Provision a Child VM
66

77
```bash
88
spawn <agent> <cloud> --headless --output json --prompt "task description"
99
```
1010

11-
## Agents: claude, codex, openclaw, zeroclaw, opencode, kilocode, hermes, junie
12-
## Clouds: hetzner, digitalocean, aws, gcp, sprite
11+
**Agents:** claude, codex, openclaw, zeroclaw, opencode, kilocode, hermes, junie
12+
**Clouds:** hetzner, digitalocean, aws, gcp, sprite
1313

14-
## Example
14+
Returns JSON: `{"status":"success","ip_address":"...","ssh_user":"root","server_id":"..."}`
15+
16+
## Running Prompts on Child VMs
17+
18+
`--headless` only provisions — to run work on the child, SSH in with `bash -lc`:
1519

1620
```bash
17-
spawn claude hetzner --headless --output json --prompt "Implement the auth module"
21+
# Claude Code (use -p, NOT --print or --headless)
22+
ssh -o StrictHostKeyChecking=accept-new root@<ip> "bash -lc 'claude -p --dangerously-skip-permissions \"your prompt\"'"
23+
24+
# Codex CLI
25+
ssh -o StrictHostKeyChecking=accept-new root@<ip> "bash -lc 'codex --quiet \"your prompt\"'"
1826
```
1927

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

2235
## Managing Children
2336

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

2841
## Context
2942

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

0 commit comments

Comments
 (0)