- /search command to search across memory, history, and configuration - history-browser.py for browsing and analyzing session history - install.sh for first-time setup with directory creation and validation - daily-maintenance.sh for scheduled backup, cleanup, and validation - systemd timer units for automated daily maintenance at 6 AM - Updated shell completions with 11 aliases - Test suite now covers 19 tests - Bump version to 1.1.0 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
226 lines
5.8 KiB
Bash
Executable File
226 lines
5.8 KiB
Bash
Executable File
#!/bin/bash
|
||
# Install/setup script for Claude Code configuration
|
||
# Run: ./install.sh
|
||
|
||
set -euo pipefail
|
||
|
||
CLAUDE_DIR="${HOME}/.claude"
|
||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
|
||
# Colors
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
BLUE='\033[0;34m'
|
||
NC='\033[0m'
|
||
|
||
info() { echo -e "${BLUE}ℹ${NC} $1"; }
|
||
success() { echo -e "${GREEN}✓${NC} $1"; }
|
||
warn() { echo -e "${YELLOW}⚠${NC} $1"; }
|
||
error() { echo -e "${RED}✗${NC} $1"; }
|
||
|
||
echo "🚀 Claude Code Configuration Setup"
|
||
echo ""
|
||
|
||
# Check if this is the right directory
|
||
if [[ ! -f "${CLAUDE_DIR}/CLAUDE.md" ]]; then
|
||
error "CLAUDE.md not found. Are you in the right directory?"
|
||
exit 1
|
||
fi
|
||
|
||
# Step 1: Create required directories
|
||
info "Creating directories..."
|
||
dirs=(
|
||
"${CLAUDE_DIR}/state/sysadmin"
|
||
"${CLAUDE_DIR}/state/programmer"
|
||
"${CLAUDE_DIR}/state/personal-assistant/memory"
|
||
"${CLAUDE_DIR}/state/personal-assistant/history"
|
||
"${CLAUDE_DIR}/backups"
|
||
"${CLAUDE_DIR}/logs"
|
||
"${CLAUDE_DIR}/mcp/gmail"
|
||
"${CLAUDE_DIR}/mcp/delegation"
|
||
)
|
||
|
||
for dir in "${dirs[@]}"; do
|
||
if [[ ! -d "$dir" ]]; then
|
||
mkdir -p "$dir"
|
||
success "Created $dir"
|
||
fi
|
||
done
|
||
|
||
# Step 2: Initialize state files if missing
|
||
info "Initializing state files..."
|
||
|
||
# PA preferences
|
||
pa_prefs="${CLAUDE_DIR}/state/personal-assistant-preferences.json"
|
||
if [[ ! -f "$pa_prefs" ]]; then
|
||
cat > "$pa_prefs" << 'EOF'
|
||
{
|
||
"version": "1.0",
|
||
"context_level": "moderate",
|
||
"created": "$(date -Iseconds)"
|
||
}
|
||
EOF
|
||
success "Created personal-assistant-preferences.json"
|
||
fi
|
||
|
||
# Session context
|
||
session_ctx="${CLAUDE_DIR}/state/personal-assistant/session-context.json"
|
||
if [[ ! -f "$session_ctx" ]]; then
|
||
echo '{"context_level": null}' > "$session_ctx"
|
||
success "Created session-context.json"
|
||
fi
|
||
|
||
# General instructions
|
||
gi_file="${CLAUDE_DIR}/state/personal-assistant/general-instructions.json"
|
||
if [[ ! -f "$gi_file" ]]; then
|
||
cat > "$gi_file" << 'EOF'
|
||
{
|
||
"version": "1.0",
|
||
"instructions": []
|
||
}
|
||
EOF
|
||
success "Created general-instructions.json"
|
||
fi
|
||
|
||
# Memory files
|
||
memory_files=("preferences" "decisions" "projects" "facts")
|
||
for mem in "${memory_files[@]}"; do
|
||
mem_file="${CLAUDE_DIR}/state/personal-assistant/memory/${mem}.json"
|
||
if [[ ! -f "$mem_file" ]]; then
|
||
cat > "$mem_file" << EOF
|
||
{
|
||
"version": "1.0",
|
||
"description": "${mem^} learned from sessions",
|
||
"items": []
|
||
}
|
||
EOF
|
||
success "Created memory/${mem}.json"
|
||
fi
|
||
done
|
||
|
||
# Memory meta
|
||
meta_file="${CLAUDE_DIR}/state/personal-assistant/memory/meta.json"
|
||
if [[ ! -f "$meta_file" ]]; then
|
||
cat > "$meta_file" << 'EOF'
|
||
{
|
||
"version": "1.0",
|
||
"last_updated": null,
|
||
"last_summarized_session": null
|
||
}
|
||
EOF
|
||
success "Created memory/meta.json"
|
||
fi
|
||
|
||
# History index
|
||
history_idx="${CLAUDE_DIR}/state/personal-assistant/history/index.json"
|
||
if [[ ! -f "$history_idx" ]]; then
|
||
cat > "$history_idx" << 'EOF'
|
||
{
|
||
"version": "1.0",
|
||
"sessions": []
|
||
}
|
||
EOF
|
||
success "Created history/index.json"
|
||
fi
|
||
|
||
# KB files
|
||
for kb in "${CLAUDE_DIR}/state/kb.json" "${CLAUDE_DIR}/state/personal-assistant/kb.json"; do
|
||
if [[ ! -f "$kb" ]]; then
|
||
echo '{}' > "$kb"
|
||
success "Created $(basename "$kb")"
|
||
fi
|
||
done
|
||
|
||
# Sysadmin autonomy
|
||
sysadmin_auto="${CLAUDE_DIR}/state/sysadmin/session-autonomy.json"
|
||
if [[ ! -f "$sysadmin_auto" ]]; then
|
||
cat > "$sysadmin_auto" << 'EOF'
|
||
{
|
||
"level": "conservative",
|
||
"set_at": null,
|
||
"expires": null
|
||
}
|
||
EOF
|
||
success "Created sysadmin/session-autonomy.json"
|
||
fi
|
||
|
||
# Step 3: Make scripts executable
|
||
info "Setting script permissions..."
|
||
find "${CLAUDE_DIR}" -name "*.sh" -type f -exec chmod +x {} \;
|
||
find "${CLAUDE_DIR}" -name "*.py" -type f -exec chmod +x {} \;
|
||
success "Made scripts executable"
|
||
|
||
# Step 4: Validate JSON files
|
||
info "Validating JSON files..."
|
||
json_errors=0
|
||
while IFS= read -r -d '' file; do
|
||
if ! python3 -c "import json; json.load(open('$file'))" 2>/dev/null; then
|
||
error "Invalid JSON: $file"
|
||
json_errors=$((json_errors + 1))
|
||
fi
|
||
done < <(find "${CLAUDE_DIR}/state" -name "*.json" -print0)
|
||
|
||
if [[ $json_errors -eq 0 ]]; then
|
||
success "All JSON files valid"
|
||
else
|
||
warn "$json_errors JSON file(s) have errors"
|
||
fi
|
||
|
||
# Step 5: Check Python dependencies
|
||
info "Checking Python dependencies..."
|
||
missing_deps=()
|
||
|
||
python3 -c "import google.oauth2.credentials" 2>/dev/null || missing_deps+=("google-auth")
|
||
python3 -c "import googleapiclient.discovery" 2>/dev/null || missing_deps+=("google-api-python-client")
|
||
|
||
if [[ ${#missing_deps[@]} -gt 0 ]]; then
|
||
warn "Missing Python packages for Gmail/Calendar:"
|
||
for dep in "${missing_deps[@]}"; do
|
||
echo " - $dep"
|
||
done
|
||
echo ""
|
||
echo "Install with: pip install ${missing_deps[*]}"
|
||
echo "Or set up venv: cd ~/.claude/mcp/gmail && python3 -m venv venv && source venv/bin/activate && pip install gmail-mcp"
|
||
else
|
||
success "Python dependencies available"
|
||
fi
|
||
|
||
# Step 6: Check kubectl
|
||
info "Checking kubectl..."
|
||
if command -v kubectl &> /dev/null; then
|
||
success "kubectl found: $(kubectl version --client --short 2>/dev/null || echo 'installed')"
|
||
else
|
||
warn "kubectl not found (k8s features will be limited)"
|
||
fi
|
||
|
||
# Step 7: Shell completions hint
|
||
echo ""
|
||
info "Shell completions available. Add to your shell config:"
|
||
echo ""
|
||
echo " # For bash"
|
||
echo " source ~/.claude/automation/completions.bash"
|
||
echo ""
|
||
echo " # For zsh"
|
||
echo " source ~/.claude/automation/completions.zsh"
|
||
echo ""
|
||
|
||
# Step 8: Run validation
|
||
echo ""
|
||
info "Running full validation..."
|
||
if "${CLAUDE_DIR}/automation/validate-setup.sh"; then
|
||
echo ""
|
||
success "Setup complete!"
|
||
else
|
||
echo ""
|
||
warn "Setup complete with warnings. Review above."
|
||
fi
|
||
|
||
echo ""
|
||
echo "📚 Quick start:"
|
||
echo " claude # Start Claude Code"
|
||
echo " /help # Show available commands"
|
||
echo " /status # Quick status dashboard"
|
||
echo " /pa <question> # Ask personal assistant"
|
||
echo ""
|