#!/usr/bin/env bash set -euo pipefail REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" PASS=0 FAIL=0 pass() { echo " PASS: $1"; PASS=$((PASS + 1)); } fail() { echo " FAIL: $1"; FAIL=$((FAIL + 1)); } TEMP_HOME="$(mktemp -d)" trap 'rm -rf "$TEMP_HOME"' EXIT echo "Running install.sh..." HOME="$TEMP_HOME" bash "$REPO_ROOT/scripts/install.sh" > /dev/null echo "" echo "--- providers/claude-code/ → ~/.claude/ ---" while IFS= read -r -d '' src; do rel="${src#"$REPO_ROOT/providers/claude-code/"}" # provider-manifest.sh is sourced by install.sh, not deployed to ~/.claude/ [[ "$rel" == "provider-manifest.sh" ]] && continue dest="$TEMP_HOME/.claude/$rel" if diff -q "$src" "$dest" > /dev/null 2>&1; then pass "$rel deployed and matches source" else fail "$rel — missing or differs from source" fi done < <(find "$REPO_ROOT/providers/claude-code" -type f -print0) echo "" echo "--- core/ → ~/.claude/core/ ---" while IFS= read -r -d '' src; do rel="${src#"$REPO_ROOT/core/"}" dest="$TEMP_HOME/.claude/core/$rel" if diff -q "$src" "$dest" > /dev/null 2>&1; then pass "$rel deployed and matches source" else fail "$rel — missing or differs from source" fi done < <(find "$REPO_ROOT/core" -type f -print0) echo "" echo "--- no orphaned files in core/ ---" while IFS= read -r -d '' deployed; do rel="${deployed#"$TEMP_HOME/.claude/core/"}" src="$REPO_ROOT/core/$rel" if [[ -f "$src" ]]; then pass "core/$rel has a source file" else fail "core/$rel is orphaned — deleted from source but still deployed" fi done < <(find "$TEMP_HOME/.claude/core" -type f -print0) echo "" echo "--- core/AGENTS.md → ~/.agents/AGENTS.md (0015) ---" if diff -q "$REPO_ROOT/core/AGENTS.md" "$TEMP_HOME/.agents/AGENTS.md" > /dev/null 2>&1; then pass "core/AGENTS.md deployed and matches source" else fail "~/.agents/AGENTS.md — missing or differs from source" fi echo "" echo "--- skills deployed to ~/.agents/skills/ ---" while IFS= read -r -d '' src_skill; do skill_name="$(basename "$src_skill")" dest_skill="$TEMP_HOME/.agents/skills/$skill_name" if [[ -d "$dest_skill" ]]; then pass "$skill_name deployed to ~/.agents/skills/" else fail "$skill_name missing from ~/.agents/skills/" fi done < <(find "$REPO_ROOT/.agents/skills" -mindepth 1 -maxdepth 1 -type d -print0) echo "" echo "--- skill files match source ---" while IFS= read -r -d '' src; do rel="${src#"$REPO_ROOT/.agents/skills/"}" dest="$TEMP_HOME/.agents/skills/$rel" if diff -q "$src" "$dest" > /dev/null 2>&1; then pass "skills/$rel matches source" else fail "skills/$rel — missing or differs from source" fi done < <(find "$REPO_ROOT/.agents/skills" -type f -print0) echo "" echo "--- provider adapter: ~/.claude/skills/ is a symlink to ~/.agents/skills/ ---" adapter="$TEMP_HOME/.claude/skills" skills_canonical="$TEMP_HOME/.agents/skills" if [[ -L "$adapter" ]]; then resolved="$(readlink "$adapter")" if [[ "$resolved" == "$skills_canonical" ]]; then pass "~/.claude/skills → ~/.agents/skills (correct target)" else fail "~/.claude/skills symlink points to wrong target: $resolved" fi else fail "~/.claude/skills is not a symlink" fi echo "" echo "--- skills correctly replaced on second install (no double-nesting) ---" skill_name="$(basename "$(find "$REPO_ROOT/.agents/skills" -mindepth 1 -maxdepth 1 -type d | head -1)")" nested="$TEMP_HOME/.agents/skills/$skill_name/$skill_name" if [[ -d "$nested" ]]; then fail "$skill_name/$skill_name exists — skill was nested instead of replaced" else pass "$skill_name not double-nested after second install" fi echo "" echo "--- user skills preserved after install (merge, not wipe) ---" TEMP_HOME2="$(mktemp -d)" trap 'rm -rf "$TEMP_HOME2"' EXIT # Pre-create a user skill not in the source mkdir -p "$TEMP_HOME2/.agents/skills/my-custom-skill" echo "custom" > "$TEMP_HOME2/.agents/skills/my-custom-skill/SKILL.md" HOME="$TEMP_HOME2" bash "$REPO_ROOT/scripts/install.sh" > /dev/null if [[ -f "$TEMP_HOME2/.agents/skills/my-custom-skill/SKILL.md" ]]; then pass "pre-existing user skill preserved after install" else fail "pre-existing user skill was wiped by install" fi echo "" echo "--- warning emitted when adapter target is a real directory ---" TEMP_HOME3="$(mktemp -d)" trap 'rm -rf "$TEMP_HOME3"' EXIT mkdir -p "$TEMP_HOME3/.claude/skills/some-user-skill" output="$(HOME="$TEMP_HOME3" bash "$REPO_ROOT/scripts/install.sh" 2>&1)" if echo "$output" | grep -q "Warning"; then pass "warning emitted when ~/.claude/skills exists as real directory" else fail "no warning when ~/.claude/skills is a real directory" fi if [[ -d "$TEMP_HOME3/.claude/skills/some-user-skill" ]]; then pass "real directory left intact when warning emitted" else fail "real directory was destroyed despite warning" fi echo "" echo "--- idempotency: second run state is correct ---" HOME="$TEMP_HOME" bash "$REPO_ROOT/scripts/install.sh" > /dev/null 2>&1 \ && pass "second run exits zero" \ || fail "second run failed" # skill files still match source after second run while IFS= read -r -d '' src; do rel="${src#"$REPO_ROOT/.agents/skills/"}" dest="$TEMP_HOME/.agents/skills/$rel" if diff -q "$src" "$dest" > /dev/null 2>&1; then pass "idempotent: skills/$rel correct after second install" else fail "idempotent: skills/$rel corrupted after second install" fi done < <(find "$REPO_ROOT/.agents/skills" -type f -print0) # no double-nesting after second run while IFS= read -r -d '' skill_dir; do skill_name="$(basename "$skill_dir")" nested="$TEMP_HOME/.agents/skills/$skill_name/$skill_name" if [[ -d "$nested" ]]; then fail "idempotent: $skill_name double-nested after second install" else pass "idempotent: $skill_name not double-nested after second install" fi done < <(find "$REPO_ROOT/.agents/skills" -mindepth 1 -maxdepth 1 -type d -print0) # symlink still correct after second run adapter="$TEMP_HOME/.claude/skills" if [[ -L "$adapter" ]] && [[ "$(readlink "$adapter")" == "$TEMP_HOME/.agents/skills" ]]; then pass "idempotent: ~/.claude/skills symlink intact after second install" else fail "idempotent: ~/.claude/skills symlink broken after second install" fi # AGENTS.md still correct after second run if diff -q "$REPO_ROOT/core/AGENTS.md" "$TEMP_HOME/.agents/AGENTS.md" > /dev/null 2>&1; then pass "idempotent: ~/.agents/AGENTS.md correct after second install" else fail "idempotent: ~/.agents/AGENTS.md corrupted after second install" fi echo "" echo "Results: $PASS passed, $FAIL failed" [[ $FAIL -eq 0 ]]