#!/usr/bin/env bash
# ─────────────────────────────────────────────────────────────────────────────
# bootstrap.sh — install the Constitution kit into a project repo (day-zero setup).
#
# Run from the unzipped kit folder:
#   ./bootstrap.sh [TARGET_REPO_DIR] [--force]
#     TARGET_REPO_DIR   where to install (default: current directory)
#     --force           overwrite existing files (a .bak copy is kept)
#
# NON-DESTRUCTIVE by default: existing files are SKIPPED, not overwritten — so it is
# safe to run in a repo that already has a CLAUDE.md, a screen-reconstructor.md, etc.
# It scaffolds the METHOD layer (agents, commands, docs, memory, CLAUDE.md, hooks);
# it does NOT create your code solution (do that with your stack's scaffolder).
# ─────────────────────────────────────────────────────────────────────────────
set -euo pipefail

KIT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
TARGET="."
FORCE=0
for arg in "$@"; do
  case "$arg" in
    --force) FORCE=1 ;;
    -h|--help) sed -n '2,18p' "$0"; exit 0 ;;
    *) TARGET="$arg" ;;
  esac
done
TARGET="$(cd "$TARGET" && pwd)"

say() { printf '  %s\n' "$1"; }
copy() { # copy SRC DST  (respects FORCE; keeps .bak)
  local src="$1" dst="$2"
  if [[ -e "$dst" && "$FORCE" -eq 0 ]]; then say "skip   (exists)  ${dst#$TARGET/}"; return; fi
  if [[ -e "$dst" && "$FORCE" -eq 1 ]]; then cp "$dst" "$dst.bak"; say "backup .bak       ${dst#$TARGET/}.bak"; fi
  cp "$src" "$dst"; say "create            ${dst#$TARGET/}"
}

copy_doc() { # copy_doc SRC NAME  - seed docs/NAME, but skip (with a note) if NAME already exists at the repo root
  local src="$1" name="$2"
  if [[ -e "$TARGET/$name" && "$FORCE" -eq 0 ]]; then
    say "skip   (root has $name)  docs/$name  - move it into docs/ to track it there"
    return
  fi
  copy "$src" "$TARGET/docs/$name"
}

copy_tree() { # copy_tree SRC_ROOT DST_ROOT
  local sroot="$1" droot="$2" f rel
  while IFS= read -r -d '' f; do
    rel="${f#$sroot/}"
    mkdir -p "$droot/$(dirname "$rel")"
    copy "$f" "$droot/$rel"
  done < <(find "$sroot" -type f -print0)
}

echo "Installing the Constitution kit"
echo "  kit:    $KIT_DIR"
echo "  target: $TARGET"
echo

mkdir -p "$TARGET/.claude/agents" "$TARGET/.claude/commands" "$TARGET/.claude/hooks" "$TARGET/.claude/skills" "$TARGET/.claude/tools" "$TARGET/.claude/workflows" \
         "$TARGET/docs" "$TARGET/docs/APPROVAL_INBOX" "$TARGET/docs/design-system" "$TARGET/docs/reports"

# Agents (skip existing — preserves your screen-reconstructor.md and any local edits)
for f in "$KIT_DIR"/agents/*.md; do copy "$f" "$TARGET/.claude/agents/$(basename "$f")"; done
# Commands
for f in "$KIT_DIR"/commands/*.md; do copy "$f" "$TARGET/.claude/commands/$(basename "$f")"; done
# Governing docs at repo root
copy "$KIT_DIR/CONSTITUTION.md"     "$TARGET/CONSTITUTION.md"
copy "$KIT_DIR/SKILLS.md"            "$TARGET/SKILLS.md"
copy "$KIT_DIR/SPECIALIZE.md"        "$TARGET/SPECIALIZE.md"
copy "$KIT_DIR/PROMPT_TEMPLATES.md" "$TARGET/PROMPT_TEMPLATES.md"
# Boards + memory in docs/
copy_doc "$KIT_DIR/templates/SCREEN_REGISTRY.md"   "SCREEN_REGISTRY.md"
copy_doc "$KIT_DIR/templates/WORKFLOW_REGISTRY.md" "WORKFLOW_REGISTRY.md"
copy_doc "$KIT_DIR/templates/INTERACTION_REGISTRY.md" "INTERACTION_REGISTRY.md"
copy_doc "$KIT_DIR/templates/PROGRESS.md"          "PROGRESS.md"
copy_doc "$KIT_DIR/templates/INSIGHTS.md"          "INSIGHTS.md"
copy_doc "$KIT_DIR/templates/LESSONS.md"           "LESSONS.md"
copy_doc "$KIT_DIR/templates/DESIGN_BACKLOG.md"    "DESIGN_BACKLOG.md"
copy_doc "$KIT_DIR/templates/DESIGN_PROMPTS.md"    "DESIGN_PROMPTS.md"
# Master CLAUDE.md at repo root (skipped if you already have one)
copy "$KIT_DIR/templates/CLAUDE.master.md"     "$TARGET/CLAUDE.md"
# Hooks
copy "$KIT_DIR/templates/settings.json" "$TARGET/.claude/settings.json"
copy "$KIT_DIR/templates/verify.sh"     "$TARGET/.claude/hooks/verify.sh"
copy "$KIT_DIR/templates/verify.ps1"    "$TARGET/.claude/hooks/verify.ps1"
chmod +x "$TARGET/.claude/hooks/verify.sh" 2>/dev/null || true
# Preflight gate harness (recursive tree copy)
copy_tree "$KIT_DIR/scripts/preflight" "$TARGET/.claude/hooks/preflight"
# Opt-in hooks + example settings
copy "$KIT_DIR/templates/oncodeedit.ps1"                  "$TARGET/.claude/hooks/oncodeedit.ps1"
copy "$KIT_DIR/templates/notify.ps1"                      "$TARGET/.claude/hooks/notify.ps1"
copy "$KIT_DIR/templates/settings.preflight.example.json" "$TARGET/.claude/settings.preflight.example.json"
# Wave scheduler tools
copy "$KIT_DIR/tools/Compute-WaveSchedule.ps1"     "$TARGET/.claude/tools/Compute-WaveSchedule.ps1"
copy "$KIT_DIR/tools/Schedule.Tests.ps1"           "$TARGET/.claude/tools/Schedule.Tests.ps1"
copy "$KIT_DIR/tools/Verify-WaveDisjoint.ps1"       "$TARGET/.claude/tools/Verify-WaveDisjoint.ps1"
copy "$KIT_DIR/tools/Verify-WaveDisjoint.Tests.ps1" "$TARGET/.claude/tools/Verify-WaveDisjoint.Tests.ps1"
copy "$KIT_DIR/tools/RenderFilter.Tests.ps1"        "$TARGET/.claude/tools/RenderFilter.Tests.ps1"
copy "$KIT_DIR/tools/spans.fixture.json"           "$TARGET/.claude/tools/spans.fixture.json"
copy "$KIT_DIR/tools/PARALLELISM.md"               "$TARGET/.claude/tools/PARALLELISM.md"
# Metrics + contracts-surface + framework-governance tools (C1 / A3 / kit gate)
for t in Show-Metrics.ps1 Metrics.Tests.ps1 metrics.fixture.jsonl Update-ContractsSnapshot.ps1 ContractsSurface.Tests.ps1 Kit.Tests.ps1 New-KitManifest.ps1 Verify-KitInstall.ps1 Manifest.Tests.ps1 manifest-fixture-lf.txt manifest-fixture-crlfbom.txt Governance.Tests.ps1 SessionLedger.Tests.ps1; do
  copy "$KIT_DIR/tools/$t" "$TARGET/.claude/tools/$t"
done
copy "$KIT_DIR/templates/housekeep.ps1"                   "$TARGET/.claude/hooks/housekeep.ps1"
copy "$KIT_DIR/templates/settings.housekeep.example.json" "$TARGET/.claude/settings.housekeep.example.json"
copy_doc "$KIT_DIR/templates/METRICS_README.md" "METRICS_README.md"
mkdir -p "$TARGET/docs/metrics"
# Session ledger (opt-in, cross-platform): one Node implementation + guard launchers + wiring example
copy "$KIT_DIR/templates/session-ledger.js"             "$TARGET/.claude/hooks/session-ledger.js"
copy "$KIT_DIR/templates/session-hook.ps1"              "$TARGET/.claude/hooks/session-hook.ps1"
copy "$KIT_DIR/templates/session-hook.sh"               "$TARGET/.claude/hooks/session-hook.sh"
chmod +x "$TARGET/.claude/hooks/session-hook.sh" 2>/dev/null || true
copy "$KIT_DIR/templates/settings.session.example.json" "$TARGET/.claude/settings.session.example.json"
copy_doc "$KIT_DIR/templates/SESSION_SETUP.md" "SESSION_SETUP.md"
mkdir -p "$TARGET/docs/journal"
# Notify setup doc
copy_doc "$KIT_DIR/templates/NOTIFY_SETUP.md" "NOTIFY_SETUP.md"
# Reports index (docs/reports/README.md — filed by /progress-report)
mkdir -p "$TARGET/docs/reports"
copy "$KIT_DIR/templates/reports-README.md" "$TARGET/docs/reports/README.md"
# Optional code-discovery graph ignore file (codebase-memory-mcp) — seeded at repo root
copy "$KIT_DIR/templates/cbmignore" "$TARGET/.cbmignore"
[[ -e "$TARGET/docs/APPROVAL_INBOX/.gitkeep" ]] || : > "$TARGET/docs/APPROVAL_INBOX/.gitkeep"
[[ -e "$TARGET/.claude/skills/.gitkeep" ]] || : > "$TARGET/.claude/skills/.gitkeep"
copy "$KIT_DIR/templates/SKILL.template.md" "$TARGET/.claude/skills/SKILL.template.md"
# Project skills shipped with the kit (skills/<name>/*.md -> .claude/skills/<name>/)
if [[ -d "$KIT_DIR/skills" ]]; then
  for sd in "$KIT_DIR"/skills/*/; do
    [[ -d "$sd" ]] || continue
    sname="$(basename "$sd")"
    mkdir -p "$TARGET/.claude/skills/$sname"
    for sf in "$sd"*.md; do [[ -e "$sf" ]] && copy "$sf" "$TARGET/.claude/skills/$sname/$(basename "$sf")"; done
  done
fi
copy "$KIT_DIR/tools/progress.ps1"      "$TARGET/.claude/tools/progress.ps1"
# Workflow scripts shipped with the kit (workflows/*.js -> .claude/workflows/)
if [[ -d "$KIT_DIR/workflows" ]]; then
  for wf in "$KIT_DIR"/workflows/*.js; do [[ -e "$wf" ]] && copy "$wf" "$TARGET/.claude/workflows/$(basename "$wf")"; done
fi

# Provenance at birth: write the installation manifest LAST (single hasher lives in PowerShell -
# bootstrap.sh delegates rather than growing a second normalization implementation).
PSBIN="$(command -v pwsh || command -v powershell.exe || command -v powershell || true)"
if [[ -n "$PSBIN" ]]; then
  "$PSBIN" -NoProfile -ExecutionPolicy Bypass -File "$KIT_DIR/tools/New-KitManifest.ps1" -ProjectRoot "$TARGET" -KitSource "$KIT_DIR" || say "WARN manifest generation failed"
else
  say "NOTE PowerShell not found - manifest skipped; run tools/New-KitManifest.ps1 from a PS host"
fi

cat <<'NEXT'

Done. Next steps:
  1. Open CLAUDE.md and fill every <…> placeholder for this project (this is the master starting point).
  2. Re-create the agents via /agents in Claude Code so they register immediately
     (files are already on disk; /agents picks them up without a restart).
  2b. Add skills (SKILLS.md): install Anthropic's (skill-creator, frontend-design, webapp-testing,
      docx/pdf/pptx/xlsx) and author the project skills into .claude/skills/ via skill-creator.
  3. Tune .claude/hooks/verify.sh (build + quick tests) to your stack. Windows-native: point the
     Stop hook in .claude/settings.json at  pwsh -NoProfile -File "$env:CLAUDE_PROJECT_DIR/.claude/hooks/verify.ps1".
  4. Run the lifecycle (CONSTITUTION.md §2 / PROMPT_TEMPLATES.md):
       phase 0 PRD → phase 1 design → phase 2 reconstruct → phase 3 specs
       → have Claude generate docs/SCREEN_REGISTRY.md + docs/WORKFLOW_REGISTRY.md from CLAUDE.md
       → phase 4 found (human-in-the-loop) → phase 5  /build-workflow <golden workflow>.

  Tip: watch a long sweep live —  pwsh .claude/tools/progress.ps1 -Watch
  Gate the kit machinery:        pwsh .claude/tools/Kit.Tests.ps1
  Verify this installation:      pwsh .claude/tools/Verify-KitInstall.ps1
NEXT
