diff --git a/automation/README.md b/automation/README.md index a67f793..c2a4549 100644 --- a/automation/README.md +++ b/automation/README.md @@ -60,6 +60,34 @@ The `scheduler.sh` script wraps Claude CLI invocations: - Workflow logs: `~/.claude/logs/workflows/` - Journal logs: `journalctl --user -u ` +## Utility Scripts + +| Script | Purpose | +|--------|---------| +| `validate-setup.sh` | Validate configuration | +| `quick-status.sh` | Dashboard status overview | +| `backup.sh` | Create configuration backup | +| `restore.sh` | Restore from backup | +| `generate-registry.py` | Regenerate component registry | +| `validate-registry.py` | Validate component registry | + +### Usage + +```bash +# Validate setup +./validate-setup.sh + +# Quick status +./quick-status.sh + +# Backup +./backup.sh + +# Restore (lists backups, or restores specific file) +./restore.sh +./restore.sh ~/.claude/backups/claude-config-TIMESTAMP.tar.gz +``` + ## Maintenance ```bash diff --git a/automation/backup.sh b/automation/backup.sh new file mode 100755 index 0000000..bc8c7c8 --- /dev/null +++ b/automation/backup.sh @@ -0,0 +1,92 @@ +#!/bin/bash +# Backup Claude Code configuration +# Creates a timestamped archive of important files + +set -euo pipefail + +CLAUDE_DIR="${HOME}/.claude" +BACKUP_DIR="${CLAUDE_DIR}/backups" +TIMESTAMP=$(date +%Y%m%d_%H%M%S) +BACKUP_NAME="claude-config-${TIMESTAMP}" +BACKUP_PATH="${BACKUP_DIR}/${BACKUP_NAME}.tar.gz" + +# Colors +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' + +echo "📦 Claude Code Configuration Backup" +echo "" + +# Create backup directory +mkdir -p "${BACKUP_DIR}" + +# Files to backup (relative to CLAUDE_DIR) +BACKUP_ITEMS=( + "CLAUDE.md" + "README.md" + "settings.json" + ".gitignore" + ".claude-plugin" + "agents" + "commands" + "hooks" + "skills" + "workflows" + "state" + "automation" +) + +# Create temporary directory +TEMP_DIR=$(mktemp -d) +TEMP_BACKUP="${TEMP_DIR}/${BACKUP_NAME}" +mkdir -p "${TEMP_BACKUP}" + +echo "Copying files..." +for item in "${BACKUP_ITEMS[@]}"; do + if [[ -e "${CLAUDE_DIR}/${item}" ]]; then + cp -r "${CLAUDE_DIR}/${item}" "${TEMP_BACKUP}/" + echo -e " ${GREEN}✓${NC} ${item}" + else + echo -e " ${YELLOW}!${NC} ${item} (not found)" + fi +done + +# Exclude sensitive files +echo "" +echo "Excluding sensitive files..." +find "${TEMP_BACKUP}" -name "*.key" -delete 2>/dev/null || true +find "${TEMP_BACKUP}" -name "*.pem" -delete 2>/dev/null || true +find "${TEMP_BACKUP}" -name "credentials.json" -delete 2>/dev/null || true +find "${TEMP_BACKUP}" -name "token.json" -delete 2>/dev/null || true +find "${TEMP_BACKUP}" -name "settings.local.json" -delete 2>/dev/null || true + +# Create archive +echo "" +echo "Creating archive..." +tar -czf "${BACKUP_PATH}" -C "${TEMP_DIR}" "${BACKUP_NAME}" + +# Cleanup +rm -rf "${TEMP_DIR}" + +# Get size +SIZE=$(du -h "${BACKUP_PATH}" | cut -f1) + +echo "" +echo -e "${GREEN}✓${NC} Backup complete!" +echo "" +echo "Location: ${BACKUP_PATH}" +echo "Size: ${SIZE}" +echo "" + +# List recent backups +echo "Recent backups:" +ls -lht "${BACKUP_DIR}"/*.tar.gz 2>/dev/null | head -5 || echo " (none)" + +# Cleanup old backups (keep last 10) +BACKUP_COUNT=$(ls -1 "${BACKUP_DIR}"/*.tar.gz 2>/dev/null | wc -l) +if [[ ${BACKUP_COUNT} -gt 10 ]]; then + echo "" + echo "Cleaning up old backups (keeping last 10)..." + ls -1t "${BACKUP_DIR}"/*.tar.gz | tail -n +11 | xargs rm -f +fi diff --git a/automation/restore.sh b/automation/restore.sh new file mode 100755 index 0000000..c6444fd --- /dev/null +++ b/automation/restore.sh @@ -0,0 +1,115 @@ +#!/bin/bash +# Restore Claude Code configuration from backup +# Usage: restore.sh [backup-file] + +set -euo pipefail + +CLAUDE_DIR="${HOME}/.claude" +BACKUP_DIR="${CLAUDE_DIR}/backups" + +# Colors +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' + +echo "📦 Claude Code Configuration Restore" +echo "" + +# Get backup file +BACKUP_FILE="${1:-}" + +if [[ -z "${BACKUP_FILE}" ]]; then + # List available backups + echo "Available backups:" + echo "" + if ls -1t "${BACKUP_DIR}"/*.tar.gz 2>/dev/null | head -10; then + echo "" + echo "Usage: $0 " + echo "Example: $0 ${BACKUP_DIR}/claude-config-20260101_120000.tar.gz" + else + echo " No backups found in ${BACKUP_DIR}" + fi + exit 1 +fi + +# Verify backup exists +if [[ ! -f "${BACKUP_FILE}" ]]; then + echo -e "${RED}Error: Backup file not found: ${BACKUP_FILE}${NC}" + exit 1 +fi + +# Confirm restore +echo -e "${YELLOW}Warning: This will overwrite existing configuration!${NC}" +echo "" +echo "Backup: ${BACKUP_FILE}" +echo "Target: ${CLAUDE_DIR}" +echo "" +read -p "Continue? [y/N] " -n 1 -r +echo "" + +if [[ ! $REPLY =~ ^[Yy]$ ]]; then + echo "Cancelled." + exit 0 +fi + +# Create temporary directory +TEMP_DIR=$(mktemp -d) + +echo "" +echo "Extracting backup..." +tar -xzf "${BACKUP_FILE}" -C "${TEMP_DIR}" + +# Find the extracted directory +EXTRACTED_DIR=$(find "${TEMP_DIR}" -maxdepth 1 -type d -name "claude-config-*" | head -1) + +if [[ -z "${EXTRACTED_DIR}" ]]; then + echo -e "${RED}Error: Invalid backup format${NC}" + rm -rf "${TEMP_DIR}" + exit 1 +fi + +# Items to restore +RESTORE_ITEMS=( + "CLAUDE.md" + "README.md" + "settings.json" + ".gitignore" + ".claude-plugin" + "agents" + "commands" + "hooks" + "skills" + "workflows" + "state" + "automation" +) + +echo "" +echo "Restoring files..." +for item in "${RESTORE_ITEMS[@]}"; do + if [[ -e "${EXTRACTED_DIR}/${item}" ]]; then + # Backup existing before overwrite + if [[ -e "${CLAUDE_DIR}/${item}" ]]; then + rm -rf "${CLAUDE_DIR}/${item}" + fi + cp -r "${EXTRACTED_DIR}/${item}" "${CLAUDE_DIR}/" + echo -e " ${GREEN}✓${NC} ${item}" + fi +done + +# Cleanup +rm -rf "${TEMP_DIR}" + +echo "" +echo -e "${GREEN}✓${NC} Restore complete!" +echo "" +echo "Note: You may need to restart Claude Code for changes to take effect." +echo "" + +# Run validation +if [[ -x "${CLAUDE_DIR}/automation/validate-setup.sh" ]]; then + echo "Running validation..." + echo "" + "${CLAUDE_DIR}/automation/validate-setup.sh" || true +fi diff --git a/commands/README.md b/commands/README.md index 14e4ac5..39f7648 100644 --- a/commands/README.md +++ b/commands/README.md @@ -11,6 +11,8 @@ Slash commands for quick actions. User-invoked (type `/command` to trigger). | `/pa` | `/assistant`, `/ask` | Personal assistant entrypoint | | `/help` | `/commands`, `/skills` | Show available commands and skills | | `/status` | `/overview`, `/dashboard` | Quick status across all domains | +| `/summarize` | `/save-session` | Summarize and save session to memory | +| `/maintain` | `/maintenance`, `/admin` | Configuration maintenance | | `/programmer` | | Code development tasks | | `/gcal` | `/calendar`, `/cal` | Google Calendar access | | `/usage` | `/stats` | View usage statistics | diff --git a/commands/maintain.md b/commands/maintain.md new file mode 100644 index 0000000..0ea89e9 --- /dev/null +++ b/commands/maintain.md @@ -0,0 +1,84 @@ +--- +name: maintain +description: Configuration maintenance operations (backup, validate, etc.) +aliases: [maintenance, admin] +--- + +# /maintain Command + +Configuration maintenance operations. + +## Subcommands + +| Subcommand | Description | +|------------|-------------| +| `validate` | Validate configuration setup | +| `backup` | Create configuration backup | +| `restore` | Restore from backup | +| `registry` | Regenerate component registry | +| `clean` | Clean up temporary files | + +## Usage + +``` +/maintain validate # Run validation checks +/maintain backup # Create timestamped backup +/maintain restore # List and restore from backups +/maintain registry # Regenerate component-registry.json +/maintain clean # Remove temp files, old logs +``` + +## Implementation + +### validate + +```bash +~/.claude/automation/validate-setup.sh +``` + +### backup + +```bash +~/.claude/automation/backup.sh +``` + +### restore + +```bash +# List backups +~/.claude/automation/restore.sh + +# Restore specific backup +~/.claude/automation/restore.sh ~/.claude/backups/claude-config-TIMESTAMP.tar.gz +``` + +### registry + +```bash +python3 ~/.claude/automation/generate-registry.py +``` + +### clean + +Remove: +- `~/.claude/logs/workflows/*.log` older than 30 days +- `~/.claude/backups/*.tar.gz` beyond last 10 +- `~/.claude/todos/*.json` (managed by Claude Code) + +## Output Format + +``` +🔧 Maintenance: validate + +Running validation... +[validation output] + +✓ Validation complete +``` + +## When to Use + +- After making configuration changes +- Before/after major updates +- Periodically for housekeeping +- When troubleshooting issues diff --git a/commands/summarize.md b/commands/summarize.md new file mode 100644 index 0000000..9e1b34a --- /dev/null +++ b/commands/summarize.md @@ -0,0 +1,101 @@ +--- +name: summarize +description: Summarize and save the current session context +aliases: [save-session, session-summary] +--- + +# /summarize Command + +Summarize the current session and save key information to memory. + +## When Invoked + +Extract and save important information from the current conversation: + +1. **Decisions made** → `memory/decisions.json` +2. **Preferences learned** → `memory/preferences.json` +3. **Project context** → `memory/projects.json` +4. **Facts discovered** → `memory/facts.json` + +## Process + +### Step 1: Analyze Session + +Review the conversation for: +- Explicit decisions ("let's use X", "we decided Y") +- Implicit preferences ("I prefer", "always do X") +- Project-related context (paths, configs, conventions) +- Facts about the environment or user + +### Step 2: Categorize Items + +For each item, determine: +- **Category**: decision, preference, project, fact +- **Content**: Brief description +- **Context**: Why it matters (optional) + +### Step 3: Save to Memory + +Append to the appropriate memory file: + +```json +{ + "id": "uuid", + "date": "YYYY-MM-DD", + "content": "Description of item", + "context": "Additional context", + "session": "session-id" +} +``` + +### Step 4: Update History Index + +Mark session as summarized in `history/index.json`: + +```json +{ + "sessions": [ + { + "id": "session-id", + "started": "timestamp", + "summarized": true + } + ] +} +``` + +## Output Format + +``` +📝 Session Summary + +Saved to memory: +• Decision: Use plugin structure for .claude config +• Preference: Prefer scripts over inline code in skills +• Fact: Gmail venv at ~/.claude/mcp/gmail/venv + +Session marked as summarized. +``` + +## Memory File Locations + +| File | Content | +|------|---------| +| `~/.claude/state/personal-assistant/memory/decisions.json` | Choices made | +| `~/.claude/state/personal-assistant/memory/preferences.json` | User preferences | +| `~/.claude/state/personal-assistant/memory/projects.json` | Project context | +| `~/.claude/state/personal-assistant/memory/facts.json` | Environment facts | + +## When to Use + +- End of a productive session +- After making important decisions +- When asked to "remember this" +- Before long breaks + +## Policy + +- Only save genuinely useful information +- Avoid redundancy with existing memory +- Keep descriptions concise +- Include context when helpful diff --git a/state/component-registry.json b/state/component-registry.json index e9c6b0a..7ef0821 100644 --- a/state/component-registry.json +++ b/state/component-registry.json @@ -139,6 +139,16 @@ "description": "Quick status overview across all domains", "aliases": ["/overview", "/dashboard"], "invokes": "command:status" + }, + "/summarize": { + "description": "Summarize and save session to memory", + "aliases": ["/save-session", "/session-summary"], + "invokes": "command:summarize" + }, + "/maintain": { + "description": "Configuration maintenance (backup, validate, etc.)", + "aliases": ["/maintenance", "/admin"], + "invokes": "command:maintain" } }, "agents": {