#!/usr/bin/env bash # check-agent-docs-drift.sh — Fast drift check for per-repo agent docs. # Exits 1 if any repo has drifted from the canonical pattern. # # Modelled on check-npmrc-drift.sh. Marker-based (no generator runs), # so this is fast and side-effect-free. # # Usage: # bash scripts/check-agent-docs-drift.sh # # What is checked per repo: # 1. Legacy files MUST NOT exist (they used to duplicate AGENTS.md): # .cursorrules, .windsurfrules, .clinerules, CLAUDE.md # 2. AGENTS.md MUST contain the canonical-behavior-pointer marker. # 3. .github/copilot-instructions.md MUST contain the AUTO-GENERATED marker # AND a reference to the canonical guidelines file. # 4. .aider.conf.yml MUST exist and reference AGENTS.md. # 5. .editorconfig MUST exist with the canonical first line "root = true". # # Repair: bash scripts/update-agent-docs.sh set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPOS_TXT="${SCRIPT_DIR}/../.windsurf/workflows/repos.txt" BASE_DIR="$(cd "${SCRIPT_DIR}/../.." && pwd)" RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m' if [[ ! -f "$REPOS_TXT" ]]; then echo -e "${RED}❌ repos.txt not found: $REPOS_TXT${NC}" >&2 exit 1 fi LEGACY_FILES=(.cursorrules .windsurfrules .clinerules CLAUDE.md) AGENTS_POINTER_MARKER="" COPILOT_GENERATED_MARKER="" COPILOT_CANONICAL_REF="agent-behavior-guidelines.md" drifted=0 clean=0 missing=0 REPOS=() while IFS= read -r line; do [[ "$line" =~ ^[[:space:]]*# ]] && continue [[ -z "${line// }" ]] && continue REPOS+=("$line") done < "$REPOS_TXT" for repo in "${REPOS[@]}"; do repo_dir="${BASE_DIR}/${repo}" if [[ ! -d "$repo_dir" ]]; then continue fi if [[ ! -f "${repo_dir}/AGENTS.md" ]]; then echo -e "${YELLOW}⚠️ $repo — AGENTS.md missing${NC}" ((missing++)) || true continue fi issues=() # 1 — Legacy files must be gone. for f in "${LEGACY_FILES[@]}"; do if [[ -e "${repo_dir}/${f}" ]]; then issues+=("legacy file still present: $f") fi done # 2 — AGENTS.md must have the canonical pointer block. if ! grep -qF "$AGENTS_POINTER_MARKER" "${repo_dir}/AGENTS.md"; then issues+=("AGENTS.md missing canonical-behavior-pointer block") fi # 3 — Copilot file: must exist, must be AUTO-GENERATED, must reference canonical. copilot="${repo_dir}/.github/copilot-instructions.md" if [[ ! -f "$copilot" ]]; then issues+=(".github/copilot-instructions.md missing") else if ! grep -qF "$COPILOT_GENERATED_MARKER" "$copilot"; then issues+=(".github/copilot-instructions.md missing AUTO-GENERATED marker (hand-edited?)") fi if ! grep -qF "$COPILOT_CANONICAL_REF" "$copilot"; then issues+=(".github/copilot-instructions.md missing reference to $COPILOT_CANONICAL_REF") fi fi # 4 — Aider config: must exist and reference AGENTS.md. aider="${repo_dir}/.aider.conf.yml" if [[ ! -f "$aider" ]]; then issues+=(".aider.conf.yml missing") elif ! grep -qF "AGENTS.md" "$aider"; then issues+=(".aider.conf.yml does not reference AGENTS.md") fi # 5 — Editorconfig: must exist with canonical first line. editorconfig="${repo_dir}/.editorconfig" if [[ ! -f "$editorconfig" ]]; then issues+=(".editorconfig missing") elif ! head -1 "$editorconfig" | grep -qE '^root = true$'; then issues+=(".editorconfig first line not 'root = true' (hand-edited?)") fi if [[ ${#issues[@]} -gt 0 ]]; then echo -e "${RED}❌ $repo${NC}" for i in "${issues[@]}"; do echo " - $i" done ((drifted++)) || true else ((clean++)) || true fi done echo "────────────────────────────────" echo -e "${GREEN}✅ $clean repos in sync${NC}" [[ "$missing" -gt 0 ]] && echo -e "${YELLOW}⚠️ $missing repos missing AGENTS.md${NC}" [[ "$drifted" -gt 0 ]] && echo -e "${RED}❌ $drifted repos drifted${NC}" echo "" if [[ "$drifted" -gt 0 ]] || [[ "$missing" -gt 0 ]]; then echo "Fix: bash scripts/update-agent-docs.sh" exit 1 fi echo "All repos in sync ✅"