Commit graph

18 commits

Author SHA1 Message Date
Sprite
3a0ecd80e9 refactor: Extract ENV_TEMP pattern to inject_env_vars_local (Modal)
Created inject_env_vars_local() function in shared/common.sh to eliminate
duplicate temporary file creation pattern. Converted 10 Modal scripts:
- aider, claude, amazonq, cline, codex
- gemini, goose, interpreter, nanoclaw, openclaw

Reduces ~10-15 lines per script to 3-4 lines.

Pattern before:
  ENV_TEMP=$(mktemp)
  trap 'rm -f "${ENV_TEMP}"' EXIT
  cat > "${ENV_TEMP}" << EOF
  # [spawn:env]
  export KEY=value
  EOF
  upload_file "${ENV_TEMP}" "/tmp/env_config"
  run_server "cat /tmp/env_config >> ~/.zshrc && rm /tmp/env_config"

Pattern after:
  inject_env_vars_local upload_file run_server \
      "KEY=value"

Special case: nanoclaw.sh has additional DOTENV_TEMP for agent-specific
.env file, which remains unchanged.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-08 04:04:01 +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
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
8aeef42471 refactor: fix SC2088 tilde expansion in GCP scripts
- Replace "~/" with "$HOME/" for proper expansion
- Fix 4 SC2088 warnings in nanoclaw.sh, claude.sh, openclaw.sh
- Ensures paths resolve correctly in upload_file calls

Score: 15 (Impact: 5, Confidence: 9, Risk: 3)
2026-02-08 02:09:45 +00:00
Sprite
06586182eb refactor: add braces to variable references in modal/lib/common.sh
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-08 01:50:11 +00:00
Sprite
aaf5820d80 fix: add defensive checks for MODAL_SANDBOX_ID after create_server
All modal scripts now validate that create_server() succeeded and that
MODAL_SANDBOX_ID is set before proceeding with setup steps. This prevents
silent failures when Modal sandbox creation fails.

Changes:
- Added explicit error checking after create_server() call
- Added validation that MODAL_SANDBOX_ID is not empty
- Applied to all 10 modal scripts (nanoclaw, aider, claude, interpreter,
  cline, amazonq, gemini, openclaw, goose, codex)

Fixes SC2154 shellcheck warnings for unassigned MODAL_SANDBOX_ID variable.

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