#!/usr/bin/env bash # Completeness test: verify the kit itself is well-formed. # Checks that all expected files exist, YAML frontmatter is valid, # and no hardcoded project-specific paths remain in static/template files. set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" KIT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" PASS=0 FAIL=0 ERRORS=() pass() { PASS=$((PASS + 1)) echo " PASS: $1" } fail() { FAIL=$((FAIL + 1)) ERRORS+=("$1") echo " FAIL: $1" } echo "=== whatsinagame completeness test ===" echo "" echo "Kit directory: $KIT_DIR" echo "" # --- Test 1: Expected kit files exist --- echo "--- Test 1: Kit file inventory ---" EXPECTED_FILES=( "README.md" "LICENSE" "skill/SKILL.md" "skill/references/profile-manifests.md" "skill/references/archetype-gallery.md" "skill/references/personality-guide.md" "skill/references/git-host-patterns.md" "skill/references/customization-examples.md" "static/db/schema.sql" "static/db/connectors/config.json" "static/db/connectors/sqlite_connector.py" "static/db/connectors/ticket" "static/db/connectors/sprint" "tests/test-install.sh" "tests/test-completeness.sh" ) for f in "${EXPECTED_FILES[@]}"; do if [[ -f "$KIT_DIR/$f" ]]; then pass "$f exists" else fail "$f missing" fi done echo "" # --- Test 2: SKILL.md files have valid YAML frontmatter --- echo "--- Test 2: SKILL.md YAML frontmatter ---" while IFS= read -r -d '' skill_file; do rel_path="${skill_file#$KIT_DIR/}" # Check file starts with --- first_line=$(head -1 "$skill_file") if [[ "$first_line" != "---" ]]; then fail "$rel_path: missing YAML frontmatter opening ---" continue fi # Check for closing --- if ! sed -n '2,${/^---$/q;p}' "$skill_file" | grep -q '^'; then fail "$rel_path: missing YAML frontmatter closing ---" continue fi # Extract frontmatter and check for required fields frontmatter=$(sed -n '2,/^---$/p' "$skill_file" | head -n -1) if echo "$frontmatter" | grep -q '^name:'; then pass "$rel_path: has 'name' field" else fail "$rel_path: missing 'name' field in frontmatter" fi if echo "$frontmatter" | grep -q '^description:'; then pass "$rel_path: has 'description' field" else fail "$rel_path: missing 'description' field in frontmatter" fi done < <(find "$KIT_DIR" -name "SKILL.md" -print0) echo "" # --- Test 3: Agent template files have valid YAML frontmatter --- echo "--- Test 3: Agent template YAML frontmatter ---" AGENT_DIR="$KIT_DIR/templates/.claude/agents" if [[ -d "$AGENT_DIR" ]]; then agent_count=0 while IFS= read -r -d '' agent_file; do rel_path="${agent_file#$KIT_DIR/}" agent_count=$((agent_count + 1)) # Check file starts with --- first_line=$(head -1 "$agent_file") if [[ "$first_line" != "---" ]]; then fail "$rel_path: missing YAML frontmatter opening ---" continue fi # Check for closing --- if ! sed -n '2,${/^---$/q;p}' "$agent_file" | grep -q '^'; then fail "$rel_path: missing YAML frontmatter closing ---" continue fi # Extract frontmatter and check for required fields frontmatter=$(sed -n '2,/^---$/p' "$agent_file" | head -n -1) if echo "$frontmatter" | grep -q '^name:'; then pass "$rel_path: has 'name' field" else fail "$rel_path: missing 'name' field in frontmatter" fi if echo "$frontmatter" | grep -q '^description:'; then pass "$rel_path: has 'description' field" else fail "$rel_path: missing 'description' field in frontmatter" fi done < <(find "$AGENT_DIR" -name "*.md" -print0) if [[ $agent_count -eq 0 ]]; then fail "No agent templates found in $AGENT_DIR" else pass "Found $agent_count agent template(s)" fi else fail "Agent template directory missing: templates/.claude/agents/" fi echo "" # --- Test 4: No hardcoded project-specific paths in static files --- echo "--- Test 4: No hardcoded project-specific paths ---" # Patterns that should NOT appear in static/ or templates/ files # (they indicate the kit wasn't properly generalized) FORBIDDEN_PATTERNS=( "settled-reach" "commonwealth" "tower-of-joy" "schweitz" "jpmschweitzer" "git.schweitz.internal" ) # Files to exclude from this check (references are allowed to mention the source project) EXCLUDE_PATTERN="(customization-examples\.md|README\.md|LICENSE)$" found_forbidden=false for pattern in "${FORBIDDEN_PATTERNS[@]}"; do # Search static/ and templates/ directories, excluding known exceptions while IFS= read -r match_file; do rel_path="${match_file#$KIT_DIR/}" # Skip excluded files if echo "$rel_path" | grep -qE "$EXCLUDE_PATTERN"; then continue fi # Skip binary files if file "$match_file" | grep -q "binary\|executable"; then continue fi matches=$(grep -n "$pattern" "$match_file" 2>/dev/null || true) if [[ -n "$matches" ]]; then fail "$rel_path contains hardcoded '$pattern'" echo " $(echo "$matches" | head -3)" found_forbidden=true fi done < <(find "$KIT_DIR/static" "$KIT_DIR/templates" -type f 2>/dev/null || true) done if [[ "$found_forbidden" == false ]]; then pass "No hardcoded project-specific paths found in static/templates" fi echo "" # --- Test 5: Test scripts are executable --- echo "--- Test 5: Test scripts are executable ---" for test_script in "$KIT_DIR/tests/"*.sh; do rel_path="${test_script#$KIT_DIR/}" if [[ -x "$test_script" ]]; then pass "$rel_path is executable" else fail "$rel_path is not executable" fi done echo "" # --- Test 6: Directory structure --- echo "--- Test 6: Expected directories ---" EXPECTED_DIRS=( "skill" "skill/references" "static" "static/db" "static/db/connectors" "templates" "templates/.claude" "templates/.claude/agents" "templates/.claude/skills" "tests" ) for d in "${EXPECTED_DIRS[@]}"; do if [[ -d "$KIT_DIR/$d" ]]; then pass "$d/ exists" else fail "$d/ missing" fi done echo "" # --- Summary --- echo "=== Results ===" echo " Passed: $PASS" echo " Failed: $FAIL" if [[ ${#ERRORS[@]} -gt 0 ]]; then echo "" echo "Failures:" for e in "${ERRORS[@]}"; do echo " - $e" done fi echo "" if [[ $FAIL -eq 0 ]]; then echo "All tests passed." exit 0 else echo "Some tests failed." exit 1 fi