#!/bin/bash # test-kb-integrity.sh — Cross-reference agent KB paths against actual files # Also finds orphaned KB files not referenced by any agent or SKILL.md # Usage: bash tests/test-kb-integrity.sh set -euo pipefail PLUGIN_ROOT="$(cd "$(dirname "$0")/.." && pwd)" PASS=0 FAIL=0 WARN=0 pass() { echo -e "\033[0;32m ✓ $1\033[0m"; PASS=$((PASS + 1)); } fail() { echo -e "\033[0;31m ✗ $1\033[0m"; FAIL=$((FAIL + 1)); } warn() { echo -e "\033[1;33m ⚠ $1\033[0m"; WARN=$((WARN + 1)); } echo "=== KB Integrity Test ===" echo "" # ------------------------------------------------------- # Check 1: Agent file references resolve # ------------------------------------------------------- echo "--- Check 1: Agent File References ---" for agent_file in "$PLUGIN_ROOT"/agents/*.md; do [ -f "$agent_file" ] || continue basename_agent="$(basename "$agent_file")" # Extract explicit file paths (references/, skills/) from agent while IFS= read -r ref_path; do ref_path=$(echo "$ref_path" | sed 's/`//g; s/"//g; s/^[[:space:]]*//; s/[[:space:]]*$//') [ -z "$ref_path" ] && continue full_path="$PLUGIN_ROOT/$ref_path" if [ -e "$full_path" ]; then pass "$basename_agent -> $ref_path" else fail "$basename_agent -> $ref_path (NOT FOUND)" fi done < <(grep -oE '(references|skills)/[a-zA-Z0-9_./-]+\.md' "$agent_file" 2>/dev/null || true) done echo "" # ------------------------------------------------------- # Check 2: SKILL.md file references resolve # ------------------------------------------------------- echo "--- Check 2: SKILL.md File References ---" for skill_file in "$PLUGIN_ROOT"/skills/*/SKILL.md; do [ -f "$skill_file" ] || continue skill_name="$(basename "$(dirname "$skill_file")")" while IFS= read -r ref_path; do ref_path=$(echo "$ref_path" | sed 's/`//g; s/"//g; s/^[[:space:]]*//; s/[[:space:]]*$//') [ -z "$ref_path" ] && continue # Resolve: references/ paths are relative to skill dir if [[ "$ref_path" == references/* ]]; then full_path="$PLUGIN_ROOT/skills/$skill_name/$ref_path" else full_path="$PLUGIN_ROOT/$ref_path" fi if [ -e "$full_path" ]; then pass "SKILL:$skill_name -> $ref_path" else fail "SKILL:$skill_name -> $ref_path (NOT FOUND)" fi done < <(grep -oE '(references|skills)/[a-zA-Z0-9_./-]+\.md' "$skill_file" 2>/dev/null || true) done echo "" # ------------------------------------------------------- # Check 3: Orphaned KB files # ------------------------------------------------------- echo "--- Check 3: Orphaned KB Files ---" ORPHAN_COUNT=0 while IFS= read -r kb_file; do rel_path="${kb_file#$PLUGIN_ROOT/}" kb_basename="$(basename "$kb_file")" # Check if this filename appears in any agent or SKILL.md if grep -rql "$kb_basename" "$PLUGIN_ROOT/agents/" "$PLUGIN_ROOT"/skills/*/SKILL.md 2>/dev/null; then : # Referenced, ok else warn "Orphaned: $rel_path" ORPHAN_COUNT=$((ORPHAN_COUNT + 1)) fi done < <(find "$PLUGIN_ROOT/skills" -path "*/references/*.md" -type f 2>/dev/null) if [ "$ORPHAN_COUNT" -eq 0 ]; then pass "No orphaned KB files found" fi echo "" # ------------------------------------------------------- # Summary # ------------------------------------------------------- TOTAL=$((PASS + FAIL)) echo "=== Results: $PASS/$TOTAL passed, $FAIL failed, $WARN warnings ===" if [ "$FAIL" -gt 0 ]; then exit 1 fi