Commit graph

48 commits

Author SHA1 Message Date
A
81bab47a74
fix: Escape API keys in continue.sh JSON configs to prevent injection (#374)
Replace vulnerable heredoc patterns across 27 continue.sh scripts with
setup_continue_config() helper that uses json_escape() + upload_config_file()
to safely handle API keys containing special characters like quotes or braces.

Also fix _save_token_to_config() in shared/common.sh which had the same
unescaped heredoc vulnerability for local token storage.

Relates to #104

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>
2026-02-11 00:13:19 -08:00
Ahmed Abushagur
8b9f9a0e5a
QA-Bot setup (#335)
* feat: testing

* feat: auto-fix dead apis

* fix: mock works

* feat: new fixtures

* fix: more clouds tested

* fix: dry run fix

* fix: civo valid size

* fix: civo result wait

* feat: fixtures

* feat: per cloud agent
2026-02-10 19:51:07 -08:00
A
571e17c559
feat: Add Continue AI coding assistant (#303)
Continue is an open-source AI coding assistant with 31K+ GitHub stars and strong HN buzz (298 points launch, 178 points v1.0). Features CLI TUI and headless modes, natively supports OpenRouter.

Evidence of community demand:
- GitHub: 31,335 stars (https://github.com/continuedev/continue)
- HN Launch: 298 points (July 2023)
- HN v1.0: 178 points (March 2025)
- YC-backed (S23)

Technical requirements met:
- Single command install: npm install -g @continuedev/cli
- Native OpenRouter support via config.json
- CLI modes: TUI (cn) and headless (cn -p)

Implemented on sprite and hetzner clouds.

Agent: agent-scout

Co-authored-by: B <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-10 16:49:31 -08:00
A
fc48279ecb
feat: Add kilocode scripts for hetzner, digitalocean, vultr, linode, lambda, aws-lightsail, gcp (#114)
Agent: gap-filler

Co-authored-by: B <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-09 19:46:21 -08:00
A
b0f924b511
fix: Prevent Python/shell injection via env vars and triple-quote strings (#102)
- Fix triple-quote injection in SSH keys (Scaleway, UpCloud), userdata
  (BinaryLane), init scripts (Civo, Kamatera), and GraphQL queries
  (RunPod) by passing data via stdin/json_escape instead of inline
  string interpolation
- Add input validation for all cloud provider env vars (region, type,
  plan, etc.) using validate_region_name/validate_resource_name to block
  shell metacharacters before they reach Python string interpolation
- Validate Modal image name as Python identifier to prevent code injection
- Validate numeric env vars (RAM, GPU count, disk size) across all providers

Affects: 19 cloud provider lib/common.sh files
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>
2026-02-09 10:22:39 -08:00
A
2915d7bca6
fix: Improve CLI error handling, fix bash compat, and update cloud READMEs (#90)
- Show clear error when --prompt/-p or --prompt-file is used without a
  value (previously silently ignored)
- Fix --prompt-file splice index bug when used after --prompt
- Replace echo -e with printf in fly/lib/common.sh for macOS bash 3.x
  compatibility
- Fix incorrect env var name in README (DIGITALOCEAN_TOKEN -> DO_API_TOKEN)
- Add missing agent entries (gptme, OpenCode, Plandex) to 11 cloud READMEs
- Add all 13 agents to Civo README (previously only had 3)

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>
2026-02-09 09:33:57 -08:00
A
1bd7b1bd07
feat: Add community-coordinator agent to refactor team (#64)
* ux: Improve error messages and user guidance across CLI and shell scripts

Enhanced error messages to be more actionable and user-friendly:

CLI improvements (commands.ts):
- Made validateNonEmptyString clearer: "is required but was not provided"
- Reordered troubleshooting steps to check matrix first (most common issue)
- Simplified 404 error message: "doesn't exist yet" vs "may not be implemented"
- Changed "Troubleshooting steps" to just "Troubleshooting" (less formal)

Shared library improvements (shared/common.sh):
- OAuth cancellation now explains why API key is needed and where to get it
- safe_read non-TTY error explains what non-interactive mode is with example
- get_resource_name error shows exact env var syntax needed
- Agent verification failures now list specific possible causes
- All improvements add context and next steps rather than just stating the problem

Hetzner library improvements (hetzner/lib/common.sh):
- Replaced technical "Remediation" with friendly "How to fix"
- Changed log_warn to log_error for error conditions (consistent severity)
- Added spacing for better readability of multi-line errors
- Made server creation errors more specific about account issues

All changes focus on helping users understand WHAT went wrong and HOW to fix it.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: Replace issue-triager with community-coordinator agent

Replace the issue-triager agent in the refactor team with a
community-coordinator that actively engages with GitHub issues:
acknowledges reports, posts interim updates, delegates to relevant
teammates, and posts final resolutions — so reporters feel heard.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-09 02:58:26 -08:00
L
0708ff1700
fix: Use robust OpenCode install method across all clouds (#48)
The upstream OpenCode installer pipes `curl -# -L | tar xz` which fails
in container exec environments (Sprite, E2B, Modal, Daytona) where the
binary stream gets corrupted through the exec layer, producing
"gzip: stdin: not in gzip format" errors.

Added opencode_install_cmd() to shared/common.sh that downloads the
binary to a file first, then extracts it. Updated all 17 opencode.sh
scripts to use this robust method instead of the upstream installer.

The previous fix (#44) only addressed Sprite with a hardcoded
linux-x86_64 architecture. This fix detects OS/arch dynamically and
applies to all cloud providers.

Fixes #42

Co-authored-by: Sprite <noreply@sprite.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-07 23:02:18 -08:00
L
7f956b8d8e
Add Plandex coding agent with 14 cloud implementations (#36)
Plandex is an open source AI coding agent for complex tasks (15k+ GitHub
stars, multiple HN frontpage posts). It natively supports OpenRouter via
OPENROUTER_API_KEY environment variable and installs via a single curl
command. Go-based CLI with sandbox and version control for AI changes.

Implemented on all 14 clouds: sprite, hetzner, digitalocean, vultr,
linode, lambda, aws-lightsail, gcp, e2b, modal, fly, civo, scaleway,
daytona.

Co-authored-by: Sprite <noreply@sprite.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-07 21:35:04 -08:00
Sprite
ea844c272b Add OpenCode agent (10.8k stars, 319pt HN post)
OpenCode is a Go-based AI coding agent with a terminal TUI (Bubble Tea).
It natively supports OpenRouter as a built-in provider via OPENROUTER_API_KEY.

- Add opencode agent to manifest.json with env config
- Implement sprite/opencode.sh for Sprite cloud
- Implement hetzner/opencode.sh for Hetzner Cloud
- Add matrix entries (implemented: sprite, hetzner; missing: rest)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-08 05:13:37 +00:00
Sprite
cdd0d4e93e refactor: Extract ENV_TEMP pattern to inject_env_vars_ssh (SSH providers)
Converted 34 scripts across 6 SSH-based providers to use inject_env_vars_ssh:
- digitalocean: amazonq, cline, gemini (3 scripts)
- hetzner: amazonq, cline, gemini (3 scripts)
- linode: amazonq, cline, gemini (3 scripts)
- vultr: amazonq, cline, gemini (3 scripts)
- aws-lightsail: all agents except openclaw (10 scripts)
- lambda: all agents except openclaw (10 scripts)

Plus aws-lightsail/openclaw and lambda/openclaw (2 scripts)

Each conversion replaces 11-15 lines of temp file management with a single
inject_env_vars_ssh call that handles creation, upload, sourcing, and cleanup.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-08 04:11:15 +00:00
L
b6ee6b6ab1
Add guardrails: CLAUDE.md rules, hooks, pre-commit validation (#33)
* feat: add gptme agent to spawn matrix

Add gptme (https://github.com/gptme/gptme) - a personal AI agent in the
terminal with tools for code editing, terminal commands, web browsing,
and more. Natively supports OpenRouter via OPENROUTER_API_KEY.

- Add gptme agent entry to manifest.json with OpenRouter env vars
- Implement sprite/gptme.sh deployment script
- Implement hetzner/gptme.sh deployment script
- Add "missing" matrix entries for remaining 8 clouds
- Update README.md with usage instructions for Sprite and Hetzner

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add Fly.io cloud provider with claude and aider agents

Add Fly.io as a new cloud provider using the Machines REST API for
provisioning and flyctl CLI for SSH access. Docker-based machines
with pay-per-second pricing.

- Create fly/lib/common.sh with Fly.io Machines API integration
- Implement fly/claude.sh for Claude Code deployment
- Implement fly/aider.sh for Aider deployment
- Update README.md with Fly.io usage instructions and env vars

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add gemini, amazonq, cline, gptme to Fly.io

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add openclaw, nanoclaw, goose, codex, interpreter to Fly.io

Implements 5 new agent scripts for the Fly.io cloud provider:
- fly/openclaw.sh: OpenClaw with gateway + TUI, model selection, config
- fly/nanoclaw.sh: NanoClaw WhatsApp agent with .env configuration
- fly/goose.sh: Block's Goose agent with OpenRouter provider
- fly/codex.sh: OpenAI Codex CLI with OpenRouter base URL override
- fly/interpreter.sh: Open Interpreter with OpenRouter base URL override

All scripts follow the Fly.io pattern (flyctl-based, no IP args for
run_server/interactive_session) and use upload_file for env injection.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add gptme agent to 8 remaining clouds

Implement gptme agent scripts for digitalocean, vultr, linode, lambda,
aws-lightsail, gcp, e2b, and modal. Each script follows the exact
pattern of that cloud's existing aider.sh, adapted for gptme's install
and launch commands. Updates manifest.json matrix entries from "missing"
to "implemented".

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Add guardrails from insights: CLAUDE.md rules, hooks, pre-commit

Based on usage insights analysis:

CLAUDE.md:
- Shell script rules: curl|bash compat, macOS bash 3.x compat
- Autonomous loop rules: test after each iteration, never revert fixes
- Git workflow rules: always use feature branches

.claude/settings.json:
- PostToolUse hook validates .sh files on every Write/Edit:
  syntax check, no relative source, no echo -e, no set -u

.githooks/pre-commit:
- Blocks commits with: syntax errors, relative sources, echo -e,
  set -euo, references to deleted functions
- Install: git config core.hooksPath .githooks

README.md:
- Added developer setup section with hook installation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Sprite <noreply@sprite.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-07 20:02:19 -08:00
Sprite
6d4eca6d5d refactor: add SC2154 disable for API token variables
- hetzner/lib/common.sh:31 - HCLOUD_TOKEN set by caller
- digitalocean/lib/common.sh:36 - DO_API_TOKEN set by caller
- Silences false positive warnings for intentionally external variables
- These tokens are exported by ensure_*_token functions before use
2026-02-08 03:21:48 +00:00
Sprite
7a21be18fc fix: remove undefined ENV_TEMP from nanoclaw trap handlers
- 5 nanoclaw scripts only create DOTENV_TEMP but trap referenced both
- Causes trap to fail silently when trying to rm undefined variable
- Fix: Change trap from both temps to just DOTENV_TEMP
- Affected: digitalocean, hetzner, linode, sprite, vultr

Root cause: Automated trap addition in Round 19 incorrectly detected
these files as using both temp variables (DOTENV_TEMP contains substring
ENV_TEMP which caused false positive in grep check)
2026-02-08 03:20:36 +00:00
Sprite
91c466c008 refactor: add trap cleanup for temp files in agent scripts
- Add trap 'rm -f "${ENV_TEMP}"' EXIT after mktemp creation
- Scripts with DOTENV_TEMP get combined trap for both files
- Remove manual rm calls that are now redundant
- Prevents temp file leaks on early script exit (errors, signals)
- Affects 67 agent scripts across all providers

Impact: Prevents /tmp pollution in production deployments
Score: 90 (Impact: 9, Confidence: 10, Risk: 1)
2026-02-08 03:15:48 +00:00
Sprite
0f5a11b1c9 fix: repair broken Python error parsing in Hetzner and DigitalOcean (CRITICAL)
Fixed 2 critical syntax errors in API error handling:
- Hetzner line 160-161: Malformed error_msg assignment
- DigitalOcean line 172-173: Broken error_msg assignment

These were introduced during Round 15 refactoring and would crash
whenever users encountered API errors during server creation.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-08 03:05:38 +00:00
Sprite
55ef42c82e refactor: add shellcheck disables for intentional SSH_OPTS word splitting
Add SC2086 disable comments to interactive_session() functions in
GCP, Hetzner, and DigitalOcean providers. SSH_OPTS is intentionally
unquoted to allow word splitting for multiple SSH options.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-08 02:56:08 +00:00
Sprite
f20568aea0 fix: repair broken Python multi-line assignments in 3 providers
Fixed malformed Python command assignments in:
- hetzner/lib/common.sh: Separated declaration and assignment for error_msg and userdata_json
- digitalocean/lib/common.sh: Fixed error_msg assignment split across lines
- vultr/lib/common.sh: Fixed saved_key and two error_msg assignments

Pattern applied: Separate `local var` declaration from `var=$(command)` assignment
to avoid bash syntax errors.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-08 02:47:13 +00:00
Sprite
f5d210aa19 refactor: add explicit timeout to wait_for_cloud_init calls
Add explicit timeout parameter (60 seconds) to all wait_for_cloud_init calls
across linode, vultr, digitalocean, hetzner, gcp, and aws-lightsail providers.

This makes timeout configuration more explicit and easier to tune per-provider
or per-agent in the future. The value of 60 matches the default in the
wait_for_cloud_init function implementations.

Modified 60 agent scripts (10 agents × 6 providers).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-08 02:38:19 +00:00
Sprite
cabdbc37ba refactor: add pipefail to error handling flags
Changed 65 agent scripts from `set -e` to `set -eo pipefail` to ensure
errors in piped commands are properly caught. This prevents silent
failures when commands like `curl | bash` fail in the middle.

Files updated across all cloud providers:
- aws-lightsail: 10 scripts
- digitalocean: 3 scripts
- e2b: 10 scripts
- gcp: 10 scripts
- hetzner: 3 scripts
- lambda: 10 scripts
- linode: 3 scripts
- modal: 10 scripts
- sprite: 3 scripts
- vultr: 3 scripts

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-08 02:34:45 +00:00
Sprite
e0dfc9672a refactor: fix shellcheck directive placement in agent scripts
- Move shellcheck source directives before if statements
- Fix 90 SC1073/SC1123 parse errors
- Enables full shellcheck analysis of agent scripts

Score: 90 (Impact: 18, Confidence: 10, Risk: 2)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-08 02:32:08 +00:00
Sprite
0cab5827de refactor: consolidate OpenClaw config setup to shared helper
- Add setup_openclaw_config() to shared/common.sh
- Replace ~350 lines of duplicate config code across 10 files
- Uses callback pattern for provider-specific upload/run operations

Score: 14 (Impact: 7, Confidence: 8, Risk: 4)
2026-02-08 02:25:17 +00:00
Sprite
f9dd9a7bf5 refactor: consolidate Claude Code config setup to shared helper
- Add setup_claude_code_config() to shared/common.sh
- Replace ~400 lines of duplicate config code across 10 files
- Uses callback pattern for provider-specific upload/run operations
- Net reduction: 325 lines (81.2% reduction)

Score: 16 (Impact: 8, Confidence: 8, Risk: 4)
2026-02-08 02:22:06 +00:00
Sprite
eff8ded1bd refactor: add shellcheck source directives for provider variables
- Add shellcheck source comments to all agent scripts
- Tells shellcheck where provider-exported variables are defined
- Fix 132+ SC2154 warnings across all providers

Score: 30 (Impact: 6, Confidence: 10, Risk: 2)
2026-02-08 02:17:04 +00:00
Sprite
0f53c81052 refactor: fix SC2140 quoting in inject_env_vars calls
- Remove unnecessary inner quotes in environment variable values
- Fix 30+ SC2140 warnings across 28 provider scripts
- Pattern: "VAR=\"value\"" → "VAR=value"

Score: 35 (Impact: 7, Confidence: 10, Risk: 2)
2026-02-08 02:11:45 +00:00
Sprite
c7fe5ca9f2 refactor: fix SC2155 declaration issues in lib files
- Separate variable declaration from command assignment
- Prevents masking command exit codes
- Fix 7 SC2155 warnings in modal, sprite, and shared libs

Score: 30 (Impact: 6, Confidence: 10, Risk: 2)
2026-02-08 02:10:02 +00:00
Sprite
3b6c761904 refactor: add username parameter to generic_ssh_wait
- Add required username parameter to generic_ssh_wait()
- Update SSH command to use dynamic username instead of hardcoded "root"
- Update all existing callers to pass username explicitly
- Enables GCP and AWS Lightsail to adopt generic_ssh_wait in future

Score: 40 (Impact: 8, Confidence: 10, Risk: 2)
2026-02-08 01:58:48 +00:00
Sprite
f2afdea792 refactor: extract ensure_ssh_key duplication to shared library (~220 lines)
Eliminates duplicate SSH key registration logic across 5 cloud providers
(Hetzner, DigitalOcean, Vultr, Linode, Lambda) by introducing a generic
callback-based pattern in shared/common.sh.

Before: Each provider had ~45 lines of nearly identical code for:
- Generating SSH keys if missing
- Getting fingerprints
- Checking if key exists with provider
- Registering key if not exists
- Error handling

After: Providers implement 2 simple callbacks:
- check_callback: provider-specific API call to check if key exists
- register_callback: provider-specific API call to register key

The shared function handles:
- Key generation (via generate_ssh_key_if_missing)
- Fingerprint extraction (via get_ssh_fingerprint)
- Flow control and logging
- Callback orchestration

Changes:
- shared/common.sh: Added ensure_ssh_key_with_provider() function
- hetzner/lib/common.sh: Refactored to use callbacks
- digitalocean/lib/common.sh: Refactored to use callbacks
- vultr/lib/common.sh: Refactored to use callbacks
- linode/lib/common.sh: Refactored to use callbacks
- lambda/lib/common.sh: Refactored to use callbacks

Benefits:
- DRY: Eliminates ~220 lines of duplicate code
- Maintainability: Bug fixes in registration flow benefit all providers
- Consistency: All providers use identical registration logic
- Extensibility: New providers can reuse this pattern

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-08 01:33:06 +00:00
Sprite
a631faf4fe refactor: suppress SC2086 for intentional SSH_OPTS word splitting
SSH_OPTS contains multiple flags that must be word-split, so unquoted
usage is intentional. Added shellcheck directives to suppress false
positive warnings across all cloud provider common.sh files.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-08 01:29:56 +00:00
Sprite
331fa3a6ac refactor: replace raw color echo with log_warn in provider libraries
Replaced raw echo -e "${YELLOW}...${NC}" statements with log_warn calls
in ensure_*_token functions across all provider libraries. This fixes
SC2154 shellcheck warnings for undeclared YELLOW and NC color variables
and improves code consistency.

Files changed:
- digitalocean/lib/common.sh:62
- hetzner/lib/common.sh:60
- linode/lib/common.sh:49
- vultr/lib/common.sh:55
- lambda/lib/common.sh:49
- e2b/lib/common.sh:52

Benefits:
- Eliminates 6 SC2154 shellcheck warnings
- Uses centralized logging function that already handles yellow coloring
- Improves code maintainability and consistency

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-08 01:20:43 +00:00
Sprite
0b4fe29026 refactor: fix SC2154 warnings for SSH_OPTS in provider libraries
Added shellcheck directive comments before first SSH_OPTS usage in:
- aws-lightsail/lib/common.sh
- gcp/lib/common.sh
- lambda/lib/common.sh
- vultr/lib/common.sh
- linode/lib/common.sh
- hetzner/lib/common.sh
- digitalocean/lib/common.sh

SSH_OPTS is defined in shared/common.sh but shellcheck can't detect
cross-file variable definitions, so we suppress the warning with
an explanatory comment.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-08 01:20:06 +00:00
Sprite
0ad6680f1f refactor: extract duplicate get_server_name logic to shared function
- Add get_resource_name() to shared/common.sh
  - Generic function for env-var-or-prompt pattern
  - Uses indirect expansion ${!var} for dynamic env vars
  - Preserves exact behavior: env check → prompt → error

- Update 9 cloud providers to use shared function:
  - aws-lightsail: LIGHTSAIL_SERVER_NAME
  - digitalocean: DO_DROPLET_NAME (with validation)
  - gcp: GCP_INSTANCE_NAME
  - hetzner: HETZNER_SERVER_NAME (with validation)
  - linode: LINODE_SERVER_NAME (with validation)
  - sprite: SPRITE_NAME (with validation)
  - vultr: VULTR_SERVER_NAME (with validation)
  - e2b: E2B_SANDBOX_NAME
  - modal: MODAL_SANDBOX_NAME

- Reduces code duplication: ~120 lines → ~25 lines
- Maintains backward compatibility (env vars, prompts, errors unchanged)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-08 01:16:20 +00:00
L
591066cd53
Use ${VAR:-} for all optional env var checks (#28)
Protects against 'unbound variable' errors even if set -u is
re-enabled or inherited. Every [[ -n "$UPPER_VAR" ]] pattern now
uses [[ -n "${UPPER_VAR:-}" ]] to safely default to empty.

Co-authored-by: Sprite <noreply@sprite.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-07 16:28:12 -08:00
L
4087deb14e
Drop nounset (set -u) flag — incompatible with env var checks (#27)
The autonomous refactoring added `set -euo pipefail` but the scripts
check optional env vars with `[[ -n "$VAR" ]]` which is a fatal error
under nounset when the var isn't set (e.g. SPRITE_NAME, OPENROUTER_API_KEY).

Fix: downgrade to `set -eo pipefail` across all 42 affected files.

Co-authored-by: Sprite <noreply@sprite.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-07 16:22:04 -08:00
L
7e952d1310
Fix shared/common.sh loading for curl-piped execution (#26)
When scripts run via `bash <(curl ...)`, BASH_SOURCE resolves to
/dev/fd/N, making the relative path `../../shared/common.sh` fail.

Fix: add remote fallback — try local file first, fall back to
fetching shared/common.sh from GitHub via eval+curl.

Applied to all 5 refactored lib/common.sh files (sprite, hetzner,
digitalocean, vultr, linode).

Co-authored-by: Sprite <noreply@sprite.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-07 16:16:51 -08:00
L
3fb2e77b03
Autonomous refactoring: 5 rounds, ~1,400 lines eliminated, production-ready
Five rounds of autonomous AI agent team refactoring with security fixes, code consolidation, and expanded test coverage.
2026-02-08 00:06:46 +00:00
L
6ac59e6bb3
Fix OAuth server for macOS bash 3.x (#24)
Three issues broke the OAuth callback server on macOS:

1. echo -e doesn't work in bash 3.x — \r\n appears as literal text
   in the HTTP response, browser gets malformed headers.
   Fix: pre-write response with printf to a file before the subshell.

2. local variables inside ( ... ) & subshell — undefined behavior in
   bash 3.x since subshells aren't function scope.
   Fix: use plain variables in subshells.

3. ((elapsed++)) when elapsed=0 evaluates to falsy — set -e kills
   the script on the first iteration of the timeout loop.
   Fix: use elapsed=$((elapsed + 1)) instead.

Also simplified nc_listen detection to only check for BusyBox
(the -p flag check could misfire on macOS nc).

Applied to all 10 lib/common.sh files.

Co-authored-by: Sprite <noreply@sprite.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-07 14:21:47 -08:00
L
13896ba52d
Fix macOS bash compatibility: replace source <(curl) with eval (#23)
macOS ships bash 3.x which doesn't support nested process substitution.
When scripts are run via `bash <(curl ...)`, the inner `source <(curl ...)`
for loading common.sh fails silently, causing "command not found" errors.

Fix: replace `source <(curl -fsSL URL)` with `eval "$(curl -fsSL URL)"`
across all 100 agent scripts. eval+curl works on bash 3.x and newer.

Co-authored-by: Sprite <noreply@sprite.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-07 14:13:56 -08:00
L
70399cb8a7
Add E2B + Modal sandbox providers, restructure README (#22)
New sandbox-type cloud providers (no SSH, SDK-driven exec):
- e2b/: E2B sandboxed containers via CLI (~150ms cold start)
- modal/: Modal sandboxed containers via Python SDK (sub-second cold start)

README restructure:
- Root README.md simplified to matrix table with launch links
- Per-cloud README.md files with detailed docs, env vars, non-interactive mode

Matrix now 10 agents x 10 clouds = 100/100 implemented.

Co-authored-by: Sprite <noreply@sprite.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-07 14:11:04 -08:00
L
c3e83ea00a
Add Cline as tenth agent across all clouds (#18)
Cline is an open-source AI coding agent for the terminal.
Works with OpenRouter via OPENAI_BASE_URL override.

- Implemented on all 7 clouds
- Matrix now 10 agents x 7 clouds = 70/70 implemented

Co-authored-by: Sprite <noreply@sprite.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-07 12:01:38 -08:00
L
74eb301d59
Add Amazon Q CLI as ninth agent across all clouds (#17)
AWS's AI coding assistant, works with OpenRouter via OPENAI_BASE_URL override.
Installed via official installer script, launched with `q chat`.

- Implemented on all 7 clouds
- Matrix now 9 agents x 7 clouds = 63/63 implemented

Co-authored-by: Sprite <noreply@sprite.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-07 11:58:37 -08:00
L
5fde5ebbdc
Add Gemini CLI (Google) as eighth agent across all clouds (#15)
Google's open-source coding agent, works with OpenRouter via
OPENAI_BASE_URL override and GEMINI_API_KEY env var.

- Implemented on all 6 clouds: sprite, hetzner, digitalocean, vultr, linode, aws-lightsail
- Matrix now 8 agents x 6 clouds = 48/48 implemented

Co-authored-by: Sprite <noreply@sprite.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-07 11:50:40 -08:00
L
4f4d87c234
Add Open Interpreter as seventh agent across all clouds (#13)
Open Interpreter provides a natural language interface for computer control.
Works with OpenRouter via OPENAI_BASE_URL=https://openrouter.ai/api/v1.

- Implemented on all 5 clouds: sprite, hetzner, digitalocean, vultr, linode
- Matrix now 7 agents x 5 clouds = 35/35 implemented

Co-authored-by: Sprite <noreply@sprite.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-07 09:30:27 -08:00
L
5a2f82cdbe
Add Codex CLI (OpenAI) as sixth agent across all clouds (#11)
OpenAI's open-source coding agent, works with OpenRouter via
OPENAI_BASE_URL=https://openrouter.ai/api/v1 override.

- sprite/codex.sh, hetzner/codex.sh, digitalocean/codex.sh, vultr/codex.sh
- Matrix now 6 agents x 4 clouds = 24/24 implemented

Co-authored-by: Sprite <noreply@sprite.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-07 09:21:23 -08:00
L
7de02db81b
Add Goose agent (Block) across all clouds (#9)
Goose is Block's open-source model-agnostic AI coding agent.
Supports OpenRouter via GOOSE_PROVIDER=openrouter env var.

- sprite/goose.sh, hetzner/goose.sh, digitalocean/goose.sh
- Matrix now 5 agents x 3 clouds = 15/15 implemented

Co-authored-by: Sprite <noreply@sprite.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-07 08:58:51 -08:00
L
ff531d00b8
Add Aider as fourth agent across all clouds (#8)
Aider is the most popular open-source AI pair programming CLI.
Natively supports OpenRouter via OPENROUTER_API_KEY env var
and --model openrouter/... flag.

- sprite/aider.sh, hetzner/aider.sh, digitalocean/aider.sh
- Matrix now 4 agents x 3 clouds = 12/12 implemented

Co-authored-by: Sprite <noreply@sprite.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-07 08:56:07 -08:00
L
78e009176b
Add OpenClaw and NanoClaw scripts for Hetzner Cloud (#6)
Fills the remaining 2 gaps in the agents x clouds matrix:
- hetzner/openclaw.sh: provisions Hetzner server with OpenClaw gateway + TUI
- hetzner/nanoclaw.sh: provisions Hetzner server with NanoClaw WhatsApp agent

Matrix is now 100% complete (3 agents x 2 clouds = 6/6 implemented).

Co-authored-by: Sprite <noreply@sprite.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-07 08:49:11 -08:00
L
bd30565d86
Add Hetzner Cloud spawn system for provisioning servers via REST API (#4)
Parallel to the existing sprite/ directory, adds hetzner/ scripts that
provision Hetzner Cloud servers with Claude Code + OpenRouter using
curl-based API calls (no hcloud CLI dependency).

Co-authored-by: Sprite <noreply@sprite.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-07 07:25:03 -08:00