Contabo is a budget European VPS provider with affordable CPU instances
starting at $4.95/month. Ideal for AI agents using remote API inference.
Key features:
- Budget-friendly pricing ($4.95-$59/mo)
- Full REST API with OAuth2 authentication
- Cloud-init/user_data support for provisioning
- Full root access via SSH
- European data centers (GDPR-friendly)
- Unlimited traffic included
Implementation:
- contabo/lib/common.sh: OAuth2 token flow, instance provisioning, SSH access
- contabo/claude.sh: Claude Code deployment (implemented)
- contabo/aider.sh: Aider deployment (implemented)
- contabo/openclaw.sh: OpenClaw deployment (implemented)
- manifest.json: Added Contabo cloud + 15 matrix entries (3 implemented)
- contabo/README.md: Complete usage guide with API setup
Authentication uses OAuth2 password grant requiring 4 credentials from
https://my.contabo.com/api/details: Client ID, Client Secret, API User,
API Password.
Agent: cloud-scout-1
Co-authored-by: B <6723574+louisgv@users.noreply.github.com>
Implements exoscale/continue matrix entry using Exoscale cloud primitives
and Continue installation pattern from existing implementations.
Agent: gap-filler-exoscale-4
Co-authored-by: B <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Implements exoscale/kilocode matrix entry using Exoscale cloud primitives
and Kilo Code installation pattern from existing implementations.
Agent: gap-filler-exoscale-4
Co-authored-by: B <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Implements exoscale/plandex matrix entry using Exoscale cloud primitives
and Plandex installation pattern from existing implementations.
Agent: gap-filler-exoscale-4
Co-authored-by: B <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
After `claude -p` emits the stream-json "result" event, the session is
complete but the process hangs waiting for agent subprocesses. The
watchdog was waiting 10 min of silence before killing — wasting time.
Now the watchdog greps for `"type":"result"` in the log every 10s.
Once detected: 30s grace for cleanup, then kill. Also treats
SESSION_ENDED as success for checkpoint creation.
Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add Exoscale as a new cloud provider to Spawn with:
- European cloud with per-second billing across 7 zones
- CLI-based provisioning via exo tool (auto-installed)
- SSH access with ubuntu user
- Implements claude, aider, and goose agents
Technical details:
- exoscale/lib/common.sh: Provider primitives using exo CLI
- Auto-installs exo CLI from GitHub releases (v1.90.1)
- Supports EXOSCALE_API_KEY + EXOSCALE_API_SECRET auth
- Default zone: ch-gva-2 (Geneva), configurable to 6 other zones
- Uses standard.small instance type by default
- Cloud-init support for agent setup
- Full OpenRouter integration for all agents
Matrix: Added 15 missing entries, implemented 3 (claude, aider, goose)
Agent: cloud-scout
Co-authored-by: B <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Adds Continue CLI integration on Civo cloud platform using:
- Bun install for @continuedev/cli
- OpenRouter API key injection via OAuth
- Config file at ~/.continue/config.json with OpenRouter provider
- Interactive TUI launch via 'cn' command
Agent: gap-filler-civo-continue
Co-authored-by: B <6723574+louisgv@users.noreply.github.com>
Implements daytona/continue.sh script following the standard pattern:
- Sources daytona/lib/common.sh for cloud-specific primitives
- Installs Continue CLI via npm
- Injects OPENROUTER_API_KEY into shell environment
- Creates ~/.continue/config.json with OpenRouter provider
- Launches Continue TUI via interactive session
Updates manifest.json matrix entry to "implemented".
Agent: gap-filler-daytona-continue
Co-authored-by: B <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Add Continue CLI agent deployment script for OVHcloud. Uses OVH's Public
Cloud API for provisioning, installs Continue CLI via npm, and configures
OpenRouter integration with ~/.continue/config.json.
Agent: gap-filler-ovh-continue
Co-authored-by: B <6723574+louisgv@users.noreply.github.com>
Implements binarylane/continue.sh to run Continue CLI on BinaryLane servers.
- Uses BinaryLane REST API to provision Ubuntu 24.04 server
- Installs Node.js via NVM and Continue CLI (@continuedev/cli)
- Configures OpenRouter integration in ~/.continue/config.json
- Launches interactive TUI mode (cn command)
Agent: gap-filler-binarylane-continue
Co-authored-by: B <6723574+louisgv@users.noreply.github.com>
Adds Continue CLI support on Fly.io by combining Fly.io's Machines API
primitives with Continue's setup steps. Includes OpenRouter config injection
via ~/.continue/config.json.
Agent: gap-filler-fly-continue
Co-authored-by: B <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Add Continue agent script for Scaleway cloud provider.
Uses scaleway/lib/common.sh primitives for provisioning and SSH connectivity.
Installs Continue CLI via npm, creates OpenRouter config at ~/.continue/config.json,
and launches interactive TUI mode via cn command.
Agent: gap-filler-scaleway-continue
Co-authored-by: B <6723574+louisgv@users.noreply.github.com>
Implements Continue.dev CLI agent on UpCloud cloud platform:
- Uses UpCloud REST API to provision server
- Installs Continue CLI via npm
- Injects OpenRouter API key into environment
- Creates ~/.continue/config.json with OpenRouter provider
- Launches Continue in TUI mode
Agent: gap-filler-upcloud-continue
Co-authored-by: B <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
- Spinner completion messages now show "done" state instead of repeating
the in-progress message (e.g., "Loading manifest" instead of "Loading manifest...")
- Script failures show actionable troubleshooting (missing credentials,
rate limits, dependencies) instead of generic "Script exited with code N"
- Ctrl+C (exit code 130) exits silently instead of showing an error
- Fuzzy matching for unknown agents/clouds now also searches display names,
so "Hetzner" suggests "hetzner" even when the key doesn't fuzzy-match
Agent: ux-engineer
Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Root cause: `claude -p` (print mode) terminates the session when the
model produces a text response with no tool call. The team lead would
spawn 6 agents, output "I'll wait for messages", and the session would
end — orphaning all agents.
Fix: the prompt now explains the technical constraint (must always
include a tool call) and prescribes an active polling loop using
TaskList + `sleep 30` + gh pr list to stay alive while waiting for
teammate messages, instead of passively waiting.
Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replaces the naive `claude | tee` pipe with a background process +
watchdog loop that monitors log file growth every 10 seconds.
If no output is produced for 10 minutes (IDLE_TIMEOUT=600s), the
watchdog kills the hung process. This catches stuck API calls,
network hangs, and the team lead silently exiting while teammates
are orphaned — much faster than waiting for the 75min RUN_TIMEOUT_MS.
Team cycle: 10min idle timeout, 60min hard wall-clock timeout
Single cycle: 10min idle timeout, 35min hard wall-clock timeout
The next cron trigger starts a fresh cycle automatically.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Rename "Missing" column to "Not available on" to avoid confusion
- Change "all clouds" to "-- all clouds supported" for full coverage agents
- Only show +/- grid legend in grid view (not compact view)
- Fix help text alignment for "spawn list" command
Agent: ux-engineer
Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
- create_server(): Validate hostname, plan, region env vars with
validate_resource_name(); pass all values via sys.argv instead of
string interpolation in Python code
- ensure_ssh_key(): Build SSH key JSON payload with json.dumps via
sys.argv instead of raw string interpolation (prevents SSH key
content from breaking JSON)
- _cherry_json_field(), _cherry_find_key_by_fingerprint(): Use
sys.argv instead of bash variable interpolation in Python strings
Agent: security-auditor
Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The team lead was spawning 6 agents then exiting because the prompt
lacked explicit instructions to stay alive and wait for messages (the
discovery prompt has this, refactor didn't). Added the WaitForMessage
monitoring loop pattern from discovery.sh.
Also increased IDLE_TIMEOUT from 180s to 600s — 3 min was too
aggressive, killing legitimate cycles where agents are working and the
leader is waiting for their responses.
Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Creates agent deployment scripts for Cherry Servers that were marked
as "implemented" in manifest.json but were missing the actual script
files, causing 12 test failures in script-syntax.test.ts.
Added scripts: claude, nanoclaw, aider, codex, interpreter, gemini,
amazonq, cline, gptme, opencode, plandex, kilocode
Agent: test-engineer
Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The IONOS provider interpolated $IONOS_USERNAME and $IONOS_PASSWORD
directly into Python string literals when saving credentials, allowing
arbitrary code execution via crafted credential values containing
single quotes. Use json_escape + printf instead (matching the pattern
used by all other providers). Also validate IONOS_LOCATION format and
numeric env vars (IONOS_CORES, IONOS_RAM, IONOS_DISK_SIZE).
Agent: security-auditor
Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Users typing "spawn Claude" or "spawn Claude Code" now get resolved
to the correct key automatically instead of an "invalid characters"
error. Works for both agents and clouds in single-arg info and
two-arg run paths.
Agent: ux-engineer
Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The lead was spawning teammates via Task (fire-and-forget) and then
ending its conversation after 14 turns. Teammates became orphaned
with no coordination or shutdown sequence.
Added three changes to the team lead prompt:
1. Upfront warning: "your session MUST stay alive for the entire cycle"
2. New "Monitoring Loop" section with explicit WaitForMessage pattern
and common-mistake callout (BAD: spawn then exit, GOOD: spawn then
WaitForMessage loop then shutdown)
3. End instruction restructured into 3 mandatory phases:
Setup → Monitor (WaitForMessage loop) → Shutdown
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The team lead's claude process can hang indefinitely when an API call
doesn't return (observed: pre-flight check hung for 30+ min while 6
agents were orphaned). The hard timeout waits the full 40 min.
Now monitors log file growth every 10s. If no output for 3 minutes
(IDLE_TIMEOUT=180s), the process is killed immediately. The next
5-minute cron trigger starts a fresh cycle — no wasted time.
Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ensure_sprite_exists() now polls `sprite list` until the sprite
appears (up to 30s) instead of a fixed sleep. This eliminates the
spurious "sprite not found" errors that appeared while the sprite
was still provisioning.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Budget European provider starting at $2/month for 1 vCore/1GB RAM
- REST API via CloudAPI v6 with Basic Auth (username + password)
- Datacenter-based resource organization (auto-creates if needed)
- Volume-based boot disks with cloud-init support
- Implemented 3 agents: claude, aider, goose
- 11 agents marked as missing for future implementation
Agent: cloud-scout-1
Co-authored-by: B <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>