Commit graph

25 commits

Author SHA1 Message Date
A
cf53ea1fb2
fix: use log_step (cyan) for in-progress messages instead of log_info (green) (#757)
Consistently use log_step for progress/status messages ("Waiting for...",
"Fetching...", "Creating...") and reserve log_info for success/completion
messages. This gives users a clear visual distinction between operations
that are still running (cyan) vs operations that have completed (green).

Also adds periodic progress updates to silent polling loops in ramnode,
cherry, and netcup IP wait functions so users see activity during long waits.

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-12 15:48:38 -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
7c693db35b
refactor: extract check_ssh_key_by_fingerprint into shared helper (#552)
13 cloud providers had identical 5-line check_ssh_key functions that
fetch SSH keys from the provider API and grep for the fingerprint.
Extract this pattern into a shared check_ssh_key_by_fingerprint helper
in shared/common.sh, reducing each cloud's function to a single line.

Affected clouds: BinaryLane, Cherry, Civo, Contabo, DigitalOcean,
Genesis Cloud, Hetzner, Hostinger, Latitude, Linode, OVH, Scaleway,
Vultr.

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 16:12:07 -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
be5f9f1087
refactor: extract get_validated_server_name to eliminate 18 duplicate get_server_name functions (#535)
18 cloud lib/common.sh files had identical 7-line get_server_name()
functions (get_resource_name + validate_server_name + echo). Added a
shared get_validated_server_name helper to shared/common.sh and replaced
all duplicates with one-line delegations. Net -110 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 14:42:09 -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
79e3b887c9
refactor: extract ensure_multi_credentials to reduce duplication across 5 providers (#468)
Add a generic ensure_multi_credentials() helper to shared/common.sh that
handles the env-var/config-file/prompt/test/save flow for providers needing
multiple credentials. This eliminates ~270 lines of duplicated logic across
contabo, netcup, ramnode, ionos, and upcloud, replacing it with single
function calls.

Each provider's ensure_*_credentials() function is now 3-8 lines instead
of 30-65 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 07:48:32 -08:00
A
c1e009a66e
refactor: replace custom config loaders with shared helpers in 3 cloud libs (#444)
Replace inline Python config loading (`_load_*_config`) and custom JSON
save functions (`_save_*_config`) in OVH, UpCloud, and Contabo with the
shared `_load_json_config_fields` and `_save_json_config` helpers.

Removes 85 lines of duplicated credential persistence code while
preserving identical behavior (env -> config file -> prompt -> save).

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 04:56:01 -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
52ed7dcfbc
refactor: extract generic_wait_for_instance to reduce duplication across 7 clouds (#415)
Seven cloud providers had nearly identical instance status polling loops
(20-36 lines each). Extract the shared pattern into generic_wait_for_instance()
in shared/common.sh and replace the duplicated loops with one-liner calls.

Clouds refactored: Civo, Contabo, DigitalOcean, GenesisCloud, Linode, UpCloud, Vultr
Net reduction: ~99 lines (-185/+86)

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 02:28:18 -08:00
A
ae74b0264b
feat: Add Contabo opencode support (#402)
Agent: gap-filler-contabo-3

Co-authored-by: B <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-11 01:30:22 -08:00
A
efd535fecd
feat: Add Contabo codex support (#404)
Agent: gap-filler-contabo-1

Co-authored-by: B <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-11 01:30:04 -08:00
A
39057697eb
feat: Add Contabo cline support (#399)
Agent: gap-filler-contabo-2

Co-authored-by: B <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-11 01:29:45 -08:00
A
614ae7eaca
feat: Add Contabo plandex and continue support (#398)
Agent: gap-filler-contabo-4

Co-authored-by: B <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-11 01:29:23 -08:00
A
b10f826384
feat: Add Contabo goose support (#396)
Agent: gap-filler-contabo-1

Co-authored-by: B <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-11 01:29:13 -08:00
A
aaa8bd71a5
feat: Add Contabo gptme support (#393)
Agent: gap-filler-contabo-3

Co-authored-by: B <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-11 01:28:56 -08:00
A
6e77ba6b0b
feat: Add Contabo interpreter support (#392)
Agent: gap-filler-contabo-2

Co-authored-by: B <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-11 01:28:48 -08:00
A
b96243904c
feat: Add Contabo gemini support (#380)
Agent: gap-filler-contabo-2

Co-authored-by: B <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-11 00:51:09 -08:00
A
48262d96e5
refactor: Extract sub-functions from longest create_server functions (#369)
Split the two longest functions in the codebase into focused sub-functions:

Contabo create_server (108 -> 52 lines):
- _contabo_get_ssh_secret_ids: fetch SSH secret IDs from API
- _contabo_build_instance_body: construct API request JSON
- _contabo_wait_for_instance: poll until instance is running

Genesis Cloud create_server (91 -> 42 lines):
- _genesis_get_ssh_key_ids: fetch SSH key IDs from API
- _genesis_build_instance_body: construct API request JSON
- _genesis_wait_for_instance: poll until instance is active

No behavioral changes - pure restructuring for readability.

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 23:46:24 -08:00
A
78fe6a0f2b
feat: Add Contabo NanoClaw deployment script (#367)
Implement contabo/nanoclaw.sh with WhatsApp-based AI agent support.

- Uses Contabo VPS provisioning via OAuth API
- Installs tsx, clones nanoclaw repo, builds with npm
- Configures OpenRouter API credentials via env vars and .env file
- Launches interactive session with WhatsApp QR code auth

Agent: gap-filler-contabo-1

Co-authored-by: B <6723574+louisgv@users.noreply.github.com>
2026-02-10 23:32:21 -08:00
A
6319b6ba74
feat: Add contabo/amazonq.sh script (#366)
Implement Amazon Q CLI on Contabo VPS. Uses OAuth password grant auth, provisions V45 instance with cloud-init, installs Amazon Q CLI, injects OpenRouter env vars (OPENAI_API_KEY, OPENAI_BASE_URL), and launches interactive Q chat session.

Agent: gap-filler-contabo-2

Co-authored-by: B <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-10 23:32:11 -08:00
A
e34fb655ff
feat: Add contabo/kilocode.sh script (#365)
Implements Kilo Code deployment on Contabo VPS:
- Uses Contabo OAuth API for server provisioning
- Installs @kilocode/cli via npm
- Injects OpenRouter API key as KILO_OPEN_ROUTER_API_KEY
- Sets KILO_PROVIDER_TYPE=openrouter for native OpenRouter support
- Launches interactive Kilo Code CLI session

Agent: gap-filler-remaining

Co-authored-by: B <6723574+louisgv@users.noreply.github.com>
2026-02-10 23:32:08 -08:00
A
75e3703c55
fix: Validate env var inputs in Hostinger and Contabo create_server (#361)
Hostinger: HOSTINGER_OS_TEMPLATE was interpolated into Python code
without validation, allowing Python code injection via env var.
Added validate_resource_name check.

Contabo: CONTABO_PRODUCT_ID, CONTABO_REGION, CONTABO_IMAGE_ID were
interpolated into Python strings without validation. CONTABO_PERIOD
was interpolated as bare Python (not even quoted), allowing arbitrary
code execution. Added validate_resource_name, validate_region_name,
and integer validation checks.

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-10 23:18:35 -08:00
A
4c00f3781e
refactor: Reduce complexity in cherry and contabo cloud libraries (#359)
Cherry Servers (cherry/lib/common.sh):
- Replace 59-line ensure_ssh_key with ensure_ssh_key_with_provider (1 line)
- Replace 22-line verify_server_connectivity with generic_ssh_wait (1 line)
- Replace 18-line ensure_cherry_token with ensure_api_token_with_provider (5 lines)
- Replace raw curl calls with cherry_api wrapper using generic_cloud_api
- Use $SSH_OPTS instead of hardcoded SSH options in run_server/upload_file/interactive_session
- Change exit 1 to return 1 for testability and consistency
- Remove unused _cherry_find_key_by_fingerprint helper

Contabo (contabo/lib/common.sh):
- Replace 47-line contabo_api (separate GET/POST/DELETE branches) with
  generic_cloud_api (5-line wrapper, gains automatic retry with backoff)
- Extract 54-line ensure_contabo_credentials into helpers:
  _load_contabo_config, _prompt_contabo_cred, _save_contabo_config
- Fix config save to use json_escape instead of raw variable interpolation
- Add check_python_available and environment variable fast-path

Net: -73 lines, 2 files changed

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 22:49:41 -08:00
A
ed4d37d0fa
feat: Add Contabo cloud provider with claude, aider, openclaw (#353)
Contabo is a budget European VPS provider with affordable CPU instances
starting at $4.95/month. Ideal for AI agents using remote API inference.

Key features:
- Budget-friendly pricing ($4.95-$59/mo)
- Full REST API with OAuth2 authentication
- Cloud-init/user_data support for provisioning
- Full root access via SSH
- European data centers (GDPR-friendly)
- Unlimited traffic included

Implementation:
- contabo/lib/common.sh: OAuth2 token flow, instance provisioning, SSH access
- contabo/claude.sh: Claude Code deployment (implemented)
- contabo/aider.sh: Aider deployment (implemented)
- contabo/openclaw.sh: OpenClaw deployment (implemented)
- manifest.json: Added Contabo cloud + 15 matrix entries (3 implemented)
- contabo/README.md: Complete usage guide with API setup

Authentication uses OAuth2 password grant requiring 4 credentials from
https://my.contabo.com/api/details: Client ID, Client Secret, API User,
API Password.

Agent: cloud-scout-1

Co-authored-by: B <6723574+louisgv@users.noreply.github.com>
2026-02-10 20:40:42 -08:00