Every script now has the established header format: PURPOSE with ─────── separator, OPERATIONAL MODEL, DESIGN PRINCIPLES, OPERATIONAL SAFEGUARDS, CONFIGURATION, and RUNTIME MODES — structured with full ====== banner sections throughout. Orchestrators converted from compact ── inline format to full banners. Stale emby-fallback and dirty sync references removed from Plugin/user_script_plug-in.sh.
182 lines
8.8 KiB
Bash
Executable File
182 lines
8.8 KiB
Bash
Executable File
#!/bin/bash
|
|
# ==============================================================================================
|
|
# ================================= Claude Code Startup ========================================
|
|
# ==============================================================================================
|
|
#
|
|
# PURPOSE
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
# Restores Claude Code's persistent data after an Unraid reboot.
|
|
# /root is RAM — wiped on every boot. This script re-creates symlinks so
|
|
# Claude's memory, sessions, settings, and binary survive across reboots.
|
|
#
|
|
# Storage mode is read from the host conf file:
|
|
#
|
|
# HOST*_STORAGE_MODE_INTERNAL=true → Internal (boot) mode
|
|
# .claude data → /boot/config/claude
|
|
# binary → /boot/config/claude-bin
|
|
# No array dependency — runs even before array mounts.
|
|
#
|
|
# HOST*_STORAGE_MODE_INTERNAL=false → Appdata mode
|
|
# .claude data → /mnt/user/appdata/claude-code/.claude
|
|
# binary → /mnt/user/appdata/claude-code/local/share/claude
|
|
# Requires array to be mounted.
|
|
#
|
|
# On first run in either mode, migrates any existing live data to persistent
|
|
# storage. Subsequent runs only re-create the symlinks.
|
|
#
|
|
# Standalone script — no common.sh dependency. Safe to run directly from
|
|
# terminal or from array_started.sh.
|
|
#
|
|
# ==============================================================================================
|
|
# DESIGN PRINCIPLES
|
|
# ==============================================================================================
|
|
#
|
|
# Mode-Aware Paths
|
|
# Storage mode is read from host*.conf before any symlink is created. Internal
|
|
# mode (boot) requires no array — symlinks resolve immediately. Appdata mode
|
|
# requires the array to be mounted before symlinks are useful.
|
|
#
|
|
# Migrate on First Run
|
|
# If live data already exists at /root/.claude and the persistent store is
|
|
# empty, the live data is moved to persistent storage on first run. Subsequent
|
|
# runs only re-create the symlinks — migration is one-time.
|
|
#
|
|
# No common.sh Dependency
|
|
# Runs before load_config.sh is available (early in ARRAY_START_SCRIPTS).
|
|
# All logic is self-contained — no ecosystem functions used.
|
|
#
|
|
# ==============================================================================================
|
|
# OPERATIONAL SAFEGUARDS
|
|
# ==============================================================================================
|
|
#
|
|
# Conf probe — reads storage mode from Configurations/host*.conf directly
|
|
# Migration guard — only migrates if persistent store is empty; never overwrites
|
|
# Symlink-safe — removes existing symlink before re-creating; won't error on re-run
|
|
#
|
|
# ==============================================================================================
|
|
# 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.
|
|
#
|
|
# ==============================================================================================
|
|
|
|
LAUNCH=false
|
|
[[ "$1" == "--launch" ]] && LAUNCH=true
|
|
|
|
_log() { echo " ✅ $*"; }
|
|
_warn() { echo " ⚠️ $*"; }
|
|
_err() { echo " ❌ $*" >&2; }
|
|
|
|
echo ""
|
|
echo "━━━ Claude Code Startup ━━━"
|
|
echo ""
|
|
|
|
# ── Detect storage mode ───────────────────────────────────────────────────────────────────────
|
|
CONF_DIR="/boot/config/plugins/varaverk/Configurations"
|
|
STORAGE_INTERNAL=false
|
|
for _conf in "$CONF_DIR"/host*.conf; do
|
|
[[ -f "$_conf" ]] || continue
|
|
if grep -q "_STORAGE_MODE_INTERNAL=true" "$_conf" 2>/dev/null; then
|
|
STORAGE_INTERNAL=true
|
|
break
|
|
fi
|
|
done
|
|
|
|
if [[ "$STORAGE_INTERNAL" == true ]]; then
|
|
CLAUDE_DATA="/boot/config/plugins/varaverk/claude-data"
|
|
CLAUDE_BIN="/boot/config/plugins/varaverk/claude-bin"
|
|
_log "Storage mode: internal boot"
|
|
else
|
|
PERSIST_DIR="/mnt/user/appdata/claude-code"
|
|
CLAUDE_DATA="$PERSIST_DIR/.claude"
|
|
CLAUDE_BIN="$PERSIST_DIR/local/share/claude"
|
|
_log "Storage mode: appdata"
|
|
fi
|
|
|
|
# ── Array check (appdata mode only) ──────────────────────────────────────────────────────────
|
|
if [[ "$STORAGE_INTERNAL" == false ]]; then
|
|
if ! mountpoint -q /mnt/user 2>/dev/null; then
|
|
_err "Array not mounted — /mnt/user not available (required for appdata mode)"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# ── Create persistent dirs ────────────────────────────────────────────────────────────────────
|
|
mkdir -p "$CLAUDE_DATA" "$CLAUDE_BIN"
|
|
|
|
# ── Migrate from old /boot/config/claude location (internal mode only) ───────────────────────
|
|
if [[ "$STORAGE_INTERNAL" == true && -d /boot/config/claude && "$CLAUDE_DATA" != "/boot/config/claude" ]]; then
|
|
if [[ -z "$(ls -A "$CLAUDE_DATA" 2>/dev/null)" ]]; then
|
|
_warn "Migrating old /boot/config/claude → $CLAUDE_DATA"
|
|
cp -a /boot/config/claude/. "$CLAUDE_DATA/"
|
|
_log "Migrated .claude data from old location"
|
|
fi
|
|
fi
|
|
|
|
# ── 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 ───────────────────────────────────────────────────────────────────────────
|
|
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"
|
|
|
|
# ── Symlink CLAUDE.md ─────────────────────────────────────────────────────────────────────────
|
|
CLAUDE_MD="/boot/config/plugins/varaverk/CLAUDE.md"
|
|
if [[ -f "$CLAUDE_MD" ]]; then
|
|
ln -sfn "$CLAUDE_MD" /root/CLAUDE.md
|
|
_log "CLAUDE.md → $CLAUDE_MD"
|
|
else
|
|
_warn "CLAUDE.md not found at $CLAUDE_MD — skipping symlink"
|
|
fi
|
|
|
|
# ── 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 ""
|
|
|
|
if [[ "$LAUNCH" == false ]]; then
|
|
_log "Setup complete — run 'claude' to start"
|
|
echo ""
|
|
exit 0
|
|
fi
|
|
|
|
# ── Launch ────────────────────────────────────────────────────────────────────────────────────
|
|
export PATH="$HOME/.local/bin:$PATH"
|
|
exec claude
|