1
0

run-test.sh 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. #!/usr/bin/env bash
  2. # Test explicit skill requests (user names a skill directly)
  3. # Usage: ./run-test.sh <skill-name> <prompt-file>
  4. #
  5. # Tests whether Claude invokes a skill when the user explicitly requests it by name
  6. # (without using the plugin namespace prefix)
  7. #
  8. # Uses isolated HOME to avoid user context interference
  9. set -e
  10. SKILL_NAME="$1"
  11. PROMPT_FILE="$2"
  12. MAX_TURNS="${3:-3}"
  13. if [ -z "$SKILL_NAME" ] || [ -z "$PROMPT_FILE" ]; then
  14. echo "Usage: $0 <skill-name> <prompt-file> [max-turns]"
  15. echo "Example: $0 subagent-driven-development ./prompts/subagent-driven-development-please.txt"
  16. exit 1
  17. fi
  18. # Get the directory where this script lives
  19. SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
  20. # Get the superpowers plugin root (two levels up)
  21. PLUGIN_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)"
  22. TIMESTAMP=$(date +%s)
  23. OUTPUT_DIR="/tmp/superpowers-tests/${TIMESTAMP}/explicit-skill-requests/${SKILL_NAME}"
  24. mkdir -p "$OUTPUT_DIR"
  25. # Read prompt from file
  26. PROMPT=$(cat "$PROMPT_FILE")
  27. echo "=== Explicit Skill Request Test ==="
  28. echo "Skill: $SKILL_NAME"
  29. echo "Prompt file: $PROMPT_FILE"
  30. echo "Max turns: $MAX_TURNS"
  31. echo "Output dir: $OUTPUT_DIR"
  32. echo ""
  33. # Copy prompt for reference
  34. cp "$PROMPT_FILE" "$OUTPUT_DIR/prompt.txt"
  35. # Create a minimal project directory for the test
  36. PROJECT_DIR="$OUTPUT_DIR/project"
  37. mkdir -p "$PROJECT_DIR/docs/superpowers/plans"
  38. # Create a dummy plan file for mid-conversation tests
  39. cat > "$PROJECT_DIR/docs/superpowers/plans/auth-system.md" << 'EOF'
  40. # Auth System Implementation Plan
  41. ## Task 1: Add User Model
  42. Create user model with email and password fields.
  43. ## Task 2: Add Auth Routes
  44. Create login and register endpoints.
  45. ## Task 3: Add JWT Middleware
  46. Protect routes with JWT validation.
  47. EOF
  48. # Run Claude with isolated environment
  49. LOG_FILE="$OUTPUT_DIR/claude-output.json"
  50. cd "$PROJECT_DIR"
  51. echo "Plugin dir: $PLUGIN_DIR"
  52. echo "Running claude -p with explicit skill request..."
  53. echo "Prompt: $PROMPT"
  54. echo ""
  55. timeout 300 claude -p "$PROMPT" \
  56. --plugin-dir "$PLUGIN_DIR" \
  57. --dangerously-skip-permissions \
  58. --max-turns "$MAX_TURNS" \
  59. --output-format stream-json \
  60. > "$LOG_FILE" 2>&1 || true
  61. echo ""
  62. echo "=== Results ==="
  63. # Check if skill was triggered (look for Skill tool invocation)
  64. # Match either "skill":"skillname" or "skill":"namespace:skillname"
  65. SKILL_PATTERN='"skill":"([^"]*:)?'"${SKILL_NAME}"'"'
  66. if grep -q '"name":"Skill"' "$LOG_FILE" && grep -qE "$SKILL_PATTERN" "$LOG_FILE"; then
  67. echo "PASS: Skill '$SKILL_NAME' was triggered"
  68. TRIGGERED=true
  69. else
  70. echo "FAIL: Skill '$SKILL_NAME' was NOT triggered"
  71. TRIGGERED=false
  72. fi
  73. # Show what skills WERE triggered
  74. echo ""
  75. echo "Skills triggered in this run:"
  76. grep -o '"skill":"[^"]*"' "$LOG_FILE" 2>/dev/null | sort -u || echo " (none)"
  77. # Check if Claude took action BEFORE invoking the skill (the failure mode)
  78. echo ""
  79. echo "Checking for premature action..."
  80. # Look for tool invocations before the Skill invocation
  81. # This detects the failure mode where Claude starts doing work without loading the skill
  82. FIRST_SKILL_LINE=$(grep -n '"name":"Skill"' "$LOG_FILE" | head -1 | cut -d: -f1)
  83. if [ -n "$FIRST_SKILL_LINE" ]; then
  84. # Check if any non-Skill, non-system tools were invoked before the first Skill invocation
  85. # Filter out task tracking tools (planning is ok) and other non-action tools
  86. PREMATURE_TOOLS=$(head -n "$FIRST_SKILL_LINE" "$LOG_FILE" | \
  87. grep '"type":"tool_use"' | \
  88. grep -v '"name":"Skill"' | \
  89. grep -vE '"name":"(TodoWrite|TaskCreate|TaskUpdate|TaskList|TaskGet)"' || true)
  90. if [ -n "$PREMATURE_TOOLS" ]; then
  91. echo "WARNING: Tools invoked BEFORE Skill tool:"
  92. echo "$PREMATURE_TOOLS" | head -5
  93. echo ""
  94. echo "This indicates Claude started working before loading the requested skill."
  95. else
  96. echo "OK: No premature tool invocations detected"
  97. fi
  98. else
  99. echo "WARNING: No Skill invocation found at all"
  100. fi
  101. # Show first assistant message
  102. echo ""
  103. echo "First assistant response (truncated):"
  104. grep '"type":"assistant"' "$LOG_FILE" | head -1 | jq -r '.message.content[0].text // .message.content' 2>/dev/null | head -c 500 || echo " (could not extract)"
  105. echo ""
  106. echo "Full log: $LOG_FILE"
  107. echo "Timestamp: $TIMESTAMP"
  108. if [ "$TRIGGERED" = "true" ]; then
  109. exit 0
  110. else
  111. exit 1
  112. fi