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)
This commit is contained in:
Sprite 2026-02-08 02:22:06 +00:00
parent f78d5c474b
commit f9dd9a7bf5
12 changed files with 119 additions and 383 deletions

View file

@ -63,45 +63,9 @@ run_server "$LIGHTSAIL_SERVER_IP" "cat /tmp/env_config >> ~/.zshrc && rm /tmp/en
rm "$ENV_TEMP"
# 8. Configure Claude Code settings
log_warn "Configuring Claude Code..."
run_server "$LIGHTSAIL_SERVER_IP" "mkdir -p ~/.claude"
# Upload settings.json
SETTINGS_TEMP=$(mktemp)
cat > "$SETTINGS_TEMP" << EOF
{
"theme": "dark",
"editor": "vim",
"env": {
"CLAUDE_CODE_ENABLE_TELEMETRY": "0",
"ANTHROPIC_BASE_URL": "https://openrouter.ai/api",
"ANTHROPIC_AUTH_TOKEN": "${OPENROUTER_API_KEY}"
},
"permissions": {
"defaultMode": "bypassPermissions",
"dangerouslySkipPermissions": true
}
}
EOF
upload_file "$LIGHTSAIL_SERVER_IP" "$SETTINGS_TEMP" "/home/ubuntu/.claude/settings.json"
rm "$SETTINGS_TEMP"
# Upload ~/.claude.json global state
GLOBAL_STATE_TEMP=$(mktemp)
cat > "$GLOBAL_STATE_TEMP" << EOF
{
"hasCompletedOnboarding": true,
"bypassPermissionsModeAccepted": true
}
EOF
upload_file "$LIGHTSAIL_SERVER_IP" "$GLOBAL_STATE_TEMP" "/home/ubuntu/.claude.json"
rm "$GLOBAL_STATE_TEMP"
# Create empty CLAUDE.md
run_server "$LIGHTSAIL_SERVER_IP" "touch ~/.claude/CLAUDE.md"
setup_claude_code_config "$OPENROUTER_API_KEY" \
"upload_file $LIGHTSAIL_SERVER_IP" \
"run_server $LIGHTSAIL_SERVER_IP"
echo ""
log_info "Lightsail instance setup completed successfully!"

View file

@ -64,45 +64,9 @@ inject_env_vars_ssh "$DO_SERVER_IP" upload_file run_server \
"CLAUDE_CODE_ENABLE_TELEMETRY=0"
# 8. Configure Claude Code settings
log_warn "Configuring Claude Code..."
run_server "$DO_SERVER_IP" "mkdir -p ~/.claude"
SETTINGS_TEMP=$(mktemp)
chmod 600 "$SETTINGS_TEMP"
track_temp_file "$SETTINGS_TEMP"
cat > "$SETTINGS_TEMP" << EOF
{
"theme": "dark",
"editor": "vim",
"env": {
"CLAUDE_CODE_ENABLE_TELEMETRY": "0",
"ANTHROPIC_BASE_URL": "https://openrouter.ai/api",
"ANTHROPIC_AUTH_TOKEN": "${OPENROUTER_API_KEY}"
},
"permissions": {
"defaultMode": "bypassPermissions",
"dangerouslySkipPermissions": true
}
}
EOF
upload_file "$DO_SERVER_IP" "$SETTINGS_TEMP" "/root/.claude/settings.json"
GLOBAL_STATE_TEMP=$(mktemp)
chmod 600 "$GLOBAL_STATE_TEMP"
track_temp_file "$GLOBAL_STATE_TEMP"
cat > "$GLOBAL_STATE_TEMP" << EOF
{
"hasCompletedOnboarding": true,
"bypassPermissionsModeAccepted": true
}
EOF
upload_file "$DO_SERVER_IP" "$GLOBAL_STATE_TEMP" "/root/.claude.json"
# Note: temp files will be cleaned up by trap handler
run_server "$DO_SERVER_IP" "touch ~/.claude/CLAUDE.md"
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!"

View file

@ -60,45 +60,9 @@ run_server "cat /tmp/env_config >> ~/.zshrc && rm /tmp/env_config"
rm "$ENV_TEMP"
# 7. Configure Claude Code settings
log_warn "Configuring Claude Code..."
run_server "mkdir -p ~/.claude"
# Upload settings.json
SETTINGS_TEMP=$(mktemp)
cat > "$SETTINGS_TEMP" << EOF
{
"theme": "dark",
"editor": "vim",
"env": {
"CLAUDE_CODE_ENABLE_TELEMETRY": "0",
"ANTHROPIC_BASE_URL": "https://openrouter.ai/api",
"ANTHROPIC_AUTH_TOKEN": "${OPENROUTER_API_KEY}"
},
"permissions": {
"defaultMode": "bypassPermissions",
"dangerouslySkipPermissions": true
}
}
EOF
upload_file "$SETTINGS_TEMP" ~/.claude/settings.json
rm "$SETTINGS_TEMP"
# Upload ~/.claude.json global state
GLOBAL_STATE_TEMP=$(mktemp)
cat > "$GLOBAL_STATE_TEMP" << EOF
{
"hasCompletedOnboarding": true,
"bypassPermissionsModeAccepted": true
}
EOF
upload_file "$GLOBAL_STATE_TEMP" ~/.claude.json
rm "$GLOBAL_STATE_TEMP"
# Create empty CLAUDE.md
run_server "touch ~/.claude/CLAUDE.md"
setup_claude_code_config "$OPENROUTER_API_KEY" \
"upload_file" \
"run_server"
echo ""
log_info "E2B sandbox setup completed successfully!"

View file

@ -63,45 +63,9 @@ run_server "$GCP_SERVER_IP" "cat /tmp/env_config >> ~/.zshrc && rm /tmp/env_conf
rm "$ENV_TEMP"
# 8. Configure Claude Code settings
log_warn "Configuring Claude Code..."
run_server "$GCP_SERVER_IP" "mkdir -p ~/.claude"
# Upload settings.json
SETTINGS_TEMP=$(mktemp)
cat > "$SETTINGS_TEMP" << EOF
{
"theme": "dark",
"editor": "vim",
"env": {
"CLAUDE_CODE_ENABLE_TELEMETRY": "0",
"ANTHROPIC_BASE_URL": "https://openrouter.ai/api",
"ANTHROPIC_AUTH_TOKEN": "${OPENROUTER_API_KEY}"
},
"permissions": {
"defaultMode": "bypassPermissions",
"dangerouslySkipPermissions": true
}
}
EOF
upload_file "$GCP_SERVER_IP" "$SETTINGS_TEMP" "$HOME/.claude/settings.json"
rm "$SETTINGS_TEMP"
# Upload ~/.claude.json global state
GLOBAL_STATE_TEMP=$(mktemp)
cat > "$GLOBAL_STATE_TEMP" << EOF
{
"hasCompletedOnboarding": true,
"bypassPermissionsModeAccepted": true
}
EOF
upload_file "$GCP_SERVER_IP" "$GLOBAL_STATE_TEMP" "$HOME/.claude.json"
rm "$GLOBAL_STATE_TEMP"
# Create empty CLAUDE.md
run_server "$GCP_SERVER_IP" "touch ~/.claude/CLAUDE.md"
setup_claude_code_config "$OPENROUTER_API_KEY" \
"upload_file $GCP_SERVER_IP" \
"run_server $GCP_SERVER_IP"
echo ""
log_info "GCP instance setup completed successfully!"

View file

@ -60,47 +60,9 @@ inject_env_vars_ssh "$HETZNER_SERVER_IP" upload_file run_server \
"CLAUDE_CODE_ENABLE_TELEMETRY=0"
# 8. Configure Claude Code settings
log_warn "Configuring Claude Code..."
run_server "$HETZNER_SERVER_IP" "mkdir -p ~/.claude"
# Upload settings.json
SETTINGS_TEMP=$(mktemp)
chmod 600 "$SETTINGS_TEMP"
cat > "$SETTINGS_TEMP" << EOF
{
"theme": "dark",
"editor": "vim",
"env": {
"CLAUDE_CODE_ENABLE_TELEMETRY": "0",
"ANTHROPIC_BASE_URL": "https://openrouter.ai/api",
"ANTHROPIC_AUTH_TOKEN": "${OPENROUTER_API_KEY}"
},
"permissions": {
"defaultMode": "bypassPermissions",
"dangerouslySkipPermissions": true
}
}
EOF
upload_file "$HETZNER_SERVER_IP" "$SETTINGS_TEMP" "/root/.claude/settings.json"
rm "$SETTINGS_TEMP"
# Upload ~/.claude.json global state
GLOBAL_STATE_TEMP=$(mktemp)
chmod 600 "$GLOBAL_STATE_TEMP"
cat > "$GLOBAL_STATE_TEMP" << EOF
{
"hasCompletedOnboarding": true,
"bypassPermissionsModeAccepted": true
}
EOF
upload_file "$HETZNER_SERVER_IP" "$GLOBAL_STATE_TEMP" "/root/.claude.json"
rm "$GLOBAL_STATE_TEMP"
# Create empty CLAUDE.md
run_server "$HETZNER_SERVER_IP" "touch ~/.claude/CLAUDE.md"
setup_claude_code_config "$OPENROUTER_API_KEY" \
"upload_file $HETZNER_SERVER_IP" \
"run_server $HETZNER_SERVER_IP"
echo ""
log_info "Hetzner server setup completed successfully!"

View file

@ -63,45 +63,9 @@ run_server "$LAMBDA_SERVER_IP" "cat /tmp/env_config >> ~/.zshrc && rm /tmp/env_c
rm "$ENV_TEMP"
# 8. Configure Claude Code settings
log_warn "Configuring Claude Code..."
run_server "$LAMBDA_SERVER_IP" "mkdir -p ~/.claude"
# Upload settings.json
SETTINGS_TEMP=$(mktemp)
cat > "$SETTINGS_TEMP" << EOF
{
"theme": "dark",
"editor": "vim",
"env": {
"CLAUDE_CODE_ENABLE_TELEMETRY": "0",
"ANTHROPIC_BASE_URL": "https://openrouter.ai/api",
"ANTHROPIC_AUTH_TOKEN": "${OPENROUTER_API_KEY}"
},
"permissions": {
"defaultMode": "bypassPermissions",
"dangerouslySkipPermissions": true
}
}
EOF
upload_file "$LAMBDA_SERVER_IP" "$SETTINGS_TEMP" "/home/ubuntu/.claude/settings.json"
rm "$SETTINGS_TEMP"
# Upload ~/.claude.json global state
GLOBAL_STATE_TEMP=$(mktemp)
cat > "$GLOBAL_STATE_TEMP" << EOF
{
"hasCompletedOnboarding": true,
"bypassPermissionsModeAccepted": true
}
EOF
upload_file "$LAMBDA_SERVER_IP" "$GLOBAL_STATE_TEMP" "/home/ubuntu/.claude.json"
rm "$GLOBAL_STATE_TEMP"
# Create empty CLAUDE.md
run_server "$LAMBDA_SERVER_IP" "touch ~/.claude/CLAUDE.md"
setup_claude_code_config "$OPENROUTER_API_KEY" \
"upload_file $LAMBDA_SERVER_IP" \
"run_server $LAMBDA_SERVER_IP"
echo ""
log_info "Lambda Cloud instance setup completed successfully!"

View file

@ -29,38 +29,9 @@ inject_env_vars_ssh "$LINODE_SERVER_IP" upload_file run_server \
"ANTHROPIC_API_KEY=" \
"CLAUDE_CODE_SKIP_ONBOARDING=1" \
"CLAUDE_CODE_ENABLE_TELEMETRY=0"
log_warn "Configuring Claude Code..."
run_server "$LINODE_SERVER_IP" "mkdir -p ~/.claude"
SETTINGS_TEMP=$(mktemp)
chmod 600 "$SETTINGS_TEMP"
cat > "$SETTINGS_TEMP" << EOF
{
"theme": "dark",
"editor": "vim",
"env": {
"CLAUDE_CODE_ENABLE_TELEMETRY": "0",
"ANTHROPIC_BASE_URL": "https://openrouter.ai/api",
"ANTHROPIC_AUTH_TOKEN": "${OPENROUTER_API_KEY}"
},
"permissions": {
"defaultMode": "bypassPermissions",
"dangerouslySkipPermissions": true
}
}
EOF
upload_file "$LINODE_SERVER_IP" "$SETTINGS_TEMP" "/root/.claude/settings.json"
rm "$SETTINGS_TEMP"
GLOBAL_STATE_TEMP=$(mktemp)
chmod 600 "$GLOBAL_STATE_TEMP"
cat > "$GLOBAL_STATE_TEMP" << EOF
{
"hasCompletedOnboarding": true,
"bypassPermissionsModeAccepted": true
}
EOF
upload_file "$LINODE_SERVER_IP" "$GLOBAL_STATE_TEMP" "/root/.claude.json"
rm "$GLOBAL_STATE_TEMP"
run_server "$LINODE_SERVER_IP" "touch ~/.claude/CLAUDE.md"
setup_claude_code_config "$OPENROUTER_API_KEY" \
"upload_file $LINODE_SERVER_IP" \
"run_server $LINODE_SERVER_IP"
echo ""
log_info "Linode setup completed successfully!"
log_info "Server: $SERVER_NAME (ID: $LINODE_SERVER_ID, IP: $LINODE_SERVER_IP)"

View file

@ -66,45 +66,9 @@ run_server "cat /tmp/env_config >> ~/.zshrc && rm /tmp/env_config"
rm "$ENV_TEMP"
# 7. Configure Claude Code settings
log_warn "Configuring Claude Code..."
run_server "mkdir -p ~/.claude"
# Upload settings.json
SETTINGS_TEMP=$(mktemp)
cat > "$SETTINGS_TEMP" << EOF
{
"theme": "dark",
"editor": "vim",
"env": {
"CLAUDE_CODE_ENABLE_TELEMETRY": "0",
"ANTHROPIC_BASE_URL": "https://openrouter.ai/api",
"ANTHROPIC_AUTH_TOKEN": "${OPENROUTER_API_KEY}"
},
"permissions": {
"defaultMode": "bypassPermissions",
"dangerouslySkipPermissions": true
}
}
EOF
upload_file "$SETTINGS_TEMP" ~/.claude/settings.json
rm "$SETTINGS_TEMP"
# Upload ~/.claude.json global state
GLOBAL_STATE_TEMP=$(mktemp)
cat > "$GLOBAL_STATE_TEMP" << EOF
{
"hasCompletedOnboarding": true,
"bypassPermissionsModeAccepted": true
}
EOF
upload_file "$GLOBAL_STATE_TEMP" ~/.claude.json
rm "$GLOBAL_STATE_TEMP"
# Create empty CLAUDE.md
run_server "touch ~/.claude/CLAUDE.md"
setup_claude_code_config "$OPENROUTER_API_KEY" \
"upload_file" \
"run_server"
echo ""
log_info "Modal sandbox setup completed successfully!"

View file

@ -980,6 +980,81 @@ EOF
log_info "API token saved to ${config_file}"
}
# ============================================================
# Claude Code configuration setup
# ============================================================
# Setup Claude Code configuration files (settings.json, .claude.json, CLAUDE.md)
# This consolidates the config setup pattern used by all claude.sh scripts
# Usage: setup_claude_code_config OPENROUTER_KEY UPLOAD_CALLBACK RUN_CALLBACK
#
# Arguments:
# OPENROUTER_KEY - OpenRouter API key to inject into config
# UPLOAD_CALLBACK - Function to upload files: func(local_path, remote_path)
# RUN_CALLBACK - Function to run commands: func(command)
#
# Example (SSH-based clouds):
# setup_claude_code_config "$OPENROUTER_API_KEY" \
# "upload_file $SERVER_IP" \
# "run_server $SERVER_IP"
#
# Example (Sprite):
# setup_claude_code_config "$OPENROUTER_API_KEY" \
# "upload_file_sprite $SPRITE_NAME" \
# "run_sprite $SPRITE_NAME"
setup_claude_code_config() {
local openrouter_key="${1}"
local upload_callback="${2}"
local run_callback="${3}"
log_warn "Configuring Claude Code..."
# Create ~/.claude directory
${run_callback} "mkdir -p ~/.claude"
# Create settings.json
local settings_temp
settings_temp=$(mktemp)
chmod 600 "${settings_temp}"
track_temp_file "${settings_temp}"
cat > "${settings_temp}" << EOF
{
"theme": "dark",
"editor": "vim",
"env": {
"CLAUDE_CODE_ENABLE_TELEMETRY": "0",
"ANTHROPIC_BASE_URL": "https://openrouter.ai/api",
"ANTHROPIC_AUTH_TOKEN": "${openrouter_key}"
},
"permissions": {
"defaultMode": "bypassPermissions",
"dangerouslySkipPermissions": true
}
}
EOF
${upload_callback} "${settings_temp}" "/root/.claude/settings.json"
# Create .claude.json global state
local global_state_temp
global_state_temp=$(mktemp)
chmod 600 "${global_state_temp}"
track_temp_file "${global_state_temp}"
cat > "${global_state_temp}" << EOF
{
"hasCompletedOnboarding": true,
"bypassPermissionsModeAccepted": true
}
EOF
${upload_callback} "${global_state_temp}" "/root/.claude.json"
# Create empty CLAUDE.md
${run_callback} "touch ~/.claude/CLAUDE.md"
}
# ============================================================
# SSH key registration helpers
# ============================================================

View file

@ -51,47 +51,9 @@ inject_env_vars_sprite "$SPRITE_NAME" \
"CLAUDE_CODE_ENABLE_TELEMETRY=0"
# Setup Claude Code settings to bypass initial setup
log_warn "Configuring Claude Code..."
run_sprite "$SPRITE_NAME" "mkdir -p ~/.claude"
# Create Claude settings.json via file upload
SETTINGS_TEMP=$(mktemp)
chmod 600 "$SETTINGS_TEMP"
cat > "$SETTINGS_TEMP" << EOF
{
"theme": "dark",
"editor": "vim",
"env": {
"CLAUDE_CODE_ENABLE_TELEMETRY": "0",
"ANTHROPIC_BASE_URL": "https://openrouter.ai/api",
"ANTHROPIC_AUTH_TOKEN": "${OPENROUTER_API_KEY}"
},
"permissions": {
"defaultMode": "bypassPermissions",
"dangerouslySkipPermissions": true
}
}
EOF
sprite exec -s "$SPRITE_NAME" -file "$SETTINGS_TEMP:/tmp/claude_settings" -- bash -c "mv /tmp/claude_settings ~/.claude/settings.json"
rm "$SETTINGS_TEMP"
# Create ~/.claude.json global state to skip onboarding and trust dialogs
GLOBAL_STATE_TEMP=$(mktemp)
chmod 600 "$GLOBAL_STATE_TEMP"
cat > "$GLOBAL_STATE_TEMP" << EOF
{
"hasCompletedOnboarding": true,
"bypassPermissionsModeAccepted": true
}
EOF
sprite exec -s "$SPRITE_NAME" -file "$GLOBAL_STATE_TEMP:/tmp/claude_global" -- bash -c "mv /tmp/claude_global ~/.claude.json"
rm "$GLOBAL_STATE_TEMP"
# Create empty CLAUDE.md to prevent first-run prompts
run_sprite "$SPRITE_NAME" "touch ~/.claude/CLAUDE.md"
setup_claude_code_config "$OPENROUTER_API_KEY" \
"upload_file_sprite $SPRITE_NAME" \
"run_sprite $SPRITE_NAME"
echo ""
log_info "✅ Sprite setup completed successfully!"

View file

@ -132,4 +132,18 @@ inject_env_vars_sprite() {
rm "${env_temp}"
}
# Upload file to sprite (for use with setup_claude_code_config callback)
# Usage: upload_file_sprite SPRITE_NAME LOCAL_PATH REMOTE_PATH
# Example: upload_file_sprite "$SPRITE_NAME" "/tmp/settings.json" "/root/.claude/settings.json"
upload_file_sprite() {
local sprite_name="${1}"
local local_path="${2}"
local remote_path="${3}"
# Generate a unique temp path to avoid collisions
local temp_remote="/tmp/sprite_upload_$(basename "${remote_path}")_$$"
sprite exec -s "${sprite_name}" -file "${local_path}:${temp_remote}" -- bash -c "mkdir -p \$(dirname '${remote_path}') && mv '${temp_remote}' '${remote_path}'"
}
# Note: Provider-agnostic functions (nc_listen, open_browser, OAuth helpers, validate_model_id) are now in shared/common.sh

View file

@ -43,41 +43,9 @@ inject_env_vars_ssh "$VULTR_SERVER_IP" upload_file run_server \
"CLAUDE_CODE_SKIP_ONBOARDING=1" \
"CLAUDE_CODE_ENABLE_TELEMETRY=0"
log_warn "Configuring Claude Code..."
run_server "$VULTR_SERVER_IP" "mkdir -p ~/.claude"
SETTINGS_TEMP=$(mktemp)
chmod 600 "$SETTINGS_TEMP"
cat > "$SETTINGS_TEMP" << EOF
{
"theme": "dark",
"editor": "vim",
"env": {
"CLAUDE_CODE_ENABLE_TELEMETRY": "0",
"ANTHROPIC_BASE_URL": "https://openrouter.ai/api",
"ANTHROPIC_AUTH_TOKEN": "${OPENROUTER_API_KEY}"
},
"permissions": {
"defaultMode": "bypassPermissions",
"dangerouslySkipPermissions": true
}
}
EOF
upload_file "$VULTR_SERVER_IP" "$SETTINGS_TEMP" "/root/.claude/settings.json"
rm "$SETTINGS_TEMP"
GLOBAL_STATE_TEMP=$(mktemp)
chmod 600 "$GLOBAL_STATE_TEMP"
cat > "$GLOBAL_STATE_TEMP" << EOF
{
"hasCompletedOnboarding": true,
"bypassPermissionsModeAccepted": true
}
EOF
upload_file "$VULTR_SERVER_IP" "$GLOBAL_STATE_TEMP" "/root/.claude.json"
rm "$GLOBAL_STATE_TEMP"
run_server "$VULTR_SERVER_IP" "touch ~/.claude/CLAUDE.md"
setup_claude_code_config "$OPENROUTER_API_KEY" \
"upload_file $VULTR_SERVER_IP" \
"run_server $VULTR_SERVER_IP"
echo ""
log_info "Vultr instance setup completed successfully!"