Files
Varaverk/Tools/claude_startup.sh
T
Gmer4Lfe d9ed8c7704 claude_startup: flip default to setup-only, add --launch flag
Default behavior is now setup-only (symlinks + binary, no interactive launch)
so array_started.sh can call it directly without arguments. Use --launch to
start an interactive Claude session.
2026-06-05 16:04:53 -04:00

113 lines
5.8 KiB
Bash
Executable File

#!/bin/bash
# ==============================================================================================
# ================================= Claude Code Startup ========================================
# ==============================================================================================
#
# PURPOSE
# ─────────────────────────────────────────────────────────────────────────────
# Restores Claude Code's persistent data after an Unraid reboot and launches Claude.
# Unraid's root filesystem lives in RAM — /root/.claude and /root/.local are wiped on
# every reboot. This script symlinks both directories back to persistent appdata storage
# before launching Claude, so memory, sessions, and settings survive across reboots.
#
# On first run with no existing persistent data, migrates from the current live locations:
# /root/.claude → PERSIST_DIR/.claude (memory, sessions, settings)
# /root/.local/share/claude → PERSIST_DIR/local/share/claude (installed binaries)
# Subsequent runs skip the migration and only create the symlinks.
#
# Standalone script — no common.sh dependency. Safe to run directly from terminal
# or from array_started.sh.
#
# ==============================================================================================
# RUNTIME MODES
# ==============================================================================================
#
# claude_startup.sh
# Set up persistent symlinks only — default, used by array_started.sh on boot.
#
# claude_startup.sh --launch
# Set up persistent symlinks and launch Claude interactively.
#
# ==============================================================================================
PERSIST_DIR="/mnt/user/appdata/claude-code"
CLAUDE_DATA="$PERSIST_DIR/.claude"
CLAUDE_BIN="$PERSIST_DIR/local/share/claude"
LAUNCH=false
[[ "$1" == "--launch" ]] && LAUNCH=true
# Standalone — no common.sh dependency
_log() { echo " ✅ $*"; }
_warn() { echo " ⚠️ $*"; }
_err() { echo " ❌ $*" >&2; }
echo ""
echo "━━━ Claude Code Startup ━━━"
echo ""
# ── Array must be mounted ─────────────────────────────────────────────────────────────────────
if ! mountpoint -q /mnt/user 2>/dev/null; then
_err "Array not mounted — /mnt/user not available"
exit 1
fi
# ── Create persistent dirs ────────────────────────────────────────────────────────────────────
mkdir -p "$CLAUDE_DATA" "$CLAUDE_BIN"
# ── Migrate .claude on first run ──────────────────────────────────────────────────────────────
if [[ ! -L /root/.claude && -d /root/.claude ]]; then
_warn "First run — migrating /root/.claude → $CLAUDE_DATA"
cp -a /root/.claude/. "$CLAUDE_DATA/"
rm -rf /root/.claude
_log "Migrated .claude (memory, sessions, settings)"
elif [[ -z "$(ls -A "$CLAUDE_DATA" 2>/dev/null)" && -d /root/.claude ]]; then
_warn "Persistent storage empty — copying current .claude data"
cp -a /root/.claude/. "$CLAUDE_DATA/"
_log "Copied .claude data to persistent storage"
fi
# ── Migrate Claude binaries on first run ──────────────────────────────────────────────────────
if [[ ! -L /root/.local/share/claude && -d /root/.local/share/claude ]]; then
_warn "First run — migrating Claude binaries → $CLAUDE_BIN"
cp -a /root/.local/share/claude/. "$CLAUDE_BIN/"
_log "Migrated Claude binaries"
fi
# ── Create symlinks ───────────────────────────────────────────────────────────────────────────
# Remove any real directories first — ln -sfn silently creates inside a dir instead of
# replacing it, which produces a circular symlink on subsequent runs after migration.
mkdir -p /root/.local/share /root/.local/bin
[[ -d /root/.claude && ! -L /root/.claude ]] && rm -rf /root/.claude
ln -sfn "$CLAUDE_DATA" /root/.claude
_log ".claude → $CLAUDE_DATA"
[[ -d /root/.local/share/claude && ! -L /root/.local/share/claude ]] && rm -rf /root/.local/share/claude
ln -sfn "$CLAUDE_BIN" /root/.local/share/claude
_log "claude binary → $CLAUDE_BIN"
# ── Point the claude binary at the latest installed version ───────────────────────────────────
LATEST=$(ls "$CLAUDE_BIN/versions/" 2>/dev/null | sort -V | tail -1)
if [[ -z "$LATEST" ]]; then
_err "No Claude versions found in $CLAUDE_BIN/versions/"
_err "Install Claude Code first: npm install -g @anthropic-ai/claude-code"
exit 1
fi
ln -sfn "$CLAUDE_BIN/versions/$LATEST" /root/.local/bin/claude
_log "claude v$LATEST ready"
echo ""
# ── Setup-only mode (used by array_started.sh or other callers) ─────────────────────────────────
if [[ "$LAUNCH" == false ]]; then
_log "Setup complete — run 'claude' to start"
echo ""
exit 0
fi
# ── Launch ────────────────────────────────────────────────────────────────────────────────────
export PATH="$HOME/.local/bin:$PATH"
exec claude