@amsterdamdatalabs/enact-extensions 0.1.5 → 0.1.8
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 +2 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/install.d.ts.map +1 -1
- package/dist/install.js +15 -1
- package/dist/install.js.map +1 -1
- package/dist/internal/agents.d.ts +29 -0
- package/dist/internal/agents.d.ts.map +1 -0
- package/dist/internal/agents.js +83 -0
- package/dist/internal/agents.js.map +1 -0
- package/extensions/enact-context/hooks/hooks.json +20 -0
- package/extensions/enact-core/.agents/plugin.json +39 -0
- package/extensions/enact-core/hooks/hooks.json +14 -0
- package/extensions/enact-factory/.agents/plugin.json +9 -3
- package/extensions/enact-factory/agents/architect.toml +30 -0
- package/extensions/enact-factory/agents/code-reviewer.toml +29 -0
- package/extensions/enact-factory/agents/critic.toml +35 -0
- package/extensions/enact-factory/agents/executor.toml +23 -0
- package/extensions/enact-factory/agents/explore.toml +22 -0
- package/extensions/enact-factory/agents/planner.toml +23 -0
- package/extensions/enact-factory/agents/verifier.toml +29 -0
- package/extensions/enact-factory/skills/ai-slop-cleaner/SKILL.md +52 -0
- package/extensions/enact-factory/skills/azdo-ci-strategy/SKILL.md +262 -0
- package/extensions/enact-factory/skills/azdo-ci-strategy/references/build-failures.md +60 -0
- package/extensions/enact-factory/skills/azdo-ci-strategy/references/cli-reference.md +87 -0
- package/extensions/enact-factory/skills/azdo-ci-strategy/references/policies-and-pipelines.md +132 -0
- package/extensions/enact-factory/skills/azdo-ci-strategy/references/troubleshooting.md +53 -0
- package/extensions/enact-factory/skills/deep-interview/SKILL.md +72 -0
- package/extensions/enact-factory/skills/drive-loop/SKILL.md +259 -0
- package/extensions/enact-factory/skills/drive-loop/references/contract-schema.md +107 -0
- package/extensions/enact-factory/skills/hyperplan/SKILL.md +51 -0
- package/extensions/enact-factory/skills/looplan/SKILL.md +103 -0
- package/extensions/enact-factory/skills/plan/SKILL.md +71 -0
- package/extensions/enact-factory/skills/remove-deadcode/SKILL.md +41 -0
- package/extensions/enact-factory/skills/research/SKILL.md +73 -0
- package/extensions/enact-factory/skills/review/SKILL.md +48 -0
- package/extensions/enact-factory/skills/security-research/SKILL.md +54 -0
- package/extensions/enact-factory/skills/tdd/SKILL.md +56 -0
- package/extensions/enact-factory/skills/trace/SKILL.md +37 -0
- package/extensions/enact-factory/skills/ultraqa/SKILL.md +79 -0
- package/extensions/enact-factory/skills/work-with-workitem/SKILL.md +51 -0
- package/extensions/enact-factory/skills/workitem-triage/SKILL.md +15 -0
- package/extensions/enact-loop/.agents/plugin.json +46 -0
- package/extensions/enact-loop/.mcp.json +1 -0
- package/extensions/enact-loop/hooks/hooks.json +27 -0
- package/extensions/enact-loop/skills/enact-loop/SKILL.md +327 -0
- package/extensions/enact-operator/.agents/plugin.json +0 -1
- package/extensions/enact-operator/hooks/hooks.json +0 -35
- package/extensions/enact-wiki/skills/wiki/SKILL.md +42 -0
- package/extensions/plugin-dev/.agents/plugin.json +4 -6
- package/extensions/plugin-dev/agents/plugin-validator.md +1 -1
- package/extensions/plugin-dev/skills/agent-development/SKILL.md +7 -7
- package/extensions/plugin-dev/{commands/create-plugin.md → skills/create-plugin/SKILL.md} +44 -37
- package/extensions/plugin-dev/skills/plugin-dev-guide/SKILL.md +13 -14
- package/extensions/plugin-dev/skills/skill-development/SKILL.md +0 -2
- package/extensions/plugin-dev/{commands/start.md → skills/start/SKILL.md} +7 -6
- package/package.json +11 -6
- package/scripts/check-hooks.mjs +174 -0
- package/scripts/check-principles.mjs +101 -0
- package/scripts/enact-extensions.mjs +87 -3
- package/scripts/lib/run-validate.mjs +36 -2
- package/scripts/lib/ups-router.mjs +432 -0
- package/spec/enact.json +4 -0
- package/spec/enact.md +5 -2
- package/extensions/cmux/.agents/plugin.json +0 -37
- package/extensions/cmux/skills/cmux/SKILL.md +0 -82
- package/extensions/cmux/skills/cmux/agents/openai.yaml +0 -4
- package/extensions/cmux/skills/cmux/references/handles-and-identify.md +0 -35
- package/extensions/cmux/skills/cmux/references/panes-surfaces.md +0 -37
- package/extensions/cmux/skills/cmux/references/trigger-flash-and-health.md +0 -23
- package/extensions/cmux/skills/cmux/references/windows-workspaces.md +0 -31
- package/extensions/cmux/skills/cmux-vm-monitor/SKILL.md +0 -122
- package/extensions/cmux/skills/cmux-vm-monitor/agents/openai.yaml +0 -4
- package/extensions/cmux/skills/cmux-vm-monitor/references/cmux-commands.md +0 -66
- package/extensions/cmux/skills/cmux-vm-monitor/scripts/codex_vm_monitor.sh +0 -45
- package/extensions/cmux/skills/cmux-workspace/SKILL.md +0 -93
- package/extensions/devops/.agents/plugin.json +0 -36
- package/extensions/devops/skills/azure-devops-cli/SKILL.md +0 -431
- package/extensions/devops/skills/azure-devops-cli/agents/openai.yaml +0 -4
- package/extensions/devops/skills/ci-pipeline-strategy/SKILL.md +0 -217
- package/extensions/devops/skills/ci-pipeline-strategy/agents/openai.yaml +0 -4
- package/extensions/enact-factory/hooks/user-prompt-submit.mjs +0 -67
- package/extensions/enact-operator/commands/doctor.md +0 -39
- package/extensions/enact-operator/commands/setup.md +0 -51
- package/extensions/plugin-dev/.mcp.json +0 -3
- package/extensions/plugin-dev/commands/_archive/create-marketplace.md +0 -427
- package/extensions/plugin-dev/commands/_archive/plugin-dev-guide.md +0 -12
- package/extensions/plugin-dev/hooks/hooks.json +0 -3
- package/extensions/plugin-dev/skills/command-development/SKILL.md +0 -763
- package/extensions/plugin-dev/skills/command-development/examples/plugin-commands.md +0 -612
- package/extensions/plugin-dev/skills/command-development/examples/simple-commands.md +0 -527
- package/extensions/plugin-dev/skills/command-development/references/advanced-workflows.md +0 -762
- package/extensions/plugin-dev/skills/command-development/references/documentation-patterns.md +0 -769
- package/extensions/plugin-dev/skills/command-development/references/frontmatter-reference.md +0 -508
- package/extensions/plugin-dev/skills/command-development/references/interactive-commands.md +0 -966
- package/extensions/plugin-dev/skills/command-development/references/marketplace-considerations.md +0 -943
- package/extensions/plugin-dev/skills/command-development/references/plugin-features-reference.md +0 -637
- package/extensions/plugin-dev/skills/command-development/references/plugin-integration.md +0 -191
- package/extensions/plugin-dev/skills/command-development/references/skill-tool.md +0 -447
- package/extensions/plugin-dev/skills/command-development/references/testing-strategies.md +0 -723
- package/extensions/plugin-dev/skills/command-development/scripts/check-frontmatter.sh +0 -234
- package/extensions/plugin-dev/skills/command-development/scripts/validate-command.sh +0 -160
- /package/extensions/enact-operator/{skills/_variants.md → docs/skill-variants.md} +0 -0
|
@@ -1,234 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# Command Frontmatter Validator
|
|
3
|
-
# Validates YAML frontmatter fields in command files
|
|
4
|
-
|
|
5
|
-
set -euo pipefail
|
|
6
|
-
|
|
7
|
-
# Usage
|
|
8
|
-
if [ $# -eq 0 ]; then
|
|
9
|
-
echo "Usage: $0 <path/to/command.md> [command2.md ...]"
|
|
10
|
-
echo ""
|
|
11
|
-
echo "Validates frontmatter fields for:"
|
|
12
|
-
echo " - 'model' field (sonnet, opus, haiku, or full model ID)"
|
|
13
|
-
echo " - 'description' length (warns if > 60 chars)"
|
|
14
|
-
echo " - 'allowed-tools' format"
|
|
15
|
-
echo " - 'argument-hint' format"
|
|
16
|
-
echo " - 'disable-model-invocation' boolean"
|
|
17
|
-
echo " - Unknown fields (warning)"
|
|
18
|
-
echo ""
|
|
19
|
-
echo "Examples:"
|
|
20
|
-
echo " $0 .claude/commands/review.md"
|
|
21
|
-
echo " $0 commands/*.md"
|
|
22
|
-
exit 1
|
|
23
|
-
fi
|
|
24
|
-
|
|
25
|
-
# Known frontmatter fields for commands
|
|
26
|
-
KNOWN_FIELDS="description model allowed-tools argument-hint disable-model-invocation"
|
|
27
|
-
|
|
28
|
-
total_errors=0
|
|
29
|
-
total_warnings=0
|
|
30
|
-
|
|
31
|
-
check_frontmatter() {
|
|
32
|
-
local COMMAND_FILE="$1"
|
|
33
|
-
local error_count=0
|
|
34
|
-
local warning_count=0
|
|
35
|
-
|
|
36
|
-
echo "🔍 Checking frontmatter: $COMMAND_FILE"
|
|
37
|
-
echo ""
|
|
38
|
-
|
|
39
|
-
# Check file exists
|
|
40
|
-
if [ ! -f "$COMMAND_FILE" ]; then
|
|
41
|
-
echo "❌ Error: File not found: $COMMAND_FILE"
|
|
42
|
-
return 1
|
|
43
|
-
fi
|
|
44
|
-
|
|
45
|
-
# Check for frontmatter
|
|
46
|
-
if ! head -n 1 "$COMMAND_FILE" | grep -q "^---"; then
|
|
47
|
-
echo "ℹ️ No frontmatter found (frontmatter is optional)"
|
|
48
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
49
|
-
echo "✅ $COMMAND_FILE: No frontmatter to validate"
|
|
50
|
-
echo ""
|
|
51
|
-
return 0
|
|
52
|
-
fi
|
|
53
|
-
|
|
54
|
-
# Extract frontmatter - only the first block between lines 1 and the second ---
|
|
55
|
-
# Use awk to get content between first and second --- markers only
|
|
56
|
-
local frontmatter
|
|
57
|
-
frontmatter=$(awk '
|
|
58
|
-
/^---$/ { count++; if (count == 2) exit; next }
|
|
59
|
-
count == 1 { print }
|
|
60
|
-
' "$COMMAND_FILE")
|
|
61
|
-
|
|
62
|
-
if [ -z "$frontmatter" ]; then
|
|
63
|
-
echo "⚠️ Warning: Empty frontmatter block"
|
|
64
|
-
((warning_count++))
|
|
65
|
-
total_warnings=$((total_warnings + warning_count))
|
|
66
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
67
|
-
echo "⚠️ $COMMAND_FILE: Passed with $warning_count warning(s)"
|
|
68
|
-
echo ""
|
|
69
|
-
return 0
|
|
70
|
-
fi
|
|
71
|
-
|
|
72
|
-
echo "Frontmatter found. Validating fields..."
|
|
73
|
-
echo ""
|
|
74
|
-
|
|
75
|
-
# Check 'model' field
|
|
76
|
-
if echo "$frontmatter" | grep -q "^model:"; then
|
|
77
|
-
local model
|
|
78
|
-
model=$(echo "$frontmatter" | grep "^model:" | cut -d: -f2 | tr -d ' ')
|
|
79
|
-
|
|
80
|
-
# Valid values: sonnet, opus, haiku, or full model ID (claude-*)
|
|
81
|
-
if [[ "$model" =~ ^(sonnet|opus|haiku)$ ]]; then
|
|
82
|
-
echo "✅ model: $model (shorthand)"
|
|
83
|
-
elif [[ "$model" =~ ^claude- ]]; then
|
|
84
|
-
echo "✅ model: $model (full model ID)"
|
|
85
|
-
else
|
|
86
|
-
echo "❌ Error: Invalid model '$model'"
|
|
87
|
-
echo " Valid: sonnet, opus, haiku, or full model ID (e.g., claude-sonnet-4-5-20250929)"
|
|
88
|
-
((error_count++))
|
|
89
|
-
fi
|
|
90
|
-
fi
|
|
91
|
-
|
|
92
|
-
# Check 'description' field
|
|
93
|
-
if echo "$frontmatter" | grep -q "^description:"; then
|
|
94
|
-
local desc
|
|
95
|
-
desc=$(echo "$frontmatter" | grep "^description:" | cut -d: -f2- | sed 's/^ *//')
|
|
96
|
-
local length=${#desc}
|
|
97
|
-
|
|
98
|
-
if [ "$length" -eq 0 ]; then
|
|
99
|
-
echo "⚠️ Warning: Empty description"
|
|
100
|
-
((warning_count++))
|
|
101
|
-
elif [ "$length" -gt 80 ]; then
|
|
102
|
-
echo "⚠️ Warning: Description too long ($length chars, recommend < 60)"
|
|
103
|
-
((warning_count++))
|
|
104
|
-
elif [ "$length" -gt 60 ]; then
|
|
105
|
-
echo "⚠️ Warning: Description length $length (recommend < 60 chars)"
|
|
106
|
-
((warning_count++))
|
|
107
|
-
else
|
|
108
|
-
echo "✅ description: $length chars"
|
|
109
|
-
fi
|
|
110
|
-
fi
|
|
111
|
-
|
|
112
|
-
# Check 'allowed-tools' field
|
|
113
|
-
if echo "$frontmatter" | grep -q "^allowed-tools:"; then
|
|
114
|
-
local tools
|
|
115
|
-
tools=$(echo "$frontmatter" | grep "^allowed-tools:" | cut -d: -f2- | sed 's/^ *//')
|
|
116
|
-
|
|
117
|
-
if [ -z "$tools" ]; then
|
|
118
|
-
echo "⚠️ Warning: Empty allowed-tools field"
|
|
119
|
-
((warning_count++))
|
|
120
|
-
else
|
|
121
|
-
# Check for common patterns
|
|
122
|
-
if [[ "$tools" == "*" ]]; then
|
|
123
|
-
echo "⚠️ Warning: allowed-tools: * grants all tools (consider restricting)"
|
|
124
|
-
((warning_count++))
|
|
125
|
-
elif [[ "$tools" =~ Bash\(\*\) ]]; then
|
|
126
|
-
echo "⚠️ Warning: Bash(*) is very permissive (consider Bash(git:*) or similar)"
|
|
127
|
-
((warning_count++))
|
|
128
|
-
else
|
|
129
|
-
echo "✅ allowed-tools: $tools"
|
|
130
|
-
fi
|
|
131
|
-
fi
|
|
132
|
-
fi
|
|
133
|
-
|
|
134
|
-
# Check 'argument-hint' field
|
|
135
|
-
if echo "$frontmatter" | grep -q "^argument-hint:"; then
|
|
136
|
-
local hint
|
|
137
|
-
hint=$(echo "$frontmatter" | grep "^argument-hint:" | cut -d: -f2- | sed 's/^ *//')
|
|
138
|
-
|
|
139
|
-
if [ -z "$hint" ]; then
|
|
140
|
-
echo "⚠️ Warning: Empty argument-hint field"
|
|
141
|
-
((warning_count++))
|
|
142
|
-
else
|
|
143
|
-
# Check for bracket convention
|
|
144
|
-
if [[ ! "$hint" =~ \[.*\] ]]; then
|
|
145
|
-
echo "⚠️ Warning: argument-hint missing bracket convention (e.g., [arg-name])"
|
|
146
|
-
((warning_count++))
|
|
147
|
-
else
|
|
148
|
-
echo "✅ argument-hint: $hint"
|
|
149
|
-
fi
|
|
150
|
-
fi
|
|
151
|
-
fi
|
|
152
|
-
|
|
153
|
-
# Check 'disable-model-invocation' field
|
|
154
|
-
if echo "$frontmatter" | grep -q "^disable-model-invocation:"; then
|
|
155
|
-
local value
|
|
156
|
-
value=$(echo "$frontmatter" | grep "^disable-model-invocation:" | cut -d: -f2 | tr -d ' ')
|
|
157
|
-
|
|
158
|
-
if [[ "$value" =~ ^(true|false)$ ]]; then
|
|
159
|
-
echo "✅ disable-model-invocation: $value"
|
|
160
|
-
else
|
|
161
|
-
echo "❌ Error: disable-model-invocation must be true or false (got '$value')"
|
|
162
|
-
((error_count++))
|
|
163
|
-
fi
|
|
164
|
-
fi
|
|
165
|
-
|
|
166
|
-
# Check for unknown fields
|
|
167
|
-
echo ""
|
|
168
|
-
echo "Checking for unknown fields..."
|
|
169
|
-
local unknown_found=false
|
|
170
|
-
|
|
171
|
-
while IFS= read -r line; do
|
|
172
|
-
# Skip empty lines
|
|
173
|
-
[ -z "$line" ] && continue
|
|
174
|
-
|
|
175
|
-
# Extract field name (everything before the colon)
|
|
176
|
-
local field
|
|
177
|
-
field=$(echo "$line" | grep -oE "^[a-z-]+" || true)
|
|
178
|
-
|
|
179
|
-
if [ -n "$field" ]; then
|
|
180
|
-
local known=false
|
|
181
|
-
for known_field in $KNOWN_FIELDS; do
|
|
182
|
-
if [ "$field" = "$known_field" ]; then
|
|
183
|
-
known=true
|
|
184
|
-
break
|
|
185
|
-
fi
|
|
186
|
-
done
|
|
187
|
-
|
|
188
|
-
if [ "$known" = false ]; then
|
|
189
|
-
echo "⚠️ Warning: Unknown field '$field'"
|
|
190
|
-
((warning_count++))
|
|
191
|
-
unknown_found=true
|
|
192
|
-
fi
|
|
193
|
-
fi
|
|
194
|
-
done <<< "$frontmatter"
|
|
195
|
-
|
|
196
|
-
if [ "$unknown_found" = false ]; then
|
|
197
|
-
echo "✅ No unknown fields"
|
|
198
|
-
fi
|
|
199
|
-
|
|
200
|
-
# Summary
|
|
201
|
-
echo ""
|
|
202
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
203
|
-
if [ $error_count -eq 0 ] && [ $warning_count -eq 0 ]; then
|
|
204
|
-
echo "✅ $COMMAND_FILE: All frontmatter checks passed!"
|
|
205
|
-
elif [ $error_count -eq 0 ]; then
|
|
206
|
-
echo "⚠️ $COMMAND_FILE: Passed with $warning_count warning(s)"
|
|
207
|
-
else
|
|
208
|
-
echo "❌ $COMMAND_FILE: Failed with $error_count error(s) and $warning_count warning(s)"
|
|
209
|
-
fi
|
|
210
|
-
echo ""
|
|
211
|
-
|
|
212
|
-
total_errors=$((total_errors + error_count))
|
|
213
|
-
total_warnings=$((total_warnings + warning_count))
|
|
214
|
-
|
|
215
|
-
return $error_count
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
# Process all provided files
|
|
219
|
-
for file in "$@"; do
|
|
220
|
-
check_frontmatter "$file" || true
|
|
221
|
-
done
|
|
222
|
-
|
|
223
|
-
# Final summary for multiple files
|
|
224
|
-
if [ $# -gt 1 ]; then
|
|
225
|
-
echo "═══════════════════════════════════════"
|
|
226
|
-
echo "Total: $# files checked"
|
|
227
|
-
echo "Errors: $total_errors"
|
|
228
|
-
echo "Warnings: $total_warnings"
|
|
229
|
-
fi
|
|
230
|
-
|
|
231
|
-
if [ $total_errors -gt 0 ]; then
|
|
232
|
-
exit 1
|
|
233
|
-
fi
|
|
234
|
-
exit 0
|
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# Command File Validator
|
|
3
|
-
# Validates command file structure and syntax
|
|
4
|
-
|
|
5
|
-
set -euo pipefail
|
|
6
|
-
|
|
7
|
-
# Usage
|
|
8
|
-
if [ $# -eq 0 ]; then
|
|
9
|
-
echo "Usage: $0 <path/to/command.md> [command2.md ...]"
|
|
10
|
-
echo ""
|
|
11
|
-
echo "Validates command file for:"
|
|
12
|
-
echo " - File exists with .md extension"
|
|
13
|
-
echo " - YAML frontmatter syntax (if present)"
|
|
14
|
-
echo " - Non-empty content"
|
|
15
|
-
echo " - Correct location (warning only)"
|
|
16
|
-
echo ""
|
|
17
|
-
echo "Examples:"
|
|
18
|
-
echo " $0 .claude/commands/review.md"
|
|
19
|
-
echo " $0 commands/*.md"
|
|
20
|
-
exit 1
|
|
21
|
-
fi
|
|
22
|
-
|
|
23
|
-
total_errors=0
|
|
24
|
-
total_warnings=0
|
|
25
|
-
|
|
26
|
-
validate_command() {
|
|
27
|
-
local COMMAND_FILE="$1"
|
|
28
|
-
local error_count=0
|
|
29
|
-
local warning_count=0
|
|
30
|
-
|
|
31
|
-
echo "🔍 Validating command: $COMMAND_FILE"
|
|
32
|
-
echo ""
|
|
33
|
-
|
|
34
|
-
# Check 1: File exists
|
|
35
|
-
if [ ! -f "$COMMAND_FILE" ]; then
|
|
36
|
-
echo "❌ Error: File not found: $COMMAND_FILE"
|
|
37
|
-
return 1
|
|
38
|
-
fi
|
|
39
|
-
echo "✅ File exists"
|
|
40
|
-
|
|
41
|
-
# Check 2: .md extension
|
|
42
|
-
if [[ ! "$COMMAND_FILE" =~ \.md$ ]]; then
|
|
43
|
-
echo "❌ Error: File must have .md extension"
|
|
44
|
-
((error_count++))
|
|
45
|
-
else
|
|
46
|
-
echo "✅ Has .md extension"
|
|
47
|
-
fi
|
|
48
|
-
|
|
49
|
-
# Check 3: Non-empty file
|
|
50
|
-
if [ ! -s "$COMMAND_FILE" ]; then
|
|
51
|
-
echo "❌ Error: File is empty"
|
|
52
|
-
((error_count++))
|
|
53
|
-
else
|
|
54
|
-
echo "✅ File is not empty"
|
|
55
|
-
fi
|
|
56
|
-
|
|
57
|
-
# Check 4: YAML frontmatter syntax (if present)
|
|
58
|
-
if head -n 1 "$COMMAND_FILE" | grep -q "^---"; then
|
|
59
|
-
echo ""
|
|
60
|
-
echo "Checking YAML frontmatter..."
|
|
61
|
-
|
|
62
|
-
# Count frontmatter markers in first 50 lines
|
|
63
|
-
MARKERS=$(head -n 50 "$COMMAND_FILE" | grep -c "^---" || true)
|
|
64
|
-
if [ "$MARKERS" -lt 2 ]; then
|
|
65
|
-
echo "❌ Error: Invalid YAML frontmatter (need exactly 2 '---' markers, found $MARKERS)"
|
|
66
|
-
((error_count++))
|
|
67
|
-
elif [ "$MARKERS" -gt 2 ]; then
|
|
68
|
-
echo "⚠️ Warning: Multiple frontmatter markers detected ($MARKERS). Only first pair is used."
|
|
69
|
-
((warning_count++))
|
|
70
|
-
else
|
|
71
|
-
echo "✅ YAML frontmatter delimiters valid"
|
|
72
|
-
fi
|
|
73
|
-
|
|
74
|
-
# Check for malformed YAML (basic check)
|
|
75
|
-
# Extract frontmatter - only between first and second --- markers
|
|
76
|
-
local frontmatter
|
|
77
|
-
frontmatter=$(awk '
|
|
78
|
-
/^---$/ { count++; if (count == 2) exit; next }
|
|
79
|
-
count == 1 { print }
|
|
80
|
-
' "$COMMAND_FILE")
|
|
81
|
-
|
|
82
|
-
if [ -n "$frontmatter" ]; then
|
|
83
|
-
# Check for tabs (YAML prefers spaces)
|
|
84
|
-
if echo "$frontmatter" | grep -q $'\t'; then
|
|
85
|
-
echo "⚠️ Warning: Frontmatter contains tabs (YAML prefers spaces)"
|
|
86
|
-
((warning_count++))
|
|
87
|
-
fi
|
|
88
|
-
|
|
89
|
-
# Check for common YAML errors - key without value
|
|
90
|
-
if echo "$frontmatter" | grep -qE "^[a-z-]+:$"; then
|
|
91
|
-
echo "⚠️ Warning: Frontmatter has keys without values"
|
|
92
|
-
((warning_count++))
|
|
93
|
-
fi
|
|
94
|
-
fi
|
|
95
|
-
else
|
|
96
|
-
echo ""
|
|
97
|
-
echo "ℹ️ No YAML frontmatter (optional)"
|
|
98
|
-
fi
|
|
99
|
-
|
|
100
|
-
# Check 5: Location warning
|
|
101
|
-
echo ""
|
|
102
|
-
echo "Checking location..."
|
|
103
|
-
if [[ "$COMMAND_FILE" == *".claude/commands/"* ]] || [[ "$COMMAND_FILE" == *"/commands/"* ]]; then
|
|
104
|
-
echo "✅ File in expected commands directory"
|
|
105
|
-
else
|
|
106
|
-
echo "⚠️ Warning: File not in .claude/commands/ or plugin commands/ directory"
|
|
107
|
-
((warning_count++))
|
|
108
|
-
fi
|
|
109
|
-
|
|
110
|
-
# Check 6: Filename conventions
|
|
111
|
-
echo ""
|
|
112
|
-
echo "Checking filename..."
|
|
113
|
-
local filename
|
|
114
|
-
filename=$(basename "$COMMAND_FILE" .md)
|
|
115
|
-
|
|
116
|
-
if [[ "$filename" =~ [A-Z] ]]; then
|
|
117
|
-
echo "⚠️ Warning: Filename contains uppercase letters (recommend lowercase)"
|
|
118
|
-
((warning_count++))
|
|
119
|
-
elif [[ "$filename" =~ [[:space:]] ]]; then
|
|
120
|
-
echo "⚠️ Warning: Filename contains spaces (use hyphens instead)"
|
|
121
|
-
((warning_count++))
|
|
122
|
-
else
|
|
123
|
-
echo "✅ Filename follows conventions"
|
|
124
|
-
fi
|
|
125
|
-
|
|
126
|
-
# Summary
|
|
127
|
-
echo ""
|
|
128
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
129
|
-
if [ $error_count -eq 0 ] && [ $warning_count -eq 0 ]; then
|
|
130
|
-
echo "✅ $COMMAND_FILE: All checks passed!"
|
|
131
|
-
elif [ $error_count -eq 0 ]; then
|
|
132
|
-
echo "⚠️ $COMMAND_FILE: Passed with $warning_count warning(s)"
|
|
133
|
-
else
|
|
134
|
-
echo "❌ $COMMAND_FILE: Failed with $error_count error(s) and $warning_count warning(s)"
|
|
135
|
-
fi
|
|
136
|
-
echo ""
|
|
137
|
-
|
|
138
|
-
total_errors=$((total_errors + error_count))
|
|
139
|
-
total_warnings=$((total_warnings + warning_count))
|
|
140
|
-
|
|
141
|
-
return $error_count
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
# Process all provided files
|
|
145
|
-
for file in "$@"; do
|
|
146
|
-
validate_command "$file" || true
|
|
147
|
-
done
|
|
148
|
-
|
|
149
|
-
# Final summary for multiple files
|
|
150
|
-
if [ $# -gt 1 ]; then
|
|
151
|
-
echo "═══════════════════════════════════════"
|
|
152
|
-
echo "Total: $# files validated"
|
|
153
|
-
echo "Errors: $total_errors"
|
|
154
|
-
echo "Warnings: $total_warnings"
|
|
155
|
-
fi
|
|
156
|
-
|
|
157
|
-
if [ $total_errors -gt 0 ]; then
|
|
158
|
-
exit 1
|
|
159
|
-
fi
|
|
160
|
-
exit 0
|
|
File without changes
|