diff --git a/README.md b/README.md index 50a3456f8..52868c08a 100644 --- a/README.md +++ b/README.md @@ -324,7 +324,6 @@ If an agent fails to install or launch on a cloud: |---|---|---|---|---|---|---| | [**Claude Code**](https://claude.ai) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | [**OpenClaw**](https://github.com/openclaw/openclaw) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| [**ZeroClaw**](https://github.com/zeroclaw-labs/zeroclaw) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | [**Codex CLI**](https://github.com/openai/codex) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | [**OpenCode**](https://github.com/sst/opencode) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | [**Kilo Code**](https://github.com/Kilo-Org/kilocode) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | diff --git a/assets/agents/.sources.json b/assets/agents/.sources.json index bc49a705a..7aac941fc 100644 --- a/assets/agents/.sources.json +++ b/assets/agents/.sources.json @@ -7,10 +7,6 @@ "url": "https://openclaw.ai/apple-touch-icon.png", "ext": "png" }, - "zeroclaw": { - "url": "https://avatars.githubusercontent.com/u/261820148?s=200&v=4", - "ext": "png" - }, "codex": { "url": "https://avatars.githubusercontent.com/u/14957082?s=200&v=4", "ext": "png" diff --git a/manifest.json b/manifest.json index a9b30a67c..4a5a48221 100644 --- a/manifest.json +++ b/manifest.json @@ -89,52 +89,6 @@ "gateway" ] }, - "zeroclaw": { - "name": "ZeroClaw", - "description": "Fast, small, fully autonomous AI assistant infrastructure — deploy anywhere, swap anything", - "url": "https://github.com/zeroclaw-labs/zeroclaw", - "install": "curl -LsSf https://raw.githubusercontent.com/zeroclaw-labs/zeroclaw/a117be64fdaa31779204beadf2942c8aef57d0e5/scripts/bootstrap.sh | bash -s -- --install-rust --install-system-deps --prefer-prebuilt", - "launch": "zeroclaw agent", - "env": { - "OPENROUTER_API_KEY": "${OPENROUTER_API_KEY}", - "ZEROCLAW_PROVIDER": "openrouter" - }, - "config_files": { - "~/.zeroclaw/config.toml": { - "security": { - "autonomy": "full", - "supervised": false, - "allow_destructive": true - }, - "shell": { - "policy": "allow_all" - } - } - }, - "notes": "Rust-based agent framework built by Harvard/MIT/Sundai.Club communities. Natively supports OpenRouter via OPENROUTER_API_KEY + ZEROCLAW_PROVIDER=openrouter. Requires compilation from source (~5-10 min).", - "icon": "https://raw.githubusercontent.com/OpenRouterTeam/spawn/main/assets/agents/zeroclaw.png", - "featured_cloud": [ - "digitalocean", - "sprite" - ], - "creator": "Sundai.Club", - "repo": "zeroclaw-labs/zeroclaw", - "license": "Apache-2.0", - "created": "2026-02", - "added": "2025-12", - "github_stars": 28521, - "stars_updated": "2026-03-23", - "language": "Rust", - "runtime": "binary", - "category": "cli", - "tagline": "Fast, small, fully autonomous AI infrastructure — deploy anywhere, swap anything", - "tags": [ - "coding", - "terminal", - "rust", - "autonomous" - ] - }, "codex": { "name": "Codex CLI", "description": "OpenAI's open-source coding agent", @@ -453,37 +407,31 @@ "matrix": { "local/claude": "implemented", "local/openclaw": "implemented", - "local/zeroclaw": "implemented", "local/codex": "implemented", "local/opencode": "implemented", "local/kilocode": "implemented", "hetzner/claude": "implemented", "hetzner/openclaw": "implemented", - "hetzner/zeroclaw": "implemented", "hetzner/codex": "implemented", "hetzner/opencode": "implemented", "hetzner/kilocode": "implemented", "aws/claude": "implemented", "aws/openclaw": "implemented", - "aws/zeroclaw": "implemented", "aws/codex": "implemented", "aws/opencode": "implemented", "aws/kilocode": "implemented", "digitalocean/claude": "implemented", "digitalocean/openclaw": "implemented", - "digitalocean/zeroclaw": "implemented", "digitalocean/codex": "implemented", "digitalocean/opencode": "implemented", "digitalocean/kilocode": "implemented", "gcp/claude": "implemented", "gcp/openclaw": "implemented", - "gcp/zeroclaw": "implemented", "gcp/codex": "implemented", "gcp/opencode": "implemented", "gcp/kilocode": "implemented", "sprite/claude": "implemented", "sprite/openclaw": "implemented", - "sprite/zeroclaw": "implemented", "sprite/codex": "implemented", "sprite/opencode": "implemented", "sprite/kilocode": "implemented", diff --git a/packages/cli/package.json b/packages/cli/package.json index 2b805a43d..b8617964a 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@openrouter/spawn", - "version": "0.29.1", + "version": "0.29.2", "type": "module", "bin": { "spawn": "cli.js" diff --git a/packages/cli/src/__tests__/agent-setup-cov.test.ts b/packages/cli/src/__tests__/agent-setup-cov.test.ts index 6e6f0c739..c04d95c28 100644 --- a/packages/cli/src/__tests__/agent-setup-cov.test.ts +++ b/packages/cli/src/__tests__/agent-setup-cov.test.ts @@ -191,12 +191,6 @@ describe("createCloudAgents", () => { "ANTHROPIC_BASE_URL", ], ], - [ - "zeroclaw", - [ - "ZEROCLAW_PROVIDER=openrouter", - ], - ], [ "hermes", [ @@ -228,11 +222,6 @@ describe("createCloudAgents", () => { } }); - it("zeroclaw agent configure calls runServer", async () => { - await result.agents.zeroclaw.configure?.("sk-or-v1-test", undefined, new Set()); - expect(runner.runServer).toHaveBeenCalled(); - }); - it("all agents have launchCmd returning non-empty string", () => { for (const agent of Object.values(result.agents)) { const cmd = agent.launchCmd(); diff --git a/packages/cli/src/__tests__/security-connection-validation.test.ts b/packages/cli/src/__tests__/security-connection-validation.test.ts index 8099d1372..416942b31 100644 --- a/packages/cli/src/__tests__/security-connection-validation.test.ts +++ b/packages/cli/src/__tests__/security-connection-validation.test.ts @@ -189,7 +189,6 @@ describe("validateLaunchCmd", () => { "source ~/.spawnrc 2>/dev/null; export PATH=$HOME/.npm-global/bin:$HOME/.bun/bin:$HOME/.local/bin:$PATH; openclaw tui", "source ~/.spawnrc 2>/dev/null; source ~/.zshrc 2>/dev/null; opencode", "source ~/.spawnrc 2>/dev/null; source ~/.zshrc 2>/dev/null; kilocode", - "export PATH=$HOME/.cargo/bin:$PATH; source ~/.cargo/env 2>/dev/null; source ~/.spawnrc 2>/dev/null; zeroclaw agent", "source ~/.spawnrc 2>/dev/null; hermes", "claude", "aider", diff --git a/packages/cli/src/__tests__/spawn-skill.test.ts b/packages/cli/src/__tests__/spawn-skill.test.ts index c99ebeb60..ac6cf36b6 100644 --- a/packages/cli/src/__tests__/spawn-skill.test.ts +++ b/packages/cli/src/__tests__/spawn-skill.test.ts @@ -22,10 +22,6 @@ describe("getSpawnSkillPath", () => { "openclaw", "~/.openclaw/skills/spawn/SKILL.md", ], - [ - "zeroclaw", - "~/.zeroclaw/workspace/AGENTS.md", - ], [ "opencode", "~/.config/opencode/AGENTS.md", @@ -67,7 +63,6 @@ describe("isAppendMode", () => { "claude", "codex", "openclaw", - "zeroclaw", "opencode", "kilocode", "junie", @@ -85,7 +80,6 @@ describe("getSkillContent", () => { "claude", "codex", "openclaw", - "zeroclaw", "opencode", "kilocode", "hermes", @@ -114,7 +108,6 @@ describe("getSkillContent", () => { } for (const agent of [ - "zeroclaw", "opencode", "kilocode", "junie", @@ -184,7 +177,6 @@ describe("injectSpawnSkill", () => { "claude", "codex", "openclaw", - "zeroclaw", "opencode", "kilocode", "hermes", diff --git a/packages/cli/src/commands/link.ts b/packages/cli/src/commands/link.ts index 95eba0f4e..e84d68734 100644 --- a/packages/cli/src/commands/link.ts +++ b/packages/cli/src/commands/link.ts @@ -66,7 +66,6 @@ function defaultSshCommand(host: string, user: string, keyOpts: string[], cmd: s const KNOWN_AGENTS = [ "claude", "openclaw", - "zeroclaw", "codex", "opencode", "kilocode", @@ -79,7 +78,7 @@ type KnownAgent = (typeof KNOWN_AGENTS)[number]; function detectAgent(host: string, user: string, keyOpts: string[], runCmd: SshCommandFn): string | null { // First: check running processes const psCmd = - "ps aux 2>/dev/null | grep -oE 'claude(-code)?|openclaw|zeroclaw|codex|opencode|kilocode|hermes|junie' | grep -v grep | head -1 || true"; + "ps aux 2>/dev/null | grep -oE 'claude(-code)?|openclaw|codex|opencode|kilocode|hermes|junie' | grep -v grep | head -1 || true"; const psOut = runCmd(host, user, keyOpts, psCmd); if (psOut) { const match = KNOWN_AGENTS.find((b: KnownAgent) => psOut.includes(b)); diff --git a/packages/cli/src/digitalocean/main.ts b/packages/cli/src/digitalocean/main.ts index 3dea61cce..c8baeb710 100644 --- a/packages/cli/src/digitalocean/main.ts +++ b/packages/cli/src/digitalocean/main.ts @@ -35,7 +35,6 @@ const MARKETPLACE_IMAGES: Record = { openclaw: "openrouter-spawnopenclaw", opencode: "openrouter-spawnopencode", kilocode: "openrouter-spawnkilocode", - zeroclaw: "openrouter-spawnzeroclaw", hermes: "openrouter-spawnhermes", junie: "openrouter-spawnjunie", }; diff --git a/packages/cli/src/security.ts b/packages/cli/src/security.ts index 19a2152d1..504b9bc9d 100644 --- a/packages/cli/src/security.ts +++ b/packages/cli/src/security.ts @@ -406,7 +406,7 @@ export function validateLaunchCmd(cmd: string): void { "Invalid launch command in history: invalid agent invocation\n\n" + `Command: "${cmd}"\n` + `Rejected segment: "${lastSegment}"\n\n` + - "The final segment must be a simple binary name (e.g., 'claude', 'zeroclaw agent').\n\n" + + "The final segment must be a simple binary name (e.g., 'claude', 'hermes').\n\n" + "Your spawn history file may be corrupted or tampered with.\n" + `To fix: run 'spawn list --clear' to reset history`, ); diff --git a/packages/cli/src/shared/agent-setup.ts b/packages/cli/src/shared/agent-setup.ts index 1d0f86a6c..e94627c1c 100644 --- a/packages/cli/src/shared/agent-setup.ts +++ b/packages/cli/src/shared/agent-setup.ts @@ -592,51 +592,6 @@ export async function startGateway(runner: CloudRunner): Promise { logInfo("OpenClaw gateway started"); } -// ─── ZeroClaw Config ───────────────────────────────────────────────────────── - -async function setupZeroclawConfig(runner: CloudRunner, _apiKey: string): Promise { - logStep("Configuring ZeroClaw for autonomous operation..."); - - // Remove any pre-existing config (e.g. from Docker image extraction) before - // running onboard, which generates a fresh config with the correct API key. - await runner.runServer("rm -f ~/.zeroclaw/config.toml"); - - // Run onboard first to set up provider/key - await runner.runServer( - `source ~/.spawnrc 2>/dev/null; export PATH="$HOME/.local/bin:$HOME/.cargo/bin:$PATH"; zeroclaw onboard --api-key "\${OPENROUTER_API_KEY}" --provider openrouter`, - ); - - // Patch autonomy settings in-place. `zeroclaw onboard` already generates - // [security] and [shell] sections — so we sed the values instead of - // appending duplicate sections. - const patchScript = [ - "cd ~/.zeroclaw", - // Update existing security values (or append section if missing) - 'if grep -q "^\\[security\\]" config.toml 2>/dev/null; then', - " sed -i 's/^autonomy = .*/autonomy = \"full\"/' config.toml", - " sed -i 's/^supervised = .*/supervised = false/' config.toml", - " sed -i 's/^allow_destructive = .*/allow_destructive = true/' config.toml", - "else", - " printf '\\n[security]\\nautonomy = \"full\"\\nsupervised = false\\nallow_destructive = true\\n' >> config.toml", - "fi", - // Update existing shell policy (or append section if missing) - 'if grep -q "^\\[shell\\]" config.toml 2>/dev/null; then', - " sed -i 's/^policy = .*/policy = \"allow_all\"/' config.toml", - "else", - " printf '\\n[shell]\\npolicy = \"allow_all\"\\n' >> config.toml", - "fi", - // Force native runtime (no Docker) — zeroclaw auto-detects Docker and - // launches in a container otherwise, which hangs the interactive session. - 'if grep -q "^\\[runtime\\]" config.toml 2>/dev/null; then', - " sed -i 's/^adapter = .*/adapter = \"native\"/' config.toml", - "else", - " printf '\\n[runtime]\\nadapter = \"native\"\\n' >> config.toml", - "fi", - ].join("\n"); - await runner.runServer(patchScript); - logInfo("ZeroClaw configured for autonomous operation"); -} - // ─── OpenCode Install Command ──────────────────────────────────────────────── function openCodeInstallCmd(): string { @@ -894,10 +849,6 @@ export async function setupAutoUpdate(runner: CloudRunner, agentName: string, up // ─── Default Agent Definitions ─────────────────────────────────────────────── -// Last zeroclaw release that shipped Linux prebuilt binaries (v0.1.9a has none). -// Used for direct binary install to avoid a Rust source build timeout. -const ZEROCLAW_PREBUILT_TAG = "v0.1.7-beta.30"; - function createAgents(runner: CloudRunner): Record { return { claude: { @@ -1011,50 +962,6 @@ function createAgents(runner: CloudRunner): Record { "npm install -g ${_NPM_G_FLAGS:-} @kilocode/cli@latest", }, - zeroclaw: { - name: "ZeroClaw", - cloudInitTier: "minimal", - modelEnvVar: "ZEROCLAW_MODEL", - preProvision: detectGithubAuth, - install: async () => { - // Direct binary install from pinned release (v0.1.9a "latest" has no assets, - // causing the bootstrap --prefer-prebuilt path to 404-fail and fall back to - // a Rust source build that exceeds the 600s install timeout). - const directInstallCmd = - `_ZC_ARCH="$(uname -m)"; ` + - `if [ "$_ZC_ARCH" = "x86_64" ]; then _ZC_TARGET="x86_64-unknown-linux-gnu"; ` + - `elif [ "$_ZC_ARCH" = "aarch64" ] || [ "$_ZC_ARCH" = "arm64" ]; then _ZC_TARGET="aarch64-unknown-linux-gnu"; ` + - `else echo "Unsupported arch: $_ZC_ARCH" >&2; exit 1; fi; ` + - `_ZC_URL="https://github.com/zeroclaw-labs/zeroclaw/releases/download/${ZEROCLAW_PREBUILT_TAG}/zeroclaw-\${_ZC_TARGET}.tar.gz"; ` + - `_ZC_TMP="$(mktemp -d)"; ` + - `curl --proto '=https' -fsSL "$_ZC_URL" -o "$_ZC_TMP/zeroclaw.tar.gz" && ` + - `tar -xzf "$_ZC_TMP/zeroclaw.tar.gz" -C "$_ZC_TMP" && ` + - `{ mkdir -p "$HOME/.local/bin" && install -m 755 "$_ZC_TMP/zeroclaw" "$HOME/.local/bin/zeroclaw"; } && ` + - `rm -rf "$_ZC_TMP"`; - await installAgent(runner, "ZeroClaw", directInstallCmd, 120); - }, - envVars: (apiKey) => [ - `OPENROUTER_API_KEY=${apiKey}`, - "ZEROCLAW_PROVIDER=openrouter", - "ZEROCLAW_RUNTIME=native", - ], - configure: (apiKey) => setupZeroclawConfig(runner, apiKey), - launchCmd: () => - "export PATH=$HOME/.local/bin:$HOME/.cargo/bin:$PATH; source ~/.spawnrc 2>/dev/null; zeroclaw agent", - updateCmd: - 'export PATH="$HOME/.local/bin:$HOME/.cargo/bin:$PATH"; ' + - `_ZC_ARCH="$(uname -m)"; ` + - `if [ "$_ZC_ARCH" = "x86_64" ]; then _ZC_TARGET="x86_64-unknown-linux-gnu"; ` + - `elif [ "$_ZC_ARCH" = "aarch64" ] || [ "$_ZC_ARCH" = "arm64" ]; then _ZC_TARGET="aarch64-unknown-linux-gnu"; ` + - "else exit 1; fi; " + - `_ZC_URL="https://github.com/zeroclaw-labs/zeroclaw/releases/latest/download/zeroclaw-\${_ZC_TARGET}.tar.gz"; ` + - `_ZC_TMP="$(mktemp -d)"; ` + - `curl --proto '=https' -fsSL "$_ZC_URL" -o "$_ZC_TMP/zeroclaw.tar.gz" && ` + - `tar -xzf "$_ZC_TMP/zeroclaw.tar.gz" -C "$_ZC_TMP" && ` + - `install -m 755 "$_ZC_TMP/zeroclaw" "$HOME/.local/bin/zeroclaw" && ` + - `rm -rf "$_ZC_TMP"`, - }, - hermes: { name: "Hermes Agent", cloudInitTier: "minimal", diff --git a/packages/cli/src/shared/orchestrate.ts b/packages/cli/src/shared/orchestrate.ts index fe1b16007..72faaccb5 100644 --- a/packages/cli/src/shared/orchestrate.ts +++ b/packages/cli/src/shared/orchestrate.ts @@ -285,7 +285,7 @@ export async function runOrchestration( // Skip cloud-init for minimal-tier agents when using tarballs or snapshots. // Ubuntu 24.04 base images already have curl + git, so minimal agents (claude, - // opencode, zeroclaw, hermes) don't need the cloud-init package install step. + // opencode, hermes) don't need the cloud-init package install step. // This saves ~30-60s by just waiting for SSH instead of polling for cloud-init completion. if ( cloud.cloudName !== "local" && diff --git a/packages/cli/src/shared/spawn-skill.ts b/packages/cli/src/shared/spawn-skill.ts index 59dbd263b..df12ebf6c 100644 --- a/packages/cli/src/shared/spawn-skill.ts +++ b/packages/cli/src/shared/spawn-skill.ts @@ -30,7 +30,7 @@ You have the \`spawn\` CLI installed. Use it to provision cloud VMs with AI agen spawn --headless --output json --prompt "task description" \`\`\` -**Agents:** claude, codex, cursor, openclaw, zeroclaw, opencode, kilocode, hermes, junie +**Agents:** claude, codex, cursor, openclaw, opencode, kilocode, hermes, junie **Clouds:** hetzner, digitalocean, aws, gcp, sprite Returns JSON: \`{"status":"success","ip_address":"...","ssh_user":"root","server_id":"..."}\` @@ -74,7 +74,7 @@ const HERMES_SNIPPET = ` You have the \`spawn\` CLI for creating child cloud VMs with AI agents. Use \`spawn --headless --output json --prompt "task"\` to delegate work. -Available agents: claude, codex, cursor, openclaw, zeroclaw, opencode, kilocode, hermes, junie. +Available agents: claude, codex, cursor, openclaw, 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@ "bash -lc 'claude -p --dangerously-skip-permissions \\"prompt\\"'"\`. Always use \`bash -lc\` (binaries are in ~/.local/bin/). `; @@ -104,11 +104,6 @@ const AGENT_SKILLS: Record = { content: SKILL_FRONTMATTER + SKILL_BODY, append: false, }, - zeroclaw: { - remotePath: "~/.zeroclaw/workspace/AGENTS.md", - content: SKILL_BODY, - append: false, - }, opencode: { remotePath: "~/.config/opencode/AGENTS.md", content: SKILL_BODY, diff --git a/packer/agents.json b/packer/agents.json index b6c25aec5..9ab6bb61b 100644 --- a/packer/agents.json +++ b/packer/agents.json @@ -30,13 +30,6 @@ "mkdir -p ~/.npm-global/bin && npm install -g --prefix ~/.npm-global @kilocode/cli" ] }, - "zeroclaw": { - "tier": "minimal", - "install": [ - "if [ ! -f /swapfile ]; then fallocate -l 4G /swapfile && chmod 600 /swapfile && mkswap /swapfile && swapon /swapfile; fi", - "curl -LsSf https://raw.githubusercontent.com/zeroclaw-labs/zeroclaw/a117be64fdaa31779204beadf2942c8aef57d0e5/scripts/bootstrap.sh | bash -s -- --install-rust --install-system-deps --prefer-prebuilt" - ] - }, "hermes": { "tier": "minimal", "install": [ diff --git a/packer/scripts/capture-agent.sh b/packer/scripts/capture-agent.sh index 4a7bee768..7f5498c2b 100644 --- a/packer/scripts/capture-agent.sh +++ b/packer/scripts/capture-agent.sh @@ -13,9 +13,9 @@ fi # Validate agent name against allowed list to prevent injection case "${AGENT_NAME}" in - openclaw|codex|kilocode|claude|opencode|zeroclaw|hermes|junie) ;; + openclaw|codex|kilocode|claude|opencode|hermes|junie) ;; *) - printf 'Error: Invalid agent name: %s\nAllowed: openclaw, codex, kilocode, claude, opencode, zeroclaw, hermes, junie\n' "${AGENT_NAME}" >&2 + printf 'Error: Invalid agent name: %s\nAllowed: openclaw, codex, kilocode, claude, opencode, hermes, junie\n' "${AGENT_NAME}" >&2 exit 1 ;; esac @@ -44,9 +44,6 @@ case "${AGENT_NAME}" in opencode) echo "/root/.opencode/" >> "${PATHS_FILE}" ;; - zeroclaw) - echo "/root/.cargo/bin/zeroclaw" >> "${PATHS_FILE}" - ;; hermes) echo "/root/.local/bin/hermes" >> "${PATHS_FILE}" echo "/root/.local/share/" >> "${PATHS_FILE}" diff --git a/sh/aws/README.md b/sh/aws/README.md index 962c92581..269d2c35b 100644 --- a/sh/aws/README.md +++ b/sh/aws/README.md @@ -24,12 +24,6 @@ bash <(curl -fsSL https://openrouter.ai/labs/spawn/aws/claude.sh) bash <(curl -fsSL https://openrouter.ai/labs/spawn/aws/openclaw.sh) ``` -#### ZeroClaw - -```bash -bash <(curl -fsSL https://openrouter.ai/labs/spawn/aws/zeroclaw.sh) -``` - #### Codex CLI ```bash diff --git a/sh/aws/zeroclaw.sh b/sh/aws/zeroclaw.sh deleted file mode 100644 index 0b6188de6..000000000 --- a/sh/aws/zeroclaw.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash -set -eo pipefail - -# Thin shim: ensures bun is available, runs bundled aws.js (local or from GitHub release) - -_ensure_bun() { - if command -v bun &>/dev/null; then return 0; fi - printf '\033[0;36mInstalling bun...\033[0m\n' >&2 - curl -fsSL --proto '=https' --show-error https://bun.sh/install?version=1.3.9 | bash >/dev/null || { printf '\033[0;31mFailed to install bun\033[0m\n' >&2; exit 1; } - export PATH="$HOME/.bun/bin:$PATH" - command -v bun &>/dev/null || { printf '\033[0;31mbun not found after install\033[0m\n' >&2; exit 1; } -} - -_ensure_bun - -# SPAWN_CLI_DIR override — force local source (used by e2e tests) -if [[ -n "${SPAWN_CLI_DIR:-}" && -f "$SPAWN_CLI_DIR/packages/cli/src/aws/main.ts" ]]; then - exec bun run "$SPAWN_CLI_DIR/packages/cli/src/aws/main.ts" zeroclaw "$@" -fi - -# Remote — download and run compiled TypeScript bundle -AWS_JS=$(mktemp) -trap 'rm -f "$AWS_JS"' EXIT -curl -fsSL --proto '=https' "https://github.com/OpenRouterTeam/spawn/releases/download/aws-latest/aws.js" -o "$AWS_JS" \ - || { printf '\033[0;31mFailed to download aws.js\033[0m\n' >&2; exit 1; } -exec bun run "$AWS_JS" zeroclaw "$@" diff --git a/sh/digitalocean/README.md b/sh/digitalocean/README.md index 0d0d9225e..6b2c50e74 100644 --- a/sh/digitalocean/README.md +++ b/sh/digitalocean/README.md @@ -16,12 +16,6 @@ bash <(curl -fsSL https://openrouter.ai/labs/spawn/digitalocean/claude.sh) bash <(curl -fsSL https://openrouter.ai/labs/spawn/digitalocean/openclaw.sh) ``` -#### ZeroClaw - -```bash -bash <(curl -fsSL https://openrouter.ai/labs/spawn/digitalocean/zeroclaw.sh) -``` - #### Codex CLI ```bash diff --git a/sh/digitalocean/zeroclaw.sh b/sh/digitalocean/zeroclaw.sh deleted file mode 100644 index 097664e95..000000000 --- a/sh/digitalocean/zeroclaw.sh +++ /dev/null @@ -1,84 +0,0 @@ -#!/bin/bash -set -eo pipefail - -# Thin shim: ensures bun is available, runs bundled digitalocean.js (local or from GitHub release) -# Includes restart loop for SIGTERM recovery on DigitalOcean - -_AGENT_NAME="zeroclaw" -_MAX_RETRIES=3 - -_ensure_bun() { - if command -v bun &>/dev/null; then return 0; fi - printf '\033[0;36mInstalling bun...\033[0m\n' >&2 - curl -fsSL --proto '=https' --show-error https://bun.sh/install?version=1.3.9 | bash >/dev/null || { printf '\033[0;31mFailed to install bun\033[0m\n' >&2; exit 1; } - export PATH="$HOME/.bun/bin:$PATH" - command -v bun &>/dev/null || { printf '\033[0;31mbun not found after install\033[0m\n' >&2; exit 1; } -} - -# Run command in the foreground so bun gets full terminal access (raw mode, -# arrow keys for interactive prompts). The old pattern backgrounded the child -# with & + wait so a SIGTERM trap could forward the signal, but that removed -# bun from the foreground process group and broke @clack/prompts multiselect. -# Now SIGTERM is detected from exit code 143 (128 + 15) after the child exits. -_run_with_restart() { - # In headless mode (E2E / --headless), skip the restart loop entirely. - # Restarting in headless mode creates duplicate droplets, exhausting the - # account's droplet quota and causing all subsequent agents to fail. - if [ "${SPAWN_HEADLESS:-}" = "1" ]; then - "$@" - return $? - fi - - local attempt=0 - local backoff=2 - while [ "$attempt" -lt "$_MAX_RETRIES" ]; do - attempt=$((attempt + 1)) - - "$@" - local exit_code=$? - - # Normal exit - if [ "$exit_code" -eq 0 ]; then - return 0 - fi - - # SIGTERM (143) or SIGKILL (137) — attempt restart - if [ "$exit_code" -eq 143 ] || [ "$exit_code" -eq 137 ]; then - printf '\033[0;33m[spawn/%s] Agent process terminated (exit %s). The droplet is likely still running.\033[0m\n' \ - "$_AGENT_NAME" "$exit_code" >&2 - printf '\033[0;33m[spawn/%s] Check your DigitalOcean dashboard: https://cloud.digitalocean.com/droplets\033[0m\n' \ - "$_AGENT_NAME" >&2 - if [ "$attempt" -lt "$_MAX_RETRIES" ]; then - printf '\033[0;33m[spawn/%s] Restarting (attempt %s/%s, backoff %ss)...\033[0m\n' \ - "$_AGENT_NAME" "$((attempt + 1))" "$_MAX_RETRIES" "$backoff" >&2 - sleep "$backoff" - backoff=$((backoff * 2)) - continue - else - printf '\033[0;31m[spawn/%s] Max restart attempts reached (%s). Giving up.\033[0m\n' \ - "$_AGENT_NAME" "$_MAX_RETRIES" >&2 - return "$exit_code" - fi - fi - - # Other failure — exit with the original code - return "$exit_code" - done -} - -_ensure_bun - -# SPAWN_CLI_DIR override — force local source (used by e2e tests) -if [[ -n "${SPAWN_CLI_DIR:-}" && -f "$SPAWN_CLI_DIR/packages/cli/src/digitalocean/main.ts" ]]; then - _run_with_restart bun run "$SPAWN_CLI_DIR/packages/cli/src/digitalocean/main.ts" "$_AGENT_NAME" "$@" - exit $? -fi - -# Remote — download bundled digitalocean.js from GitHub release -DO_JS=$(mktemp) -trap 'rm -f "$DO_JS"' EXIT -curl -fsSL --proto '=https' "https://github.com/OpenRouterTeam/spawn/releases/download/digitalocean-latest/digitalocean.js" -o "$DO_JS" \ - || { printf '\033[0;31mFailed to download digitalocean.js\033[0m\n' >&2; exit 1; } - -_run_with_restart bun run "$DO_JS" "$_AGENT_NAME" "$@" -exit $? diff --git a/sh/docker/zeroclaw.Dockerfile b/sh/docker/zeroclaw.Dockerfile deleted file mode 100644 index c02c0ffbd..000000000 --- a/sh/docker/zeroclaw.Dockerfile +++ /dev/null @@ -1,22 +0,0 @@ -FROM ubuntu:24.04 - -ENV DEBIAN_FRONTEND=noninteractive - -# Base packages -RUN apt-get update -y && \ - apt-get install -y --no-install-recommends \ - curl git ca-certificates build-essential unzip && \ - rm -rf /var/lib/apt/lists/* - -# ZeroClaw — bootstrap script installs Rust + builds from source -RUN curl --proto '=https' -LsSf \ - https://raw.githubusercontent.com/zeroclaw-labs/zeroclaw/a117be64fdaa31779204beadf2942c8aef57d0e5/scripts/bootstrap.sh \ - | bash -s -- --install-rust --install-system-deps --prefer-prebuilt - -# Ensure cargo bin is on PATH for all shells -RUN for rc in /root/.bashrc /root/.zshrc; do \ - grep -q '.cargo/bin' "$rc" 2>/dev/null || \ - echo 'export PATH="$HOME/.cargo/bin:$PATH"' >> "$rc"; \ - done - -CMD ["/bin/sleep", "inf"] diff --git a/sh/e2e/lib/common.sh b/sh/e2e/lib/common.sh index 9cdb64e47..c04656a4e 100644 --- a/sh/e2e/lib/common.sh +++ b/sh/e2e/lib/common.sh @@ -5,7 +5,7 @@ set -eo pipefail # --------------------------------------------------------------------------- # Constants # --------------------------------------------------------------------------- -ALL_AGENTS="claude openclaw zeroclaw codex opencode kilocode hermes junie cursor" +ALL_AGENTS="claude openclaw codex opencode kilocode hermes junie cursor" PROVISION_TIMEOUT="${PROVISION_TIMEOUT:-720}" INSTALL_WAIT="${INSTALL_WAIT:-600}" INPUT_TEST_TIMEOUT="${INPUT_TEST_TIMEOUT:-120}" diff --git a/sh/e2e/lib/provision.sh b/sh/e2e/lib/provision.sh index 39553fdc5..f211b980d 100644 --- a/sh/e2e/lib/provision.sh +++ b/sh/e2e/lib/provision.sh @@ -275,11 +275,6 @@ CLOUD_ENV printf 'export OPENAI_BASE_URL=%q\n' "https://openrouter.ai/api/v1" } >> "${env_tmp}" ;; - zeroclaw) - { - printf 'export ZEROCLAW_PROVIDER=%q\n' "openrouter" - } >> "${env_tmp}" - ;; hermes) { printf 'export OPENAI_BASE_URL=%q\n' "https://openrouter.ai/api/v1" @@ -393,10 +388,6 @@ _ensure_agent_binary() { bin_name="codex" install_cmd="mkdir -p ~/.npm-global && npm install -g --prefix ~/.npm-global @openai/codex" ;; - zeroclaw) - bin_name="zeroclaw" - install_cmd="curl -LsSf https://raw.githubusercontent.com/zeroclaw-labs/zeroclaw/a117be64fdaa31779204beadf2942c8aef57d0e5/scripts/bootstrap.sh | bash -s -- --install-rust --install-system-deps --prefer-prebuilt" - ;; opencode) bin_name="opencode" install_cmd="curl -fsSL https://opencode.ai/install | bash" diff --git a/sh/e2e/lib/verify.sh b/sh/e2e/lib/verify.sh index fd80ed488..0f47080ea 100644 --- a/sh/e2e/lib/verify.sh +++ b/sh/e2e/lib/verify.sh @@ -274,40 +274,6 @@ input_test_openclaw() { return 1 } -input_test_zeroclaw() { - local app="$1" - - _validate_timeout || return 1 - - log_step "Running input test for zeroclaw..." - # Base64-encode the prompt and stage it to a remote temp file. - # Use -m/--message for non-interactive single-message mode (not -p which is --provider). - local encoded_prompt - encoded_prompt=$(printf '%s' "${INPUT_TEST_PROMPT}" | base64 -w 0 2>/dev/null || printf '%s' "${INPUT_TEST_PROMPT}" | base64 | tr -d '\n') - _validate_base64 "${encoded_prompt}" || return 1 - _stage_prompt_remotely "${app}" "${encoded_prompt}" - _stage_timeout_remotely "${app}" "${INPUT_TEST_TIMEOUT}" - - local output - # The prompt and timeout are read from staged temp files — no interpolation in this command. - output=$(cloud_exec "${app}" "\ - source ~/.spawnrc 2>/dev/null; source ~/.cargo/env 2>/dev/null; \ - _TIMEOUT=\$(cat /tmp/.e2e-timeout); \ - rm -rf /tmp/e2e-test && mkdir -p /tmp/e2e-test && cd /tmp/e2e-test && git init -q; \ - PROMPT=\$(cat /tmp/.e2e-prompt | base64 -d); \ - timeout \"\$_TIMEOUT\" zeroclaw agent -m \"\$PROMPT\"" 2>&1) || true - - if printf '%s' "${output}" | grep -qx "${INPUT_TEST_MARKER}"; then - log_ok "zeroclaw input test — marker found in response" - return 0 - else - log_err "zeroclaw input test — marker '${INPUT_TEST_MARKER}' not found in response" - log_err "Response (last 5 lines):" - printf '%s\n' "${output}" | tail -5 >&2 - return 1 - fi -} - input_test_opencode() { log_warn "opencode is TUI-only — skipping input test" return 0 @@ -355,7 +321,6 @@ run_input_test() { claude) input_test_claude "${app}" ;; codex) input_test_codex "${app}" ;; openclaw) input_test_openclaw "${app}" ;; - zeroclaw) input_test_zeroclaw "${app}" ;; opencode) input_test_opencode ;; kilocode) input_test_kilocode ;; hermes) input_test_hermes ;; @@ -557,40 +522,6 @@ _openclaw_verify_gateway_resilience() { fi } -verify_zeroclaw() { - local app="$1" - local failures=0 - - # Binary check (may be in ~/.local/bin or ~/.cargo/bin depending on install method) - log_step "Checking zeroclaw binary..." - if cloud_exec "${app}" "export PATH=\$HOME/.local/bin:\$HOME/.cargo/bin:\$PATH; source ~/.cargo/env 2>/dev/null; command -v zeroclaw" >/dev/null 2>&1; then - log_ok "zeroclaw binary found" - else - log_err "zeroclaw binary not found" - failures=$((failures + 1)) - fi - - # Env check: ZEROCLAW_PROVIDER - log_step "Checking zeroclaw env (ZEROCLAW_PROVIDER)..." - if cloud_exec "${app}" "grep -q ZEROCLAW_PROVIDER ~/.spawnrc" >/dev/null 2>&1; then - log_ok "ZEROCLAW_PROVIDER present in .spawnrc" - else - log_err "ZEROCLAW_PROVIDER not found in .spawnrc" - failures=$((failures + 1)) - fi - - # Env check: provider is openrouter - log_step "Checking zeroclaw uses openrouter..." - if cloud_exec "${app}" "grep ZEROCLAW_PROVIDER ~/.spawnrc | grep -q openrouter" >/dev/null 2>&1; then - log_ok "ZEROCLAW_PROVIDER set to openrouter" - else - log_err "ZEROCLAW_PROVIDER not set to openrouter" - failures=$((failures + 1)) - fi - - return "${failures}" -} - verify_codex() { local app="$1" local failures=0 @@ -810,7 +741,6 @@ verify_agent() { case "${agent}" in claude) verify_claude "${app}" || agent_failures=$? ;; openclaw) verify_openclaw "${app}" || agent_failures=$? ;; - zeroclaw) verify_zeroclaw "${app}" || agent_failures=$? ;; codex) verify_codex "${app}" || agent_failures=$? ;; opencode) verify_opencode "${app}" || agent_failures=$? ;; kilocode) verify_kilocode "${app}" || agent_failures=$? ;; diff --git a/sh/gcp/README.md b/sh/gcp/README.md index 3e94a857a..b55d485ce 100644 --- a/sh/gcp/README.md +++ b/sh/gcp/README.md @@ -18,12 +18,6 @@ bash <(curl -fsSL https://openrouter.ai/labs/spawn/gcp/claude.sh) bash <(curl -fsSL https://openrouter.ai/labs/spawn/gcp/openclaw.sh) ``` -#### ZeroClaw - -```bash -bash <(curl -fsSL https://openrouter.ai/labs/spawn/gcp/zeroclaw.sh) -``` - #### Codex CLI ```bash diff --git a/sh/gcp/zeroclaw.sh b/sh/gcp/zeroclaw.sh deleted file mode 100644 index 8f265a3f5..000000000 --- a/sh/gcp/zeroclaw.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash -set -eo pipefail - -# Thin shim: ensures bun is available, runs bundled gcp.js (local or from GitHub release) - -_ensure_bun() { - if command -v bun &>/dev/null; then return 0; fi - printf '\033[0;36mInstalling bun...\033[0m\n' >&2 - curl -fsSL --proto '=https' --show-error https://bun.sh/install?version=1.3.9 | bash >/dev/null || { printf '\033[0;31mFailed to install bun\033[0m\n' >&2; exit 1; } - export PATH="$HOME/.bun/bin:$PATH" - command -v bun &>/dev/null || { printf '\033[0;31mbun not found after install\033[0m\n' >&2; exit 1; } -} - -_ensure_bun - -# SPAWN_CLI_DIR override — force local source (used by e2e tests) -if [[ -n "${SPAWN_CLI_DIR:-}" && -f "$SPAWN_CLI_DIR/packages/cli/src/gcp/main.ts" ]]; then - exec bun run "$SPAWN_CLI_DIR/packages/cli/src/gcp/main.ts" zeroclaw "$@" -fi - -# Remote — download bundled gcp.js from GitHub release -GCP_JS=$(mktemp) -trap 'rm -f "$GCP_JS"' EXIT -curl -fsSL --proto '=https' "https://github.com/OpenRouterTeam/spawn/releases/download/gcp-latest/gcp.js" -o "$GCP_JS" \ - || { printf '\033[0;31mFailed to download gcp.js\033[0m\n' >&2; exit 1; } - -exec bun run "$GCP_JS" zeroclaw "$@" diff --git a/sh/hetzner/README.md b/sh/hetzner/README.md index 919be65a9..6a35177a6 100644 --- a/sh/hetzner/README.md +++ b/sh/hetzner/README.md @@ -16,12 +16,6 @@ bash <(curl -fsSL https://openrouter.ai/labs/spawn/hetzner/claude.sh) bash <(curl -fsSL https://openrouter.ai/labs/spawn/hetzner/openclaw.sh) ``` -#### ZeroClaw - -```bash -bash <(curl -fsSL https://openrouter.ai/labs/spawn/hetzner/zeroclaw.sh) -``` - #### Codex CLI ```bash diff --git a/sh/hetzner/zeroclaw.sh b/sh/hetzner/zeroclaw.sh deleted file mode 100644 index 4a1fc50be..000000000 --- a/sh/hetzner/zeroclaw.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash -set -eo pipefail - -_ensure_bun() { - if command -v bun &>/dev/null; then return 0; fi - printf '\033[0;36mInstalling bun...\033[0m\n' >&2 - curl -fsSL --proto '=https' --show-error https://bun.sh/install?version=1.3.9 | bash >/dev/null || { printf '\033[0;31mFailed to install bun\033[0m\n' >&2; exit 1; } - export PATH="$HOME/.bun/bin:$PATH" - command -v bun &>/dev/null || { printf '\033[0;31mbun not found after install\033[0m\n' >&2; exit 1; } -} -_ensure_bun - -# SPAWN_CLI_DIR override — force local source (used by e2e tests) -if [[ -n "${SPAWN_CLI_DIR:-}" && -f "$SPAWN_CLI_DIR/packages/cli/src/hetzner/main.ts" ]]; then - exec bun run "$SPAWN_CLI_DIR/packages/cli/src/hetzner/main.ts" zeroclaw "$@" -fi - -HETZNER_JS=$(mktemp) -trap 'rm -f "$HETZNER_JS"' EXIT -curl -fsSL --proto '=https' "https://github.com/OpenRouterTeam/spawn/releases/download/hetzner-latest/hetzner.js" -o "$HETZNER_JS" \ - || { printf '\033[0;31mFailed to download hetzner.js\033[0m\n' >&2; exit 1; } -exec bun run "$HETZNER_JS" zeroclaw "$@" diff --git a/sh/local/README.md b/sh/local/README.md index 082db3cf9..945ae14f0 100644 --- a/sh/local/README.md +++ b/sh/local/README.md @@ -11,7 +11,6 @@ If you have the [spawn CLI](https://github.com/OpenRouterTeam/spawn) installed: ```bash spawn claude local spawn openclaw local -spawn zeroclaw local spawn codex local spawn opencode local spawn kilocode local @@ -25,7 +24,6 @@ Or run directly without the CLI: ```bash bash <(curl -fsSL https://openrouter.ai/labs/spawn/local/claude.sh) bash <(curl -fsSL https://openrouter.ai/labs/spawn/local/openclaw.sh) -bash <(curl -fsSL https://openrouter.ai/labs/spawn/local/zeroclaw.sh) bash <(curl -fsSL https://openrouter.ai/labs/spawn/local/codex.sh) bash <(curl -fsSL https://openrouter.ai/labs/spawn/local/opencode.sh) bash <(curl -fsSL https://openrouter.ai/labs/spawn/local/kilocode.sh) diff --git a/sh/local/zeroclaw.sh b/sh/local/zeroclaw.sh deleted file mode 100644 index 0acf20571..000000000 --- a/sh/local/zeroclaw.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash -set -eo pipefail - -# Thin shim: ensures bun is available, runs bundled local.js (local or from GitHub release) - -_ensure_bun() { - if command -v bun &>/dev/null; then return 0; fi - printf '\033[0;36mInstalling bun...\033[0m\n' >&2 - curl -fsSL --proto '=https' --show-error https://bun.sh/install?version=1.3.9 | bash >/dev/null || { printf '\033[0;31mFailed to install bun\033[0m\n' >&2; exit 1; } - export PATH="$HOME/.bun/bin:$PATH" - command -v bun &>/dev/null || { printf '\033[0;31mbun not found after install\033[0m\n' >&2; exit 1; } -} - -_ensure_bun - -# SPAWN_CLI_DIR override — force local source (used by e2e tests) -if [[ -n "${SPAWN_CLI_DIR:-}" && -f "$SPAWN_CLI_DIR/packages/cli/src/local/main.ts" ]]; then - exec bun run "$SPAWN_CLI_DIR/packages/cli/src/local/main.ts" zeroclaw "$@" -fi - -# Remote — download bundled local.js from GitHub release -LOCAL_JS=$(mktemp) -trap 'rm -f "$LOCAL_JS"' EXIT -curl -fsSL --proto '=https' "https://github.com/OpenRouterTeam/spawn/releases/download/local-latest/local.js" -o "$LOCAL_JS" \ - || { printf '\033[0;31mFailed to download local.js\033[0m\n' >&2; exit 1; } - -exec bun run "$LOCAL_JS" zeroclaw "$@" diff --git a/sh/sprite/README.md b/sh/sprite/README.md index 23fb0b118..57e951ce7 100644 --- a/sh/sprite/README.md +++ b/sh/sprite/README.md @@ -16,12 +16,6 @@ bash <(curl -fsSL https://openrouter.ai/labs/spawn/sprite/claude.sh) bash <(curl -fsSL https://openrouter.ai/labs/spawn/sprite/openclaw.sh) ``` -#### ZeroClaw - -```bash -bash <(curl -fsSL https://openrouter.ai/labs/spawn/sprite/zeroclaw.sh) -``` - #### Codex CLI ```bash diff --git a/sh/sprite/zeroclaw.sh b/sh/sprite/zeroclaw.sh deleted file mode 100644 index bf0985665..000000000 --- a/sh/sprite/zeroclaw.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash -set -eo pipefail - -# Thin shim: ensures bun is available, runs bundled sprite.js (local or from GitHub release) - -_ensure_bun() { - if command -v bun &>/dev/null; then return 0; fi - printf '\033[0;36mInstalling bun...\033[0m\n' >&2 - curl -fsSL --proto '=https' --show-error https://bun.sh/install?version=1.3.9 | bash >/dev/null || { printf '\033[0;31mFailed to install bun\033[0m\n' >&2; exit 1; } - export PATH="$HOME/.bun/bin:$PATH" - command -v bun &>/dev/null || { printf '\033[0;31mbun not found after install\033[0m\n' >&2; exit 1; } -} - -_ensure_bun - -# SPAWN_CLI_DIR override — force local source (used by e2e tests) -if [[ -n "${SPAWN_CLI_DIR:-}" && -f "$SPAWN_CLI_DIR/packages/cli/src/sprite/main.ts" ]]; then - exec bun run "$SPAWN_CLI_DIR/packages/cli/src/sprite/main.ts" zeroclaw "$@" -fi - -# Remote — download bundled sprite.js from GitHub release -SPRITE_JS=$(mktemp) -trap 'rm -f "$SPRITE_JS"' EXIT -curl -fsSL --proto '=https' "https://github.com/OpenRouterTeam/spawn/releases/download/sprite-latest/sprite.js" -o "$SPRITE_JS" \ - || { printf '\033[0;31mFailed to download sprite.js\033[0m\n' >&2; exit 1; } - -exec bun run "$SPRITE_JS" zeroclaw "$@" diff --git a/sh/test/e2e-lib.sh b/sh/test/e2e-lib.sh index 64ddd98da..e55a61c40 100644 --- a/sh/test/e2e-lib.sh +++ b/sh/test/e2e-lib.sh @@ -106,8 +106,8 @@ result=$(make_app_name "openclaw") assert_match "make_app_name openclaw (aws)" '^e2e-aws-openclaw-[0-9]+$' "${result}" ACTIVE_CLOUD="sprite" -result=$(make_app_name "zeroclaw") -assert_match "make_app_name zeroclaw (sprite)" '^e2e-sprite-zeroclaw-[0-9]+$' "${result}" +result=$(make_app_name "codex") +assert_match "make_app_name codex (sprite)" '^e2e-sprite-codex-[0-9]+$' "${result}" # Reset ACTIVE_CLOUD="" diff --git a/skills/claude/SKILL.md b/skills/claude/SKILL.md index c78fb699a..5b2d77321 100644 --- a/skills/claude/SKILL.md +++ b/skills/claude/SKILL.md @@ -14,7 +14,7 @@ You have the `spawn` CLI installed. Use it to provision cloud VMs with AI agents spawn --headless --output json --prompt "task description" ``` -**Agents:** claude, codex, cursor, openclaw, zeroclaw, opencode, kilocode, hermes, junie +**Agents:** claude, codex, cursor, openclaw, opencode, kilocode, hermes, junie **Clouds:** hetzner, digitalocean, aws, gcp, sprite Returns JSON: `{"status":"success","ip_address":"...","ssh_user":"root","server_id":"..."}` diff --git a/skills/codex/SKILL.md b/skills/codex/SKILL.md index c78fb699a..5b2d77321 100644 --- a/skills/codex/SKILL.md +++ b/skills/codex/SKILL.md @@ -14,7 +14,7 @@ You have the `spawn` CLI installed. Use it to provision cloud VMs with AI agents spawn --headless --output json --prompt "task description" ``` -**Agents:** claude, codex, cursor, openclaw, zeroclaw, opencode, kilocode, hermes, junie +**Agents:** claude, codex, cursor, openclaw, opencode, kilocode, hermes, junie **Clouds:** hetzner, digitalocean, aws, gcp, sprite Returns JSON: `{"status":"success","ip_address":"...","ssh_user":"root","server_id":"..."}` diff --git a/skills/hermes/SOUL.md b/skills/hermes/SOUL.md index 67796141a..1caae2838 100644 --- a/skills/hermes/SOUL.md +++ b/skills/hermes/SOUL.md @@ -4,6 +4,6 @@ You have the `spawn` CLI for creating child cloud VMs with AI agents. Use `spawn --headless --output json --prompt "task"` to delegate work. -Available agents: claude, codex, cursor, openclaw, zeroclaw, opencode, kilocode, hermes, junie. +Available agents: claude, codex, cursor, openclaw, 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@ "bash -lc 'claude -p --dangerously-skip-permissions \"prompt\"'"`. Always use `bash -lc` (binaries are in ~/.local/bin/). diff --git a/skills/junie/AGENTS.md b/skills/junie/AGENTS.md index e8b718040..b6be851c1 100644 --- a/skills/junie/AGENTS.md +++ b/skills/junie/AGENTS.md @@ -8,7 +8,7 @@ You have the `spawn` CLI installed. Use it to provision cloud VMs with AI agents spawn --headless --output json --prompt "task description" ``` -**Agents:** claude, codex, cursor, openclaw, zeroclaw, opencode, kilocode, hermes, junie +**Agents:** claude, codex, cursor, openclaw, opencode, kilocode, hermes, junie **Clouds:** hetzner, digitalocean, aws, gcp, sprite Returns JSON: `{"status":"success","ip_address":"...","ssh_user":"root","server_id":"..."}` diff --git a/skills/kilocode/spawn.md b/skills/kilocode/spawn.md index e8b718040..b6be851c1 100644 --- a/skills/kilocode/spawn.md +++ b/skills/kilocode/spawn.md @@ -8,7 +8,7 @@ You have the `spawn` CLI installed. Use it to provision cloud VMs with AI agents spawn --headless --output json --prompt "task description" ``` -**Agents:** claude, codex, cursor, openclaw, zeroclaw, opencode, kilocode, hermes, junie +**Agents:** claude, codex, cursor, openclaw, opencode, kilocode, hermes, junie **Clouds:** hetzner, digitalocean, aws, gcp, sprite Returns JSON: `{"status":"success","ip_address":"...","ssh_user":"root","server_id":"..."}` diff --git a/skills/openclaw/SKILL.md b/skills/openclaw/SKILL.md index c78fb699a..5b2d77321 100644 --- a/skills/openclaw/SKILL.md +++ b/skills/openclaw/SKILL.md @@ -14,7 +14,7 @@ You have the `spawn` CLI installed. Use it to provision cloud VMs with AI agents spawn --headless --output json --prompt "task description" ``` -**Agents:** claude, codex, cursor, openclaw, zeroclaw, opencode, kilocode, hermes, junie +**Agents:** claude, codex, cursor, openclaw, opencode, kilocode, hermes, junie **Clouds:** hetzner, digitalocean, aws, gcp, sprite Returns JSON: `{"status":"success","ip_address":"...","ssh_user":"root","server_id":"..."}` diff --git a/skills/opencode/AGENTS.md b/skills/opencode/AGENTS.md index e8b718040..b6be851c1 100644 --- a/skills/opencode/AGENTS.md +++ b/skills/opencode/AGENTS.md @@ -8,7 +8,7 @@ You have the `spawn` CLI installed. Use it to provision cloud VMs with AI agents spawn --headless --output json --prompt "task description" ``` -**Agents:** claude, codex, cursor, openclaw, zeroclaw, opencode, kilocode, hermes, junie +**Agents:** claude, codex, cursor, openclaw, opencode, kilocode, hermes, junie **Clouds:** hetzner, digitalocean, aws, gcp, sprite Returns JSON: `{"status":"success","ip_address":"...","ssh_user":"root","server_id":"..."}` diff --git a/skills/zeroclaw/AGENTS.md b/skills/zeroclaw/AGENTS.md deleted file mode 100644 index e8b718040..000000000 --- a/skills/zeroclaw/AGENTS.md +++ /dev/null @@ -1,46 +0,0 @@ -# Spawn — Create Child VMs - -You have the `spawn` CLI installed. Use it to provision cloud VMs with AI agents. - -## Provision a Child VM - -```bash -spawn --headless --output json --prompt "task description" -``` - -**Agents:** claude, codex, cursor, 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@ "bash -lc 'claude -p --dangerously-skip-permissions \"your prompt\"'" - -# Codex CLI -ssh -o StrictHostKeyChecking=accept-new root@ "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/` -- **Never create non-root users** to work around permission issues — just use `-p` - -## Managing Children - -- `spawn list --json` — see running children -- `spawn delete --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 -