Commit graph

45 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
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
84c6b935f7
refactor: Decompose Linode and GenesisCloud create_server functions (#219)
Extract helper functions from the two largest create_server functions:

Linode (99 lines -> 30-line orchestrator):
- _linode_fetch_ssh_keys: fetch authorized SSH public keys
- _linode_build_create_payload: build userdata, root password, request body
- _linode_wait_for_active: poll until instance is running

GenesisCloud (92 lines -> 28-line orchestrator):
- _genesis_fetch_ssh_key_ids: fetch SSH key IDs
- _genesis_build_create_payload: build userdata and request body
- _genesis_wait_for_active: poll until instance is active

Agent: complexity-hunter

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-10 12:32:40 -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
95a629ef36
refactor: Deduplicate Vultr and Linode token management using shared helper (#84)
Replace hand-rolled ensure_vultr_token() and ensure_linode_token() with
calls to ensure_api_token_with_provider(), matching the pattern already
used by Hetzner, DigitalOcean, Lambda, E2B, and Scaleway.

Extracts test_vultr_token() and test_linode_token() validation functions
to preserve provider-specific error messages and remediation guidance.

Removes ~70 lines of duplicated env-check/config-file/prompt/save logic.

Agent: complexity-hunter

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 08:32:52 -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
Sprite
8f37ce3649 refactor: Automated improvements from cycle 1
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-08 06:02:07 +00: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
998aaead01 Add Civo interpreter script
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
f4b8be10a8 refactor: Quote INSTANCE_STATUS_POLL_DELAY in sleep commands
Fixed SC2086 warnings by adding quotes around ${INSTANCE_STATUS_POLL_DELAY}
in 4 provider libraries. This prevents potential word splitting bugs if
the variable contains unexpected whitespace.

Files updated:
- linode/lib/common.sh:231
- vultr/lib/common.sh:226
- aws-lightsail/lib/common.sh:133
- digitalocean/lib/common.sh:211

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-08 03:46:17 +00:00
Sprite
44948fb523 fix: split inline variable assignment in linode config (SC2318)
- Line 43: config_dir assignment not yet in effect when config_file uses it
- Split into two lines to ensure proper initialization order
- Prevents potential path resolution bugs
2026-02-08 03:21:00 +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
fe6674717b fix: repair broken Python assignments in Linode provider (CRITICAL)
Fixed 3 critical syntax errors preventing script execution:
- Line 45-46: Malformed saved_token assignment
- Line 65-66: Broken error_msg assignment in token validation
- Line 110-111: Broken error_msg in SSH key registration
- Line 164-165: Malformed root_pass assignment

These were introduced during Round 15 refactoring and prevented
Linode authentication and server creation from working.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-08 03:01: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
63db82c590 refactor: extract sleep values to configurable constants
Extract hardcoded sleep values in wait loops to environment-configurable
constants at the top of provider lib/common.sh files:

- INSTANCE_STATUS_POLL_DELAY (default: 5s, Lambda: 10s) - for instance status checks
- SSH_RETRY_DELAY (default: 5s) - for SSH connection retries
- SPRITE_CONNECTIVITY_POLL_DELAY (default: 5s) - for sprite connectivity checks

This allows users to tune timeout behavior globally via environment variables
without modifying code.

Files modified:
- linode/lib/common.sh
- vultr/lib/common.sh
- aws-lightsail/lib/common.sh
- sprite/lib/common.sh
- digitalocean/lib/common.sh
- lambda/lib/common.sh

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-08 02:37:35 +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
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
e781506604
Add Linode (Akamai) as fifth cloud provider with all 6 agents (#12)
Linode instances via REST API v4, with cloud-init via metadata.user_data.
- linode/lib/common.sh: API wrapper, token management, instance lifecycle
- All 6 agents: claude, openclaw, nanoclaw, aider, goose, codex

Matrix now 6 agents x 5 clouds = 30/30 implemented.

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