claude-flow-novice 2.2.4 → 2.2.5

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 (288) hide show
  1. package/package.json +9 -8
  2. package/scripts/.claude-flow/metrics/agent-metrics.json +1 -0
  3. package/scripts/.claude-flow/metrics/performance.json +9 -0
  4. package/scripts/.claude-flow/metrics/task-metrics.json +10 -0
  5. package/scripts/CLEANUP_OPTIMIZATION_REPORT.json +312 -0
  6. package/scripts/CLEANUP_PERFORMANCE_OPTIMIZATION.md +387 -0
  7. package/scripts/CLEANUP_QUICK_START.md +268 -0
  8. package/scripts/CLEANUP_TEST_RESULTS.md +205 -0
  9. package/scripts/README.md +339 -0
  10. package/scripts/ace-query.sh +384 -0
  11. package/scripts/agent-token-analysis.js +430 -0
  12. package/scripts/auto-setup.js +332 -0
  13. package/scripts/build/README.md +167 -0
  14. package/scripts/build/build-config.js +27 -0
  15. package/scripts/build/build-prompt-copier.sh +30 -0
  16. package/scripts/build/performance-monitor.js +869 -0
  17. package/scripts/build/prepare-publish.js +150 -0
  18. package/scripts/build/typescript-fixer.js +621 -0
  19. package/scripts/build/unified-builder.sh +428 -0
  20. package/scripts/build/update-bin-version.js +32 -0
  21. package/scripts/build/validate-agents.js +238 -0
  22. package/scripts/build-index.js +43 -0
  23. package/scripts/build-orchestrator.js +320 -0
  24. package/scripts/check-routing-stats.cjs +122 -0
  25. package/scripts/ci-validation.js +375 -0
  26. package/scripts/cleanup-blocking-coordination.sh +420 -0
  27. package/scripts/cleanup-idle-sessions.sh +59 -0
  28. package/scripts/collect-build-metrics.js +65 -0
  29. package/scripts/demo/README.md +79 -0
  30. package/scripts/demo/autoscaling-demo-simplified.js +963 -0
  31. package/scripts/demo/comprehensive-dashboard-test.js +693 -0
  32. package/scripts/demo/confidence-log.js +87 -0
  33. package/scripts/demo/confidence-report.js +82 -0
  34. package/scripts/demo/demo-multi-swarm-coordination.js +325 -0
  35. package/scripts/demo/demo-production-deployment.js +399 -0
  36. package/scripts/demo/demo-visualization-system.js +149 -0
  37. package/scripts/demo/performance-analysis.cjs +71 -0
  38. package/scripts/demo/performance-analysis.js +71 -0
  39. package/scripts/demo/test-autoscaling-demo.js +314 -0
  40. package/scripts/dependency-optimizer.js +349 -0
  41. package/scripts/dependency-security-assessment.js +331 -0
  42. package/scripts/deploy-sdk.sh +176 -0
  43. package/scripts/deployment-readiness-report.json +179 -0
  44. package/scripts/dev/README.md +264 -0
  45. package/scripts/dev/claude-flow-wrapper.sh +35 -0
  46. package/scripts/dev/claude-monitor.py +419 -0
  47. package/scripts/dev/claude-sparc.sh +562 -0
  48. package/scripts/dev/claude-wrapper.sh +17 -0
  49. package/scripts/dev/demo-phase3-compliance.js +172 -0
  50. package/scripts/dev/demo-task-system.ts +224 -0
  51. package/scripts/dev/deployment-validator.js +315 -0
  52. package/scripts/dev/spawn-claude-terminal.sh +32 -0
  53. package/scripts/dev/start-portal.sh +506 -0
  54. package/scripts/dev/start-web-ui.js +15 -0
  55. package/scripts/dev/stop-portal.sh +311 -0
  56. package/scripts/dev/validate-examples.ts +288 -0
  57. package/scripts/dev/validate-phase2.cjs +451 -0
  58. package/scripts/dev/validate-phase2.js +785 -0
  59. package/scripts/dev/validate-phase3.cjs +208 -0
  60. package/scripts/dev/validate-security-remediation.js +1 -0
  61. package/scripts/ecosystem.config.cjs +90 -0
  62. package/scripts/fix-js-extensions.js +167 -0
  63. package/scripts/generate-basic-types.js +73 -0
  64. package/scripts/generate-changelog.js +318 -0
  65. package/scripts/git-hooks/pre-commit.sh +143 -0
  66. package/scripts/health-checks.js +634 -0
  67. package/scripts/hook-wrapper.sh +54 -0
  68. package/scripts/install/README.md +375 -0
  69. package/scripts/install/REDIS_SETUP_VALIDATION.json +245 -0
  70. package/scripts/install/check-prerequisites.js +303 -0
  71. package/scripts/install/config-wizard.js +606 -0
  72. package/scripts/install/dependency-checker.js +385 -0
  73. package/scripts/install/health-check.js +765 -0
  74. package/scripts/install/install.js +256 -0
  75. package/scripts/install/installation-benchmark.js +461 -0
  76. package/scripts/install/quick-install.js +720 -0
  77. package/scripts/install/quick-start-wizard.js +295 -0
  78. package/scripts/install/redis-cli.js +289 -0
  79. package/scripts/install/redis-install-guides.md +407 -0
  80. package/scripts/install/redis-setup.js +559 -0
  81. package/scripts/install/redis-test.js +278 -0
  82. package/scripts/install/service-manager.js +672 -0
  83. package/scripts/install/setup.js +832 -0
  84. package/scripts/install/uninstall.js +526 -0
  85. package/scripts/install/update.js +461 -0
  86. package/scripts/install-pre-commit-hook.sh +127 -0
  87. package/scripts/legacy/README.md +272 -0
  88. package/scripts/legacy/batch-fix-ts.sh +54 -0
  89. package/scripts/legacy/build-migration.sh +105 -0
  90. package/scripts/legacy/build-monitor.js +209 -0
  91. package/scripts/legacy/build-with-filter.sh +84 -0
  92. package/scripts/legacy/build-workaround.sh +71 -0
  93. package/scripts/legacy/fix-ts-advanced.js +358 -0
  94. package/scripts/legacy/fix-ts-final.sh +50 -0
  95. package/scripts/legacy/fix-ts-targeted.sh +49 -0
  96. package/scripts/legacy/fix-typescript-errors.js +305 -0
  97. package/scripts/legacy/force-build.sh +63 -0
  98. package/scripts/legacy/optimize-performance.js +400 -0
  99. package/scripts/legacy/performance-monitor.js +263 -0
  100. package/scripts/legacy/performance-monitoring.js +532 -0
  101. package/scripts/legacy/performance-test-runner.js +645 -0
  102. package/scripts/legacy/quick-fix-ts.js +281 -0
  103. package/scripts/legacy/safe-build.sh +63 -0
  104. package/scripts/memory-monitor-coordinator.js +322 -0
  105. package/scripts/migrate-to-sdk.sh +520 -0
  106. package/scripts/migration/QUICK-START.md +189 -0
  107. package/scripts/migration/QUICK-START.md.backup-1760135091363 +189 -0
  108. package/scripts/migration/README.md +464 -0
  109. package/scripts/migration/TASK-1.3.2-COMPLETION-REPORT.md +500 -0
  110. package/scripts/migration/TASK-1.3.2-COMPLETION-REPORT.md.backup-1760135091348 +500 -0
  111. package/scripts/migration/UPDATE-PATHS-README.md +464 -0
  112. package/scripts/migration/UPDATE-PATHS-README.md.backup-1760135091337 +464 -0
  113. package/scripts/migration/example-patterns.json +19 -0
  114. package/scripts/migration/install-arm64.js +78 -0
  115. package/scripts/migration/install.js +83 -0
  116. package/scripts/migration/migrate-hooks.js +173 -0
  117. package/scripts/migration/migration-examples.ts +318 -0
  118. package/scripts/migration/reorganize-workspace.js +504 -0
  119. package/scripts/migration/test-update-paths.js +359 -0
  120. package/scripts/migration/update-paths.js +664 -0
  121. package/scripts/migration/validate-migration.js +647 -0
  122. package/scripts/monitor-loop.sh +65 -0
  123. package/scripts/monitor-memory.sh +47 -0
  124. package/scripts/monitor-migration.js +339 -0
  125. package/scripts/monitor.py +43 -0
  126. package/scripts/monitoring/README.md +178 -0
  127. package/scripts/monitoring/alert-monitor.sh +220 -0
  128. package/scripts/monitoring/analyze-resources.sh +199 -0
  129. package/scripts/monitoring/dashboards/rate-limiting-dashboard.json +211 -0
  130. package/scripts/monitoring/dynamic-monitor.sh +85 -0
  131. package/scripts/monitoring/launch-stability-test.sh +184 -0
  132. package/scripts/monitoring/monitor-test.sh +93 -0
  133. package/scripts/monitoring/pre-test-validation.sh +208 -0
  134. package/scripts/monitoring/quick-test-alerting.sh +118 -0
  135. package/scripts/monitoring/quick-test-rate-limiting.sh +206 -0
  136. package/scripts/monitoring/rate-limiting-monitor.sh +380 -0
  137. package/scripts/monitoring/resource-monitor.sh +126 -0
  138. package/scripts/monitoring/stability-monitor.js +429 -0
  139. package/scripts/monitoring/test-monitor-quick.sh +54 -0
  140. package/scripts/monitoring/view-alerts.sh +307 -0
  141. package/scripts/npm-metrics-collector.js +482 -0
  142. package/scripts/npm-package-validation.cjs +299 -0
  143. package/scripts/optimization/build-optimizer.js +438 -0
  144. package/scripts/optimization/config-validator.js +761 -0
  145. package/scripts/optimization/test-optimization.js +432 -0
  146. package/scripts/optimization/unified-activation.js +839 -0
  147. package/scripts/optimize-package-swarm.js +54 -0
  148. package/scripts/performance/ACTIVATION_COMMANDS.md +292 -0
  149. package/scripts/performance/sqlite-enhanced-activation.sh +583 -0
  150. package/scripts/performance/test-enhanced-backend.sh +504 -0
  151. package/scripts/performance-monitor.js +644 -0
  152. package/scripts/performance-test-runner.js +698 -0
  153. package/scripts/post-deployment-monitoring.js +350 -0
  154. package/scripts/post-edit-pipeline.js +2091 -0
  155. package/scripts/post-install-claude-md.js +78 -0
  156. package/scripts/postinstall.js +79 -0
  157. package/scripts/pre-publish-validation.cjs +212 -0
  158. package/scripts/pre-publish-validation.js +429 -0
  159. package/scripts/redis-lua/cleanup-blocking-coordination.lua +198 -0
  160. package/scripts/release-announcement.js +425 -0
  161. package/scripts/release-notification.js +248 -0
  162. package/scripts/release-rollback.js +376 -0
  163. package/scripts/release-validation.js +460 -0
  164. package/scripts/rollback-sdk.sh +66 -0
  165. package/scripts/run-production-validation.ts +590 -0
  166. package/scripts/run-stability-validation.sh +687 -0
  167. package/scripts/security/README.md +339 -0
  168. package/scripts/security/deployment-validation.cjs +279 -0
  169. package/scripts/security/envelope-encryption-confidence-report.cjs +422 -0
  170. package/scripts/security/install-git-hooks.sh +132 -0
  171. package/scripts/security/install-git-secrets.sh +295 -0
  172. package/scripts/security/rotate-api-keys.js +469 -0
  173. package/scripts/security/ruv-swarm-safe.js +74 -0
  174. package/scripts/security/security-audit.cjs +538 -0
  175. package/scripts/security/setup-redis-auth.sh +397 -0
  176. package/scripts/security/validate-envelope-encryption.cjs +340 -0
  177. package/scripts/security-scan.js +492 -0
  178. package/scripts/src/web/frontend/.claude-flow/metrics/agent-metrics.json +1 -0
  179. package/scripts/src/web/frontend/.claude-flow/metrics/performance.json +9 -0
  180. package/scripts/src/web/frontend/.claude-flow/metrics/task-metrics.json +10 -0
  181. package/scripts/switch-api.sh +158 -0
  182. package/scripts/sync-agents.js +290 -0
  183. package/scripts/test/50-agent-test.js +625 -0
  184. package/scripts/test/NEW_STABILITY_TEST_GUIDE.md +407 -0
  185. package/scripts/test/README.md +236 -0
  186. package/scripts/test/STABILITY_TEST_EXAMPLE.md +347 -0
  187. package/scripts/test/STABILITY_TEST_README.md +480 -0
  188. package/scripts/test/agent-worker.js +309 -0
  189. package/scripts/test/ai-coordination-test.js +650 -0
  190. package/scripts/test/ai-mesh-coordination-test.js +416 -0
  191. package/scripts/test/check-links.ts +274 -0
  192. package/scripts/test/check-performance-regression.ts +168 -0
  193. package/scripts/test/cli-agent-coordination-test.js +313 -0
  194. package/scripts/test/coordinator-multilingual-test.js +396 -0
  195. package/scripts/test/coordinator-transparency-demo.js +585 -0
  196. package/scripts/test/coverage-report.ts +692 -0
  197. package/scripts/test/generate-swarm-tests.js +633 -0
  198. package/scripts/test/integration-test-validation.cjs +253 -0
  199. package/scripts/test/load-test-swarm.js +576 -0
  200. package/scripts/test/mesh-coordination-zero-overlap-test.js +740 -0
  201. package/scripts/test/multilingual-hello-world-test.js +390 -0
  202. package/scripts/test/quick-multilingual-demo.js +464 -0
  203. package/scripts/test/real-agent-test.js +312 -0
  204. package/scripts/test/run-phase3-compliance-tests.js +427 -0
  205. package/scripts/test/run-stability-test-examples.sh +292 -0
  206. package/scripts/test/stability-results/stability-metrics.jsonl +83 -0
  207. package/scripts/test/stability-results/stability-test-report.json +128 -0
  208. package/scripts/test/stability-results/stability-test.log +1827 -0
  209. package/scripts/test/stability-test-50-agents.js +734 -0
  210. package/scripts/test/test-batch-tasks.ts +29 -0
  211. package/scripts/test/test-byzantine-resolution.js +246 -0
  212. package/scripts/test/test-claude-spawn-options.sh +63 -0
  213. package/scripts/test/test-cli-wizard.js +331 -0
  214. package/scripts/test/test-comprehensive.js +401 -0
  215. package/scripts/test/test-coordination-features.ts +238 -0
  216. package/scripts/test/test-fallback-systems.js +276 -0
  217. package/scripts/test/test-init-command.ts +302 -0
  218. package/scripts/test/test-mcp.ts +251 -0
  219. package/scripts/test/test-runner.ts +568 -0
  220. package/scripts/test/test-swarm-integration.sh +92 -0
  221. package/scripts/test/test-swarm.ts +142 -0
  222. package/scripts/test/validation-summary.ts +408 -0
  223. package/scripts/test-cleanup-performance.sh +416 -0
  224. package/scripts/test-dashboard-auth.cjs +203 -0
  225. package/scripts/test-docker-deployment.sh +207 -0
  226. package/scripts/test-npm-package.cjs +167 -0
  227. package/scripts/test-provider-routing.cjs +226 -0
  228. package/scripts/test-routing-telemetry.cjs +147 -0
  229. package/scripts/test-runner.cjs +154 -0
  230. package/scripts/test-zai-10k.cjs +81 -0
  231. package/scripts/test-zai-api.cjs +191 -0
  232. package/scripts/test-zai-diagnostic.cjs +151 -0
  233. package/scripts/test-zai-final.cjs +128 -0
  234. package/scripts/test-zai-with-env.cjs +85 -0
  235. package/scripts/utils/README.md +261 -0
  236. package/scripts/utils/clean-build-artifacts.sh +94 -0
  237. package/scripts/utils/cleanup-root.sh +69 -0
  238. package/scripts/utils/fix-cliffy-imports.js +307 -0
  239. package/scripts/utils/fix-duplicate-imports.js +114 -0
  240. package/scripts/utils/fix-error-handling.cjs +70 -0
  241. package/scripts/utils/fix-import-paths.js +104 -0
  242. package/scripts/utils/fix-imports.js +116 -0
  243. package/scripts/utils/fix-shebang.js +78 -0
  244. package/scripts/utils/fix-test-modules.js +27 -0
  245. package/scripts/utils/fix-timezone-issue-246.js +200 -0
  246. package/scripts/utils/fix-ts-comprehensive.py +182 -0
  247. package/scripts/utils/fix-ts-targeted-batch.js +250 -0
  248. package/scripts/utils/remove-benchmark-conflicts.sh +140 -0
  249. package/scripts/utils/simple-test-fixer.js +190 -0
  250. package/scripts/utils/validate-metrics-structure.cjs +144 -0
  251. package/scripts/validate-agent-hooks.js +506 -0
  252. package/scripts/validate-changelog.js +241 -0
  253. package/scripts/validate-coordination-cli.js +69 -0
  254. package/scripts/validate-coordination-toggle-integration.cjs +501 -0
  255. package/scripts/validate-docker-infrastructure.sh +502 -0
  256. package/scripts/validate-entry-points.js +300 -0
  257. package/scripts/validate-stage3-performance.ts +377 -0
  258. package/scripts/validate-template-bundling.js +180 -0
  259. package/scripts/validation/README.md +33 -0
  260. package/scripts/validation/acl-security-validation.cjs +214 -0
  261. package/scripts/validation/acl-security-validation.js +402 -0
  262. package/scripts/validation/byzantine-verification.js +407 -0
  263. package/scripts/validation/final-phase-2-consensus.cjs +219 -0
  264. package/scripts/validation/final-security-validation.js +791 -0
  265. package/scripts/validation/final-wasm-validation.cjs +840 -0
  266. package/scripts/validation/integration-test-analysis.js +105 -0
  267. package/scripts/validation/phase-0-comprehensive-validation.js +474 -0
  268. package/scripts/validation/phase-0-consensus-report.js +139 -0
  269. package/scripts/validation/phase-0-final-report.js +112 -0
  270. package/scripts/validation/phase-0-redis-consensus-report.js +129 -0
  271. package/scripts/validation/phase-0-validation-improved.js +490 -0
  272. package/scripts/validation/phase-0-validation-test.js +65 -0
  273. package/scripts/validation/phase-1-consensus-report.cjs +342 -0
  274. package/scripts/validation/phase-1-consensus-validation.cjs +551 -0
  275. package/scripts/validation/phase-1-consensus-validation.js +551 -0
  276. package/scripts/validation/phase-2-consensus-report.cjs +186 -0
  277. package/scripts/validation/phase-2-validation.cjs +171 -0
  278. package/scripts/validation/phase-2-validation.js +171 -0
  279. package/scripts/validation/phase-4-consensus-report.js +181 -0
  280. package/scripts/validation/phase-4-final-validation.js +351 -0
  281. package/scripts/validation/phase-5-consensus-report.cjs +113 -0
  282. package/scripts/validation/phase-5-consensus-report.js +113 -0
  283. package/scripts/validation/security-analysis.js +49 -0
  284. package/scripts/validation/security-validation.js +492 -0
  285. package/scripts/validation/simple-security-validation.js +464 -0
  286. package/scripts/verify-installation.js +112 -0
  287. package/scripts/verify-mcp-server.js +86 -0
  288. package/scripts/verify-sdk-phase1.cjs +293 -0
@@ -0,0 +1,506 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Agent Lifecycle Hooks Validator
5
+ *
6
+ * Validates agent profile hooks for:
7
+ * - Shell syntax correctness
8
+ * - Environment variable usage
9
+ * - Dangerous commands
10
+ * - Performance anti-patterns
11
+ * - Security vulnerabilities
12
+ *
13
+ * Usage:
14
+ * node scripts/validate-agent-hooks.js --all # Validate all agents
15
+ * node scripts/validate-agent-hooks.js <agent-file.md> # Validate specific agent
16
+ * node scripts/validate-agent-hooks.js --all --ci # CI mode (exit 1 on errors)
17
+ * node scripts/validate-agent-hooks.js --all --verbose # Verbose output
18
+ *
19
+ * Sprint: 2.2 - Agent Lifecycle Hooks
20
+ * Epic: production-blocking-coordination
21
+ */
22
+
23
+ import fs from 'fs';
24
+ import path from 'path';
25
+ import { fileURLToPath } from 'url';
26
+ import { execSync } from 'child_process';
27
+ import yaml from 'js-yaml';
28
+
29
+ const __filename = fileURLToPath(import.meta.url);
30
+ const __dirname = path.dirname(__filename);
31
+
32
+ // ===== CONFIGURATION =====
33
+
34
+ const HOOK_NAMES = ['on_blocking_start', 'on_signal_received', 'on_blocking_timeout'];
35
+
36
+ const REQUIRED_ENV_VARS = ['AGENT_ID', 'TASK', 'SWARM_ID', 'ITERATION', 'PHASE'];
37
+
38
+ const DANGEROUS_PATTERNS = [
39
+ { pattern: /rm\s+-rf\s+\//, severity: 'critical', message: 'Destructive: rm -rf /' },
40
+ { pattern: /dd\s+if=/, severity: 'critical', message: 'Dangerous: dd command' },
41
+ { pattern: /mkfs/, severity: 'critical', message: 'Dangerous: mkfs command' },
42
+ { pattern: /chmod\s+777/, severity: 'high', message: 'Security: chmod 777' },
43
+ { pattern: /sudo\s+/, severity: 'high', message: 'Privilege escalation: sudo' },
44
+ { pattern: /nc\s+-l/, severity: 'medium', message: 'Network: netcat listener' },
45
+ { pattern: /sqlite3.*DROP/, severity: 'critical', message: 'Database: Direct DROP statement' },
46
+ { pattern: /eval\s+/, severity: 'high', message: 'Security: eval command' },
47
+ { pattern: /\$\([^)]*rm[^)]*\)/, severity: 'high', message: 'Command substitution with rm' },
48
+ { pattern: />\s*\/dev\/sd[a-z]/, severity: 'critical', message: 'Direct disk write' },
49
+ ];
50
+
51
+ const PERFORMANCE_ANTI_PATTERNS = [
52
+ { pattern: /sleep\s+[5-9]\d+/, severity: 'high', message: 'Performance: sleep > 50 seconds' },
53
+ { pattern: /for\s+\w+\s+in\s+\$\(find/, severity: 'medium', message: 'Performance: Loop over find' },
54
+ { pattern: /curl.*--max-time\s+[5-9]\d+/, severity: 'medium', message: 'Performance: Long HTTP timeout' },
55
+ { pattern: /while\s+true/, severity: 'high', message: 'Performance: Infinite loop detected' },
56
+ ];
57
+
58
+ const SHELL_SYNTAX_PATTERNS = [
59
+ { pattern: /\$\{[^}]+\}/, name: 'Variable expansion', valid: true },
60
+ { pattern: /\$\([^)]+\)/, name: 'Command substitution', valid: true },
61
+ { pattern: /\$[A-Z_][A-Z0-9_]*\b(?!\{)/, name: 'Unquoted variable', valid: false, fix: 'Use "${VAR}" instead of $VAR' },
62
+ { pattern: /\|\|/, name: 'OR operator', valid: true },
63
+ { pattern: /&&/, name: 'AND operator', valid: true },
64
+ ];
65
+
66
+ // ===== VALIDATION FUNCTIONS =====
67
+
68
+ /**
69
+ * Extract YAML frontmatter from markdown file
70
+ */
71
+ function extractFrontmatter(content) {
72
+ // Normalize line endings to handle both LF and CRLF
73
+ const normalizedContent = content.replace(/\r\n/g, '\n');
74
+ const frontmatterRegex = /^---\n([\s\S]*?)\n---/;
75
+ const match = normalizedContent.match(frontmatterRegex);
76
+
77
+ if (!match) {
78
+ return null;
79
+ }
80
+
81
+ try {
82
+ return yaml.load(match[1]);
83
+ } catch (error) {
84
+ throw new Error(`Invalid YAML frontmatter: ${error.message}`);
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Validate shell syntax using bash -n
90
+ */
91
+ function validateShellSyntax(hookScript, hookName) {
92
+ const issues = [];
93
+
94
+ try {
95
+ // Create temporary file for syntax check
96
+ const tempFile = `/tmp/hook_validate_${Date.now()}.sh`;
97
+ fs.writeFileSync(tempFile, `#!/bin/bash\n${hookScript}`);
98
+
99
+ // Run bash syntax check
100
+ execSync(`bash -n ${tempFile}`, { encoding: 'utf8', stdio: 'pipe' });
101
+
102
+ // Clean up
103
+ fs.unlinkSync(tempFile);
104
+
105
+ issues.push({
106
+ severity: 'info',
107
+ message: `Shell syntax valid for ${hookName}`,
108
+ type: 'syntax',
109
+ });
110
+ } catch (error) {
111
+ issues.push({
112
+ severity: 'error',
113
+ message: `Shell syntax error in ${hookName}: ${error.stderr || error.message}`,
114
+ type: 'syntax',
115
+ });
116
+ }
117
+
118
+ return issues;
119
+ }
120
+
121
+ /**
122
+ * Check for environment variable usage
123
+ */
124
+ function validateEnvVars(hookScript, hookName) {
125
+ const issues = [];
126
+ const usedVars = new Set();
127
+
128
+ // Extract all ${VAR} patterns
129
+ const varPattern = /\$\{([A-Z_][A-Z0-9_]*)\}/g;
130
+ let match;
131
+
132
+ while ((match = varPattern.exec(hookScript)) !== null) {
133
+ usedVars.add(match[1]);
134
+ }
135
+
136
+ // Check for required variables
137
+ const missingRequired = REQUIRED_ENV_VARS.filter((v) => !usedVars.has(v));
138
+
139
+ if (missingRequired.length > 0 && hookName === 'on_blocking_start') {
140
+ issues.push({
141
+ severity: 'warning',
142
+ message: `${hookName}: Consider using required variables: ${missingRequired.join(', ')}`,
143
+ type: 'env_vars',
144
+ });
145
+ }
146
+
147
+ // Check for unquoted variables (security risk)
148
+ const unquotedPattern = /\$([A-Z_][A-Z0-9_]*)\b(?!\{)/g;
149
+ const unquotedMatches = [];
150
+
151
+ while ((match = unquotedPattern.exec(hookScript)) !== null) {
152
+ unquotedMatches.push(match[1]);
153
+ }
154
+
155
+ if (unquotedMatches.length > 0) {
156
+ issues.push({
157
+ severity: 'high',
158
+ message: `${hookName}: Unquoted variables (injection risk): ${unquotedMatches.join(', ')}`,
159
+ type: 'security',
160
+ fix: 'Use "${VAR}" instead of $VAR',
161
+ });
162
+ }
163
+
164
+ return issues;
165
+ }
166
+
167
+ /**
168
+ * Check for dangerous commands
169
+ */
170
+ function validateDangerousCommands(hookScript, hookName) {
171
+ const issues = [];
172
+
173
+ for (const { pattern, severity, message } of DANGEROUS_PATTERNS) {
174
+ if (pattern.test(hookScript)) {
175
+ issues.push({
176
+ severity,
177
+ message: `${hookName}: ${message}`,
178
+ type: 'dangerous_command',
179
+ pattern: pattern.toString(),
180
+ });
181
+ }
182
+ }
183
+
184
+ return issues;
185
+ }
186
+
187
+ /**
188
+ * Check for performance anti-patterns
189
+ */
190
+ function validatePerformance(hookScript, hookName) {
191
+ const issues = [];
192
+
193
+ for (const { pattern, severity, message } of PERFORMANCE_ANTI_PATTERNS) {
194
+ if (pattern.test(hookScript)) {
195
+ issues.push({
196
+ severity,
197
+ message: `${hookName}: ${message}`,
198
+ type: 'performance',
199
+ pattern: pattern.toString(),
200
+ });
201
+ }
202
+ }
203
+
204
+ // Check for missing error handling
205
+ if (!hookScript.includes('|| true') && !hookScript.includes('|| echo')) {
206
+ issues.push({
207
+ severity: 'medium',
208
+ message: `${hookName}: Missing error handling (consider '|| true' for non-critical commands)`,
209
+ type: 'error_handling',
210
+ });
211
+ }
212
+
213
+ return issues;
214
+ }
215
+
216
+ /**
217
+ * Validate hook execution time estimate
218
+ */
219
+ function estimateExecutionTime(hookScript, hookName) {
220
+ const issues = [];
221
+ let estimatedTime = 0;
222
+
223
+ // Estimate based on patterns
224
+ if (hookScript.includes('find')) estimatedTime += 2000; // 2s for find
225
+ if (hookScript.includes('curl') || hookScript.includes('wget')) estimatedTime += 3000; // 3s for HTTP
226
+ if (hookScript.includes('git')) estimatedTime += 1000; // 1s for git
227
+ if (hookScript.includes('/sqlite-memory')) estimatedTime += 500; // 500ms for memory op
228
+ if (hookScript.includes('/eventbus')) estimatedTime += 300; // 300ms for event
229
+
230
+ // Count command substitutions
231
+ const cmdSubCount = (hookScript.match(/\$\(/g) || []).length;
232
+ estimatedTime += cmdSubCount * 200; // 200ms per command substitution
233
+
234
+ if (estimatedTime > 5000) {
235
+ issues.push({
236
+ severity: 'critical',
237
+ message: `${hookName}: Estimated execution time ${estimatedTime}ms exceeds 5s timeout`,
238
+ type: 'performance',
239
+ estimatedTime,
240
+ });
241
+ } else if (estimatedTime > 3000) {
242
+ issues.push({
243
+ severity: 'warning',
244
+ message: `${hookName}: Estimated execution time ${estimatedTime}ms (consider optimizing for < 3s)`,
245
+ type: 'performance',
246
+ estimatedTime,
247
+ });
248
+ } else {
249
+ issues.push({
250
+ severity: 'info',
251
+ message: `${hookName}: Estimated execution time ${estimatedTime}ms (good)`,
252
+ type: 'performance',
253
+ estimatedTime,
254
+ });
255
+ }
256
+
257
+ return issues;
258
+ }
259
+
260
+ /**
261
+ * Validate a single hook
262
+ */
263
+ function validateHook(hookScript, hookName) {
264
+ const issues = [];
265
+
266
+ if (!hookScript || hookScript.trim().length === 0) {
267
+ return [
268
+ {
269
+ severity: 'info',
270
+ message: `${hookName}: Empty hook (no-op)`,
271
+ type: 'empty',
272
+ },
273
+ ];
274
+ }
275
+
276
+ // Run all validations
277
+ issues.push(...validateShellSyntax(hookScript, hookName));
278
+ issues.push(...validateEnvVars(hookScript, hookName));
279
+ issues.push(...validateDangerousCommands(hookScript, hookName));
280
+ issues.push(...validatePerformance(hookScript, hookName));
281
+ issues.push(...estimateExecutionTime(hookScript, hookName));
282
+
283
+ return issues;
284
+ }
285
+
286
+ /**
287
+ * Validate agent profile file
288
+ */
289
+ function validateAgentProfile(filePath) {
290
+ const results = {
291
+ file: filePath,
292
+ valid: true,
293
+ issues: [],
294
+ hooks: {},
295
+ };
296
+
297
+ try {
298
+ // Read file
299
+ const content = fs.readFileSync(filePath, 'utf8');
300
+
301
+ // Extract frontmatter
302
+ const frontmatter = extractFrontmatter(content);
303
+
304
+ if (!frontmatter) {
305
+ results.valid = false;
306
+ results.issues.push({
307
+ severity: 'error',
308
+ message: 'No YAML frontmatter found',
309
+ type: 'frontmatter',
310
+ });
311
+ return results;
312
+ }
313
+
314
+ // Check if hooks exist
315
+ if (!frontmatter.hooks) {
316
+ results.issues.push({
317
+ severity: 'info',
318
+ message: 'No hooks defined (optional)',
319
+ type: 'hooks',
320
+ });
321
+ return results;
322
+ }
323
+
324
+ // Validate each hook
325
+ for (const hookName of HOOK_NAMES) {
326
+ if (frontmatter.hooks[hookName]) {
327
+ const hookIssues = validateHook(frontmatter.hooks[hookName], hookName);
328
+ results.hooks[hookName] = hookIssues;
329
+ results.issues.push(...hookIssues);
330
+ }
331
+ }
332
+
333
+ // Check for unknown hooks
334
+ const unknownHooks = Object.keys(frontmatter.hooks).filter((h) => !HOOK_NAMES.includes(h));
335
+ if (unknownHooks.length > 0) {
336
+ results.issues.push({
337
+ severity: 'warning',
338
+ message: `Unknown hooks: ${unknownHooks.join(', ')}`,
339
+ type: 'hooks',
340
+ });
341
+ }
342
+
343
+ // Determine overall validity
344
+ const hasCritical = results.issues.some((i) => i.severity === 'critical');
345
+ const hasError = results.issues.some((i) => i.severity === 'error');
346
+
347
+ results.valid = !hasCritical && !hasError;
348
+ } catch (error) {
349
+ results.valid = false;
350
+ results.issues.push({
351
+ severity: 'error',
352
+ message: `Validation failed: ${error.message}`,
353
+ type: 'exception',
354
+ });
355
+ }
356
+
357
+ return results;
358
+ }
359
+
360
+ /**
361
+ * Find all agent profile files
362
+ */
363
+ function findAgentProfiles() {
364
+ const agentsDir = path.join(__dirname, '..', '.claude', 'agents');
365
+ const profiles = [];
366
+
367
+ function scanDir(dir) {
368
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
369
+
370
+ for (const entry of entries) {
371
+ const fullPath = path.join(dir, entry.name);
372
+
373
+ if (entry.isDirectory()) {
374
+ scanDir(fullPath);
375
+ } else if (entry.isFile() && entry.name.endsWith('.md')) {
376
+ profiles.push(fullPath);
377
+ }
378
+ }
379
+ }
380
+
381
+ scanDir(agentsDir);
382
+ return profiles;
383
+ }
384
+
385
+ /**
386
+ * Format validation results
387
+ */
388
+ function formatResults(results, verbose = false) {
389
+ const severityColors = {
390
+ critical: '\x1b[31m', // Red
391
+ error: '\x1b[31m', // Red
392
+ high: '\x1b[33m', // Yellow
393
+ warning: '\x1b[33m', // Yellow
394
+ medium: '\x1b[36m', // Cyan
395
+ info: '\x1b[32m', // Green
396
+ };
397
+ const reset = '\x1b[0m';
398
+
399
+ console.log(`\n${results.valid ? '✅' : '❌'} ${path.basename(results.file)}`);
400
+
401
+ if (verbose || !results.valid) {
402
+ const groupedIssues = {};
403
+
404
+ for (const issue of results.issues) {
405
+ if (!groupedIssues[issue.severity]) {
406
+ groupedIssues[issue.severity] = [];
407
+ }
408
+ groupedIssues[issue.severity].push(issue);
409
+ }
410
+
411
+ for (const [severity, issues] of Object.entries(groupedIssues)) {
412
+ const color = severityColors[severity] || '';
413
+ console.log(`\n ${color}${severity.toUpperCase()}${reset}:`);
414
+
415
+ for (const issue of issues) {
416
+ console.log(` - ${issue.message}`);
417
+ if (issue.fix) {
418
+ console.log(` Fix: ${issue.fix}`);
419
+ }
420
+ if (verbose && issue.pattern) {
421
+ console.log(` Pattern: ${issue.pattern}`);
422
+ }
423
+ }
424
+ }
425
+ }
426
+
427
+ return results.valid;
428
+ }
429
+
430
+ /**
431
+ * Generate summary report
432
+ */
433
+ function generateSummary(allResults) {
434
+ const total = allResults.length;
435
+ const valid = allResults.filter((r) => r.valid).length;
436
+ const invalid = total - valid;
437
+
438
+ const issuesBySeverity = {};
439
+ for (const result of allResults) {
440
+ for (const issue of result.issues) {
441
+ issuesBySeverity[issue.severity] = (issuesBySeverity[issue.severity] || 0) + 1;
442
+ }
443
+ }
444
+
445
+ console.log('\n' + '='.repeat(60));
446
+ console.log('VALIDATION SUMMARY');
447
+ console.log('='.repeat(60));
448
+ console.log(`\nTotal agents: ${total}`);
449
+ console.log(`Valid: ${valid} ✅`);
450
+ console.log(`Invalid: ${invalid} ❌`);
451
+
452
+ if (Object.keys(issuesBySeverity).length > 0) {
453
+ console.log('\nIssues by severity:');
454
+ for (const [severity, count] of Object.entries(issuesBySeverity)) {
455
+ console.log(` ${severity}: ${count}`);
456
+ }
457
+ }
458
+
459
+ console.log('\n' + '='.repeat(60) + '\n');
460
+
461
+ return invalid === 0;
462
+ }
463
+
464
+ // ===== MAIN =====
465
+
466
+ async function main() {
467
+ const args = process.argv.slice(2);
468
+ const flags = {
469
+ all: args.includes('--all'),
470
+ ci: args.includes('--ci'),
471
+ verbose: args.includes('--verbose'),
472
+ };
473
+
474
+ const files = args.filter((arg) => !arg.startsWith('--'));
475
+
476
+ let profilesToValidate = [];
477
+
478
+ if (flags.all) {
479
+ profilesToValidate = findAgentProfiles();
480
+ console.log(`Found ${profilesToValidate.length} agent profiles`);
481
+ } else if (files.length > 0) {
482
+ profilesToValidate = files.map((f) => path.resolve(f));
483
+ } else {
484
+ console.error('Usage: node validate-agent-hooks.js [--all] [--ci] [--verbose] [file.md...]');
485
+ process.exit(1);
486
+ }
487
+
488
+ const allResults = [];
489
+
490
+ for (const filePath of profilesToValidate) {
491
+ const results = validateAgentProfile(filePath);
492
+ allResults.push(results);
493
+ formatResults(results, flags.verbose);
494
+ }
495
+
496
+ const success = generateSummary(allResults);
497
+
498
+ if (flags.ci && !success) {
499
+ process.exit(1);
500
+ }
501
+ }
502
+
503
+ main().catch((error) => {
504
+ console.error('Fatal error:', error);
505
+ process.exit(1);
506
+ });