mirror of
https://github.com/hanzoskill/claude-connect.git
synced 2026-10-30 21:04:28 +00:00
285 lines
9.9 KiB
Bash
285 lines
9.9 KiB
Bash
#!/bin/bash
|
|
# install.sh - One-time setup for claude-oauth-refresher
|
|
|
|
set -e
|
|
|
|
# Colors
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
CYAN='\033[0;36m'
|
|
NC='\033[0m'
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
CONFIG_FILE="$SCRIPT_DIR/claude-oauth-refresh-config.json"
|
|
PLIST_FILE="com.bot.claude-oauth-refresher.plist"
|
|
LAUNCHAGENTS_DIR="$HOME/Library/LaunchAgents"
|
|
|
|
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
echo -e "${BLUE} claude-oauth-refresher installer${NC}"
|
|
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
echo ""
|
|
echo -e "${CYAN}This installer runs ONCE to set up automatic token refresh.${NC}"
|
|
echo -e "${CYAN}The refresh job will run every 2 hours in the background.${NC}"
|
|
echo ""
|
|
echo -e "${CYAN}To change settings later:${NC}"
|
|
echo -e " 1. Edit: $CONFIG_FILE"
|
|
echo -e " 2. Ask Bot: \"disable Claude refresh notifications\""
|
|
echo -e " 3. Changes apply automatically - no need to re-run installer!"
|
|
echo ""
|
|
read -p "Press Enter to continue..." -r
|
|
echo ""
|
|
|
|
# Step 1: Verify setup
|
|
echo -e "${BLUE}[1/6]${NC} Running verification..."
|
|
if "$SCRIPT_DIR/verify-setup.sh"; then
|
|
echo ""
|
|
else
|
|
echo ""
|
|
echo -e "${RED}Verification failed. Please fix the errors above.${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# Step 2: Config
|
|
echo -e "${BLUE}[2/6]${NC} Setting up config..."
|
|
|
|
# Try to auto-detect notification settings
|
|
DETECTED_CHANNEL=""
|
|
DETECTED_TARGET=""
|
|
if [[ -x "$SCRIPT_DIR/detect-notification-config.sh" ]]; then
|
|
if detection=$("$SCRIPT_DIR/detect-notification-config.sh" 2>/dev/null); then
|
|
DETECTED_CHANNEL=$(echo "$detection" | cut -d'|' -f1)
|
|
DETECTED_TARGET=$(echo "$detection" | cut -d'|' -f2)
|
|
echo -e "${GREEN}✓${NC} Auto-detected: $DETECTED_CHANNEL → $DETECTED_TARGET"
|
|
fi
|
|
fi
|
|
|
|
# Check if config already exists (from old config.json or new name)
|
|
EXISTING_CONFIG=""
|
|
if [[ -f "$SCRIPT_DIR/config.json" ]]; then
|
|
EXISTING_CONFIG="$SCRIPT_DIR/config.json"
|
|
elif [[ -f "$CONFIG_FILE" ]]; then
|
|
EXISTING_CONFIG="$CONFIG_FILE"
|
|
fi
|
|
|
|
if [[ -n "$EXISTING_CONFIG" ]]; then
|
|
echo -e "${YELLOW}⚠${NC} Config already exists: $EXISTING_CONFIG"
|
|
echo ""
|
|
read -p "Overwrite with new interactive config? [y/N] " -n 1 -r
|
|
echo ""
|
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
# Migrate old config.json to new name if needed
|
|
if [[ "$EXISTING_CONFIG" == "$SCRIPT_DIR/config.json" ]]; then
|
|
echo "Migrating config.json → claude-oauth-refresh-config.json"
|
|
# Check if it has old notification structure
|
|
if jq -e '.notify_on_success' "$EXISTING_CONFIG" &> /dev/null; then
|
|
# Migrate old format to new
|
|
OLD_SUCCESS=$(jq -r '.notify_on_success // false' "$EXISTING_CONFIG")
|
|
OLD_FAILURE=$(jq -r '.notify_on_failure // true' "$EXISTING_CONFIG")
|
|
jq --argjson on_success "$OLD_SUCCESS" \
|
|
--argjson on_failure "$OLD_FAILURE" \
|
|
'del(.notify_on_success, .notify_on_failure) | .notifications = {on_success: $on_success, on_failure: $on_failure}' \
|
|
"$EXISTING_CONFIG" > "$CONFIG_FILE"
|
|
echo -e "${GREEN}✓${NC} Migrated to new config format with notification types"
|
|
rm "$EXISTING_CONFIG"
|
|
else
|
|
mv "$EXISTING_CONFIG" "$CONFIG_FILE"
|
|
echo -e "${GREEN}✓${NC} Renamed to new config filename"
|
|
fi
|
|
fi
|
|
echo "Keeping existing config"
|
|
echo ""
|
|
else
|
|
# User wants to reconfigure
|
|
CREATE_NEW_CONFIG=true
|
|
fi
|
|
else
|
|
CREATE_NEW_CONFIG=true
|
|
fi
|
|
|
|
# Interactive notification setup
|
|
if [[ "$CREATE_NEW_CONFIG" == "true" ]]; then
|
|
echo ""
|
|
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
echo -e "${CYAN} Configure Notifications${NC}"
|
|
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
echo ""
|
|
echo -e "${YELLOW}💡 Recommendation:${NC} Keep all enabled for the first run to verify it works."
|
|
echo " You can disable them later by:"
|
|
echo " 1. Editing: $CONFIG_FILE"
|
|
echo " 2. Asking Bot: \"disable Claude refresh notifications\""
|
|
echo ""
|
|
|
|
# Prompt for each notification type
|
|
read -p "Enable \"✅ Token refreshed!\" notification? [Y/n] " -n 1 -r NOTIFY_SUCCESS_INPUT
|
|
echo ""
|
|
if [[ $NOTIFY_SUCCESS_INPUT =~ ^[Nn]$ ]]; then
|
|
NOTIFY_SUCCESS="false"
|
|
else
|
|
NOTIFY_SUCCESS="true"
|
|
fi
|
|
|
|
read -p "Enable \"❌ Refresh failed\" notification? [Y/n] " -n 1 -r NOTIFY_FAILURE_INPUT
|
|
echo ""
|
|
if [[ $NOTIFY_FAILURE_INPUT =~ ^[Nn]$ ]]; then
|
|
NOTIFY_FAILURE="false"
|
|
else
|
|
NOTIFY_FAILURE="true"
|
|
fi
|
|
|
|
echo ""
|
|
echo -e "${GREEN}✓${NC} Notification preferences saved"
|
|
echo ""
|
|
|
|
# Create config with detected values or prompts
|
|
if [[ -n "$DETECTED_CHANNEL" ]] && [[ -n "$DETECTED_TARGET" ]]; then
|
|
cat > "$CONFIG_FILE" << EOF
|
|
{
|
|
"refresh_buffer_minutes": 30,
|
|
"log_file": "~/bot/logs/claude-oauth-refresh.log",
|
|
"notifications": {
|
|
"on_success": $NOTIFY_SUCCESS,
|
|
"on_failure": $NOTIFY_FAILURE
|
|
},
|
|
"notification_channel": "$DETECTED_CHANNEL",
|
|
"notification_target": "$DETECTED_TARGET"
|
|
}
|
|
EOF
|
|
echo -e "${GREEN}✓${NC} Created config with auto-detected values"
|
|
echo " → Channel: $DETECTED_CHANNEL"
|
|
echo " → Target: $DETECTED_TARGET"
|
|
else
|
|
cat > "$CONFIG_FILE" << EOF
|
|
{
|
|
"refresh_buffer_minutes": 30,
|
|
"log_file": "~/bot/logs/claude-oauth-refresh.log",
|
|
"notifications": {
|
|
"on_success": $NOTIFY_SUCCESS,
|
|
"on_failure": $NOTIFY_FAILURE
|
|
},
|
|
"notification_channel": "telegram",
|
|
"notification_target": "YOUR_CHAT_ID"
|
|
}
|
|
EOF
|
|
echo -e "${YELLOW}⚠${NC} Could not auto-detect notification settings"
|
|
echo ""
|
|
echo "Please configure your notification target:"
|
|
echo " → Edit: $CONFIG_FILE"
|
|
echo " → See SKILL.md section: 'Finding Your Target ID'"
|
|
echo ""
|
|
read -p "Press Enter when ready to continue..." -r
|
|
fi
|
|
fi
|
|
echo ""
|
|
|
|
# Step 3: Test refresh
|
|
echo -e "${BLUE}[3/6]${NC} Testing token refresh..."
|
|
chmod +x "$SCRIPT_DIR"/*.sh
|
|
if "$SCRIPT_DIR/refresh-token.sh"; then
|
|
echo -e "${GREEN}✓${NC} Refresh successful"
|
|
else
|
|
echo -e "${RED}✗${NC} Refresh failed - check logs"
|
|
tail -10 ~/bot/logs/claude-oauth-refresh.log
|
|
exit 1
|
|
fi
|
|
echo ""
|
|
|
|
# Step 4: Create launchd plist
|
|
echo -e "${BLUE}[4/6]${NC} Creating launchd service..."
|
|
cat > "$SCRIPT_DIR/$PLIST_FILE" << EOF
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
<plist version="1.0">
|
|
<dict>
|
|
<key>Label</key>
|
|
<string>com.bot.claude-oauth-refresher</string>
|
|
|
|
<key>ProgramArguments</key>
|
|
<array>
|
|
<string>$SCRIPT_DIR/refresh-token.sh</string>
|
|
</array>
|
|
|
|
<key>StartInterval</key>
|
|
<integer>7200</integer>
|
|
|
|
<key>RunAtLoad</key>
|
|
<true/>
|
|
|
|
<key>StandardOutPath</key>
|
|
<string>$HOME/bot/logs/claude-oauth-refresher-stdout.log</string>
|
|
|
|
<key>StandardErrorPath</key>
|
|
<string>$HOME/bot/logs/claude-oauth-refresher-stderr.log</string>
|
|
|
|
<key>WorkingDirectory</key>
|
|
<string>$SCRIPT_DIR</string>
|
|
|
|
<key>EnvironmentVariables</key>
|
|
<dict>
|
|
<key>PATH</key>
|
|
<string>/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:$HOME/.local/bin</string>
|
|
</dict>
|
|
</dict>
|
|
</plist>
|
|
EOF
|
|
echo -e "${GREEN}✓${NC} Created $PLIST_FILE"
|
|
echo ""
|
|
|
|
# Step 5: Install launchd plist
|
|
echo -e "${BLUE}[5/6]${NC} Installing launchd service..."
|
|
mkdir -p "$LAUNCHAGENTS_DIR"
|
|
|
|
# Unload if already loaded
|
|
if launchctl list | grep -q "com.bot.claude-oauth-refresher"; then
|
|
launchctl unload "$LAUNCHAGENTS_DIR/$PLIST_FILE" 2>/dev/null || true
|
|
echo " → Unloaded existing service"
|
|
fi
|
|
|
|
cp "$SCRIPT_DIR/$PLIST_FILE" "$LAUNCHAGENTS_DIR/$PLIST_FILE"
|
|
launchctl load "$LAUNCHAGENTS_DIR/$PLIST_FILE"
|
|
echo -e "${GREEN}✓${NC} Loaded service (runs every 2 hours)"
|
|
echo ""
|
|
|
|
# Step 6: Verify
|
|
echo -e "${BLUE}[6/6]${NC} Verifying installation..."
|
|
sleep 2
|
|
if launchctl list | grep -q "com.bot.claude-oauth-refresher"; then
|
|
echo -e "${GREEN}✓${NC} Service is running"
|
|
else
|
|
echo -e "${YELLOW}⚠${NC} Service may not be loaded (check: launchctl list)"
|
|
fi
|
|
echo ""
|
|
|
|
# Summary
|
|
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
echo -e "${GREEN}✓ Installation complete!${NC}"
|
|
echo ""
|
|
echo "What happens now:"
|
|
echo " • Refresh runs automatically 30 minutes before token expiry"
|
|
echo " • Claude tokens expire ~8 hours after refresh"
|
|
echo " • Next refresh in ~7.5 hours from last successful refresh"
|
|
echo " • Config changes apply automatically (just edit the file)"
|
|
echo " • Only re-run this installer to reinstall/fix"
|
|
echo ""
|
|
echo "Notification settings:"
|
|
if [[ -f "$CONFIG_FILE" ]]; then
|
|
SHOW_SUCCESS=$(jq -r '.notifications.on_success' "$CONFIG_FILE" 2>/dev/null || echo "unknown")
|
|
SHOW_FAILURE=$(jq -r '.notifications.on_failure' "$CONFIG_FILE" 2>/dev/null || echo "unknown")
|
|
echo " • Success (✅): $SHOW_SUCCESS"
|
|
echo " • Failure (❌): $SHOW_FAILURE"
|
|
fi
|
|
echo ""
|
|
echo "Change settings:"
|
|
echo " • Edit: $CONFIG_FILE"
|
|
echo " • Or ask Bot: \"disable Claude refresh notifications\""
|
|
echo ""
|
|
echo "Monitor:"
|
|
echo " • Logs: tail -f ~/bot/logs/claude-oauth-refresh.log"
|
|
echo " • Status: launchctl list | grep claude-oauth-refresher"
|
|
echo " • Manual test: $SCRIPT_DIR/refresh-token.sh"
|
|
echo ""
|
|
echo "Uninstall:"
|
|
echo " • Run: $SCRIPT_DIR/uninstall.sh"
|
|
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|