@amsterdamdatalabs/enact-extensions 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +94 -20
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/install.d.ts +89 -0
- package/dist/install.d.ts.map +1 -1
- package/dist/install.js +219 -18
- package/dist/install.js.map +1 -1
- package/dist/validate/index.d.ts +21 -0
- package/dist/validate/index.d.ts.map +1 -1
- package/dist/validate/index.js +77 -0
- package/dist/validate/index.js.map +1 -1
- package/extensions/cmux/.agents/plugin.json +37 -0
- package/extensions/cmux/skills/cmux/SKILL.md +82 -0
- package/extensions/cmux/skills/cmux/agents/openai.yaml +4 -0
- package/extensions/cmux/skills/cmux/references/handles-and-identify.md +35 -0
- package/extensions/cmux/skills/cmux/references/panes-surfaces.md +37 -0
- package/extensions/cmux/skills/cmux/references/trigger-flash-and-health.md +23 -0
- package/extensions/cmux/skills/cmux/references/windows-workspaces.md +31 -0
- package/extensions/cmux/skills/cmux-vm-monitor/SKILL.md +122 -0
- package/extensions/cmux/skills/cmux-vm-monitor/agents/openai.yaml +4 -0
- package/extensions/cmux/skills/cmux-vm-monitor/references/cmux-commands.md +66 -0
- package/extensions/cmux/skills/cmux-vm-monitor/scripts/codex_vm_monitor.sh +45 -0
- package/extensions/cmux/skills/cmux-workspace/SKILL.md +93 -0
- package/extensions/dev-state/.agents/plugin.json +35 -0
- package/extensions/dev-state/skills/dev-state-plan-graduation/SKILL.md +194 -0
- package/extensions/dev-state/skills/dev-state-plan-graduation/agents/openai.yaml +4 -0
- package/extensions/dev-state/skills/dev-state-plan-graduation/references/reference.md +130 -0
- package/extensions/devops/.agents/plugin.json +36 -0
- package/extensions/devops/skills/azure-devops-cli/SKILL.md +431 -0
- package/extensions/devops/skills/azure-devops-cli/agents/openai.yaml +4 -0
- package/extensions/devops/skills/ci-pipeline-strategy/SKILL.md +217 -0
- package/extensions/devops/skills/ci-pipeline-strategy/agents/openai.yaml +4 -0
- package/{plugins/net-revenue-management/.codex-plugin → extensions/net-revenue-management/.agents}/plugin.json +10 -6
- package/extensions/plugin-dev/.agents/plugin.json +42 -0
- package/extensions/plugin-dev/.mcp.json +3 -0
- package/extensions/plugin-dev/agents/agent-creator.md +199 -0
- package/extensions/plugin-dev/agents/plugin-validator.md +91 -0
- package/extensions/plugin-dev/agents/skill-reviewer.md +212 -0
- package/extensions/plugin-dev/commands/_archive/create-marketplace.md +427 -0
- package/extensions/plugin-dev/commands/_archive/plugin-dev-guide.md +12 -0
- package/extensions/plugin-dev/commands/create-plugin.md +498 -0
- package/extensions/plugin-dev/commands/start.md +81 -0
- package/extensions/plugin-dev/hooks/hooks.json +3 -0
- package/extensions/plugin-dev/skills/agent-development/SKILL.md +641 -0
- package/extensions/plugin-dev/skills/agent-development/examples/agent-creation-prompt.md +250 -0
- package/extensions/plugin-dev/skills/agent-development/examples/complete-agent-examples.md +461 -0
- package/extensions/plugin-dev/skills/agent-development/references/advanced-agent-fields.md +246 -0
- package/extensions/plugin-dev/skills/agent-development/references/agent-creation-system-prompt.md +216 -0
- package/extensions/plugin-dev/skills/agent-development/references/permission-modes-rules.md +226 -0
- package/extensions/plugin-dev/skills/agent-development/references/system-prompt-design.md +464 -0
- package/extensions/plugin-dev/skills/agent-development/references/triggering-examples.md +474 -0
- package/extensions/plugin-dev/skills/agent-development/scripts/create-agent-skeleton.sh +176 -0
- package/extensions/plugin-dev/skills/agent-development/scripts/test-agent-trigger.sh +227 -0
- package/extensions/plugin-dev/skills/agent-development/scripts/validate-agent.sh +227 -0
- package/extensions/plugin-dev/skills/command-development/SKILL.md +763 -0
- package/extensions/plugin-dev/skills/command-development/examples/plugin-commands.md +612 -0
- package/extensions/plugin-dev/skills/command-development/examples/simple-commands.md +527 -0
- package/extensions/plugin-dev/skills/command-development/references/advanced-workflows.md +762 -0
- package/extensions/plugin-dev/skills/command-development/references/documentation-patterns.md +769 -0
- package/extensions/plugin-dev/skills/command-development/references/frontmatter-reference.md +508 -0
- package/extensions/plugin-dev/skills/command-development/references/interactive-commands.md +966 -0
- package/extensions/plugin-dev/skills/command-development/references/marketplace-considerations.md +943 -0
- package/extensions/plugin-dev/skills/command-development/references/plugin-features-reference.md +637 -0
- package/extensions/plugin-dev/skills/command-development/references/plugin-integration.md +191 -0
- package/extensions/plugin-dev/skills/command-development/references/skill-tool.md +447 -0
- package/extensions/plugin-dev/skills/command-development/references/testing-strategies.md +723 -0
- package/extensions/plugin-dev/skills/command-development/scripts/check-frontmatter.sh +234 -0
- package/extensions/plugin-dev/skills/command-development/scripts/validate-command.sh +160 -0
- package/extensions/plugin-dev/skills/hook-development/SKILL.md +861 -0
- package/extensions/plugin-dev/skills/hook-development/examples/load-context.sh +55 -0
- package/extensions/plugin-dev/skills/hook-development/examples/validate-bash.sh +57 -0
- package/extensions/plugin-dev/skills/hook-development/examples/validate-write.sh +48 -0
- package/extensions/plugin-dev/skills/hook-development/references/advanced.md +871 -0
- package/extensions/plugin-dev/skills/hook-development/references/hook-input-schemas.md +145 -0
- package/extensions/plugin-dev/skills/hook-development/references/migration.md +392 -0
- package/extensions/plugin-dev/skills/hook-development/references/patterns.md +430 -0
- package/extensions/plugin-dev/skills/hook-development/scripts/README.md +181 -0
- package/extensions/plugin-dev/skills/hook-development/scripts/hook-linter.sh +153 -0
- package/extensions/plugin-dev/skills/hook-development/scripts/test-hook.sh +276 -0
- package/extensions/plugin-dev/skills/hook-development/scripts/validate-hook-schema.sh +159 -0
- package/extensions/plugin-dev/skills/mcp-integration/SKILL.md +775 -0
- package/extensions/plugin-dev/skills/mcp-integration/examples/http-server.json +20 -0
- package/extensions/plugin-dev/skills/mcp-integration/examples/sse-server.json +19 -0
- package/extensions/plugin-dev/skills/mcp-integration/examples/stdio-server.json +38 -0
- package/extensions/plugin-dev/skills/mcp-integration/examples/ws-server.json +26 -0
- package/extensions/plugin-dev/skills/mcp-integration/references/authentication.md +601 -0
- package/extensions/plugin-dev/skills/mcp-integration/references/server-discovery.md +190 -0
- package/extensions/plugin-dev/skills/mcp-integration/references/server-types.md +572 -0
- package/extensions/plugin-dev/skills/mcp-integration/references/tool-usage.md +623 -0
- package/extensions/plugin-dev/skills/plugin-dev-guide/SKILL.md +222 -0
- package/extensions/plugin-dev/skills/plugin-structure/SKILL.md +705 -0
- package/extensions/plugin-dev/skills/plugin-structure/examples/advanced-plugin.md +774 -0
- package/extensions/plugin-dev/skills/plugin-structure/examples/minimal-plugin.md +83 -0
- package/extensions/plugin-dev/skills/plugin-structure/examples/standard-plugin.md +611 -0
- package/extensions/plugin-dev/skills/plugin-structure/references/advanced-topics.md +289 -0
- package/extensions/plugin-dev/skills/plugin-structure/references/component-patterns.md +592 -0
- package/extensions/plugin-dev/skills/plugin-structure/references/github-actions.md +233 -0
- package/extensions/plugin-dev/skills/plugin-structure/references/headless-ci-mode.md +193 -0
- package/extensions/plugin-dev/skills/plugin-structure/references/manifest-reference.md +625 -0
- package/extensions/plugin-dev/skills/plugin-structure/references/output-styles.md +116 -0
- package/extensions/plugin-dev/skills/skill-development/SKILL.md +564 -0
- package/extensions/plugin-dev/skills/skill-development/examples/complete-skill.md +465 -0
- package/extensions/plugin-dev/skills/skill-development/examples/frontmatter-templates.md +167 -0
- package/extensions/plugin-dev/skills/skill-development/examples/minimal-skill.md +111 -0
- package/extensions/plugin-dev/skills/skill-development/references/advanced-frontmatter.md +225 -0
- package/extensions/plugin-dev/skills/skill-development/references/commands-vs-skills.md +39 -0
- package/extensions/plugin-dev/skills/skill-development/references/skill-creation-workflow.md +379 -0
- package/extensions/plugin-dev/skills/skill-development/references/skill-creator-original.md +210 -0
- package/package.json +8 -11
- package/scripts/enact-extensions.mjs +751 -16
- package/scripts/hooks/session-start-drift-check.mjs +58 -0
- package/scripts/lib/build-index.mjs +50 -0
- package/scripts/lib/bundle-hash.mjs +137 -0
- package/scripts/lib/hooks.mjs +389 -0
- package/scripts/lib/ledger.mjs +162 -0
- package/scripts/lib/list-bundles.mjs +70 -0
- package/scripts/lib/outdated.mjs +144 -0
- package/scripts/lib/provision-mcp.mjs +369 -0
- package/scripts/lib/resolve-bundle.mjs +121 -0
- package/scripts/lib/run-install.mjs +321 -39
- package/scripts/lib/run-uninstall.mjs +220 -0
- package/scripts/lib/run-update.mjs +152 -0
- package/scripts/lib/run-validate.mjs +12 -18
- package/scripts/lib/serve.mjs +454 -0
- package/scripts/postinstall.mjs +63 -0
- package/scripts/setup-enact-context.sh +2 -2
- package/spec/index.json +59 -0
- package/web/assets/README.md +111 -0
- package/web/assets/logo-full.png +0 -0
- package/web/assets/logo-slim.png +0 -0
- package/web/assets/tokens/base.css +45 -0
- package/web/assets/tokens/colors.css +248 -0
- package/web/assets/tokens/effects.css +24 -0
- package/web/assets/tokens/fonts.css +8 -0
- package/web/assets/tokens/index.css +18 -0
- package/web/assets/tokens/spacing.css +50 -0
- package/web/index.html +1188 -0
- package/.agents/plugins/marketplace.json +0 -20
- package/catalog/enact-context.json +0 -9
- package/catalog/enact-factory.json +0 -7
- package/catalog/enact-operator.json +0 -7
- package/catalog/enact-wiki.json +0 -7
- package/catalog/net-revenue-management.json +0 -8
- package/scripts/rename-supervisor-to-operator.pl +0 -66
- package/scripts/sync-manifests.mjs +0 -23
- package/scripts/validate-catalog.mjs +0 -37
- package/scripts/validate-plugin.mjs +0 -10
- /package/{plugins → extensions}/net-revenue-management/.mcp.json +0 -0
- /package/{plugins → extensions}/net-revenue-management/skills/net-revenue-risks/SKILL.md +0 -0
- /package/{plugins → extensions}/net-revenue-management/skills/net-revenue-scenario/SKILL.md +0 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Agent Trigger Test Helper
|
|
3
|
+
# Extracts triggering examples and validates example block formatting
|
|
4
|
+
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
|
|
7
|
+
# Usage
|
|
8
|
+
if [ $# -eq 0 ]; then
|
|
9
|
+
echo "Usage: $0 <path/to/agent.md>"
|
|
10
|
+
echo ""
|
|
11
|
+
echo "This script helps test agent triggering by:"
|
|
12
|
+
echo " - Extracting <example> blocks from description"
|
|
13
|
+
echo " - Parsing user phrases that should trigger the agent"
|
|
14
|
+
echo " - Validating example block formatting"
|
|
15
|
+
echo " - Providing manual testing guidance"
|
|
16
|
+
exit 1
|
|
17
|
+
fi
|
|
18
|
+
|
|
19
|
+
AGENT_FILE="$1"
|
|
20
|
+
|
|
21
|
+
echo "🔍 Analyzing agent triggers: $AGENT_FILE"
|
|
22
|
+
echo ""
|
|
23
|
+
|
|
24
|
+
# Check file exists
|
|
25
|
+
if [ ! -f "$AGENT_FILE" ]; then
|
|
26
|
+
echo "❌ File not found: $AGENT_FILE"
|
|
27
|
+
exit 1
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
# Check frontmatter exists
|
|
31
|
+
FIRST_LINE=$(head -1 "$AGENT_FILE")
|
|
32
|
+
if [ "$FIRST_LINE" != "---" ]; then
|
|
33
|
+
echo "❌ File must start with YAML frontmatter (---)"
|
|
34
|
+
exit 1
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
# Extract agent name
|
|
38
|
+
NAME=$(sed -n '/^---$/,/^---$/p' "$AGENT_FILE" | grep '^name:' | sed 's/name: *//' | sed 's/^"\(.*\)"$/\1/' | head -1)
|
|
39
|
+
|
|
40
|
+
if [ -z "$NAME" ]; then
|
|
41
|
+
echo "❌ Could not extract agent name"
|
|
42
|
+
exit 1
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
echo "📋 Agent: $NAME"
|
|
46
|
+
echo ""
|
|
47
|
+
|
|
48
|
+
# Extract full frontmatter section
|
|
49
|
+
FRONTMATTER=$(awk '
|
|
50
|
+
/^---$/ { count++; next }
|
|
51
|
+
count == 1 { print }
|
|
52
|
+
' "$AGENT_FILE")
|
|
53
|
+
|
|
54
|
+
# Extract description - handles multi-line YAML
|
|
55
|
+
# Description ends when we hit another top-level field (model:, color:, tools:, etc.)
|
|
56
|
+
DESCRIPTION=$(echo "$FRONTMATTER" | awk '
|
|
57
|
+
/^description:/ {
|
|
58
|
+
in_desc = 1
|
|
59
|
+
sub(/^description: */, "")
|
|
60
|
+
if ($0 != "") print
|
|
61
|
+
next
|
|
62
|
+
}
|
|
63
|
+
in_desc && /^(model|color|tools|name):/ { exit }
|
|
64
|
+
in_desc { print }
|
|
65
|
+
')
|
|
66
|
+
|
|
67
|
+
if [ -z "$DESCRIPTION" ]; then
|
|
68
|
+
echo "❌ Could not extract description"
|
|
69
|
+
exit 1
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
# Count example blocks
|
|
73
|
+
EXAMPLE_COUNT=$(echo "$DESCRIPTION" | grep -c '<example>' 2>/dev/null || echo 0)
|
|
74
|
+
|
|
75
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
76
|
+
echo "📊 EXAMPLE ANALYSIS"
|
|
77
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
78
|
+
echo ""
|
|
79
|
+
|
|
80
|
+
if [ "$EXAMPLE_COUNT" -eq 0 ]; then
|
|
81
|
+
echo "⚠️ No <example> blocks found in description"
|
|
82
|
+
echo ""
|
|
83
|
+
echo "Agent descriptions should include 2-4 example blocks showing"
|
|
84
|
+
echo "when the agent should be triggered."
|
|
85
|
+
echo ""
|
|
86
|
+
echo "Example format:"
|
|
87
|
+
echo " <example>"
|
|
88
|
+
echo " Context: [Scenario description]"
|
|
89
|
+
echo ' user: "[User request]"'
|
|
90
|
+
echo ' assistant: "[How Claude responds]"'
|
|
91
|
+
echo " <commentary>"
|
|
92
|
+
echo " [Why this triggers the agent]"
|
|
93
|
+
echo " </commentary>"
|
|
94
|
+
echo " </example>"
|
|
95
|
+
exit 1
|
|
96
|
+
fi
|
|
97
|
+
|
|
98
|
+
echo "Found $EXAMPLE_COUNT example block(s)"
|
|
99
|
+
echo ""
|
|
100
|
+
|
|
101
|
+
# Extract and display each example
|
|
102
|
+
# Use awk to extract example blocks
|
|
103
|
+
echo "$DESCRIPTION" | awk '
|
|
104
|
+
/<example>/ { in_example=1; example=""; next }
|
|
105
|
+
/<\/example>/ {
|
|
106
|
+
in_example=0
|
|
107
|
+
example_num++
|
|
108
|
+
print "───────────────────────────────────────"
|
|
109
|
+
print "Example " example_num ":"
|
|
110
|
+
print "───────────────────────────────────────"
|
|
111
|
+
print example
|
|
112
|
+
print ""
|
|
113
|
+
next
|
|
114
|
+
}
|
|
115
|
+
in_example { example = example $0 "\n" }
|
|
116
|
+
' | while IFS= read -r line; do
|
|
117
|
+
echo "$line"
|
|
118
|
+
done
|
|
119
|
+
|
|
120
|
+
echo ""
|
|
121
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
122
|
+
echo "🎯 TRIGGER PHRASES"
|
|
123
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
124
|
+
echo ""
|
|
125
|
+
|
|
126
|
+
# Initialize warning counter early (used across sections)
|
|
127
|
+
warning_count=0
|
|
128
|
+
|
|
129
|
+
# Extract user phrases from examples
|
|
130
|
+
USER_PHRASES=$(echo "$DESCRIPTION" | grep -oE 'user: *"[^"]*"' | sed 's/user: *"//' | sed 's/"$//' || true)
|
|
131
|
+
|
|
132
|
+
if [ -z "$USER_PHRASES" ]; then
|
|
133
|
+
echo "⚠️ Could not extract user phrases from examples"
|
|
134
|
+
echo ""
|
|
135
|
+
echo "Make sure examples include 'user: \"phrase\"' format"
|
|
136
|
+
((warning_count++))
|
|
137
|
+
else
|
|
138
|
+
echo "Use these phrases to test agent triggering:"
|
|
139
|
+
echo ""
|
|
140
|
+
echo "$USER_PHRASES" | while IFS= read -r phrase; do
|
|
141
|
+
echo " → $phrase"
|
|
142
|
+
done
|
|
143
|
+
fi
|
|
144
|
+
|
|
145
|
+
echo ""
|
|
146
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
147
|
+
echo "✅ VALIDATION"
|
|
148
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
149
|
+
echo ""
|
|
150
|
+
|
|
151
|
+
# Check for "Use this agent when" pattern
|
|
152
|
+
if ! echo "$DESCRIPTION" | grep -qi 'use this agent when'; then
|
|
153
|
+
echo "⚠️ Description should start with 'Use this agent when...'"
|
|
154
|
+
((warning_count++))
|
|
155
|
+
else
|
|
156
|
+
echo "✅ Has 'Use this agent when' pattern"
|
|
157
|
+
fi
|
|
158
|
+
|
|
159
|
+
# Check example count
|
|
160
|
+
if [ "$EXAMPLE_COUNT" -lt 2 ]; then
|
|
161
|
+
echo "⚠️ Only $EXAMPLE_COUNT example(s) - recommend 2-4 examples"
|
|
162
|
+
((warning_count++))
|
|
163
|
+
elif [ "$EXAMPLE_COUNT" -gt 4 ]; then
|
|
164
|
+
echo "⚠️ $EXAMPLE_COUNT examples - consider trimming to 2-4"
|
|
165
|
+
((warning_count++))
|
|
166
|
+
else
|
|
167
|
+
echo "✅ Good number of examples ($EXAMPLE_COUNT)"
|
|
168
|
+
fi
|
|
169
|
+
|
|
170
|
+
# Check for commentary in examples
|
|
171
|
+
COMMENTARY_COUNT=$(echo "$DESCRIPTION" | grep -c '<commentary>' 2>/dev/null || echo 0)
|
|
172
|
+
COMMENTARY_COUNT=$(echo "$COMMENTARY_COUNT" | tr -d '[:space:]')
|
|
173
|
+
if [ "$COMMENTARY_COUNT" -lt "$EXAMPLE_COUNT" ]; then
|
|
174
|
+
echo "⚠️ Some examples missing <commentary> blocks"
|
|
175
|
+
((warning_count++))
|
|
176
|
+
else
|
|
177
|
+
echo "✅ All examples have commentary"
|
|
178
|
+
fi
|
|
179
|
+
|
|
180
|
+
# Check for Context in examples
|
|
181
|
+
CONTEXT_COUNT=$(echo "$DESCRIPTION" | grep -ci 'context:' 2>/dev/null || echo 0)
|
|
182
|
+
CONTEXT_COUNT=$(echo "$CONTEXT_COUNT" | tr -d '[:space:]')
|
|
183
|
+
if [ "$CONTEXT_COUNT" -lt "$EXAMPLE_COUNT" ]; then
|
|
184
|
+
echo "⚠️ Some examples missing Context: lines"
|
|
185
|
+
((warning_count++))
|
|
186
|
+
else
|
|
187
|
+
echo "✅ All examples have context"
|
|
188
|
+
fi
|
|
189
|
+
|
|
190
|
+
# Check for assistant responses
|
|
191
|
+
ASSISTANT_COUNT=$(echo "$DESCRIPTION" | grep -c 'assistant:' 2>/dev/null || echo 0)
|
|
192
|
+
ASSISTANT_COUNT=$(echo "$ASSISTANT_COUNT" | tr -d '[:space:]')
|
|
193
|
+
if [ "$ASSISTANT_COUNT" -lt "$EXAMPLE_COUNT" ]; then
|
|
194
|
+
echo "⚠️ Some examples missing assistant: responses"
|
|
195
|
+
((warning_count++))
|
|
196
|
+
else
|
|
197
|
+
echo "✅ All examples have assistant responses"
|
|
198
|
+
fi
|
|
199
|
+
|
|
200
|
+
echo ""
|
|
201
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
202
|
+
echo "📖 MANUAL TESTING GUIDE"
|
|
203
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
204
|
+
echo ""
|
|
205
|
+
echo "To test agent triggering:"
|
|
206
|
+
echo ""
|
|
207
|
+
echo "1. Load your plugin in Claude Code:"
|
|
208
|
+
echo " claude --plugin-dir /path/to/plugin"
|
|
209
|
+
echo ""
|
|
210
|
+
echo "2. Try the trigger phrases listed above"
|
|
211
|
+
echo ""
|
|
212
|
+
echo "3. Verify Claude loads the agent (look for agent indicator)"
|
|
213
|
+
echo ""
|
|
214
|
+
echo "4. Test variations of the phrases to ensure robust triggering"
|
|
215
|
+
echo ""
|
|
216
|
+
echo "5. Test negative cases - phrases that should NOT trigger"
|
|
217
|
+
echo ""
|
|
218
|
+
|
|
219
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
220
|
+
|
|
221
|
+
if [ "$warning_count" -eq 0 ]; then
|
|
222
|
+
echo "✅ All validations passed!"
|
|
223
|
+
exit 0
|
|
224
|
+
else
|
|
225
|
+
echo "⚠️ Completed with $warning_count warning(s)"
|
|
226
|
+
exit 0
|
|
227
|
+
fi
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Agent File Validator
|
|
3
|
+
# Validates agent markdown files for correct structure and content
|
|
4
|
+
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
|
|
7
|
+
# Usage
|
|
8
|
+
if [ $# -eq 0 ]; then
|
|
9
|
+
echo "Usage: $0 <path/to/agent.md>"
|
|
10
|
+
echo ""
|
|
11
|
+
echo "Validates agent file for:"
|
|
12
|
+
echo " - YAML frontmatter structure"
|
|
13
|
+
echo " - Required fields (name, description, model, color)"
|
|
14
|
+
echo " - Field formats and constraints"
|
|
15
|
+
echo " - System prompt presence and length"
|
|
16
|
+
echo " - Example blocks in description"
|
|
17
|
+
exit 1
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
AGENT_FILE="$1"
|
|
21
|
+
|
|
22
|
+
echo "🔍 Validating agent file: $AGENT_FILE"
|
|
23
|
+
echo ""
|
|
24
|
+
|
|
25
|
+
# Check 1: File exists
|
|
26
|
+
if [ ! -f "$AGENT_FILE" ]; then
|
|
27
|
+
echo "❌ File not found: $AGENT_FILE"
|
|
28
|
+
exit 1
|
|
29
|
+
fi
|
|
30
|
+
echo "✅ File exists"
|
|
31
|
+
|
|
32
|
+
# Check 2: Starts with ---
|
|
33
|
+
FIRST_LINE=$(head -1 "$AGENT_FILE")
|
|
34
|
+
if [ "$FIRST_LINE" != "---" ]; then
|
|
35
|
+
echo "❌ File must start with YAML frontmatter (---)"
|
|
36
|
+
exit 1
|
|
37
|
+
fi
|
|
38
|
+
echo "✅ Starts with frontmatter"
|
|
39
|
+
|
|
40
|
+
# Check 3: Has closing ---
|
|
41
|
+
if ! tail -n +2 "$AGENT_FILE" | grep -q '^---$'; then
|
|
42
|
+
echo "❌ Frontmatter not closed (missing second ---)"
|
|
43
|
+
exit 1
|
|
44
|
+
fi
|
|
45
|
+
echo "✅ Frontmatter properly closed"
|
|
46
|
+
|
|
47
|
+
# Extract frontmatter and system prompt
|
|
48
|
+
FRONTMATTER=$(sed -n '/^---$/,/^---$/{ /^---$/d; p; }' "$AGENT_FILE")
|
|
49
|
+
SYSTEM_PROMPT=$(awk '/^---$/{i++; next} i>=2' "$AGENT_FILE")
|
|
50
|
+
|
|
51
|
+
# Check 4: Required fields
|
|
52
|
+
echo ""
|
|
53
|
+
echo "Checking required fields..."
|
|
54
|
+
|
|
55
|
+
error_count=0
|
|
56
|
+
warning_count=0
|
|
57
|
+
|
|
58
|
+
# Check name field
|
|
59
|
+
NAME=$(echo "$FRONTMATTER" | grep '^name:' | sed 's/name: *//' | sed 's/^"\(.*\)"$/\1/')
|
|
60
|
+
|
|
61
|
+
if [ -z "$NAME" ]; then
|
|
62
|
+
echo "❌ Missing required field: name"
|
|
63
|
+
((error_count++))
|
|
64
|
+
else
|
|
65
|
+
echo "✅ name: $NAME"
|
|
66
|
+
|
|
67
|
+
# Validate name format
|
|
68
|
+
if ! [[ "$NAME" =~ ^[a-z0-9][a-z0-9-]*[a-z0-9]$ ]]; then
|
|
69
|
+
echo "❌ name must start/end with lowercase alphanumeric and contain only lowercase letters, numbers, hyphens"
|
|
70
|
+
((error_count++))
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
# Validate name length
|
|
74
|
+
name_length=${#NAME}
|
|
75
|
+
if [ "$name_length" -lt 3 ]; then
|
|
76
|
+
echo "❌ name too short (minimum 3 characters)"
|
|
77
|
+
((error_count++))
|
|
78
|
+
elif [ "$name_length" -gt 50 ]; then
|
|
79
|
+
echo "❌ name too long (maximum 50 characters)"
|
|
80
|
+
((error_count++))
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
# Check for generic names
|
|
84
|
+
if [[ "$NAME" =~ ^(helper|assistant|agent|tool)$ ]]; then
|
|
85
|
+
echo "⚠️ name is too generic: $NAME"
|
|
86
|
+
((warning_count++))
|
|
87
|
+
fi
|
|
88
|
+
fi
|
|
89
|
+
|
|
90
|
+
# Check description field - handles multi-line YAML
|
|
91
|
+
# Description ends when we hit another top-level field (model:, color:, tools:, name:)
|
|
92
|
+
DESCRIPTION=$(echo "$FRONTMATTER" | awk '
|
|
93
|
+
/^description:/ {
|
|
94
|
+
in_desc = 1
|
|
95
|
+
sub(/^description: */, "")
|
|
96
|
+
if ($0 != "") print
|
|
97
|
+
next
|
|
98
|
+
}
|
|
99
|
+
in_desc && /^(model|color|tools|name):/ { exit }
|
|
100
|
+
in_desc { print }
|
|
101
|
+
')
|
|
102
|
+
|
|
103
|
+
if [ -z "$DESCRIPTION" ]; then
|
|
104
|
+
echo "❌ Missing required field: description"
|
|
105
|
+
((error_count++))
|
|
106
|
+
else
|
|
107
|
+
desc_length=${#DESCRIPTION}
|
|
108
|
+
echo "✅ description: ${desc_length} characters"
|
|
109
|
+
|
|
110
|
+
if [ "$desc_length" -lt 10 ]; then
|
|
111
|
+
echo "⚠️ description too short (minimum 10 characters recommended)"
|
|
112
|
+
((warning_count++))
|
|
113
|
+
elif [ "$desc_length" -gt 5000 ]; then
|
|
114
|
+
echo "⚠️ description very long (over 5000 characters)"
|
|
115
|
+
((warning_count++))
|
|
116
|
+
fi
|
|
117
|
+
|
|
118
|
+
# Check for example blocks
|
|
119
|
+
if ! echo "$DESCRIPTION" | grep -q '<example>'; then
|
|
120
|
+
echo "⚠️ description should include <example> blocks for triggering"
|
|
121
|
+
((warning_count++))
|
|
122
|
+
fi
|
|
123
|
+
|
|
124
|
+
# Check for "Use this agent when" pattern
|
|
125
|
+
if ! echo "$DESCRIPTION" | grep -qi 'use this agent when'; then
|
|
126
|
+
echo "⚠️ description should start with 'Use this agent when...'"
|
|
127
|
+
((warning_count++))
|
|
128
|
+
fi
|
|
129
|
+
fi
|
|
130
|
+
|
|
131
|
+
# Check model field
|
|
132
|
+
MODEL=$(echo "$FRONTMATTER" | grep '^model:' | sed 's/model: *//')
|
|
133
|
+
|
|
134
|
+
if [ -z "$MODEL" ]; then
|
|
135
|
+
echo "❌ Missing required field: model"
|
|
136
|
+
((error_count++))
|
|
137
|
+
else
|
|
138
|
+
echo "✅ model: $MODEL"
|
|
139
|
+
|
|
140
|
+
case "$MODEL" in
|
|
141
|
+
inherit|sonnet|opus|haiku)
|
|
142
|
+
# Valid model
|
|
143
|
+
;;
|
|
144
|
+
*)
|
|
145
|
+
echo "⚠️ Unknown model: $MODEL (valid: inherit, sonnet, opus, haiku)"
|
|
146
|
+
((warning_count++))
|
|
147
|
+
;;
|
|
148
|
+
esac
|
|
149
|
+
fi
|
|
150
|
+
|
|
151
|
+
# Check color field
|
|
152
|
+
COLOR=$(echo "$FRONTMATTER" | grep '^color:' | sed 's/color: *//')
|
|
153
|
+
|
|
154
|
+
if [ -z "$COLOR" ]; then
|
|
155
|
+
echo "❌ Missing required field: color"
|
|
156
|
+
((error_count++))
|
|
157
|
+
else
|
|
158
|
+
echo "✅ color: $COLOR"
|
|
159
|
+
|
|
160
|
+
case "$COLOR" in
|
|
161
|
+
blue|cyan|green|yellow|magenta|red)
|
|
162
|
+
# Valid color
|
|
163
|
+
;;
|
|
164
|
+
*)
|
|
165
|
+
echo "⚠️ Unknown color: $COLOR (valid: blue, cyan, green, yellow, magenta, red)"
|
|
166
|
+
((warning_count++))
|
|
167
|
+
;;
|
|
168
|
+
esac
|
|
169
|
+
fi
|
|
170
|
+
|
|
171
|
+
# Check tools field (optional)
|
|
172
|
+
TOOLS=$(echo "$FRONTMATTER" | grep '^tools:' | sed 's/tools: *//')
|
|
173
|
+
|
|
174
|
+
if [ -n "$TOOLS" ]; then
|
|
175
|
+
echo "✅ tools: $TOOLS"
|
|
176
|
+
else
|
|
177
|
+
echo "💡 tools: not specified (agent has access to all tools)"
|
|
178
|
+
fi
|
|
179
|
+
|
|
180
|
+
# Check 5: System prompt
|
|
181
|
+
echo ""
|
|
182
|
+
echo "Checking system prompt..."
|
|
183
|
+
|
|
184
|
+
if [ -z "$SYSTEM_PROMPT" ]; then
|
|
185
|
+
echo "❌ System prompt is empty"
|
|
186
|
+
((error_count++))
|
|
187
|
+
else
|
|
188
|
+
prompt_length=${#SYSTEM_PROMPT}
|
|
189
|
+
echo "✅ System prompt: $prompt_length characters"
|
|
190
|
+
|
|
191
|
+
if [ "$prompt_length" -lt 20 ]; then
|
|
192
|
+
echo "❌ System prompt too short (minimum 20 characters)"
|
|
193
|
+
((error_count++))
|
|
194
|
+
elif [ "$prompt_length" -gt 10000 ]; then
|
|
195
|
+
echo "⚠️ System prompt very long (over 10,000 characters)"
|
|
196
|
+
((warning_count++))
|
|
197
|
+
fi
|
|
198
|
+
|
|
199
|
+
# Check for second person
|
|
200
|
+
if ! echo "$SYSTEM_PROMPT" | grep -Eq "You are|You will|Your"; then
|
|
201
|
+
echo "⚠️ System prompt should use second person (You are..., You will...)"
|
|
202
|
+
((warning_count++))
|
|
203
|
+
fi
|
|
204
|
+
|
|
205
|
+
# Check for structure
|
|
206
|
+
if ! echo "$SYSTEM_PROMPT" | grep -Eqi "responsibilities|process|steps"; then
|
|
207
|
+
echo "💡 Consider adding clear responsibilities or process steps"
|
|
208
|
+
fi
|
|
209
|
+
|
|
210
|
+
if ! echo "$SYSTEM_PROMPT" | grep -qi "output"; then
|
|
211
|
+
echo "💡 Consider defining output format expectations"
|
|
212
|
+
fi
|
|
213
|
+
fi
|
|
214
|
+
|
|
215
|
+
echo ""
|
|
216
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
217
|
+
|
|
218
|
+
if [ $error_count -eq 0 ] && [ $warning_count -eq 0 ]; then
|
|
219
|
+
echo "✅ All checks passed!"
|
|
220
|
+
exit 0
|
|
221
|
+
elif [ $error_count -eq 0 ]; then
|
|
222
|
+
echo "⚠️ Validation passed with $warning_count warning(s)"
|
|
223
|
+
exit 0
|
|
224
|
+
else
|
|
225
|
+
echo "❌ Validation failed with $error_count error(s) and $warning_count warning(s)"
|
|
226
|
+
exit 1
|
|
227
|
+
fi
|