Remove the db/connectors → tooling/db/ symlink added in Sprint 21 (#274) and migrate all references to use tooling/db/ directly. - Delete tracked symlink from db/connectors - Remove duplicate db/connectors/* permission patterns from settings - Update project-structure.md to reflect removal - Move whatsinagame/static/db/connectors/ to whatsinagame/static/tooling/db/ - Update 20 whatsinagame template, skill, and test files - Update comment references in client/tests/test_anti_tedium.gd - Historical docs (old sprint briefings, changelog, discussions) left as-is Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
257 lines
6.6 KiB
Bash
Executable File
257 lines
6.6 KiB
Bash
Executable File
#!/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/tooling/db/config.json"
|
|
"static/tooling/db/sqlite_connector.py"
|
|
"static/tooling/db/ticket"
|
|
"static/tooling/db/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/tooling/db"
|
|
"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
|