Commit graph

34 commits

Author SHA1 Message Date
A
bcb59eb925
fix: stop sourcing rc files in launch command — fnm env destroys PATH (#1261)
Root cause: the launch command did `source ~/.bashrc; source ~/.zshrc; claude`.
The .zshrc contains `eval "$(fnm env)"` which outputs PATH with literal
"$PATH" in quotes instead of expanding it, destroying the entire PATH.

Confirmed via debugging:
- `ssh -t ... 'export PATH=...; which claude'` → works (/root/.bun/bin/claude)
- `ssh -t ... 'export PATH=...; source ~/.zshrc; which claude'` → "command not found"
- `source ~/.zshrc; echo $PATH` → `"/run/user/0/fnm_multishells/...":"$PATH"` (broken)

Fix:
- Remove `source ~/.bashrc` and `source ~/.zshrc` from ALL launch commands
- ssh -t creates a pseudo-terminal, so bash auto-sources .bashrc for env vars
- Explicit PATH export is all we need for finding the claude binary
- Remove fnm eval snippet from _finalize_claude_install (it poisoned rc files)
- Also: clean up stale ~/.bash_profile, fix cloud-init PATH, move node
  install after bun attempt

Co-authored-by: lab <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-16 01:06:55 -08:00
A
3030b1d036
fix: revert .profile writes, use explicit PATH in launch commands (#1260)
Stop writing env vars to ~/.profile and ~/.bash_profile — only write to
.bashrc and .zshrc. The .profile approach caused issues because login
shells source it inconsistently across distros, and creating .bash_profile
makes bash -l skip .profile entirely.

Replace `bash -lc claude` launch commands with explicit PATH export +
source pattern across all cloud providers. This ensures claude is found
regardless of shell initialization quirks.

Co-authored-by: lab <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-16 00:43:49 -08:00
A
dac4c62d6c
fix: try bun before npm for Claude Code install, fix PATH in launch (#1249)
Two fixes:
1. Swap fallback order from curl → npm → bun to curl → bun → npm.
   Bun is faster and typically pre-installed. Use `bun i -g`.

2. Fix "claude: command not found" at launch. The default .bashrc has
   a non-interactive guard (`case $- in *i*) ;; *) return;; esac`)
   that skips PATH exports when sourced from SSH command strings.
   Fix: write env config to ~/.profile (always sourced by login shells)
   in addition to .bashrc/.zshrc, and launch with `bash -lc claude`
   which starts a login shell that sources ~/.profile.

Co-authored-by: lab <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-15 23:44:02 -08:00
A
db06ff84e0
fix: run claude install --force and persist fnm PATH to shell configs (#1245)
After installing Claude Code (via any method), run `claude install --force`
to set up shell integration, then ensure fnm bootstrap is persisted to both
.bashrc and .zshrc so interactive sessions can find node.

Also simplify all launch commands across 9 clouds: instead of hardcoding
PATH entries that may miss fnm, source the rc files which now contain all
the necessary PATH entries from both inject_env_vars and _finalize_claude_install.

Co-authored-by: lab <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-15 23:34:09 -08:00
A
6357e0b2d1
fix: ask GitHub CLI setup before provisioning, not after (#1243)
Previously offer_github_auth prompted interactively inside inject_env_vars_*,
which runs after the server is already provisioned. This means the user sits
through provisioning before being asked a simple yes/no question.

Split into two phases:
- prompt_github_auth: asks the question early (before create_server)
- offer_github_auth: executes the install later (after server is up),
  using the stored answer without re-prompting

Falls back to interactive prompt if prompt_github_auth was never called,
so non-claude scripts and older clouds keep working unchanged.

Co-authored-by: lab <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-15 23:20:59 -08:00
A
d0847986f8
fix: use shared install_claude_code across all clouds with fnm PATH fix (#1242)
All cloud claude.sh scripts had inline curl-only installs with no fallback.
When the curl installer failed (transient outage, rate limit), installation
failed with no recovery. Additionally, fnm-installed Node.js was invisible
to subsequent SSH sessions because each SSH command runs in a non-interactive
shell that doesn't source .bashrc/.zshrc.

Changes:
- Migrate 8 cloud scripts to use shared install_claude_code (curl → npm → bun)
- Move _ensure_node_runtime before npm/bun install attempts (not after)
- Add fnm paths to claude_path so node is discoverable across SSH sessions
- Prefix npm/bun install commands with claude_path for PATH visibility
- Update test assertion to match new install_claude_code behavior

Co-authored-by: lab <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-15 23:16:23 -08:00
L
d8ac64863d
fix: inject env vars into both .bashrc and .zshrc, fix PATH across all clouds (#1213)
API keys and env vars were only written to .zshrc, so SSH sessions using
bash couldn't find credentials. Also fixes incorrect ~/.claude/local/bin
PATH (claude installs to ~/.local/bin) and syncs interactive_session PATH
with cloud-init PATH across all 9 clouds.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-15 17:30:40 -08:00
A
f121b60d80
fix(ux): show post-session summary with server status and reconnect info (#1037)
After an interactive SSH session ends, users are now shown:
- A warning that their server is still running (and may incur charges)
- A link to the cloud provider's dashboard to manage/delete it
- The SSH command to reconnect

This prevents users from unknowingly leaving servers running after
exiting their agent session. Covers all 25 SSH-based cloud providers.

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 20:06:40 -05:00
A
f586e19790
fix(security): replace unquoted heredocs with printf to prevent shell expansion in API keys (#1031)
Unquoted `<< EOF` heredocs in nanoclaw .env file creation cause shell
expansion of the API key value. If an API key contains `$`, backticks,
or `\`, the value is silently corrupted or could trigger command
execution. Replace with `printf '%s'` which safely writes the value
without interpretation.

Also fix unquoted variable expansion in upload_config_file's mv command
and the github-codespaces/openclaw.sh config heredoc.

Fixes 34 scripts across all cloud providers.

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 19:41:10 -05:00
A
d2fbd325b0
refactor: decompose fly get_server_name and oracle _setup_vcn_networking (#1000)
- fly/lib/common.sh: Replace 23-line get_server_name() that duplicated
  env-var-check, prompt, and validation logic with a one-line call to the
  shared get_validated_server_name helper, matching all other cloud providers.

- oracle/lib/common.sh: Break _setup_vcn_networking (48 lines, 3 distinct
  responsibilities) into focused helpers:
  - _create_internet_gateway: creates the IGW resource
  - _add_default_route: configures the route table
  - _add_ssh_security_rules: opens SSH port in the security list
  The orchestrator _setup_vcn_networking now delegates to these three helpers.

Agent: complexity-hunter

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
2026-02-13 12:57:11 -08:00
A
0f60a2b082
fix: add actionable guidance to agent installation failures across 126 scripts (#966)
Add log_install_failed helper to shared/common.sh that provides
structured troubleshooting for agent install failures: possible causes,
SSH debug command (when server IP available), manual install command,
and re-run suggestion. Also improve SSH key registration error message.

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 10:14:03 -08:00
A
fd80f1992c
fix: improve error messages for GCP, AWS Lightsail, Cherry, and Oracle (#957)
- GCP: capture gcloud stderr on failure, add common issues guidance,
  use _log_diagnostic for ensure_gcloud errors
- AWS Lightsail: add common issues for create_server failure,
  use _log_diagnostic for ensure_aws_cli errors,
  improve instance timeout message with actionable steps
- Cherry Servers: use extract_api_error_message instead of raw response
  dump, add common issues for server creation failure
- Oracle Cloud: capture OCI CLI stderr on instance launch failure,
  add common issues for VCN, subnet, and instance creation errors

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 09:00:10 -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
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
fdc5d5e58b
refactor: extract shared SSH helpers to eliminate ~410 lines of duplication (#429)
Add ssh_run_server, ssh_upload_file, ssh_interactive_session, and
ssh_verify_connectivity to shared/common.sh. These four functions
were copy-pasted identically across 21 cloud provider lib files,
differing only in SSH username (root vs ubuntu).

Providers now set SSH_USER and delegate to the shared helpers via
one-line wrappers, reducing each provider's lib by ~20 lines.

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-11 03:45:18 -08:00
A
53bd5cc620
refactor: Extract sub-functions from oracle and ionos create_server() (#376)
Oracle create_server (60 lines -> 32 lines):
- _encode_userdata_b64: base64-encode cloud-init data
- _launch_oci_instance: OCI CLI launch call + shape config + error handling

IONOS create_server (53 lines -> 47 lines):
- _ionos_build_server_body: build JSON request body for server creation
- _ionos_launch_and_attach: API call + volume attachment logic

Agent: complexity-hunter

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
2026-02-11 00:32:34 -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
56778b89e0
feat: Add Continue agent for 7 clouds (Kamatera, Cherry, Oracle, Koyeb, Northflank, Railway, Render) (#314)
Implemented Continue CLI TUI mode on:
- kamatera/continue.sh
- cherry/continue.sh
- oracle/continue.sh
- koyeb/continue.sh
- northflank/continue.sh
- railway/continue.sh
- render/continue.sh

All scripts follow the standard pattern:
1. Source cloud-specific lib/common.sh
2. Authenticate with cloud provider
3. Provision server/container
4. Install Continue CLI via npm
5. Inject OpenRouter API key
6. Create ~/.continue/config.json with OpenRouter provider
7. Launch interactive TUI session with 'cn' command

Agent: gap-filler-3

Co-authored-by: B <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-10 18:00:42 -08:00
A
9eb3a41eba
refactor: Decompose oversized OCI functions into focused helpers (#169)
Break down _get_subnet_id() (101 lines) and create_server() (87 lines)
into smaller, single-responsibility functions:

- _create_vcn(): VCN creation (19 lines)
- _setup_vcn_networking(): Internet gateway, route table, security list (47 lines)
- _create_subnet(): Subnet creation with AD lookup (25 lines)
- _get_subnet_id(): Now just finds or orchestrates creation (22 lines)
- _get_instance_public_ip(): VNIC lookup and IP extraction (27 lines)
- create_server(): Now delegates IP retrieval (59 lines)

Agent: complexity-hunter

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
2026-02-10 07:17:18 -08:00
A
b96e122a11
feat: Add oracle/gptme.sh (#161)
Implement gptme agent script for Oracle Cloud Infrastructure.
Installs gptme via pip, verifies installation, prompts for model
selection, and launches interactive gptme session with OpenRouter.

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 22:17:02 -08:00
A
6102cd3f33
feat: Add oracle/interpreter.sh (#160)
Implement Open Interpreter agent deployment on Oracle Cloud
Infrastructure. Installs via pip, configures OpenRouter API
integration via OPENAI_BASE_URL proxy.

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 22:16:57 -08:00
A
cffd1f4ef3
feat: Add oracle/codex.sh (#157)
Implement Codex CLI agent deployment on Oracle Cloud Infrastructure.
Installs @openai/codex via npm, configures OpenRouter API integration
via OPENAI_BASE_URL proxy.

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 22:15:59 -08:00
A
6ec6e1f699
feat: Add oracle/kilocode.sh (#153)
Implement Kilo Code agent deployment on Oracle Cloud Infrastructure.
Sets KILO_PROVIDER_TYPE=openrouter and KILO_OPEN_ROUTER_API_KEY env vars.

Agent: gap-filler

Co-authored-by: B <6723574+louisgv@users.noreply.github.com>
2026-02-09 22:15:43 -08:00
A
d35574bb07
feat: Add oracle/cline.sh (#152)
Implement Cline agent script for Oracle Cloud Infrastructure.
Installs cline via npm, configures OpenRouter API keys,
and launches interactive cline session.

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 22:15:33 -08:00
A
0c185085cc
feat: Add oracle/nanoclaw.sh (#151)
Implement NanoClaw agent deployment on Oracle Cloud Infrastructure.
Installs tsx and clones nanoclaw repo, configures .env with Anthropic
API key proxied through OpenRouter, launches WhatsApp QR auth flow.

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 22:15:05 -08:00
A
31489f13de
feat: Add oracle/plandex.sh (#148)
Implement Plandex agent deployment on Oracle Cloud Infrastructure.
Includes installation verification step.

Agent: gap-filler

Co-authored-by: B <6723574+louisgv@users.noreply.github.com>
2026-02-09 22:14:39 -08:00
A
ae89c06459
feat: Add oracle/amazonq.sh (#147)
Implement Amazon Q CLI agent script for Oracle Cloud Infrastructure.
Installs Amazon Q via official installer, configures OpenRouter API keys,
and launches interactive q chat session.

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 22:14:36 -08:00
A
64b0bb602a
feat: Add oracle/openclaw.sh (#144)
Implement OpenClaw agent deployment on Oracle Cloud Infrastructure.
Uses OCI CLI for provisioning, installs openclaw via bun, configures
OpenRouter API integration with gateway+TUI launch.

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 22:13:57 -08:00
A
cef924d189
feat: Add oracle/opencode.sh (#143)
Implement OpenCode agent deployment on Oracle Cloud Infrastructure.
Uses opencode_install_cmd helper from shared/common.sh.

Agent: gap-filler

Co-authored-by: B <6723574+louisgv@users.noreply.github.com>
2026-02-09 22:13:46 -08:00
A
a43034432f
feat: Add oracle/gemini.sh (#142)
Implement Gemini CLI agent script for Oracle Cloud Infrastructure.
Installs @google/gemini-cli via npm, configures OpenRouter API keys,
and launches interactive gemini session.

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 22:13:42 -08:00
A
76c824c12d
feat: Add Oracle Cloud Infrastructure provider with 3 agent scripts (#130)
Add OCI as a new cloud provider using the OCI CLI for compute instance
provisioning. Includes lib/common.sh with full lifecycle management
(create, SSH, cloud-init, destroy) and auto-creates VCN/subnet if needed.
Implements claude, aider, and goose agent scripts. Supports Always Free
tier shapes (VM.Standard.E2.1.Micro) and flex shapes.

Agent: cloud-scout

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 20:52:29 -08:00