agency-agents/scripts/lint-agents.sh
jiangnan 976c08e4c3 Add CI workflow to validate agent file format
Adds a lint script and GitHub Actions workflow that checks agent
markdown files for required YAML frontmatter fields (name, description,
color) and recommends standard sections. Only changed files in PRs
are validated to avoid blocking on pre-existing issues.
2026-03-06 04:37:53 +08:00

115 lines
2.5 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# Validates agent markdown files:
# 1. YAML frontmatter must exist with name, description, color (ERROR)
# 2. Recommended sections checked but only warned (WARN)
# 3. File must have meaningful content
#
# Usage: ./scripts/lint-agents.sh [file ...]
# If no files given, scans all agent directories.
set -euo pipefail
AGENT_DIRS=(
design
engineering
marketing
product
project-management
testing
support
spatial-computing
specialized
)
REQUIRED_FRONTMATTER=("name" "description" "color")
RECOMMENDED_SECTIONS=("Identity" "Core Mission" "Critical Rules")
errors=0
warnings=0
lint_file() {
local file="$1"
# 1. Check frontmatter delimiters
local first_line
first_line=$(head -1 "$file")
if [[ "$first_line" != "---" ]]; then
echo "ERROR $file: missing frontmatter opening ---"
((errors++))
return
fi
# Extract frontmatter (between first and second ---)
local frontmatter
frontmatter=$(awk 'NR==1{next} /^---$/{exit} {print}' "$file")
if [[ -z "$frontmatter" ]]; then
echo "ERROR $file: empty or malformed frontmatter"
((errors++))
return
fi
# 2. Check required frontmatter fields
for field in "${REQUIRED_FRONTMATTER[@]}"; do
if ! echo "$frontmatter" | grep -qE "^${field}:"; then
echo "ERROR $file: missing frontmatter field '${field}'"
((errors++))
fi
done
# 3. Check recommended sections (warn only)
local body
body=$(awk 'BEGIN{n=0} /^---$/{n++; next} n>=2{print}' "$file")
for section in "${RECOMMENDED_SECTIONS[@]}"; do
if ! echo "$body" | grep -qi "$section"; then
echo "WARN $file: missing recommended section '${section}'"
((warnings++))
fi
done
# 4. Check file has meaningful content
if [[ $(echo "$body" | wc -w) -lt 50 ]]; then
echo "WARN $file: body seems very short (< 50 words)"
((warnings++))
fi
}
# Collect files to lint
files=()
if [[ $# -gt 0 ]]; then
files=("$@")
else
for dir in "${AGENT_DIRS[@]}"; do
if [[ -d "$dir" ]]; then
while IFS= read -r f; do
files+=("$f")
done < <(find "$dir" -maxdepth 1 -name "*.md" -type f | sort)
fi
done
fi
if [[ ${#files[@]} -eq 0 ]]; then
echo "No agent files found."
exit 1
fi
echo "Linting ${#files[@]} agent files..."
echo ""
for file in "${files[@]}"; do
lint_file "$file"
done
echo ""
echo "Results: ${errors} error(s), ${warnings} warning(s) in ${#files[@]} files."
if [[ $errors -gt 0 ]]; then
echo "FAILED: fix the errors above before merging."
exit 1
else
echo "PASSED"
exit 0
fi