diff --git a/install.sh b/install.sh index c8f69fe..48a9c4b 100755 --- a/install.sh +++ b/install.sh @@ -14,6 +14,23 @@ say() { printf '\033[1;36m[install]\033[0m %s\n' "$*"; } warn() { printf '\033[1;33m[warn]\033[0m %s\n' "$*"; } err() { printf '\033[1;31m[error]\033[0m %s\n' "$*" >&2; } +# Backup a populated target directory to a timestamped sibling before clobber. +# No-op if target is absent or contains no regular files (recursively). This +# means freshly-mkdir'd scaffolds are NOT backed up — only real user content. +# Only called on $AGENTS_DIR/_blocks, _templates, _assembler, $HOOKS_DIR, +# $SKILLS_DIR — never on $KIT_DIR source. +backup_dir() { + local target="$1" + [ -d "$target" ] || return 0 + # No regular files anywhere under target → nothing worth preserving + if [ -z "$(find "$target" -type f -print -quit 2>/dev/null)" ]; then + return 0 + fi + local backup="${target}.bak-$(date +%s)" + cp -a "$target" "$backup" + say "backed up existing $target to $backup" +} + # --- prerequisites ---------------------------------------------------------- say "checking prerequisites" if ! command -v cargo >/dev/null 2>&1; then @@ -44,6 +61,7 @@ mkdir -p \ # --- copy blocks (overwrite ours; blocks are SSoT from kit) ---------------- say "copying shared blocks -> $AGENTS_DIR/_blocks/" +backup_dir "$AGENTS_DIR/_blocks" cp -f "$KIT_DIR/_blocks/"*.md "$AGENTS_DIR/_blocks/" # --- copy generic manifests, DO NOT overwrite user's existing manifests ----- @@ -63,11 +81,13 @@ say " copied $copied, skipped $skipped (already present)" # --- copy template --------------------------------------------------------- if compgen -G "$KIT_DIR/_templates/*.template" >/dev/null; then say "copying specialist template" + backup_dir "$AGENTS_DIR/_templates" cp -f "$KIT_DIR/_templates/"*.template "$AGENTS_DIR/_templates/" fi # --- copy assembler source (always refresh) -------------------------------- say "copying assembler source" +backup_dir "$AGENTS_DIR/_assembler" cp -f "$KIT_DIR/_assembler/Cargo.toml" "$AGENTS_DIR/_assembler/" cp -f "$KIT_DIR/_assembler/src/"*.rs "$AGENTS_DIR/_assembler/src/" if [[ -f "$KIT_DIR/_assembler/.gitignore" ]]; then @@ -76,6 +96,7 @@ fi # --- copy hooks (refresh; hooks are logic, not config) --------------------- say "copying hooks -> $HOOKS_DIR/" +backup_dir "$HOOKS_DIR" for h in assemble-agents.sh assemble-validate.sh no-hand-edit-agents.sh; do cp -f "$KIT_DIR/hooks/$h" "$HOOKS_DIR/$h" chmod +x "$HOOKS_DIR/$h" @@ -84,6 +105,7 @@ done # --- copy skills ----------------------------------------------------------- if [[ -d "$KIT_DIR/skills" ]]; then say "copying skills" + backup_dir "$SKILLS_DIR" for skill_dir in "$KIT_DIR/skills/"*/; do [ -d "$skill_dir" ] || continue skill_name="$(basename "$skill_dir")"