validate-agent.sh 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. #!/bin/bash
  2. # Agent File Validator
  3. # Validates agent markdown files for correct structure and content
  4. set -euo pipefail
  5. # Usage
  6. if [ $# -eq 0 ]; then
  7. echo "Usage: $0 <path/to/agent.md>"
  8. echo ""
  9. echo "Validates agent file for:"
  10. echo " - YAML frontmatter structure"
  11. echo " - Required fields (name, description, model, color)"
  12. echo " - Field formats and constraints"
  13. echo " - System prompt presence and length"
  14. echo " - Example blocks in description"
  15. exit 1
  16. fi
  17. AGENT_FILE="$1"
  18. echo "🔍 Validating agent file: $AGENT_FILE"
  19. echo ""
  20. # Check 1: File exists
  21. if [ ! -f "$AGENT_FILE" ]; then
  22. echo "❌ File not found: $AGENT_FILE"
  23. exit 1
  24. fi
  25. echo "✅ File exists"
  26. # Check 2: Starts with ---
  27. FIRST_LINE=$(head -1 "$AGENT_FILE")
  28. if [ "$FIRST_LINE" != "---" ]; then
  29. echo "❌ File must start with YAML frontmatter (---)"
  30. exit 1
  31. fi
  32. echo "✅ Starts with frontmatter"
  33. # Check 3: Has closing ---
  34. if ! tail -n +2 "$AGENT_FILE" | grep -q '^---$'; then
  35. echo "❌ Frontmatter not closed (missing second ---)"
  36. exit 1
  37. fi
  38. echo "✅ Frontmatter properly closed"
  39. # Extract frontmatter and system prompt
  40. FRONTMATTER=$(sed -n '/^---$/,/^---$/{ /^---$/d; p; }' "$AGENT_FILE")
  41. SYSTEM_PROMPT=$(awk '/^---$/{i++; next} i>=2' "$AGENT_FILE")
  42. # Check 4: Required fields
  43. echo ""
  44. echo "Checking required fields..."
  45. error_count=0
  46. warning_count=0
  47. # Check name field
  48. NAME=$(echo "$FRONTMATTER" | grep '^name:' | sed 's/name: *//' | sed 's/^"\(.*\)"$/\1/')
  49. if [ -z "$NAME" ]; then
  50. echo "❌ Missing required field: name"
  51. ((error_count++))
  52. else
  53. echo "✅ name: $NAME"
  54. # Validate name format
  55. if ! [[ "$NAME" =~ ^[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]$ ]]; then
  56. echo "❌ name must start/end with alphanumeric and contain only letters, numbers, hyphens"
  57. ((error_count++))
  58. fi
  59. # Validate name length
  60. name_length=${#NAME}
  61. if [ $name_length -lt 3 ]; then
  62. echo "❌ name too short (minimum 3 characters)"
  63. ((error_count++))
  64. elif [ $name_length -gt 50 ]; then
  65. echo "❌ name too long (maximum 50 characters)"
  66. ((error_count++))
  67. fi
  68. # Check for generic names
  69. if [[ "$NAME" =~ ^(helper|assistant|agent|tool)$ ]]; then
  70. echo "⚠️ name is too generic: $NAME"
  71. ((warning_count++))
  72. fi
  73. fi
  74. # Check description field
  75. DESCRIPTION=$(echo "$FRONTMATTER" | grep '^description:' | sed 's/description: *//')
  76. if [ -z "$DESCRIPTION" ]; then
  77. echo "❌ Missing required field: description"
  78. ((error_count++))
  79. else
  80. desc_length=${#DESCRIPTION}
  81. echo "✅ description: ${desc_length} characters"
  82. if [ $desc_length -lt 10 ]; then
  83. echo "⚠️ description too short (minimum 10 characters recommended)"
  84. ((warning_count++))
  85. elif [ $desc_length -gt 5000 ]; then
  86. echo "⚠️ description very long (over 5000 characters)"
  87. ((warning_count++))
  88. fi
  89. # Check for example blocks
  90. if ! echo "$DESCRIPTION" | grep -q '<example>'; then
  91. echo "⚠️ description should include <example> blocks for triggering"
  92. ((warning_count++))
  93. fi
  94. # Check for "Use this agent when" pattern
  95. if ! echo "$DESCRIPTION" | grep -qi 'use this agent when'; then
  96. echo "⚠️ description should start with 'Use this agent when...'"
  97. ((warning_count++))
  98. fi
  99. fi
  100. # Check model field
  101. MODEL=$(echo "$FRONTMATTER" | grep '^model:' | sed 's/model: *//')
  102. if [ -z "$MODEL" ]; then
  103. echo "❌ Missing required field: model"
  104. ((error_count++))
  105. else
  106. echo "✅ model: $MODEL"
  107. case "$MODEL" in
  108. inherit|sonnet|opus|haiku)
  109. # Valid model
  110. ;;
  111. *)
  112. echo "⚠️ Unknown model: $MODEL (valid: inherit, sonnet, opus, haiku)"
  113. ((warning_count++))
  114. ;;
  115. esac
  116. fi
  117. # Check color field
  118. COLOR=$(echo "$FRONTMATTER" | grep '^color:' | sed 's/color: *//')
  119. if [ -z "$COLOR" ]; then
  120. echo "❌ Missing required field: color"
  121. ((error_count++))
  122. else
  123. echo "✅ color: $COLOR"
  124. case "$COLOR" in
  125. blue|cyan|green|yellow|magenta|red)
  126. # Valid color
  127. ;;
  128. *)
  129. echo "⚠️ Unknown color: $COLOR (valid: blue, cyan, green, yellow, magenta, red)"
  130. ((warning_count++))
  131. ;;
  132. esac
  133. fi
  134. # Check tools field (optional)
  135. TOOLS=$(echo "$FRONTMATTER" | grep '^tools:' | sed 's/tools: *//')
  136. if [ -n "$TOOLS" ]; then
  137. echo "✅ tools: $TOOLS"
  138. else
  139. echo "💡 tools: not specified (agent has access to all tools)"
  140. fi
  141. # Check 5: System prompt
  142. echo ""
  143. echo "Checking system prompt..."
  144. if [ -z "$SYSTEM_PROMPT" ]; then
  145. echo "❌ System prompt is empty"
  146. ((error_count++))
  147. else
  148. prompt_length=${#SYSTEM_PROMPT}
  149. echo "✅ System prompt: $prompt_length characters"
  150. if [ $prompt_length -lt 20 ]; then
  151. echo "❌ System prompt too short (minimum 20 characters)"
  152. ((error_count++))
  153. elif [ $prompt_length -gt 10000 ]; then
  154. echo "⚠️ System prompt very long (over 10,000 characters)"
  155. ((warning_count++))
  156. fi
  157. # Check for second person
  158. if ! echo "$SYSTEM_PROMPT" | grep -q "You are\|You will\|Your"; then
  159. echo "⚠️ System prompt should use second person (You are..., You will...)"
  160. ((warning_count++))
  161. fi
  162. # Check for structure
  163. if ! echo "$SYSTEM_PROMPT" | grep -qi "responsibilities\|process\|steps"; then
  164. echo "💡 Consider adding clear responsibilities or process steps"
  165. fi
  166. if ! echo "$SYSTEM_PROMPT" | grep -qi "output"; then
  167. echo "💡 Consider defining output format expectations"
  168. fi
  169. fi
  170. echo ""
  171. echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
  172. if [ $error_count -eq 0 ] && [ $warning_count -eq 0 ]; then
  173. echo "✅ All checks passed!"
  174. exit 0
  175. elif [ $error_count -eq 0 ]; then
  176. echo "⚠️ Validation passed with $warning_count warning(s)"
  177. exit 0
  178. else
  179. echo "❌ Validation failed with $error_count error(s) and $warning_count warning(s)"
  180. exit 1
  181. fi