From 3ae07799da6dd9033d99b9705d6bd33278ae723b Mon Sep 17 00:00:00 2001 From: Steve Nims Date: Sun, 7 Dec 2025 19:21:05 -0500 Subject: [PATCH 1/3] fix: add missing test-agent-trigger.sh script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SKILL.md documentation referenced test-agent-trigger.sh but the script didn't exist, causing confusion for users following the docs. This script helps test agent triggering by: - Extracting blocks from agent descriptions - Parsing user phrases that should trigger the agent - Validating example block formatting - Providing manual testing guidance Fixes #9 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../scripts/test-agent-trigger.sh | 226 ++++++++++++++++++ 1 file changed, 226 insertions(+) create mode 100755 plugins/plugin-dev/skills/agent-development/scripts/test-agent-trigger.sh diff --git a/plugins/plugin-dev/skills/agent-development/scripts/test-agent-trigger.sh b/plugins/plugin-dev/skills/agent-development/scripts/test-agent-trigger.sh new file mode 100755 index 0000000..c610792 --- /dev/null +++ b/plugins/plugin-dev/skills/agent-development/scripts/test-agent-trigger.sh @@ -0,0 +1,226 @@ +#!/bin/bash +# Agent Trigger Test Helper +# Extracts triggering examples and validates example block formatting + +set -euo pipefail + +# Usage +if [ $# -eq 0 ]; then + echo "Usage: $0 " + echo "" + echo "This script helps test agent triggering by:" + echo " - Extracting blocks from description" + echo " - Parsing user phrases that should trigger the agent" + echo " - Validating example block formatting" + echo " - Providing manual testing guidance" + exit 1 +fi + +AGENT_FILE="$1" + +echo "🔍 Analyzing agent triggers: $AGENT_FILE" +echo "" + +# Check file exists +if [ ! -f "$AGENT_FILE" ]; then + echo "❌ File not found: $AGENT_FILE" + exit 1 +fi + +# Check frontmatter exists +FIRST_LINE=$(head -1 "$AGENT_FILE") +if [ "$FIRST_LINE" != "---" ]; then + echo "❌ File must start with YAML frontmatter (---)" + exit 1 +fi + +# Extract agent name +NAME=$(sed -n '/^---$/,/^---$/p' "$AGENT_FILE" | grep '^name:' | sed 's/name: *//' | sed 's/^"\(.*\)"$/\1/' | head -1) + +if [ -z "$NAME" ]; then + echo "❌ Could not extract agent name" + exit 1 +fi + +echo "📋 Agent: $NAME" +echo "" + +# Extract full frontmatter section +FRONTMATTER=$(awk ' + /^---$/ { count++; next } + count == 1 { print } +' "$AGENT_FILE") + +# Extract description - handles multi-line YAML +# Description ends when we hit another top-level field (model:, color:, tools:, etc.) +DESCRIPTION=$(echo "$FRONTMATTER" | awk ' + /^description:/ { + in_desc = 1 + sub(/^description: */, "") + if ($0 != "") print + next + } + in_desc && /^(model|color|tools|name):/ { exit } + in_desc { print } +') + +if [ -z "$DESCRIPTION" ]; then + echo "❌ Could not extract description" + exit 1 +fi + +# Count example blocks +EXAMPLE_COUNT=$(echo "$DESCRIPTION" | grep -c '' || echo 0) + +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "📊 EXAMPLE ANALYSIS" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "" + +if [ "$EXAMPLE_COUNT" -eq 0 ]; then + echo "⚠️ No blocks found in description" + echo "" + echo "Agent descriptions should include 2-4 example blocks showing" + echo "when the agent should be triggered." + echo "" + echo "Example format:" + echo " " + echo " Context: [Scenario description]" + echo ' user: "[User request]"' + echo ' assistant: "[How Claude responds]"' + echo " " + echo " [Why this triggers the agent]" + echo " " + echo " " + exit 1 +fi + +echo "Found $EXAMPLE_COUNT example block(s)" +echo "" + +# Extract and display each example +# Use awk to extract example blocks +echo "$DESCRIPTION" | awk ' + // { in_example=1; example=""; next } + /<\/example>/ { + in_example=0 + example_num++ + print "───────────────────────────────────────" + print "Example " example_num ":" + print "───────────────────────────────────────" + print example + print "" + next + } + in_example { example = example $0 "\n" } +' | while IFS= read -r line; do + echo "$line" +done + +echo "" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "🎯 TRIGGER PHRASES" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "" + +# Extract user phrases from examples +USER_PHRASES=$(echo "$DESCRIPTION" | grep -oE 'user: *"[^"]*"' | sed 's/user: *"//' | sed 's/"$//' || true) + +if [ -z "$USER_PHRASES" ]; then + echo "⚠️ Could not extract user phrases from examples" + echo "" + echo "Make sure examples include 'user: \"phrase\"' format" + ((error_count++)) +else + echo "Use these phrases to test agent triggering:" + echo "" + echo "$USER_PHRASES" | while IFS= read -r phrase; do + echo " → $phrase" + done +fi + +echo "" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "✅ VALIDATION" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "" + +warning_count=0 + +# Check for "Use this agent when" pattern +if ! echo "$DESCRIPTION" | grep -qi 'use this agent when'; then + echo "⚠️ Description should start with 'Use this agent when...'" + ((warning_count++)) +else + echo "✅ Has 'Use this agent when' pattern" +fi + +# Check example count +if [ "$EXAMPLE_COUNT" -lt 2 ]; then + echo "⚠️ Only $EXAMPLE_COUNT example(s) - recommend 2-4 examples" + ((warning_count++)) +elif [ "$EXAMPLE_COUNT" -gt 4 ]; then + echo "⚠️ $EXAMPLE_COUNT examples - consider trimming to 2-4" + ((warning_count++)) +else + echo "✅ Good number of examples ($EXAMPLE_COUNT)" +fi + +# Check for commentary in examples +COMMENTARY_COUNT=$(echo "$DESCRIPTION" | grep -c '' 2>/dev/null || echo 0) +COMMENTARY_COUNT=$(echo "$COMMENTARY_COUNT" | tr -d '[:space:]') +if [ "$COMMENTARY_COUNT" -lt "$EXAMPLE_COUNT" ]; then + echo "⚠️ Some examples missing blocks" + ((warning_count++)) +else + echo "✅ All examples have commentary" +fi + +# Check for Context in examples +CONTEXT_COUNT=$(echo "$DESCRIPTION" | grep -ci 'context:' 2>/dev/null || echo 0) +CONTEXT_COUNT=$(echo "$CONTEXT_COUNT" | tr -d '[:space:]') +if [ "$CONTEXT_COUNT" -lt "$EXAMPLE_COUNT" ]; then + echo "⚠️ Some examples missing Context: lines" + ((warning_count++)) +else + echo "✅ All examples have context" +fi + +# Check for assistant responses +ASSISTANT_COUNT=$(echo "$DESCRIPTION" | grep -c 'assistant:' 2>/dev/null || echo 0) +ASSISTANT_COUNT=$(echo "$ASSISTANT_COUNT" | tr -d '[:space:]') +if [ "$ASSISTANT_COUNT" -lt "$EXAMPLE_COUNT" ]; then + echo "⚠️ Some examples missing assistant: responses" + ((warning_count++)) +else + echo "✅ All examples have assistant responses" +fi + +echo "" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "📖 MANUAL TESTING GUIDE" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "" +echo "To test agent triggering:" +echo "" +echo "1. Load your plugin in Claude Code:" +echo " cc --plugin-dir /path/to/plugin" +echo "" +echo "2. Try the trigger phrases listed above" +echo "" +echo "3. Verify Claude loads the agent (look for agent indicator)" +echo "" +echo "4. Test variations of the phrases to ensure robust triggering" +echo "" +echo "5. Test negative cases - phrases that should NOT trigger" +echo "" + +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + +if [ "$warning_count" -eq 0 ]; then + echo "✅ All validations passed!" + exit 0 +else + echo "⚠️ Completed with $warning_count warning(s)" + exit 0 +fi From dec7191a8e0a92f19f29e3ad16221b81be9da106 Mon Sep 17 00:00:00 2001 From: Steve Nims Date: Sun, 7 Dec 2025 19:23:48 -0500 Subject: [PATCH 2/3] fix: improve validate-agent.sh multi-line YAML parsing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix description extraction to handle multi-line YAML (same issue as test-agent-trigger.sh) - Add proper quoting for shellcheck compliance The script was only reading the first line of descriptions, missing example blocks in multi-line YAML format. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../scripts/validate-agent.sh | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/plugins/plugin-dev/skills/agent-development/scripts/validate-agent.sh b/plugins/plugin-dev/skills/agent-development/scripts/validate-agent.sh index ca4dfd4..ce2052c 100755 --- a/plugins/plugin-dev/skills/agent-development/scripts/validate-agent.sh +++ b/plugins/plugin-dev/skills/agent-development/scripts/validate-agent.sh @@ -72,10 +72,10 @@ else # Validate name length name_length=${#NAME} - if [ $name_length -lt 3 ]; then + if [ "$name_length" -lt 3 ]; then echo "❌ name too short (minimum 3 characters)" ((error_count++)) - elif [ $name_length -gt 50 ]; then + elif [ "$name_length" -gt 50 ]; then echo "❌ name too long (maximum 50 characters)" ((error_count++)) fi @@ -87,8 +87,18 @@ else fi fi -# Check description field -DESCRIPTION=$(echo "$FRONTMATTER" | grep '^description:' | sed 's/description: *//') +# Check description field - handles multi-line YAML +# Description ends when we hit another top-level field (model:, color:, tools:, name:) +DESCRIPTION=$(echo "$FRONTMATTER" | awk ' + /^description:/ { + in_desc = 1 + sub(/^description: */, "") + if ($0 != "") print + next + } + in_desc && /^(model|color|tools|name):/ { exit } + in_desc { print } +') if [ -z "$DESCRIPTION" ]; then echo "❌ Missing required field: description" @@ -97,10 +107,10 @@ else desc_length=${#DESCRIPTION} echo "✅ description: ${desc_length} characters" - if [ $desc_length -lt 10 ]; then + if [ "$desc_length" -lt 10 ]; then echo "⚠️ description too short (minimum 10 characters recommended)" ((warning_count++)) - elif [ $desc_length -gt 5000 ]; then + elif [ "$desc_length" -gt 5000 ]; then echo "⚠️ description very long (over 5000 characters)" ((warning_count++)) fi @@ -178,10 +188,10 @@ else prompt_length=${#SYSTEM_PROMPT} echo "✅ System prompt: $prompt_length characters" - if [ $prompt_length -lt 20 ]; then + if [ "$prompt_length" -lt 20 ]; then echo "❌ System prompt too short (minimum 20 characters)" ((error_count++)) - elif [ $prompt_length -gt 10000 ]; then + elif [ "$prompt_length" -gt 10000 ]; then echo "⚠️ System prompt very long (over 10,000 characters)" ((warning_count++)) fi From c175e42c357851c1ebe2319c127a3984aebc201e Mon Sep 17 00:00:00 2001 From: Steve Nims Date: Sun, 7 Dec 2025 19:28:23 -0500 Subject: [PATCH 3/3] fix: resolve unbound variable bug in test-agent-trigger.sh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Address PR review feedback: - Initialize warning_count before first use (was causing crash with set -euo pipefail when no user phrases found) - Change error_count++ to warning_count++ for consistency (the message uses ⚠️ warning emoji, not ❌ error emoji) - Remove duplicate warning_count initialization 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../skills/agent-development/scripts/test-agent-trigger.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/plugins/plugin-dev/skills/agent-development/scripts/test-agent-trigger.sh b/plugins/plugin-dev/skills/agent-development/scripts/test-agent-trigger.sh index c610792..0975363 100755 --- a/plugins/plugin-dev/skills/agent-development/scripts/test-agent-trigger.sh +++ b/plugins/plugin-dev/skills/agent-development/scripts/test-agent-trigger.sh @@ -123,6 +123,9 @@ echo "🎯 TRIGGER PHRASES" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "" +# Initialize warning counter early (used across sections) +warning_count=0 + # Extract user phrases from examples USER_PHRASES=$(echo "$DESCRIPTION" | grep -oE 'user: *"[^"]*"' | sed 's/user: *"//' | sed 's/"$//' || true) @@ -130,7 +133,7 @@ if [ -z "$USER_PHRASES" ]; then echo "⚠️ Could not extract user phrases from examples" echo "" echo "Make sure examples include 'user: \"phrase\"' format" - ((error_count++)) + ((warning_count++)) else echo "Use these phrases to test agent triggering:" echo "" @@ -145,8 +148,6 @@ echo "✅ VALIDATION" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "" -warning_count=0 - # Check for "Use this agent when" pattern if ! echo "$DESCRIPTION" | grep -qi 'use this agent when'; then echo "⚠️ Description should start with 'Use this agent when...'"