fix: scope local warning to openclaw-only + improve spawn skill docs (#3074)
Some checks failed
CLI Release / Build and release CLI (push) Has been cancelled
Lint / ShellCheck (push) Has been cancelled
Lint / Biome Lint (push) Has been cancelled
Lint / macOS Compatibility (push) Has been cancelled

- 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>
This commit is contained in:
Ahmed Abushagur 2026-03-27 22:54:24 -07:00 committed by GitHub
parent a29d0d8a15
commit ccd86005ce
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 187 additions and 92 deletions

View file

@ -1,6 +1,6 @@
{
"name": "@openrouter/spawn",
"version": "0.27.5",
"version": "0.27.6",
"type": "module",
"bin": {
"spawn": "cli.js"

View file

@ -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.`);

View file

@ -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
@ -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 ───────────────────────────────────────────────────────────

View file

@ -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
## 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 Prompts on Child VMs
`--headless` only provisions — to run work on the child, SSH in with `bash -lc`:
```bash
# 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\"'"
```
### 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

View file

@ -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
## 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 Prompts on Child VMs
`--headless` only provisions — to run work on the child, SSH in with `bash -lc`:
```bash
# 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\"'"
```
### 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

View file

@ -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/).

View file

@ -2,27 +2,40 @@
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 Prompts on Child VMs
`--headless` only provisions — to run work on the child, SSH in with `bash -lc`:
```bash
# 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\"'"
```
### 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
@ -30,3 +43,4 @@ Returns JSON: `{"status":"success","ip_address":"...","ssh_user":"root","server_
- 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

View file

@ -2,27 +2,40 @@
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 Prompts on Child VMs
`--headless` only provisions — to run work on the child, SSH in with `bash -lc`:
```bash
# 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\"'"
```
### 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
@ -30,3 +43,4 @@ Returns JSON: `{"status":"success","ip_address":"...","ssh_user":"root","server_
- 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

View file

@ -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
## 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 Prompts on Child VMs
`--headless` only provisions — to run work on the child, SSH in with `bash -lc`:
```bash
# 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\"'"
```
### 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

View file

@ -2,27 +2,40 @@
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 Prompts on Child VMs
`--headless` only provisions — to run work on the child, SSH in with `bash -lc`:
```bash
# 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\"'"
```
### 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
@ -30,3 +43,4 @@ Returns JSON: `{"status":"success","ip_address":"...","ssh_user":"root","server_
- 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

View file

@ -2,27 +2,40 @@
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 Prompts on Child VMs
`--headless` only provisions — to run work on the child, SSH in with `bash -lc`:
```bash
# 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\"'"
```
### 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
@ -30,3 +43,4 @@ Returns JSON: `{"status":"success","ip_address":"...","ssh_user":"root","server_
- 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