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>
This commit is contained in:
Sprite 2026-02-08 02:34:45 +00:00
parent e0dfc9672a
commit cabdbc37ba
113 changed files with 1756 additions and 1596 deletions

View file

@ -4,8 +4,8 @@ set -eo pipefail
# Source common functions - try local file first, fall back to remote
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd)"
# shellcheck source=digitalocean/lib/common.sh
if [[ -f "$SCRIPT_DIR/lib/common.sh" ]]; then
source "$SCRIPT_DIR/lib/common.sh"
if [[ -f "${SCRIPT_DIR}/lib/common.sh" ]]; then
source "${SCRIPT_DIR}/lib/common.sh"
else
eval "$(curl -fsSL https://raw.githubusercontent.com/OpenRouterTeam/spawn/main/digitalocean/lib/common.sh)"
fi
@ -21,20 +21,20 @@ ensure_ssh_key
# 3. Get droplet name and create droplet
DROPLET_NAME=$(get_server_name)
create_server "$DROPLET_NAME"
create_server "${DROPLET_NAME}"
# 4. Wait for SSH and cloud-init
verify_server_connectivity "$DO_SERVER_IP"
wait_for_cloud_init "$DO_SERVER_IP"
verify_server_connectivity "${DO_SERVER_IP}"
wait_for_cloud_init "${DO_SERVER_IP}"
# 5. Install Aider
log_warn "Installing Aider..."
run_server "$DO_SERVER_IP" "pip install aider-chat 2>/dev/null || pip3 install aider-chat"
run_server "${DO_SERVER_IP}" "pip install aider-chat 2>/dev/null || pip3 install aider-chat"
# Verify installation succeeded
if ! run_server "$DO_SERVER_IP" "command -v aider &> /dev/null && aider --version &> /dev/null"; then
if ! run_server "${DO_SERVER_IP}" "command -v aider &> /dev/null && aider --version &> /dev/null"; then
log_error "Aider installation verification failed"
log_error "The 'aider' command is not available or not working properly on server $DO_SERVER_IP"
log_error "The 'aider' command is not available or not working properly on server ${DO_SERVER_IP}"
exit 1
fi
log_info "Aider installation verified successfully"
@ -51,16 +51,16 @@ fi
MODEL_ID=$(get_model_id_interactive "openrouter/auto" "Aider") || exit 1
log_warn "Setting up environment variables..."
inject_env_vars_ssh "$DO_SERVER_IP" upload_file run_server \
"OPENROUTER_API_KEY=$OPENROUTER_API_KEY"
inject_env_vars_ssh "${DO_SERVER_IP}" upload_file run_server \
"OPENROUTER_API_KEY=${OPENROUTER_API_KEY}"
echo ""
log_info "DigitalOcean droplet setup completed successfully!"
log_info "Droplet: $DROPLET_NAME (ID: $DO_DROPLET_ID, IP: $DO_SERVER_IP)"
log_info "Droplet: ${DROPLET_NAME} (ID: ${DO_DROPLET_ID}, IP: ${DO_SERVER_IP})"
echo ""
# 9. Start Aider interactively
log_warn "Starting Aider..."
sleep 1
clear
interactive_session "$DO_SERVER_IP" "source ~/.zshrc && aider --model openrouter/${MODEL_ID}"
interactive_session "${DO_SERVER_IP}" "source ~/.zshrc && aider --model openrouter/${MODEL_ID}"

View file

@ -1,10 +1,10 @@
#!/bin/bash
set -e
set -eo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd)"
# shellcheck source=digitalocean/lib/common.sh
if [[ -f "$SCRIPT_DIR/lib/common.sh" ]]; then
source "$SCRIPT_DIR/lib/common.sh"
if [[ -f "${SCRIPT_DIR}/lib/common.sh" ]]; then
source "${SCRIPT_DIR}/lib/common.sh"
else
eval "$(curl -fsSL https://raw.githubusercontent.com/OpenRouterTeam/spawn/main/digitalocean/lib/common.sh)"
fi
@ -16,12 +16,12 @@ ensure_do_token
ensure_ssh_key
DROPLET_NAME=$(get_server_name)
create_server "$DROPLET_NAME"
verify_server_connectivity "$DO_SERVER_IP"
wait_for_cloud_init "$DO_SERVER_IP"
create_server "${DROPLET_NAME}"
verify_server_connectivity "${DO_SERVER_IP}"
wait_for_cloud_init "${DO_SERVER_IP}"
log_warn "Installing Amazon Q CLI..."
run_server "$DO_SERVER_IP" "curl -fsSL https://desktop-release.q.us-east-1.amazonaws.com/latest/amazon-q-cli-install.sh | bash"
run_server "${DO_SERVER_IP}" "curl -fsSL https://desktop-release.q.us-east-1.amazonaws.com/latest/amazon-q-cli-install.sh | bash"
log_info "Amazon Q CLI installed"
echo ""
@ -33,23 +33,23 @@ fi
log_warn "Setting up environment variables..."
ENV_TEMP=$(mktemp)
cat > "$ENV_TEMP" << EOF
cat > "${ENV_TEMP}" << EOF
# [spawn:env]
export OPENROUTER_API_KEY="${OPENROUTER_API_KEY}"
export OPENAI_API_KEY="${OPENROUTER_API_KEY}"
export OPENAI_BASE_URL="https://openrouter.ai/api/v1"
EOF
upload_file "$DO_SERVER_IP" "$ENV_TEMP" "/tmp/env_config"
run_server "$DO_SERVER_IP" "cat /tmp/env_config >> ~/.zshrc && rm /tmp/env_config"
rm "$ENV_TEMP"
upload_file "${DO_SERVER_IP}" "${ENV_TEMP}" "/tmp/env_config"
run_server "${DO_SERVER_IP}" "cat /tmp/env_config >> ~/.zshrc && rm /tmp/env_config"
rm "${ENV_TEMP}"
echo ""
log_info "DigitalOcean droplet setup completed successfully!"
log_info "Droplet: $DROPLET_NAME (ID: $DO_DROPLET_ID, IP: $DO_SERVER_IP)"
log_info "Droplet: ${DROPLET_NAME} (ID: ${DO_DROPLET_ID}, IP: ${DO_SERVER_IP})"
echo ""
log_warn "Starting Amazon Q..."
sleep 1
clear
interactive_session "$DO_SERVER_IP" "source ~/.zshrc && q chat"
interactive_session "${DO_SERVER_IP}" "source ~/.zshrc && q chat"

View file

@ -4,8 +4,8 @@ set -eo pipefail
# Source common functions - try local file first, fall back to remote
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd)"
# shellcheck source=digitalocean/lib/common.sh
if [[ -f "$SCRIPT_DIR/lib/common.sh" ]]; then
source "$SCRIPT_DIR/lib/common.sh"
if [[ -f "${SCRIPT_DIR}/lib/common.sh" ]]; then
source "${SCRIPT_DIR}/lib/common.sh"
else
eval "$(curl -fsSL https://raw.githubusercontent.com/OpenRouterTeam/spawn/main/digitalocean/lib/common.sh)"
fi
@ -24,23 +24,23 @@ ensure_ssh_key
# 3. Get droplet name and create droplet
DROPLET_NAME=$(get_server_name)
create_server "$DROPLET_NAME"
create_server "${DROPLET_NAME}"
# 4. Wait for SSH and cloud-init
verify_server_connectivity "$DO_SERVER_IP"
wait_for_cloud_init "$DO_SERVER_IP"
verify_server_connectivity "${DO_SERVER_IP}"
wait_for_cloud_init "${DO_SERVER_IP}"
# 5. Verify Claude Code is installed (fallback to manual install)
log_warn "Verifying Claude Code installation..."
if ! run_server "$DO_SERVER_IP" "command -v claude" >/dev/null 2>&1; then
if ! run_server "${DO_SERVER_IP}" "command -v claude" >/dev/null 2>&1; then
log_warn "Claude Code not found, installing manually..."
run_server "$DO_SERVER_IP" "curl -fsSL https://claude.ai/install.sh | bash"
run_server "${DO_SERVER_IP}" "curl -fsSL https://claude.ai/install.sh | bash"
fi
# Verify installation succeeded
if ! run_server "$DO_SERVER_IP" "command -v claude &> /dev/null && claude --version &> /dev/null"; then
if ! run_server "${DO_SERVER_IP}" "command -v claude &> /dev/null && claude --version &> /dev/null"; then
log_error "Claude Code installation verification failed"
log_error "The 'claude' command is not available or not working properly on server $DO_SERVER_IP"
log_error "The 'claude' command is not available or not working properly on server ${DO_SERVER_IP}"
exit 1
fi
log_info "Claude Code installation verified successfully"
@ -55,26 +55,26 @@ fi
# 7. Inject environment variables into ~/.zshrc
log_warn "Setting up environment variables..."
inject_env_vars_ssh "$DO_SERVER_IP" upload_file run_server \
"OPENROUTER_API_KEY=$OPENROUTER_API_KEY" \
inject_env_vars_ssh "${DO_SERVER_IP}" upload_file run_server \
"OPENROUTER_API_KEY=${OPENROUTER_API_KEY}" \
"ANTHROPIC_BASE_URL=https://openrouter.ai/api" \
"ANTHROPIC_AUTH_TOKEN=$OPENROUTER_API_KEY" \
"ANTHROPIC_AUTH_TOKEN=${OPENROUTER_API_KEY}" \
"ANTHROPIC_API_KEY=" \
"CLAUDE_CODE_SKIP_ONBOARDING=1" \
"CLAUDE_CODE_ENABLE_TELEMETRY=0"
# 8. Configure Claude Code settings
setup_claude_code_config "$OPENROUTER_API_KEY" \
"upload_file $DO_SERVER_IP" \
"run_server $DO_SERVER_IP"
setup_claude_code_config "${OPENROUTER_API_KEY}" \
"upload_file ${DO_SERVER_IP}" \
"run_server ${DO_SERVER_IP}"
echo ""
log_info "DigitalOcean droplet setup completed successfully!"
log_info "Droplet: $DROPLET_NAME (ID: $DO_DROPLET_ID, IP: $DO_SERVER_IP)"
log_info "Droplet: ${DROPLET_NAME} (ID: ${DO_DROPLET_ID}, IP: ${DO_SERVER_IP})"
echo ""
# 9. Start Claude Code interactively
log_warn "Starting Claude Code..."
sleep 1
clear
interactive_session "$DO_SERVER_IP" "source ~/.zshrc && claude"
interactive_session "${DO_SERVER_IP}" "source ~/.zshrc && claude"

View file

@ -1,10 +1,10 @@
#!/bin/bash
set -e
set -eo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd)"
# shellcheck source=digitalocean/lib/common.sh
if [[ -f "$SCRIPT_DIR/lib/common.sh" ]]; then
source "$SCRIPT_DIR/lib/common.sh"
if [[ -f "${SCRIPT_DIR}/lib/common.sh" ]]; then
source "${SCRIPT_DIR}/lib/common.sh"
else
eval "$(curl -fsSL https://raw.githubusercontent.com/OpenRouterTeam/spawn/main/digitalocean/lib/common.sh)"
fi
@ -16,12 +16,12 @@ ensure_do_token
ensure_ssh_key
DROPLET_NAME=$(get_server_name)
create_server "$DROPLET_NAME"
verify_server_connectivity "$DO_SERVER_IP"
wait_for_cloud_init "$DO_SERVER_IP"
create_server "${DROPLET_NAME}"
verify_server_connectivity "${DO_SERVER_IP}"
wait_for_cloud_init "${DO_SERVER_IP}"
log_warn "Installing Cline..."
run_server "$DO_SERVER_IP" "npm install -g cline"
run_server "${DO_SERVER_IP}" "npm install -g cline"
log_info "Cline installed"
echo ""
@ -33,23 +33,23 @@ fi
log_warn "Setting up environment variables..."
ENV_TEMP=$(mktemp)
cat > "$ENV_TEMP" << EOF
cat > "${ENV_TEMP}" << EOF
# [spawn:env]
export OPENROUTER_API_KEY="${OPENROUTER_API_KEY}"
export OPENAI_API_KEY="${OPENROUTER_API_KEY}"
export OPENAI_BASE_URL="https://openrouter.ai/api/v1"
EOF
upload_file "$DO_SERVER_IP" "$ENV_TEMP" "/tmp/env_config"
run_server "$DO_SERVER_IP" "cat /tmp/env_config >> ~/.zshrc && rm /tmp/env_config"
rm "$ENV_TEMP"
upload_file "${DO_SERVER_IP}" "${ENV_TEMP}" "/tmp/env_config"
run_server "${DO_SERVER_IP}" "cat /tmp/env_config >> ~/.zshrc && rm /tmp/env_config"
rm "${ENV_TEMP}"
echo ""
log_info "DigitalOcean droplet setup completed successfully!"
log_info "Droplet: $DROPLET_NAME (ID: $DO_DROPLET_ID, IP: $DO_SERVER_IP)"
log_info "Droplet: ${DROPLET_NAME} (ID: ${DO_DROPLET_ID}, IP: ${DO_SERVER_IP})"
echo ""
log_warn "Starting Cline..."
sleep 1
clear
interactive_session "$DO_SERVER_IP" "source ~/.zshrc && cline"
interactive_session "${DO_SERVER_IP}" "source ~/.zshrc && cline"

View file

@ -3,8 +3,8 @@ set -eo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd)"
# shellcheck source=digitalocean/lib/common.sh
if [[ -f "$SCRIPT_DIR/lib/common.sh" ]]; then
source "$SCRIPT_DIR/lib/common.sh"
if [[ -f "${SCRIPT_DIR}/lib/common.sh" ]]; then
source "${SCRIPT_DIR}/lib/common.sh"
else
eval "$(curl -fsSL https://raw.githubusercontent.com/OpenRouterTeam/spawn/main/digitalocean/lib/common.sh)"
fi
@ -16,12 +16,12 @@ ensure_do_token
ensure_ssh_key
DROPLET_NAME=$(get_server_name)
create_server "$DROPLET_NAME"
verify_server_connectivity "$DO_SERVER_IP"
wait_for_cloud_init "$DO_SERVER_IP"
create_server "${DROPLET_NAME}"
verify_server_connectivity "${DO_SERVER_IP}"
wait_for_cloud_init "${DO_SERVER_IP}"
log_warn "Installing Codex CLI..."
run_server "$DO_SERVER_IP" "npm install -g @openai/codex"
run_server "${DO_SERVER_IP}" "npm install -g @openai/codex"
log_info "Codex CLI installed"
echo ""
@ -32,17 +32,17 @@ else
fi
log_warn "Setting up environment variables..."
inject_env_vars_ssh "$DO_SERVER_IP" upload_file run_server \
"OPENROUTER_API_KEY=$OPENROUTER_API_KEY" \
"OPENAI_API_KEY=$OPENROUTER_API_KEY" \
inject_env_vars_ssh "${DO_SERVER_IP}" upload_file run_server \
"OPENROUTER_API_KEY=${OPENROUTER_API_KEY}" \
"OPENAI_API_KEY=${OPENROUTER_API_KEY}" \
"OPENAI_BASE_URL=https://openrouter.ai/api/v1"
echo ""
log_info "DigitalOcean droplet setup completed successfully!"
log_info "Droplet: $DROPLET_NAME (ID: $DO_DROPLET_ID, IP: $DO_SERVER_IP)"
log_info "Droplet: ${DROPLET_NAME} (ID: ${DO_DROPLET_ID}, IP: ${DO_SERVER_IP})"
echo ""
log_warn "Starting Codex..."
sleep 1
clear
interactive_session "$DO_SERVER_IP" "source ~/.zshrc && codex"
interactive_session "${DO_SERVER_IP}" "source ~/.zshrc && codex"

View file

@ -1,10 +1,10 @@
#!/bin/bash
set -e
set -eo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd)"
# shellcheck source=digitalocean/lib/common.sh
if [[ -f "$SCRIPT_DIR/lib/common.sh" ]]; then
source "$SCRIPT_DIR/lib/common.sh"
if [[ -f "${SCRIPT_DIR}/lib/common.sh" ]]; then
source "${SCRIPT_DIR}/lib/common.sh"
else
eval "$(curl -fsSL https://raw.githubusercontent.com/OpenRouterTeam/spawn/main/digitalocean/lib/common.sh)"
fi
@ -16,12 +16,12 @@ ensure_do_token
ensure_ssh_key
DROPLET_NAME=$(get_server_name)
create_server "$DROPLET_NAME"
verify_server_connectivity "$DO_SERVER_IP"
wait_for_cloud_init "$DO_SERVER_IP"
create_server "${DROPLET_NAME}"
verify_server_connectivity "${DO_SERVER_IP}"
wait_for_cloud_init "${DO_SERVER_IP}"
log_warn "Installing Gemini CLI..."
run_server "$DO_SERVER_IP" "npm install -g @google/gemini-cli"
run_server "${DO_SERVER_IP}" "npm install -g @google/gemini-cli"
log_info "Gemini CLI installed"
echo ""
@ -33,7 +33,7 @@ fi
log_warn "Setting up environment variables..."
ENV_TEMP=$(mktemp)
cat > "$ENV_TEMP" << EOF
cat > "${ENV_TEMP}" << EOF
# [spawn:env]
export OPENROUTER_API_KEY="${OPENROUTER_API_KEY}"
@ -41,16 +41,16 @@ export GEMINI_API_KEY="${OPENROUTER_API_KEY}"
export OPENAI_API_KEY="${OPENROUTER_API_KEY}"
export OPENAI_BASE_URL="https://openrouter.ai/api/v1"
EOF
upload_file "$DO_SERVER_IP" "$ENV_TEMP" "/tmp/env_config"
run_server "$DO_SERVER_IP" "cat /tmp/env_config >> ~/.zshrc && rm /tmp/env_config"
rm "$ENV_TEMP"
upload_file "${DO_SERVER_IP}" "${ENV_TEMP}" "/tmp/env_config"
run_server "${DO_SERVER_IP}" "cat /tmp/env_config >> ~/.zshrc && rm /tmp/env_config"
rm "${ENV_TEMP}"
echo ""
log_info "DigitalOcean droplet setup completed successfully!"
log_info "Droplet: $DROPLET_NAME (ID: $DO_DROPLET_ID, IP: $DO_SERVER_IP)"
log_info "Droplet: ${DROPLET_NAME} (ID: ${DO_DROPLET_ID}, IP: ${DO_SERVER_IP})"
echo ""
log_warn "Starting Gemini..."
sleep 1
clear
interactive_session "$DO_SERVER_IP" "source ~/.zshrc && gemini"
interactive_session "${DO_SERVER_IP}" "source ~/.zshrc && gemini"

View file

@ -4,8 +4,8 @@ set -eo pipefail
# Source common functions - try local file first, fall back to remote
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd)"
# shellcheck source=digitalocean/lib/common.sh
if [[ -f "$SCRIPT_DIR/lib/common.sh" ]]; then
source "$SCRIPT_DIR/lib/common.sh"
if [[ -f "${SCRIPT_DIR}/lib/common.sh" ]]; then
source "${SCRIPT_DIR}/lib/common.sh"
else
eval "$(curl -fsSL https://raw.githubusercontent.com/OpenRouterTeam/spawn/main/digitalocean/lib/common.sh)"
fi
@ -21,15 +21,15 @@ ensure_ssh_key
# 3. Get droplet name and create droplet
DROPLET_NAME=$(get_server_name)
create_server "$DROPLET_NAME"
create_server "${DROPLET_NAME}"
# 4. Wait for SSH and cloud-init
verify_server_connectivity "$DO_SERVER_IP"
wait_for_cloud_init "$DO_SERVER_IP"
verify_server_connectivity "${DO_SERVER_IP}"
wait_for_cloud_init "${DO_SERVER_IP}"
# 5. Install Goose
log_warn "Installing Goose..."
run_server "$DO_SERVER_IP" "CONFIGURE=false curl -fsSL https://github.com/block/goose/releases/latest/download/download_cli.sh | bash"
run_server "${DO_SERVER_IP}" "CONFIGURE=false curl -fsSL https://github.com/block/goose/releases/latest/download/download_cli.sh | bash"
log_info "Goose installed"
# 6. Get OpenRouter API key
@ -41,17 +41,17 @@ else
fi
log_warn "Setting up environment variables..."
inject_env_vars_ssh "$DO_SERVER_IP" upload_file run_server \
inject_env_vars_ssh "${DO_SERVER_IP}" upload_file run_server \
"GOOSE_PROVIDER=openrouter" \
"OPENROUTER_API_KEY=$OPENROUTER_API_KEY"
"OPENROUTER_API_KEY=${OPENROUTER_API_KEY}"
echo ""
log_info "DigitalOcean droplet setup completed successfully!"
log_info "Droplet: $DROPLET_NAME (ID: $DO_DROPLET_ID, IP: $DO_SERVER_IP)"
log_info "Droplet: ${DROPLET_NAME} (ID: ${DO_DROPLET_ID}, IP: ${DO_SERVER_IP})"
echo ""
# 8. Start Goose interactively
log_warn "Starting Goose..."
sleep 1
clear
interactive_session "$DO_SERVER_IP" "source ~/.zshrc && goose"
interactive_session "${DO_SERVER_IP}" "source ~/.zshrc && goose"

View file

@ -3,8 +3,8 @@ set -eo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd)"
# shellcheck source=digitalocean/lib/common.sh
if [[ -f "$SCRIPT_DIR/lib/common.sh" ]]; then
source "$SCRIPT_DIR/lib/common.sh"
if [[ -f "${SCRIPT_DIR}/lib/common.sh" ]]; then
source "${SCRIPT_DIR}/lib/common.sh"
else
eval "$(curl -fsSL https://raw.githubusercontent.com/OpenRouterTeam/spawn/main/digitalocean/lib/common.sh)"
fi
@ -16,12 +16,12 @@ ensure_do_token
ensure_ssh_key
DROPLET_NAME=$(get_server_name)
create_server "$DROPLET_NAME"
verify_server_connectivity "$DO_SERVER_IP"
wait_for_cloud_init "$DO_SERVER_IP"
create_server "${DROPLET_NAME}"
verify_server_connectivity "${DO_SERVER_IP}"
wait_for_cloud_init "${DO_SERVER_IP}"
log_warn "Installing Open Interpreter..."
run_server "$DO_SERVER_IP" "pip install open-interpreter 2>/dev/null || pip3 install open-interpreter"
run_server "${DO_SERVER_IP}" "pip install open-interpreter 2>/dev/null || pip3 install open-interpreter"
log_info "Open Interpreter installed"
echo ""
@ -32,17 +32,17 @@ else
fi
log_warn "Setting up environment variables..."
inject_env_vars_ssh "$DO_SERVER_IP" upload_file run_server \
"OPENROUTER_API_KEY=$OPENROUTER_API_KEY" \
"OPENAI_API_KEY=$OPENROUTER_API_KEY" \
inject_env_vars_ssh "${DO_SERVER_IP}" upload_file run_server \
"OPENROUTER_API_KEY=${OPENROUTER_API_KEY}" \
"OPENAI_API_KEY=${OPENROUTER_API_KEY}" \
"OPENAI_BASE_URL=https://openrouter.ai/api/v1"
echo ""
log_info "DigitalOcean droplet setup completed successfully!"
log_info "Droplet: $DROPLET_NAME (ID: $DO_DROPLET_ID, IP: $DO_SERVER_IP)"
log_info "Droplet: ${DROPLET_NAME} (ID: ${DO_DROPLET_ID}, IP: ${DO_SERVER_IP})"
echo ""
log_warn "Starting Open Interpreter..."
sleep 1
clear
interactive_session "$DO_SERVER_IP" "source ~/.zshrc && interpreter"
interactive_session "${DO_SERVER_IP}" "source ~/.zshrc && interpreter"

View file

@ -4,8 +4,8 @@ set -eo pipefail
# Source common functions - try local file first, fall back to remote
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd)"
# shellcheck source=digitalocean/lib/common.sh
if [[ -f "$SCRIPT_DIR/lib/common.sh" ]]; then
source "$SCRIPT_DIR/lib/common.sh"
if [[ -f "${SCRIPT_DIR}/lib/common.sh" ]]; then
source "${SCRIPT_DIR}/lib/common.sh"
else
eval "$(curl -fsSL https://raw.githubusercontent.com/OpenRouterTeam/spawn/main/digitalocean/lib/common.sh)"
fi
@ -21,18 +21,18 @@ ensure_ssh_key
# 3. Get droplet name and create droplet
DROPLET_NAME=$(get_server_name)
create_server "$DROPLET_NAME"
create_server "${DROPLET_NAME}"
# 4. Wait for SSH and cloud-init
verify_server_connectivity "$DO_SERVER_IP"
wait_for_cloud_init "$DO_SERVER_IP"
verify_server_connectivity "${DO_SERVER_IP}"
wait_for_cloud_init "${DO_SERVER_IP}"
# 5. Install Node.js deps and clone nanoclaw
log_warn "Installing tsx..."
run_server "$DO_SERVER_IP" "source ~/.bashrc && bun install -g tsx"
run_server "${DO_SERVER_IP}" "source ~/.bashrc && bun install -g tsx"
log_warn "Cloning and building nanoclaw..."
run_server "$DO_SERVER_IP" "git clone https://github.com/gavrielc/nanoclaw.git ~/nanoclaw && cd ~/nanoclaw && npm install && npm run build"
run_server "${DO_SERVER_IP}" "git clone https://github.com/gavrielc/nanoclaw.git ~/nanoclaw && cd ~/nanoclaw && npm install && npm run build"
log_info "NanoClaw installed"
# 6. Get OpenRouter API key
@ -44,30 +44,30 @@ else
fi
log_warn "Setting up environment variables..."
inject_env_vars_ssh "$DO_SERVER_IP" upload_file run_server \
"OPENROUTER_API_KEY=$OPENROUTER_API_KEY" \
"ANTHROPIC_API_KEY=$OPENROUTER_API_KEY" \
inject_env_vars_ssh "${DO_SERVER_IP}" upload_file run_server \
"OPENROUTER_API_KEY=${OPENROUTER_API_KEY}" \
"ANTHROPIC_API_KEY=${OPENROUTER_API_KEY}" \
"ANTHROPIC_BASE_URL=https://openrouter.ai/api"
# 8. Create nanoclaw .env file
log_warn "Configuring nanoclaw..."
DOTENV_TEMP=$(mktemp)
chmod 600 "$DOTENV_TEMP"
cat > "$DOTENV_TEMP" << EOF
chmod 600 "${DOTENV_TEMP}"
cat > "${DOTENV_TEMP}" << EOF
ANTHROPIC_API_KEY=${OPENROUTER_API_KEY}
EOF
upload_file "$DO_SERVER_IP" "$DOTENV_TEMP" "/root/nanoclaw/.env"
rm "$DOTENV_TEMP"
upload_file "${DO_SERVER_IP}" "${DOTENV_TEMP}" "/root/nanoclaw/.env"
rm "${DOTENV_TEMP}"
echo ""
log_info "DigitalOcean droplet setup completed successfully!"
log_info "Droplet: $DROPLET_NAME (ID: $DO_DROPLET_ID, IP: $DO_SERVER_IP)"
log_info "Droplet: ${DROPLET_NAME} (ID: ${DO_DROPLET_ID}, IP: ${DO_SERVER_IP})"
echo ""
# 9. Start nanoclaw
log_warn "Starting nanoclaw..."
log_warn "You will need to scan a WhatsApp QR code to authenticate."
echo ""
interactive_session "$DO_SERVER_IP" "cd ~/nanoclaw && source ~/.zshrc && npm run dev"
interactive_session "${DO_SERVER_IP}" "cd ~/nanoclaw && source ~/.zshrc && npm run dev"

View file

@ -4,8 +4,8 @@ set -eo pipefail
# Source common functions - try local file first, fall back to remote
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd)"
# shellcheck source=digitalocean/lib/common.sh
if [[ -f "$SCRIPT_DIR/lib/common.sh" ]]; then
source "$SCRIPT_DIR/lib/common.sh"
if [[ -f "${SCRIPT_DIR}/lib/common.sh" ]]; then
source "${SCRIPT_DIR}/lib/common.sh"
else
eval "$(curl -fsSL https://raw.githubusercontent.com/OpenRouterTeam/spawn/main/digitalocean/lib/common.sh)"
fi
@ -21,15 +21,15 @@ ensure_ssh_key
# 3. Get droplet name and create droplet
DROPLET_NAME=$(get_server_name)
create_server "$DROPLET_NAME"
create_server "${DROPLET_NAME}"
# 4. Wait for SSH and cloud-init
verify_server_connectivity "$DO_SERVER_IP"
wait_for_cloud_init "$DO_SERVER_IP"
verify_server_connectivity "${DO_SERVER_IP}"
wait_for_cloud_init "${DO_SERVER_IP}"
# 5. Install openclaw via bun
log_warn "Installing openclaw..."
run_server "$DO_SERVER_IP" "source ~/.bashrc && bun install -g openclaw"
run_server "${DO_SERVER_IP}" "source ~/.bashrc && bun install -g openclaw"
log_info "OpenClaw installed"
# 6. Get OpenRouter API key
@ -44,23 +44,23 @@ fi
MODEL_ID=$(get_model_id_interactive "openrouter/auto" "Openclaw") || exit 1
log_warn "Setting up environment variables..."
inject_env_vars_ssh "$DO_SERVER_IP" upload_file run_server \
"OPENROUTER_API_KEY=$OPENROUTER_API_KEY" \
"ANTHROPIC_API_KEY=$OPENROUTER_API_KEY" \
inject_env_vars_ssh "${DO_SERVER_IP}" upload_file run_server \
"OPENROUTER_API_KEY=${OPENROUTER_API_KEY}" \
"ANTHROPIC_API_KEY=${OPENROUTER_API_KEY}" \
"ANTHROPIC_BASE_URL=https://openrouter.ai/api"
# 9. Configure openclaw
setup_openclaw_config "$OPENROUTER_API_KEY" "$MODEL_ID" \
"upload_file $DO_SERVER_IP" \
"run_server $DO_SERVER_IP"
setup_openclaw_config "${OPENROUTER_API_KEY}" "${MODEL_ID}" \
"upload_file ${DO_SERVER_IP}" \
"run_server ${DO_SERVER_IP}"
echo ""
log_info "DigitalOcean droplet setup completed successfully!"
log_info "Droplet: $DROPLET_NAME (ID: $DO_DROPLET_ID, IP: $DO_SERVER_IP)"
log_info "Droplet: ${DROPLET_NAME} (ID: ${DO_DROPLET_ID}, IP: ${DO_SERVER_IP})"
echo ""
# 10. Start openclaw gateway in background and launch TUI
log_warn "Starting openclaw..."
run_server "$DO_SERVER_IP" "source ~/.zshrc && nohup openclaw gateway > /tmp/openclaw-gateway.log 2>&1 &"
run_server "${DO_SERVER_IP}" "source ~/.zshrc && nohup openclaw gateway > /tmp/openclaw-gateway.log 2>&1 &"
sleep 2
interactive_session "$DO_SERVER_IP" "source ~/.zshrc && openclaw tui"
interactive_session "${DO_SERVER_IP}" "source ~/.zshrc && openclaw tui"