claude-vault/scripts/sync-project-memory.sh
2026-02-04 22:10:28 +01:00

181 lines
5.6 KiB
Bash
Executable File

#!/bin/bash
# 🔄 MEMORY.md SYNC SCRIPT
# Synchronisiert Projekt-spezifische MEMORY.md zwischen ~/.claude/projects/ und dem Vault
set -e
VAULT_DIR="$HOME/Work/claude-vault"
PROJECTS_DIR="$HOME/.claude/projects"
# Farben für Output
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m' # No Color
usage() {
cat << EOF
Usage: $0 [PROJECT_NAME] [OPTIONS]
Synchronisiert MEMORY.md zwischen Claude-Projekt und Vault.
ARGUMENTS:
PROJECT_NAME Name der Projekt-MEMORY.md im Vault (z.B. ligalytics-staffeleinteilung)
Ohne Angabe: Alle Projekte synchronisieren
OPTIONS:
--to-vault Erzwinge Kopie: Claude-Projekt → Vault (überschreibt Vault)
--from-vault Erzwinge Kopie: Vault → Claude-Projekt (überschreibt Projekt)
--dry-run Zeige nur an, was gemacht würde
-h, --help Zeige diese Hilfe
EXAMPLES:
$0 # Sync alle Projekte (Auto-Detect neuer)
$0 ligalytics-staffeleinteilung # Sync nur dieses Projekt
$0 ligalytics-staffeleinteilung --to-vault # Force: Projekt → Vault
$0 --dry-run # Zeige Sync-Plan ohne Ausführung
VAULT STRUCTURE:
Vault: $VAULT_DIR/projects/<project-name>/MEMORY.md
Claude: $PROJECTS_DIR/<normalized-path>/memory/MEMORY.md
EOF
exit 0
}
# Parse Arguments
PROJECT_NAME=""
FORCE_DIRECTION=""
DRY_RUN=false
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
usage
;;
--to-vault)
FORCE_DIRECTION="to-vault"
shift
;;
--from-vault)
FORCE_DIRECTION="from-vault"
shift
;;
--dry-run)
DRY_RUN=true
shift
;;
*)
PROJECT_NAME="$1"
shift
;;
esac
done
sync_project() {
local project_name="$1"
local vault_file="$VAULT_DIR/projects/${project_name}/MEMORY.md"
# Finde entsprechendes Claude-Projekt
local claude_file=""
for dir in "$PROJECTS_DIR"/*; do
if [ -f "$dir/memory/MEMORY.md" ]; then
# Prüfe ob Projekt-Name im Pfad vorkommt
if [[ "$(basename "$dir")" == *"${project_name//-/}"* ]] || [ -z "$PROJECT_NAME" ]; then
claude_file="$dir/memory/MEMORY.md"
break
fi
fi
done
# Wenn PROJECT_NAME gegeben, aber kein Claude-File gefunden: Suche exakt
if [ -n "$PROJECT_NAME" ] && [ -z "$claude_file" ]; then
# Versuche direkte Zuordnung (für ligalytics-staffeleinteilung → *ligalytics*staffeleinteilung*)
for dir in "$PROJECTS_DIR"/*; do
if [ -f "$dir/memory/MEMORY.md" ]; then
local normalized=$(basename "$dir")
if [[ "$normalized" == *"ligalytics"* ]] && [[ "$normalized" == *"staffeleinteilung"* ]]; then
claude_file="$dir/memory/MEMORY.md"
break
fi
fi
done
fi
if [ ! -f "$vault_file" ] && [ ! -f "$claude_file" ]; then
echo -e "${YELLOW}⚠ Skipped: ${project_name} (keine Dateien gefunden)${NC}"
return
fi
# Bestimme Sync-Richtung
local direction=""
if [ -n "$FORCE_DIRECTION" ]; then
direction="$FORCE_DIRECTION"
elif [ ! -f "$vault_file" ]; then
direction="to-vault"
echo -e "${YELLOW}${project_name}: Vault-Datei fehlt, kopiere von Claude${NC}"
elif [ ! -f "$claude_file" ]; then
direction="from-vault"
echo -e "${YELLOW}${project_name}: Claude-Datei fehlt, kopiere von Vault${NC}"
else
# Vergleiche Timestamps
local vault_time=$(stat -f %m "$vault_file" 2>/dev/null || stat -c %Y "$vault_file")
local claude_time=$(stat -f %m "$claude_file" 2>/dev/null || stat -c %Y "$claude_file")
if [ "$vault_time" -gt "$claude_time" ]; then
direction="from-vault"
echo -e "${GREEN}${project_name}: Vault neuer ($(date -r "$vault_time" '+%Y-%m-%d %H:%M'))${NC}"
elif [ "$claude_time" -gt "$vault_time" ]; then
direction="to-vault"
echo -e "${GREEN}${project_name}: Claude neuer ($(date -r "$claude_time" '+%Y-%m-%d %H:%M'))${NC}"
else
echo -e "${GREEN}${project_name}: Bereits synchron${NC}"
return
fi
fi
# Führe Sync aus
if [ "$DRY_RUN" = true ]; then
if [ "$direction" = "to-vault" ]; then
echo -e " ${YELLOW}[DRY-RUN]${NC} cp $claude_file$vault_file"
else
echo -e " ${YELLOW}[DRY-RUN]${NC} cp $vault_file$claude_file"
fi
else
if [ "$direction" = "to-vault" ]; then
# Erstelle Projekt-Verzeichnis falls nötig
mkdir -p "$(dirname "$vault_file")"
cp "$claude_file" "$vault_file"
echo -e " ${GREEN}✓ Kopiert:${NC} Claude → Vault"
else
cp "$vault_file" "$claude_file"
echo -e " ${GREEN}✓ Kopiert:${NC} Vault → Claude"
fi
fi
}
# Main Logic
echo -e "${GREEN}🔄 MEMORY.md SYNC${NC}"
echo "========================================"
if [ -n "$PROJECT_NAME" ]; then
# Sync einzelnes Projekt
sync_project "$PROJECT_NAME"
else
# Sync alle Projekte im Vault
echo "Synchronisiere alle Projekte..."
echo ""
for project_dir in "$VAULT_DIR/projects"/*; do
if [ -d "$project_dir" ] && [ -f "$project_dir/MEMORY.md" ]; then
project_name=$(basename "$project_dir")
sync_project "$project_name"
fi
done
fi
echo ""
echo -e "${GREEN}✓ Sync abgeschlossen${NC}"