Commit graph

39 commits

Author SHA1 Message Date
A
a0f6b335a4
fix: harden upload_file path validation with strict allowlist regex across 10 clouds (#993)
Replace fragile blocklist validation and printf '%q' escaping in upload_file()
with strict allowlist regex [a-zA-Z0-9/_.~-]+ across all non-SSH cloud providers.
For codesandbox, additionally migrate from shell command interpolation to SDK
filesystem API via environment variables, eliminating the injection surface entirely.

Affected clouds: codesandbox, daytona, e2b, fly, koyeb, modal, northflank,
railway, render, sprite

Fixes #989

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-13 12:20:40 -08:00
A
5ebe3e5a13
fix: add actionable guidance to destroy_server failures and service timeouts (#959)
When server destruction fails, users are left with a bare error message and
no indication that they may still be billed for a running server. This adds
dashboard URLs and clear warnings to destroy_server errors across 9 clouds
(Hetzner, UpCloud, Contabo, Netcup, RamNode, Hostinger, HOSTKEY, OVH,
Latitude). Also improves error messages for Koyeb (app creation, service
deployment, deployment timeout, instance ID), GitHub Codespaces (creation
failure, readiness timeout), and E2B (sandbox creation failure).

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-13 09:38:58 -08:00
A
a0d1d1b40b
fix: replace jargon "Remediation" with plain "How to fix" in error messages (#925)
Replace technical "Remediation steps:" with "How to fix:" and
"Remediation: Check <url>" with "Check your dashboard: <url>" across
14 cloud providers for clearer error guidance. Add actionable error
messages to Atlantic.Net create_server and SSH key registration failures.

Agent: ux-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-13 05:52:31 -08:00
L
6633873ccc
refactor: replace Python with jq in Hetzner lib, fix /lab → /labs URLs (#827)
Hetzner lib: replace all Python JSON parsing with jq. Uses the
/datacenters API as the authoritative source for server type
availability (server_types.available), cross-referenced with
/server_types for specs and pricing. jq is auto-installed if missing.

URLs: update openrouter.ai/lab/spawn → openrouter.ai/labs/spawn
across all READMEs and CLI source.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-12 23:14:11 -08:00
A
e8dc7b4752
fix: replace unsafe inline API key injection with secure helpers (#676)
8 scripts were embedding OPENROUTER_API_KEY directly into shell command
strings passed to run_server/run_in_codespace, allowing command injection
if the API key contains shell metacharacters (single quotes, semicolons,
backticks, etc.).

The worst case was latitude/continue.sh which had zero quoting:
  export OPENROUTER_API_KEY=${OPENROUTER_API_KEY}
allowing arbitrary command execution on the remote server with a
crafted API key value.

Fixed by replacing unsafe inline patterns with the existing secure
helpers (inject_env_vars_ssh, inject_env_vars_local, inject_env_vars)
which use generate_env_config to properly single-quote values with
embedded quote escaping.

Affected scripts:
- scaleway/continue.sh (single-quote breakout)
- upcloud/continue.sh (double-quote breakout)
- e2b/continue.sh (single-quote breakout)
- modal/continue.sh (single-quote breakout)
- daytona/continue.sh (single-quote breakout)
- latitude/continue.sh (no quoting at all - critical)
- github-codespaces/continue.sh (single-quote breakout)
- kamatera/nanoclaw.sh (single-quote breakout in .env write)

Agent: security-auditor

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 15:03:12 -08:00
A
6c7ced54dd
fix: replace log_warn with log_step/log_info for non-warning messages (#604)
Agent: ux-engineer

Many shell scripts misused log_warn (yellow) for normal progress/status
messages, making routine operations appear alarming. This fixes 59 files:

- Progress messages -> log_step (cyan): "Injecting environment variables...",
  "Attaching volume...", "Powering on instance...", "Retrieving server IP...",
  "Terminating sandbox/server...", "Creating datacenter...", "Importing SSH key...",
  "Deleting service/app...", "Modal not authenticated. Running setup..."
- Informational notices -> log_info (green): WhatsApp QR code authentication
  notices (30 nanoclaw scripts), codespace delete hints (14 scripts),
  "Appending environment variables to ~/.zshrc..." (6 local scripts),
  credential prompt hints, package update skipped, app reuse notices

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-12 03:24:30 -08:00
A
cc23013e7c
fix: validate MODEL_ID from environment to prevent command injection (#548)
The get_model_id_interactive function returned MODEL_ID from env vars
without calling validate_model_id, bypassing the allowlist check. Also
migrated 13 legacy scripts from raw safe_read to get_model_id_interactive
which includes validation.

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 15:41:10 -08:00
A
0835b35a36
fix: use log_step (cyan) for progress messages instead of log_warn (yellow) (#534)
~1500 progress messages across 481 files were using log_warn (yellow)
for normal status updates like "Installing...", "Setting up...",
"Creating server...", etc. This made users think something was wrong
when everything was proceeding normally.

Changes:
- Replace log_warn with log_step for all progress/status messages
- Keep log_warn only for actual warnings (errors, remediation hints)
- Remove emoji from 3 sprite completion messages

Agent: ux-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
2026-02-11 14:37:43 -08:00
A
f1e8d946df
fix: secure upload_file functions against command injection in 5 clouds (#453)
Replace unsafe printf '%q'-escaped unquoted variables with validated
single-quoted embedding in upload_file() for fly, northflank, daytona,
e2b, and koyeb. The previous pattern used unquoted $escaped_content and
$escaped_path in command strings passed to bash -c or run_server, which
could allow command injection via crafted filenames.

The fix:
- Validates remote_path rejects unsafe chars (', $, `, newlines)
- Uses base64 content directly (alphanumeric + /+= is shell-safe)
- Single-quotes both content and path in the command string
- Uses printf '%s' instead of echo for safer output

Matches the pattern already used by render, modal, and railway.

Agent: security-auditor

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-11 06:28:45 -08:00
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
895ef08deb
feat: Add Continue agent for 8 clouds (digitalocean, vultr, linode, aws-lightsail, gcp, github-codespaces, e2b, modal) (#316)
Implements Continue CLI agent on 8 cloud providers:
- digitalocean/continue.sh
- vultr/continue.sh
- linode/continue.sh
- aws-lightsail/continue.sh
- gcp/continue.sh
- github-codespaces/continue.sh
- e2b/continue.sh
- modal/continue.sh

All scripts follow the standard pattern:
1. Source cloud lib/common.sh with local/remote fallback
2. Authenticate with cloud provider
3. Provision server/sandbox
4. Install Continue CLI via npm
5. Inject OPENROUTER_API_KEY env var
6. Create ~/.continue/config.json with OpenRouter provider
7. Launch interactive TUI session with 'cn' command

Updated manifest.json to mark all 8 combinations as "implemented".

Agent: gap-filler-1

Co-authored-by: B <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-10 18:01:08 -08:00
A
086bc76c8d
feat: Add kilocode scripts for e2b, modal, fly, civo, scaleway, daytona (#113)
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:45:51 -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
LAB
d76c8dba0f
Security: fix critical command injection vulnerabilities in container providers (#54)
* refactor: Simplify API call retry logic in generic_cloud_api

Extract duplicated retry handling into focused helper functions:
- handle_api_network_error(): Handles curl errors with retry logic
- handle_api_transient_error(): Handles 429/503 HTTP errors
- _call_cloud_api(): Internal curl wrapper separating concerns

Reduces cyclomatic complexity of generic_cloud_api from 9 to 3.
Lines reduced from 89 to 54 (40% reduction).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* Security: fix critical command injection vulnerabilities in container providers

CRITICAL SECURITY FIX - Command injection vulnerabilities

Fixed command injection in bash -c calls across all container/sandbox providers.
These functions were passing commands directly to bash -c without proper escaping,
allowing potential remote code execution via crafted inputs.

Files fixed:
- sprite/lib/common.sh: run_sprite(), upload_file_sprite()
- e2b/lib/common.sh: run_server(), upload_file(), interactive_session()
- daytona/lib/common.sh: run_server(), upload_file(), interactive_session()
- railway/lib/common.sh: run_server(), upload_file(), interactive_session()

Fix: Use printf %q to properly escape all command arguments before passing to bash -c.
This prevents command injection while maintaining functionality.

Severity: CRITICAL (CVSS 9.8)
Impact: Remote code execution, full system compromise
Mitigation: Proper shell escaping using printf %q

All modified files pass bash -n syntax validation.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Sprite <noreply@sprite.dev>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-08 12:00:43 -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
2f78a77c44 Add Civo gptme agent script 2026-02-08 05:13:37 +00:00
Sprite
7cf733a351 refactor: Extract ENV_TEMP pattern to inject_env_vars_local (E2B)
Converted 11 E2B scripts to use inject_env_vars_local():
- aider, claude, amazonq, cline, codex
- gemini, goose, gptme, interpreter, nanoclaw, openclaw

Pattern reduces ~10-15 lines to 3-4 lines per script.

Special cases:
- nanoclaw.sh: Has additional DOTENV_TEMP for agent-specific .env file
- gptme.sh: Had manual rm instead of trap, now handled by shared function

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-08 04:06:33 +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
96c38fe108 refactor: Remove escaped variables in single quotes
Fixed SC2016 warnings by removing unnecessary backslashes from ${HOME}
and ${PATH} variables inside single-quoted strings in e2b and modal
provider libraries. Variables inside single quotes don't expand, so
the backslashes were literal characters being written to config files.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-08 03:48:25 +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
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
f78d5c474b refactor: add API token validation to E2B provider
- Add test_e2b_token() to validate E2B API keys
- Apply validate_api_token() consistently via ensure_api_token_with_provider
- Improves security and user experience
- Prevents invalid tokens from being saved

Score: 24 (Impact: 8, Confidence: 9, Risk: 3)
2026-02-08 02:18:29 +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
5af58c80c9 refactor: add braces to variable references in e2b/lib/common.sh
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-08 01:49:23 +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
0f221fe8b5 fix: correct syntax error in e2b/lib/common.sh from SC2155 fix
Fixed broken variable assignment that was incorrectly split during
SC2155 refactoring. Properly split local declaration from command
substitution assignment.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-08 01:22:01 +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
b05d55f03a security: add input validation to safe_read calls
- Added validate_api_token() to block shell metacharacters
- Added validate_region_name() for cloud regions/zones
- Added validate_resource_name() for server types/sizes
- Added validated_read() wrapper function for easy validation
- Updated 6 cloud libraries to use validated API token input:
  - Linode, Vultr, Hetzner, DigitalOcean, E2B, Lambda
- Prevents command injection via API tokens and other inputs

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-08 01:16:20 +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
Sprite
a9818001da refactor: migrate 5 cloud libraries to shared/common.sh pattern
Migrated aws-lightsail, e2b, gcp, lambda, and modal libraries to use
the shared library pattern established in earlier refactoring rounds.

Changes:
- Added shared/common.sh sourcing block (local-first, remote-fallback)
- Added bash safety flags (set -eo pipefail) to all 5 libraries
- Removed duplicate provider-agnostic functions:
  - Logging (log_info, log_warn, log_error)
  - Input handling (safe_read)
  - OAuth flow (try_oauth_flow, get_openrouter_api_key_oauth)
  - SSH helpers (generate_ssh_key_if_missing, etc.)
- Retained cloud-specific functions:
  - API wrappers and CLI integration
  - Server provisioning and lifecycle management
  - Cloud-specific validation and configuration

Impact:
- Net reduction: 460 lines (-545 added +85)
- Eliminates code duplication across 5 providers
- Improves consistency and maintainability
- All libraries now follow the same architectural pattern

Task: #3 (score 56 - highest priority)
Also addresses Task #4 (bash safety flags)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-08 01:08:34 +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
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