@paulduvall/claude-dev-toolkit 0.0.1-alpha.2 → 0.0.1-alpha.21

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.
Files changed (143) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +88 -37
  3. package/bin/claude-commands +307 -65
  4. package/commands/active/xarchitecture.md +393 -0
  5. package/commands/active/xconfig.md +127 -0
  6. package/commands/active/xcontinue.md +92 -0
  7. package/commands/active/xdebug.md +130 -0
  8. package/commands/active/xdocs.md +178 -0
  9. package/commands/active/xexplore.md +94 -0
  10. package/commands/active/xgit.md +149 -0
  11. package/commands/active/xpipeline.md +152 -0
  12. package/commands/active/xquality.md +96 -0
  13. package/commands/active/xrefactor.md +198 -0
  14. package/commands/active/xrelease.md +142 -0
  15. package/commands/active/xsecurity.md +92 -0
  16. package/commands/active/xspec.md +174 -0
  17. package/commands/active/xtdd.md +151 -0
  18. package/commands/active/xtest.md +89 -0
  19. package/commands/active/xverify.md +80 -0
  20. package/commands/experiments/xact.md +742 -0
  21. package/commands/experiments/xanalytics.md +113 -0
  22. package/commands/experiments/xanalyze.md +70 -0
  23. package/commands/experiments/xapi.md +161 -0
  24. package/commands/experiments/xatomic.md +112 -0
  25. package/commands/experiments/xaws.md +85 -0
  26. package/commands/experiments/xcicd.md +337 -0
  27. package/commands/experiments/xcommit.md +122 -0
  28. package/commands/experiments/xcompliance.md +182 -0
  29. package/commands/experiments/xconstraints.md +89 -0
  30. package/commands/experiments/xcoverage.md +90 -0
  31. package/commands/experiments/xdb.md +102 -0
  32. package/commands/experiments/xdesign.md +121 -0
  33. package/commands/experiments/xdevcontainer.md +238 -0
  34. package/commands/experiments/xevaluate.md +111 -0
  35. package/commands/experiments/xfootnote.md +12 -0
  36. package/commands/experiments/xgenerate.md +117 -0
  37. package/commands/experiments/xgovernance.md +149 -0
  38. package/commands/experiments/xgreen.md +66 -0
  39. package/commands/experiments/xiac.md +118 -0
  40. package/commands/experiments/xincident.md +137 -0
  41. package/commands/experiments/xinfra.md +115 -0
  42. package/commands/experiments/xknowledge.md +115 -0
  43. package/commands/experiments/xmaturity.md +120 -0
  44. package/commands/experiments/xmetrics.md +118 -0
  45. package/commands/experiments/xmonitoring.md +128 -0
  46. package/commands/experiments/xnew.md +903 -0
  47. package/commands/experiments/xobservable.md +114 -0
  48. package/commands/experiments/xoidc.md +165 -0
  49. package/commands/experiments/xoptimize.md +115 -0
  50. package/commands/experiments/xperformance.md +112 -0
  51. package/commands/experiments/xplanning.md +131 -0
  52. package/commands/experiments/xpolicy.md +115 -0
  53. package/commands/experiments/xproduct.md +98 -0
  54. package/commands/experiments/xreadiness.md +75 -0
  55. package/commands/experiments/xred.md +55 -0
  56. package/commands/experiments/xrisk.md +128 -0
  57. package/commands/experiments/xrules.md +124 -0
  58. package/commands/experiments/xsandbox.md +120 -0
  59. package/commands/experiments/xscan.md +102 -0
  60. package/commands/experiments/xsetup.md +123 -0
  61. package/commands/experiments/xtemplate.md +116 -0
  62. package/commands/experiments/xtrace.md +212 -0
  63. package/commands/experiments/xux.md +171 -0
  64. package/commands/experiments/xvalidate.md +104 -0
  65. package/commands/experiments/xworkflow.md +113 -0
  66. package/hooks/.smellrc.example.json +19 -0
  67. package/hooks/README.md +263 -0
  68. package/hooks/check-commit-signing.py +127 -0
  69. package/hooks/check-complexity.py +38 -0
  70. package/hooks/check-security.py +37 -0
  71. package/hooks/claude-wrapper.sh +29 -0
  72. package/hooks/config.py +110 -0
  73. package/hooks/file-logger.sh +100 -0
  74. package/hooks/lib/argument-parser.sh +427 -0
  75. package/hooks/lib/config-constants.sh +230 -0
  76. package/hooks/lib/context-manager.sh +560 -0
  77. package/hooks/lib/error-handler.sh +423 -0
  78. package/hooks/lib/execution-engine.sh +444 -0
  79. package/hooks/lib/execution-results.sh +113 -0
  80. package/hooks/lib/execution-simulation.sh +114 -0
  81. package/hooks/lib/field-validators.sh +104 -0
  82. package/hooks/lib/file-utils.sh +398 -0
  83. package/hooks/lib/subagent-discovery.sh +468 -0
  84. package/hooks/lib/subagent-validator.sh +407 -0
  85. package/hooks/lib/validation-reporter.sh +134 -0
  86. package/hooks/on-error-debug.sh +226 -0
  87. package/hooks/pre-commit-quality.sh +204 -0
  88. package/hooks/pre-commit-test-runner.sh +132 -0
  89. package/hooks/pre-write-security.sh +115 -0
  90. package/hooks/prevent-credential-exposure.sh +279 -0
  91. package/hooks/security_bandit.py +177 -0
  92. package/hooks/security_checks.py +97 -0
  93. package/hooks/security_secrets.py +81 -0
  94. package/hooks/security_trojan.py +61 -0
  95. package/hooks/settings.example.json +52 -0
  96. package/hooks/smell_checks.py +238 -0
  97. package/hooks/smell_javascript.py +231 -0
  98. package/hooks/smell_python.py +110 -0
  99. package/hooks/smell_ruff.py +70 -0
  100. package/hooks/smell_types.py +72 -0
  101. package/hooks/subagent-trigger-simple.sh +202 -0
  102. package/hooks/subagent-trigger.sh +253 -0
  103. package/hooks/suppression.py +82 -0
  104. package/hooks/tab-color.sh +70 -0
  105. package/hooks/verify-before-edit.sh +135 -0
  106. package/lib/backup-restore-command.js +140 -0
  107. package/lib/base/base-command.js +252 -0
  108. package/lib/base/command-result.js +184 -0
  109. package/lib/config/constants.js +255 -0
  110. package/lib/config.js +48 -6
  111. package/lib/configure-command.js +428 -0
  112. package/lib/dependency-validator.js +64 -5
  113. package/lib/hook-installer-core.js +2 -2
  114. package/lib/installation-instruction-generator.js +213 -495
  115. package/lib/installer.js +134 -56
  116. package/lib/oidc-command.js +740 -0
  117. package/lib/services/backup-list-service.js +226 -0
  118. package/lib/services/backup-service.js +230 -0
  119. package/lib/services/command-installer-service.js +217 -0
  120. package/lib/services/logger-service.js +201 -0
  121. package/lib/services/package-manager-service.js +319 -0
  122. package/lib/services/platform-instruction-service.js +294 -0
  123. package/lib/services/recovery-instruction-service.js +348 -0
  124. package/lib/services/restore-service.js +221 -0
  125. package/lib/setup-command.js +359 -0
  126. package/lib/setup-wizard.js +155 -262
  127. package/lib/uninstall-command.js +100 -0
  128. package/lib/utils/claude-path-config.js +184 -0
  129. package/lib/utils/file-system-utils.js +152 -0
  130. package/lib/utils.js +8 -4
  131. package/lib/verify-command.js +430 -0
  132. package/package.json +7 -3
  133. package/scripts/postinstall.js +172 -157
  134. package/subagents/debug-specialist.md +7 -0
  135. package/templates/README.md +115 -0
  136. package/templates/basic-settings.json +30 -0
  137. package/templates/comprehensive-settings.json +57 -0
  138. package/templates/global-claude.md +344 -0
  139. package/templates/hybrid-hook-config.yaml +132 -0
  140. package/templates/security-focused-settings.json +62 -0
  141. package/templates/subagent-hooks.yaml +188 -0
  142. package/lib/package-manager-service.js +0 -270
  143. package/subagents/debug-context.md +0 -197
@@ -0,0 +1,407 @@
1
+ #!/usr/bin/env bash
2
+ set -uo pipefail
3
+
4
+ # Subagent Validator Module for Subagent-Hook Integration
5
+ #
6
+ # This module provides comprehensive validation functionality for subagents,
7
+ # including format validation, content validation, and security checks.
8
+
9
+ # Include guard
10
+ [[ -n "${_SUBAGENT_VALIDATOR_LOADED:-}" ]] && return 0
11
+ _SUBAGENT_VALIDATOR_LOADED=1
12
+
13
+ # Source required modules
14
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
15
+ source "$SCRIPT_DIR/config-constants.sh"
16
+ source "$SCRIPT_DIR/file-utils.sh"
17
+ source "$SCRIPT_DIR/error-handler.sh"
18
+ source "$SCRIPT_DIR/field-validators.sh"
19
+ source "$SCRIPT_DIR/validation-reporter.sh"
20
+
21
+ ##################################
22
+ # Basic Validation Functions
23
+ ##################################
24
+
25
+ validate_subagent_file() {
26
+ local subagent_file="$1"
27
+ local validation_mode="${2:-strict}"
28
+
29
+ if [[ -z "$subagent_file" ]]; then
30
+ log_error "Subagent file path is required"
31
+ return $EXIT_VALIDATION_FAILED
32
+ fi
33
+
34
+ log_debug "Validating subagent file: $subagent_file (mode: $validation_mode)"
35
+
36
+ # Basic file validation
37
+ if ! validate_file_existence "$subagent_file"; then
38
+ return $EXIT_VALIDATION_FAILED
39
+ fi
40
+
41
+ if ! validate_file_security "$subagent_file"; then
42
+ return $EXIT_SECURITY_VIOLATION
43
+ fi
44
+
45
+ if ! validate_file_format "$subagent_file"; then
46
+ return $EXIT_VALIDATION_FAILED
47
+ fi
48
+
49
+ if ! validate_yaml_frontmatter "$subagent_file"; then
50
+ return $EXIT_VALIDATION_FAILED
51
+ fi
52
+
53
+ if [[ "$validation_mode" == "strict" ]]; then
54
+ if ! validate_subagent_content "$subagent_file"; then
55
+ return $EXIT_VALIDATION_FAILED
56
+ fi
57
+
58
+ if ! validate_subagent_metadata "$subagent_file"; then
59
+ return $EXIT_VALIDATION_FAILED
60
+ fi
61
+ fi
62
+
63
+ log_debug "Subagent file validation passed: $subagent_file"
64
+ return $EXIT_SUCCESS
65
+ }
66
+
67
+ validate_file_existence() {
68
+ local file_path="$1"
69
+
70
+ if [[ ! -f "$file_path" ]]; then
71
+ handle_missing_subagent "$(basename "$file_path" "$SUBAGENT_FILE_EXTENSION")"
72
+ return $EXIT_SUBAGENT_NOT_FOUND
73
+ fi
74
+
75
+ if [[ ! -r "$file_path" ]]; then
76
+ log_error "Subagent file not readable: $file_path"
77
+ return $EXIT_VALIDATION_FAILED
78
+ fi
79
+
80
+ return $EXIT_SUCCESS
81
+ }
82
+
83
+ validate_file_security() {
84
+ local file_path="$1"
85
+
86
+ # Validate file permissions
87
+ if ! validate_file_permissions "$file_path"; then
88
+ handle_security_violation "insecure_file_permissions" \
89
+ "File has insecure permissions" "$file_path"
90
+ return $EXIT_SECURITY_VIOLATION
91
+ fi
92
+
93
+ # Validate path safety
94
+ if ! validate_path_safety "$file_path"; then
95
+ handle_security_violation "unsafe_file_path" \
96
+ "File path contains unsafe elements" "$file_path"
97
+ return $EXIT_SECURITY_VIOLATION
98
+ fi
99
+
100
+ return $EXIT_SUCCESS
101
+ }
102
+
103
+ validate_file_format() {
104
+ local file_path="$1"
105
+
106
+ # Check file extension
107
+ if ! file_has_extension "$file_path" "$SUBAGENT_FILE_EXTENSION"; then
108
+ log_error "Invalid file extension: $file_path (expected: $SUBAGENT_FILE_EXTENSION)"
109
+ return $EXIT_VALIDATION_FAILED
110
+ fi
111
+
112
+ # Check file size
113
+ local file_content
114
+ if ! file_content=$(read_file_with_size_limit "$file_path"); then
115
+ log_error "File too large or unreadable: $file_path"
116
+ return $EXIT_VALIDATION_FAILED
117
+ fi
118
+
119
+ # Check if file appears to be binary
120
+ if file "$file_path" 2>/dev/null | grep -q "binary"; then
121
+ log_error "File appears to be binary: $file_path"
122
+ return $EXIT_VALIDATION_FAILED
123
+ fi
124
+
125
+ return $EXIT_SUCCESS
126
+ }
127
+
128
+ ##################################
129
+ # YAML Frontmatter Validation
130
+ ##################################
131
+
132
+ validate_yaml_frontmatter() {
133
+ local file_path="$1"
134
+
135
+ local content
136
+ if ! content=$(read_file_safely "$file_path"); then
137
+ log_error "Failed to read file for frontmatter validation: $file_path"
138
+ return $EXIT_VALIDATION_FAILED
139
+ fi
140
+
141
+ # Check for YAML frontmatter start
142
+ if ! echo "$content" | head -1 | grep -q "$YAML_FRONTMATTER_START"; then
143
+ log_error "Missing YAML frontmatter start marker in: $file_path"
144
+ return $EXIT_VALIDATION_FAILED
145
+ fi
146
+
147
+ # Find frontmatter end
148
+ local frontmatter_end_found=false
149
+ local line_count=0
150
+
151
+ while IFS= read -r line; do
152
+ ((line_count++))
153
+
154
+ # Skip first line (start marker)
155
+ if [[ $line_count -eq 1 ]]; then
156
+ continue
157
+ fi
158
+
159
+ if [[ "$line" == "---" ]]; then
160
+ frontmatter_end_found=true
161
+ break
162
+ fi
163
+
164
+ # Prevent infinite search
165
+ if [[ $line_count -gt 100 ]]; then
166
+ break
167
+ fi
168
+ done <<< "$content"
169
+
170
+ if [[ "$frontmatter_end_found" != true ]]; then
171
+ log_error "Missing YAML frontmatter end marker in: $file_path"
172
+ return $EXIT_VALIDATION_FAILED
173
+ fi
174
+
175
+ log_debug "YAML frontmatter structure valid: $file_path"
176
+ return $EXIT_SUCCESS
177
+ }
178
+
179
+ extract_frontmatter_field() {
180
+ local file_path="$1"
181
+ local field_name="$2"
182
+ local required="${3:-false}"
183
+
184
+ if [[ -z "$file_path" ]] || [[ -z "$field_name" ]]; then
185
+ log_error "File path and field name are required"
186
+ return $EXIT_VALIDATION_FAILED
187
+ fi
188
+
189
+ local content
190
+ if ! content=$(read_file_safely "$file_path"); then
191
+ log_error "Failed to read file: $file_path"
192
+ return $EXIT_VALIDATION_FAILED
193
+ fi
194
+
195
+ local in_frontmatter=false
196
+ local field_value=""
197
+
198
+ while IFS= read -r line; do
199
+ if [[ "$line" == "---" ]]; then
200
+ if [[ "$in_frontmatter" == true ]]; then
201
+ break # End of frontmatter
202
+ else
203
+ in_frontmatter=true
204
+ continue
205
+ fi
206
+ fi
207
+
208
+ if [[ "$in_frontmatter" == true ]]; then
209
+ if [[ "$line" =~ ^${field_name}:[[:space:]]*(.*)$ ]]; then
210
+ field_value="${BASH_REMATCH[1]}"
211
+ # Remove quotes if present
212
+ field_value="${field_value#\"}"
213
+ field_value="${field_value%\"}"
214
+ break
215
+ fi
216
+ fi
217
+ done <<< "$content"
218
+
219
+ if [[ -z "$field_value" ]] && [[ "$required" == true ]]; then
220
+ log_error "Required field missing: $field_name in $file_path"
221
+ return $EXIT_VALIDATION_FAILED
222
+ fi
223
+
224
+ echo "$field_value"
225
+ return $EXIT_SUCCESS
226
+ }
227
+
228
+ ##################################
229
+ # Content Validation Functions
230
+ ##################################
231
+
232
+ validate_subagent_metadata() {
233
+ local file_path="$1"
234
+
235
+ log_debug "Validating subagent metadata: $file_path"
236
+
237
+ # Validate required fields
238
+ local required_fields=("name" "description")
239
+ local field
240
+
241
+ for field in "${required_fields[@]}"; do
242
+ local field_value
243
+ if ! field_value=$(extract_frontmatter_field "$file_path" "$field" true); then
244
+ return $EXIT_VALIDATION_FAILED
245
+ fi
246
+
247
+ case "$field" in
248
+ "name")
249
+ if ! validate_subagent_name_field "$field_value"; then
250
+ log_error "Invalid name field in: $file_path"
251
+ return $EXIT_VALIDATION_FAILED
252
+ fi
253
+ ;;
254
+ "description")
255
+ if ! validate_description_field "$field_value"; then
256
+ log_error "Invalid description field in: $file_path"
257
+ return $EXIT_VALIDATION_FAILED
258
+ fi
259
+ ;;
260
+ esac
261
+ done
262
+
263
+ # Validate optional fields if present
264
+ local optional_fields=("version" "tools" "tags")
265
+ for field in "${optional_fields[@]}"; do
266
+ local field_value
267
+ if field_value=$(extract_frontmatter_field "$file_path" "$field" false); then
268
+ if [[ -n "$field_value" ]]; then
269
+ case "$field" in
270
+ "version")
271
+ validate_version_field "$field_value" || {
272
+ log_warning "Invalid version field in: $file_path"
273
+ }
274
+ ;;
275
+ "tools")
276
+ validate_tools_field "$field_value" || {
277
+ log_warning "Invalid tools field in: $file_path"
278
+ }
279
+ ;;
280
+ "tags")
281
+ validate_tags_field "$field_value" || {
282
+ log_warning "Invalid tags field in: $file_path"
283
+ }
284
+ ;;
285
+ esac
286
+ fi
287
+ fi
288
+ done
289
+
290
+ log_debug "Subagent metadata validation passed: $file_path"
291
+ return $EXIT_SUCCESS
292
+ }
293
+
294
+ validate_subagent_content() {
295
+ local file_path="$1"
296
+
297
+ log_debug "Validating subagent content: $file_path"
298
+
299
+ local content
300
+ if ! content=$(read_file_safely "$file_path"); then
301
+ log_error "Failed to read file for content validation: $file_path"
302
+ return $EXIT_VALIDATION_FAILED
303
+ fi
304
+
305
+ # Check for minimum content after frontmatter
306
+ local in_frontmatter=false
307
+ local frontmatter_ended=false
308
+ local content_lines=0
309
+
310
+ while IFS= read -r line; do
311
+ if [[ "$line" == "---" ]]; then
312
+ if [[ "$in_frontmatter" == true ]]; then
313
+ frontmatter_ended=true
314
+ else
315
+ in_frontmatter=true
316
+ fi
317
+ continue
318
+ fi
319
+
320
+ if [[ "$frontmatter_ended" == true ]]; then
321
+ # Count non-empty lines
322
+ if [[ -n "${line// }" ]]; then
323
+ ((content_lines++))
324
+ fi
325
+ fi
326
+ done <<< "$content"
327
+
328
+ if [[ $content_lines -lt 3 ]]; then
329
+ log_error "Insufficient content after frontmatter in: $file_path"
330
+ return $EXIT_VALIDATION_FAILED
331
+ fi
332
+
333
+ if ! validate_content_security "$content" "$file_path"; then
334
+ return $EXIT_SECURITY_VIOLATION
335
+ fi
336
+
337
+ log_debug "Subagent content validation passed: $file_path"
338
+ return $EXIT_SUCCESS
339
+ }
340
+
341
+ ##################################
342
+ # Field Validation Functions
343
+ ##################################
344
+ # See: field-validators.sh
345
+
346
+ ##################################
347
+ # Security Validation Functions
348
+ ##################################
349
+
350
+ validate_content_security() {
351
+ local content="$1"
352
+ local file_path="$2"
353
+
354
+ log_debug "Performing security validation on content"
355
+
356
+ # Check for suspicious patterns (excluding legitimate markdown)
357
+ local suspicious_patterns=(
358
+ 'rm\s+-rf\s+/'
359
+ 'curl\s+.*\|\s*sh'
360
+ 'wget\s+.*\|\s*sh'
361
+ 'eval\s*\$\('
362
+ '`[^`]*\$\([^`]*`'
363
+ 'exec\s+["\047].*[;&]'
364
+ )
365
+
366
+ local pattern
367
+ for pattern in "${suspicious_patterns[@]}"; do
368
+ if echo "$content" | grep -qE "$pattern"; then
369
+ handle_security_violation "suspicious_content" \
370
+ "Suspicious pattern detected: $pattern" "$file_path"
371
+ return $EXIT_SECURITY_VIOLATION
372
+ fi
373
+ done
374
+
375
+ # Check for potential credential exposure
376
+ local credential_patterns=(
377
+ 'password\s*[:=]\s*["\047]?[^"\047[:space:]]+["\047]?'
378
+ 'token\s*[:=]\s*["\047]?[^"\047[:space:]]+["\047]?'
379
+ 'api[_-]?key\s*[:=]\s*["\047]?[^"\047[:space:]]+["\047]?'
380
+ 'secret\s*[:=]\s*["\047]?[^"\047[:space:]]+["\047]?'
381
+ )
382
+
383
+ for pattern in "${credential_patterns[@]}"; do
384
+ if echo "$content" | grep -qiE "$pattern"; then
385
+ handle_security_violation "potential_credential_exposure" \
386
+ "Potential credential pattern detected: $pattern" "$file_path"
387
+ return $EXIT_SECURITY_VIOLATION
388
+ fi
389
+ done
390
+
391
+ log_debug "Content security validation passed"
392
+ return $EXIT_SUCCESS
393
+ }
394
+
395
+ ##################################
396
+ # Batch Validation & Reporting
397
+ ##################################
398
+ # See: validation-reporter.sh
399
+
400
+ ##################################
401
+ # Initialization
402
+ ##################################
403
+
404
+ initialize_subagent_validator() {
405
+ log_debug "Subagent validator module initialized"
406
+ return $EXIT_SUCCESS
407
+ }
@@ -0,0 +1,134 @@
1
+ #!/usr/bin/env bash
2
+ set -uo pipefail
3
+
4
+ # Validation Reporter Module
5
+ #
6
+ # Provides validation reporting and batch validation functions
7
+ # for subagent definitions.
8
+ # Extracted from subagent-validator.sh.
9
+
10
+ # Include guard
11
+ [[ -n "${_VALIDATION_REPORTER_LOADED:-}" ]] && return 0
12
+ _VALIDATION_REPORTER_LOADED=1
13
+
14
+ # Source required modules
15
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
16
+ source "$SCRIPT_DIR/config-constants.sh"
17
+ source "$SCRIPT_DIR/error-handler.sh"
18
+
19
+ ##################################
20
+ # Batch Validation Functions
21
+ ##################################
22
+
23
+ validate_all_subagents() {
24
+ local directory="${1:-$SUBAGENTS_DIR}"
25
+ local validation_mode="${2:-strict}"
26
+ local validation_results=()
27
+ local total_count=0
28
+ local passed_count=0
29
+ local failed_count=0
30
+
31
+ log_info "Validating all subagents in: $directory"
32
+
33
+ if [[ ! -d "$directory" ]]; then
34
+ log_error "Directory not found: $directory"
35
+ return $EXIT_GENERAL_ERROR
36
+ fi
37
+
38
+ find "$directory" -name "*$SUBAGENT_FILE_EXTENSION" -type f 2>/dev/null | while read -r file; do
39
+ ((total_count++))
40
+ local filename
41
+ filename=$(basename "$file")
42
+
43
+ if validate_subagent_file "$file" "$validation_mode" 2>/dev/null; then
44
+ ((passed_count++))
45
+ validation_results+=("PASS: $filename")
46
+ log_debug "Validation passed: $filename"
47
+ else
48
+ ((failed_count++))
49
+ validation_results+=("FAIL: $filename")
50
+ log_debug "Validation failed: $filename"
51
+ fi
52
+ done
53
+
54
+ # Output results
55
+ log_info "Validation Summary:"
56
+ log_info " Total subagents: $total_count"
57
+ log_info " Passed: $passed_count"
58
+ log_info " Failed: $failed_count"
59
+
60
+ # Detailed results in debug mode
61
+ if is_debug_mode 2>/dev/null; then
62
+ for result in "${validation_results[@]}"; do
63
+ log_debug " $result"
64
+ done
65
+ fi
66
+
67
+ if [[ $failed_count -gt 0 ]]; then
68
+ return $EXIT_VALIDATION_FAILED
69
+ fi
70
+
71
+ return $EXIT_SUCCESS
72
+ }
73
+
74
+ ##################################
75
+ # Validation Reporting Functions
76
+ ##################################
77
+
78
+ generate_validation_report() {
79
+ local directory="${1:-$SUBAGENTS_DIR}"
80
+ local output_format="${2:-text}"
81
+
82
+ log_info "Generating validation report for: $directory"
83
+
84
+ case "$output_format" in
85
+ "json")
86
+ generate_json_validation_report "$directory"
87
+ ;;
88
+ "text"|*)
89
+ generate_text_validation_report "$directory"
90
+ ;;
91
+ esac
92
+ }
93
+
94
+ generate_text_validation_report() {
95
+ local directory="$1"
96
+
97
+ echo "Subagent Validation Report"
98
+ echo "========================="
99
+ echo "Directory: $directory"
100
+ echo "Generated: $(date)"
101
+ echo ""
102
+
103
+ local total=0 passed=0 failed=0
104
+
105
+ find "$directory" -name "*$SUBAGENT_FILE_EXTENSION" -type f 2>/dev/null | while read -r file; do
106
+ ((total++))
107
+ local filename name
108
+ filename=$(basename "$file")
109
+ name=$(basename "$file" "$SUBAGENT_FILE_EXTENSION")
110
+
111
+ echo -n "Validating $name... "
112
+
113
+ if validate_subagent_file "$file" "strict" 2>/dev/null; then
114
+ ((passed++))
115
+ echo "PASSED"
116
+ else
117
+ ((failed++))
118
+ echo "FAILED"
119
+ validate_subagent_file "$file" "strict" 2>&1 | sed "s/^/ Error: /"
120
+ fi
121
+ echo ""
122
+ done
123
+
124
+ echo "Summary:"
125
+ echo " Total: $total"
126
+ echo " Passed: $passed"
127
+ echo " Failed: $failed"
128
+
129
+ if [[ $failed -eq 0 ]]; then
130
+ echo " Status: ALL VALID"
131
+ else
132
+ echo " Status: ISSUES FOUND"
133
+ fi
134
+ }