claude-flow-novice 2.0.3 → 2.0.4

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 (272) hide show
  1. package/dist/src/cli/commands/guidance.js +487 -668
  2. package/dist/src/cli/commands/index-validate.js +18 -29
  3. package/dist/src/cli/commands/mcp-troubleshoot.js +230 -282
  4. package/dist/src/cli/commands/neural-goal-init.js +92 -125
  5. package/dist/src/cli/commands/swarm-exec.js +317 -393
  6. package/dist/src/cli/commands/swarm.js +1 -1
  7. package/dist/src/cli/commands/validate-framework.js +983 -1100
  8. package/dist/src/cli/commands/validate.js +144 -223
  9. package/dist/src/cli/simple-commands/__tests__/agent.test.js +265 -277
  10. package/dist/src/cli/simple-commands/__tests__/memory.test.js +6 -7
  11. package/dist/src/cli/simple-commands/__tests__/swarm.test.js +373 -356
  12. package/dist/src/cli/simple-commands/__tests__/task.test.js +6 -7
  13. package/dist/src/cli/simple-commands/agent.js +157 -193
  14. package/dist/src/cli/simple-commands/analysis.js +336 -446
  15. package/dist/src/cli/simple-commands/automation-executor.js +1095 -1339
  16. package/dist/src/cli/simple-commands/automation.js +481 -469
  17. package/dist/src/cli/simple-commands/batch-manager.js +261 -313
  18. package/dist/src/cli/simple-commands/claude-telemetry.js +241 -267
  19. package/dist/src/cli/simple-commands/claude-track.js +68 -90
  20. package/dist/src/cli/simple-commands/concurrent-display.js +266 -320
  21. package/dist/src/cli/simple-commands/config.js +245 -290
  22. package/dist/src/cli/simple-commands/coordination.js +182 -234
  23. package/dist/src/cli/simple-commands/enhanced-ui-views.js +812 -615
  24. package/dist/src/cli/simple-commands/enhanced-webui-complete.js +922 -981
  25. package/dist/src/cli/simple-commands/fix-hook-variables.js +274 -294
  26. package/dist/src/cli/simple-commands/github/gh-coordinator.js +378 -457
  27. package/dist/src/cli/simple-commands/github/github-api.js +535 -574
  28. package/dist/src/cli/simple-commands/github/init.js +276 -303
  29. package/dist/src/cli/simple-commands/github.js +222 -247
  30. package/dist/src/cli/simple-commands/goal.js +51 -63
  31. package/dist/src/cli/simple-commands/hive-mind/auto-save-middleware.js +208 -278
  32. package/dist/src/cli/simple-commands/hive-mind/communication.js +601 -696
  33. package/dist/src/cli/simple-commands/hive-mind/core.js +907 -979
  34. package/dist/src/cli/simple-commands/hive-mind/db-optimizer.js +406 -655
  35. package/dist/src/cli/simple-commands/hive-mind/mcp-wrapper.js +1125 -1245
  36. package/dist/src/cli/simple-commands/hive-mind/memory.js +854 -1090
  37. package/dist/src/cli/simple-commands/hive-mind/performance-optimizer.js +459 -574
  38. package/dist/src/cli/simple-commands/hive-mind/performance-test.js +263 -347
  39. package/dist/src/cli/simple-commands/hive-mind/queen.js +727 -768
  40. package/dist/src/cli/simple-commands/hive-mind/session-manager.js +745 -1049
  41. package/dist/src/cli/simple-commands/hive-mind-optimize.js +227 -283
  42. package/dist/src/cli/simple-commands/hive-mind-wizard.js +174 -217
  43. package/dist/src/cli/simple-commands/hive-mind.js +1842 -2283
  44. package/dist/src/cli/simple-commands/hive.js +90 -79
  45. package/dist/src/cli/simple-commands/hook-safety.js +431 -521
  46. package/dist/src/cli/simple-commands/hooks/session-start-soul.js +203 -254
  47. package/dist/src/cli/simple-commands/hooks.js +1064 -1204
  48. package/dist/src/cli/simple-commands/init/agent-copier.js +294 -319
  49. package/dist/src/cli/simple-commands/init/batch-init.js +496 -562
  50. package/dist/src/cli/simple-commands/init/claude-commands/claude-flow-commands.js +13 -19
  51. package/dist/src/cli/simple-commands/init/claude-commands/optimized-claude-flow-commands.js +13 -19
  52. package/dist/src/cli/simple-commands/init/claude-commands/optimized-slash-commands.js +61 -88
  53. package/dist/src/cli/simple-commands/init/claude-commands/optimized-sparc-commands.js +125 -150
  54. package/dist/src/cli/simple-commands/init/claude-commands/slash-commands.js +42 -49
  55. package/dist/src/cli/simple-commands/init/claude-commands/sparc-commands.js +43 -61
  56. package/dist/src/cli/simple-commands/init/copy-revised-templates.js +141 -147
  57. package/dist/src/cli/simple-commands/init/executable-wrapper.js +31 -44
  58. package/dist/src/cli/simple-commands/init/gitignore-updater.js +64 -90
  59. package/dist/src/cli/simple-commands/init/help.js +104 -107
  60. package/dist/src/cli/simple-commands/init/hive-mind-init.js +509 -528
  61. package/dist/src/cli/simple-commands/init/index.js +1510 -1759
  62. package/dist/src/cli/simple-commands/init/performance-monitor.js +234 -317
  63. package/dist/src/cli/simple-commands/init/rollback/backup-manager.js +441 -504
  64. package/dist/src/cli/simple-commands/init/rollback/index.js +289 -364
  65. package/dist/src/cli/simple-commands/init/rollback/recovery-manager.js +652 -728
  66. package/dist/src/cli/simple-commands/init/rollback/rollback-executor.js +416 -481
  67. package/dist/src/cli/simple-commands/init/rollback/state-tracker.js +369 -448
  68. package/dist/src/cli/simple-commands/init/sparc/roo-readme.js +1 -2
  69. package/dist/src/cli/simple-commands/init/sparc/roomodes-config.js +122 -99
  70. package/dist/src/cli/simple-commands/init/sparc/workflows.js +32 -37
  71. package/dist/src/cli/simple-commands/init/sparc-structure.js +55 -62
  72. package/dist/src/cli/simple-commands/init/template-copier.js +421 -533
  73. package/dist/src/cli/simple-commands/init/templates/coordination-md.js +3 -6
  74. package/dist/src/cli/simple-commands/init/templates/enhanced-templates.js +344 -318
  75. package/dist/src/cli/simple-commands/init/templates/github-safe-enhanced.js +173 -218
  76. package/dist/src/cli/simple-commands/init/templates/github-safe.js +65 -75
  77. package/dist/src/cli/simple-commands/init/templates/memory-bank-md.js +3 -6
  78. package/dist/src/cli/simple-commands/init/templates/readme-files.js +2 -4
  79. package/dist/src/cli/simple-commands/init/templates/safe-hook-patterns.js +187 -230
  80. package/dist/src/cli/simple-commands/init/templates/sparc-modes.js +53 -80
  81. package/dist/src/cli/simple-commands/init/templates/verification-claude-md.js +101 -85
  82. package/dist/src/cli/simple-commands/init/validation/config-validator.js +283 -330
  83. package/dist/src/cli/simple-commands/init/validation/health-checker.js +495 -561
  84. package/dist/src/cli/simple-commands/init/validation/index.js +302 -358
  85. package/dist/src/cli/simple-commands/init/validation/mode-validator.js +308 -359
  86. package/dist/src/cli/simple-commands/init/validation/post-init-validator.js +389 -366
  87. package/dist/src/cli/simple-commands/init/validation/pre-init-validator.js +270 -268
  88. package/dist/src/cli/simple-commands/init/validation/test-runner.js +427 -447
  89. package/dist/src/cli/simple-commands/init.js +1 -2
  90. package/dist/src/cli/simple-commands/mcp-health.js +131 -158
  91. package/dist/src/cli/simple-commands/mcp-integration-layer.js +533 -634
  92. package/dist/src/cli/simple-commands/mcp.js +345 -400
  93. package/dist/src/cli/simple-commands/memory-consolidation.js +426 -537
  94. package/dist/src/cli/simple-commands/memory.js +247 -311
  95. package/dist/src/cli/simple-commands/migrate-hooks.js +39 -46
  96. package/dist/src/cli/simple-commands/monitor.js +294 -363
  97. package/dist/src/cli/simple-commands/neural.js +51 -65
  98. package/dist/src/cli/simple-commands/pair-autofix-only.js +538 -662
  99. package/dist/src/cli/simple-commands/pair-basic.js +528 -656
  100. package/dist/src/cli/simple-commands/pair-old.js +430 -543
  101. package/dist/src/cli/simple-commands/pair-working.js +615 -751
  102. package/dist/src/cli/simple-commands/pair.js +615 -751
  103. package/dist/src/cli/simple-commands/performance-hooks.js +83 -111
  104. package/dist/src/cli/simple-commands/performance-metrics.js +348 -433
  105. package/dist/src/cli/simple-commands/process-ui-enhanced.js +708 -787
  106. package/dist/src/cli/simple-commands/process-ui.js +230 -254
  107. package/dist/src/cli/simple-commands/realtime-update-system.js +525 -611
  108. package/dist/src/cli/simple-commands/sparc/architecture.js +1704 -1530
  109. package/dist/src/cli/simple-commands/sparc/commands.js +438 -516
  110. package/dist/src/cli/simple-commands/sparc/completion.js +1224 -1481
  111. package/dist/src/cli/simple-commands/sparc/coordinator.js +913 -978
  112. package/dist/src/cli/simple-commands/sparc/index.js +241 -298
  113. package/dist/src/cli/simple-commands/sparc/phase-base.js +314 -390
  114. package/dist/src/cli/simple-commands/sparc/pseudocode.js +965 -869
  115. package/dist/src/cli/simple-commands/sparc/refinement.js +980 -1273
  116. package/dist/src/cli/simple-commands/sparc/specification.js +559 -645
  117. package/dist/src/cli/simple-commands/sparc-modes/architect.js +1 -1
  118. package/dist/src/cli/simple-commands/sparc-modes/ask.js +1 -1
  119. package/dist/src/cli/simple-commands/sparc-modes/code.js +1 -1
  120. package/dist/src/cli/simple-commands/sparc-modes/debug.js +1 -1
  121. package/dist/src/cli/simple-commands/sparc-modes/devops.js +1 -1
  122. package/dist/src/cli/simple-commands/sparc-modes/docs-writer.js +1 -1
  123. package/dist/src/cli/simple-commands/sparc-modes/generic.js +1 -1
  124. package/dist/src/cli/simple-commands/sparc-modes/index.js +47 -55
  125. package/dist/src/cli/simple-commands/sparc-modes/integration.js +1 -1
  126. package/dist/src/cli/simple-commands/sparc-modes/mcp.js +1 -1
  127. package/dist/src/cli/simple-commands/sparc-modes/monitoring.js +1 -1
  128. package/dist/src/cli/simple-commands/sparc-modes/optimization.js +1 -1
  129. package/dist/src/cli/simple-commands/sparc-modes/security-review.js +1 -1
  130. package/dist/src/cli/simple-commands/sparc-modes/sparc-orchestrator.js +1 -1
  131. package/dist/src/cli/simple-commands/sparc-modes/spec-pseudocode.js +1 -1
  132. package/dist/src/cli/simple-commands/sparc-modes/supabase-admin.js +1 -1
  133. package/dist/src/cli/simple-commands/sparc-modes/swarm.js +101 -87
  134. package/dist/src/cli/simple-commands/sparc-modes/tdd.js +1 -1
  135. package/dist/src/cli/simple-commands/sparc-modes/tutorial.js +1 -1
  136. package/dist/src/cli/simple-commands/sparc.js +465 -493
  137. package/dist/src/cli/simple-commands/start-ui.js +108 -132
  138. package/dist/src/cli/simple-commands/start-wrapper.js +240 -268
  139. package/dist/src/cli/simple-commands/start.js +1 -1
  140. package/dist/src/cli/simple-commands/status.js +254 -275
  141. package/dist/src/cli/simple-commands/stream-chain-clean.js +128 -171
  142. package/dist/src/cli/simple-commands/stream-chain-fixed.js +61 -82
  143. package/dist/src/cli/simple-commands/stream-chain-real.js +267 -331
  144. package/dist/src/cli/simple-commands/stream-chain-working.js +211 -263
  145. package/dist/src/cli/simple-commands/stream-chain.js +260 -318
  146. package/dist/src/cli/simple-commands/stream-processor.js +290 -315
  147. package/dist/src/cli/simple-commands/swarm-executor.js +189 -222
  148. package/dist/src/cli/simple-commands/swarm-metrics-integration.js +208 -300
  149. package/dist/src/cli/simple-commands/swarm-ui.js +623 -703
  150. package/dist/src/cli/simple-commands/swarm-webui-integration.js +258 -286
  151. package/dist/src/cli/simple-commands/swarm.js +887 -1082
  152. package/dist/src/cli/simple-commands/task.js +161 -206
  153. package/dist/src/cli/simple-commands/timestamp-fix.js +59 -89
  154. package/dist/src/cli/simple-commands/token-tracker.js +258 -316
  155. package/dist/src/cli/simple-commands/tool-execution-framework.js +433 -519
  156. package/dist/src/cli/simple-commands/train-and-stream.js +275 -331
  157. package/dist/src/cli/simple-commands/training-pipeline.js +619 -725
  158. package/dist/src/cli/simple-commands/training.js +170 -227
  159. package/dist/src/cli/simple-commands/verification-hooks.js +261 -284
  160. package/dist/src/cli/simple-commands/verification-integration.js +389 -417
  161. package/dist/src/cli/simple-commands/verification-training-integration.js +486 -606
  162. package/dist/src/cli/simple-commands/verification.js +493 -513
  163. package/dist/src/cli/simple-commands/web-server.js +766 -836
  164. package/dist/src/cli/simple-commands/webui-validator.js +106 -124
  165. package/dist/src/coordination/event-bus/demo-wasm-integration.js +212 -251
  166. package/dist/src/coordination/event-bus/qe-event-bus.js +608 -748
  167. package/dist/src/coordination/event-bus/qe-event-bus.test.js +379 -454
  168. package/dist/src/coordination/iteration-tracker.js +363 -454
  169. package/dist/src/enterprise/analytics-manager.js +1135 -0
  170. package/dist/src/enterprise/audit-manager.js +1115 -0
  171. package/dist/src/enterprise/cloud-manager.js +891 -0
  172. package/dist/src/enterprise/deployment-manager.js +966 -0
  173. package/dist/src/enterprise/index.js +6 -0
  174. package/dist/src/enterprise/project-manager.js +584 -0
  175. package/dist/src/enterprise/security-manager.js +991 -0
  176. package/dist/src/index.js +1 -1
  177. package/dist/src/mcp/DEPRECATED.js +46 -60
  178. package/dist/src/mcp/fixes/mcp-error-fixes.js +115 -134
  179. package/dist/src/mcp/implementations/agent-tracker.js +114 -128
  180. package/dist/src/mcp/implementations/daa-tools.js +292 -350
  181. package/dist/src/mcp/implementations/workflow-tools.js +329 -361
  182. package/dist/src/mcp/mcp-config-manager.js +1183 -1331
  183. package/dist/src/mcp/mcp-server-novice-simplified.js +11 -17
  184. package/dist/src/mcp/mcp-server-novice.js +11 -17
  185. package/dist/src/mcp/mcp-server-sdk.js +11 -17
  186. package/dist/src/mcp/mcp-server.js +1620 -1484
  187. package/dist/src/mcp/ruv-swarm-wrapper.js +209 -239
  188. package/dist/src/memory/advanced-serializer.js +609 -589
  189. package/dist/src/memory/enhanced-examples.js +220 -305
  190. package/dist/src/memory/enhanced-memory.js +295 -336
  191. package/dist/src/memory/enhanced-session-serializer.js +408 -492
  192. package/dist/src/memory/fallback-memory-system.js +900 -1021
  193. package/dist/src/memory/fallback-store.js +93 -131
  194. package/dist/src/memory/high-performance-serialization.js +592 -730
  195. package/dist/src/memory/in-memory-store.js +161 -213
  196. package/dist/src/memory/index.js +123 -157
  197. package/dist/src/memory/lock-free-structures.js +578 -764
  198. package/dist/src/memory/memory-mapped-persistence.js +585 -766
  199. package/dist/src/memory/memory-pressure-manager.js +569 -707
  200. package/dist/src/memory/migration.js +358 -445
  201. package/dist/src/memory/shared-memory.js +641 -768
  202. package/dist/src/memory/sqlite-store.js +245 -325
  203. package/dist/src/memory/sqlite-wrapper.js +122 -151
  204. package/dist/src/memory/swarm-memory.js +470 -603
  205. package/dist/src/memory/test-example.js +126 -134
  206. package/dist/src/memory/ultra-fast-memory-store.js +622 -821
  207. package/dist/src/memory/unified-memory-manager.js +356 -437
  208. package/dist/src/migration/index.js +92 -0
  209. package/dist/src/migration/logger.js +121 -0
  210. package/dist/src/migration/migration-analyzer.js +268 -0
  211. package/dist/src/migration/migration-runner.js +522 -0
  212. package/dist/src/migration/migration-validator.js +285 -0
  213. package/dist/src/migration/progress-reporter.js +150 -0
  214. package/dist/src/migration/rollback-manager.js +321 -0
  215. package/dist/src/migration/tests/migration-system.test.js +7 -0
  216. package/dist/src/migration/types.js +3 -0
  217. package/dist/src/swarm/CodeRefactoringSwarm.js +777 -952
  218. package/dist/src/swarm/__tests__/integration.test.js +227 -0
  219. package/dist/src/swarm/__tests__/prompt-copier.test.js +344 -0
  220. package/dist/src/swarm/advanced-orchestrator.js +1095 -0
  221. package/dist/src/swarm/claude-code-interface.js +961 -0
  222. package/dist/src/swarm/claude-flow-executor.js +229 -0
  223. package/dist/src/swarm/consensus-coordinator.js +475 -0
  224. package/dist/src/swarm/coordinator.js +2993 -0
  225. package/dist/src/swarm/direct-executor.js +1180 -0
  226. package/dist/src/swarm/error-recovery/advanced-error-detection.js +691 -0
  227. package/dist/src/swarm/error-recovery/automated-recovery-workflows.js +998 -0
  228. package/dist/src/swarm/error-recovery/error-recovery-coordinator.js +1197 -0
  229. package/dist/src/swarm/error-recovery/recovery-monitoring.js +772 -0
  230. package/dist/src/swarm/error-recovery/resilience-architecture.js +714 -0
  231. package/dist/src/swarm/error-recovery/self-healing-mechanisms.js +1319 -0
  232. package/dist/src/swarm/error-recovery/test-error-recovery-effectiveness.js +808 -0
  233. package/dist/src/swarm/executor-v2.js +322 -0
  234. package/dist/src/swarm/executor.js +815 -0
  235. package/dist/src/swarm/hive-mind-integration.js +703 -0
  236. package/dist/src/swarm/index.js +41 -0
  237. package/dist/src/swarm/json-output-aggregator.js +267 -0
  238. package/dist/src/swarm/large-scale-coordinator.js +542 -0
  239. package/dist/src/swarm/mcp-integration-wrapper.js +628 -0
  240. package/dist/src/swarm/memory.js +1117 -0
  241. package/dist/src/swarm/optimizations/__tests__/optimization.test.js +348 -0
  242. package/dist/src/swarm/optimizations/async-file-manager.js +285 -0
  243. package/dist/src/swarm/optimizations/circular-buffer.js +162 -0
  244. package/dist/src/swarm/optimizations/connection-pool.js +244 -0
  245. package/dist/src/swarm/optimizations/index.js +28 -0
  246. package/dist/src/swarm/optimizations/optimized-executor.js +320 -0
  247. package/dist/src/swarm/optimizations/ttl-map.js +234 -0
  248. package/dist/src/swarm/prompt-cli.js +200 -0
  249. package/dist/src/swarm/prompt-copier-enhanced.js +202 -0
  250. package/dist/src/swarm/prompt-copier.js +381 -0
  251. package/dist/src/swarm/prompt-manager.js +295 -0
  252. package/dist/src/swarm/prompt-utils.js +310 -0
  253. package/dist/src/swarm/result-aggregator.js +718 -0
  254. package/dist/src/swarm/sparc-executor.js +1568 -0
  255. package/dist/src/swarm/strategies/auto.js +758 -0
  256. package/dist/src/swarm/strategies/base.js +128 -0
  257. package/dist/src/swarm/strategies/research.js +914 -0
  258. package/dist/src/swarm/strategies/strategy-metrics-patch.js +2 -0
  259. package/dist/src/swarm/types.js +52 -0
  260. package/dist/src/swarm/workers/copy-worker.js +56 -0
  261. package/dist/src/utils/__tests__/github-cli-safety-wrapper.test.js +332 -400
  262. package/dist/src/utils/github-cli-safe.js +56 -64
  263. package/dist/src/utils/github-cli-safety-wrapper.js +451 -546
  264. package/dist/src/utils/npx-isolated-cache.js +104 -119
  265. package/dist/src/utils/preference-manager.js +622 -652
  266. package/dist/src/utils/timezone-utils.js +86 -105
  267. package/dist/src/validators/epic-config-schema.js +214 -0
  268. package/dist/src/validators/index.js +10 -0
  269. package/dist/src/validators/swarm-init-validator.js +259 -0
  270. package/dist/src/validators/todowrite-batching-validator.js +215 -0
  271. package/dist/src/validators/todowrite-integration.js +187 -0
  272. package/package.json +2 -2
@@ -10,361 +10,296 @@
10
10
  * - Circuit breaker for Stop hooks
11
11
  * - Configuration validation
12
12
  * - Emergency override flags
13
- */
14
-
15
- import { printError, printWarning, printSuccess } from '../utils.js';
16
- import { existsSync, readFileSync } from 'fs';
17
- import path from 'path';
18
-
13
+ */ import { printError, printWarning, printSuccess } from "../utils.js";
14
+ import { existsSync, readFileSync } from "fs";
15
+ import path from "path";
19
16
  /**
20
17
  * Hook Safety Configuration
21
- */
22
- const HOOK_SAFETY_CONFIG = {
23
- // Maximum hook execution depth before blocking
24
- MAX_HOOK_DEPTH: 3,
25
-
26
- // Maximum Stop hook executions per session
27
- MAX_STOP_HOOK_EXECUTIONS: 2,
28
-
29
- // Circuit breaker timeout (milliseconds)
30
- CIRCUIT_BREAKER_TIMEOUT: 60000, // 1 minute
31
-
32
- // Environment variables for context detection
33
- ENV_VARS: {
34
- CONTEXT: 'CLAUDE_HOOK_CONTEXT',
35
- DEPTH: 'CLAUDE_HOOK_DEPTH',
36
- SESSION_ID: 'CLAUDE_HOOK_SESSION_ID',
37
- SKIP_HOOKS: 'CLAUDE_SKIP_HOOKS',
38
- SAFE_MODE: 'CLAUDE_SAFE_MODE',
39
- },
18
+ */ const HOOK_SAFETY_CONFIG = {
19
+ // Maximum hook execution depth before blocking
20
+ MAX_HOOK_DEPTH: 3,
21
+ // Maximum Stop hook executions per session
22
+ MAX_STOP_HOOK_EXECUTIONS: 2,
23
+ // Circuit breaker timeout (milliseconds)
24
+ CIRCUIT_BREAKER_TIMEOUT: 60000,
25
+ // Environment variables for context detection
26
+ ENV_VARS: {
27
+ CONTEXT: 'CLAUDE_HOOK_CONTEXT',
28
+ DEPTH: 'CLAUDE_HOOK_DEPTH',
29
+ SESSION_ID: 'CLAUDE_HOOK_SESSION_ID',
30
+ SKIP_HOOKS: 'CLAUDE_SKIP_HOOKS',
31
+ SAFE_MODE: 'CLAUDE_SAFE_MODE'
32
+ }
40
33
  };
41
-
42
34
  /**
43
35
  * Global hook execution tracking
44
- */
45
- class HookExecutionTracker {
46
- constructor() {
47
- this.executions = new Map();
48
- this.sessionId = this.generateSessionId();
49
- this.resetTimeout = null;
50
- }
51
-
52
- generateSessionId() {
53
- return `session-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
54
- }
55
-
56
- track(hookType) {
57
- const key = `${this.sessionId}:${hookType}`;
58
- const count = this.executions.get(key) || 0;
59
- this.executions.set(key, count + 1);
60
-
61
- // Auto-reset after timeout
62
- if (this.resetTimeout) clearTimeout(this.resetTimeout);
63
- this.resetTimeout = setTimeout(() => {
64
- this.executions.clear();
65
- }, HOOK_SAFETY_CONFIG.CIRCUIT_BREAKER_TIMEOUT);
66
-
67
- return count + 1;
68
- }
69
-
70
- getExecutionCount(hookType) {
71
- const key = `${this.sessionId}:${hookType}`;
72
- return this.executions.get(key) || 0;
73
- }
74
-
75
- reset() {
76
- this.executions.clear();
77
- this.sessionId = this.generateSessionId();
78
- }
79
- }
80
-
36
+ */ let HookExecutionTracker = class HookExecutionTracker {
37
+ generateSessionId() {
38
+ return `session-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
39
+ }
40
+ track(hookType) {
41
+ const key = `${this.sessionId}:${hookType}`;
42
+ const count = this.executions.get(key) || 0;
43
+ this.executions.set(key, count + 1);
44
+ // Auto-reset after timeout
45
+ if (this.resetTimeout) clearTimeout(this.resetTimeout);
46
+ this.resetTimeout = setTimeout(()=>{
47
+ this.executions.clear();
48
+ }, HOOK_SAFETY_CONFIG.CIRCUIT_BREAKER_TIMEOUT);
49
+ return count + 1;
50
+ }
51
+ getExecutionCount(hookType) {
52
+ const key = `${this.sessionId}:${hookType}`;
53
+ return this.executions.get(key) || 0;
54
+ }
55
+ reset() {
56
+ this.executions.clear();
57
+ this.sessionId = this.generateSessionId();
58
+ }
59
+ constructor(){
60
+ this.executions = new Map();
61
+ this.sessionId = this.generateSessionId();
62
+ this.resetTimeout = null;
63
+ }
64
+ };
81
65
  // Global instance
82
66
  const executionTracker = new HookExecutionTracker();
83
-
84
67
  /**
85
68
  * Hook Context Manager - Tracks hook execution context
86
- */
87
- export class HookContextManager {
88
- static setContext(hookType, depth = 1) {
89
- process.env[HOOK_SAFETY_CONFIG.ENV_VARS.CONTEXT] = hookType;
90
- process.env[HOOK_SAFETY_CONFIG.ENV_VARS.DEPTH] = depth.toString();
91
- process.env[HOOK_SAFETY_CONFIG.ENV_VARS.SESSION_ID] = executionTracker.sessionId;
92
- }
93
-
94
- static getContext() {
95
- return {
96
- type: process.env[HOOK_SAFETY_CONFIG.ENV_VARS.CONTEXT],
97
- depth: parseInt(process.env[HOOK_SAFETY_CONFIG.ENV_VARS.DEPTH] || '0'),
98
- sessionId: process.env[HOOK_SAFETY_CONFIG.ENV_VARS.SESSION_ID],
99
- skipHooks: process.env[HOOK_SAFETY_CONFIG.ENV_VARS.SKIP_HOOKS] === 'true',
100
- safeMode: process.env[HOOK_SAFETY_CONFIG.ENV_VARS.SAFE_MODE] === 'true',
101
- };
102
- }
103
-
104
- static clearContext() {
105
- delete process.env[HOOK_SAFETY_CONFIG.ENV_VARS.CONTEXT];
106
- delete process.env[HOOK_SAFETY_CONFIG.ENV_VARS.DEPTH];
107
- delete process.env[HOOK_SAFETY_CONFIG.ENV_VARS.SESSION_ID];
108
- }
109
-
110
- static isInHookContext() {
111
- return !!process.env[HOOK_SAFETY_CONFIG.ENV_VARS.CONTEXT];
112
- }
113
-
114
- static setSafeMode(enabled = true) {
115
- if (enabled) {
116
- process.env[HOOK_SAFETY_CONFIG.ENV_VARS.SAFE_MODE] = 'true';
117
- } else {
118
- delete process.env[HOOK_SAFETY_CONFIG.ENV_VARS.SAFE_MODE];
69
+ */ export class HookContextManager {
70
+ static setContext(hookType, depth = 1) {
71
+ process.env[HOOK_SAFETY_CONFIG.ENV_VARS.CONTEXT] = hookType;
72
+ process.env[HOOK_SAFETY_CONFIG.ENV_VARS.DEPTH] = depth.toString();
73
+ process.env[HOOK_SAFETY_CONFIG.ENV_VARS.SESSION_ID] = executionTracker.sessionId;
119
74
  }
120
- }
121
-
122
- static setSkipHooks(enabled = true) {
123
- if (enabled) {
124
- process.env[HOOK_SAFETY_CONFIG.ENV_VARS.SKIP_HOOKS] = 'true';
125
- } else {
126
- delete process.env[HOOK_SAFETY_CONFIG.ENV_VARS.SKIP_HOOKS];
75
+ static getContext() {
76
+ return {
77
+ type: process.env[HOOK_SAFETY_CONFIG.ENV_VARS.CONTEXT],
78
+ depth: parseInt(process.env[HOOK_SAFETY_CONFIG.ENV_VARS.DEPTH] || '0'),
79
+ sessionId: process.env[HOOK_SAFETY_CONFIG.ENV_VARS.SESSION_ID],
80
+ skipHooks: process.env[HOOK_SAFETY_CONFIG.ENV_VARS.SKIP_HOOKS] === 'true',
81
+ safeMode: process.env[HOOK_SAFETY_CONFIG.ENV_VARS.SAFE_MODE] === 'true'
82
+ };
83
+ }
84
+ static clearContext() {
85
+ delete process.env[HOOK_SAFETY_CONFIG.ENV_VARS.CONTEXT];
86
+ delete process.env[HOOK_SAFETY_CONFIG.ENV_VARS.DEPTH];
87
+ delete process.env[HOOK_SAFETY_CONFIG.ENV_VARS.SESSION_ID];
88
+ }
89
+ static isInHookContext() {
90
+ return !!process.env[HOOK_SAFETY_CONFIG.ENV_VARS.CONTEXT];
91
+ }
92
+ static setSafeMode(enabled = true) {
93
+ if (enabled) {
94
+ process.env[HOOK_SAFETY_CONFIG.ENV_VARS.SAFE_MODE] = 'true';
95
+ } else {
96
+ delete process.env[HOOK_SAFETY_CONFIG.ENV_VARS.SAFE_MODE];
97
+ }
98
+ }
99
+ static setSkipHooks(enabled = true) {
100
+ if (enabled) {
101
+ process.env[HOOK_SAFETY_CONFIG.ENV_VARS.SKIP_HOOKS] = 'true';
102
+ } else {
103
+ delete process.env[HOOK_SAFETY_CONFIG.ENV_VARS.SKIP_HOOKS];
104
+ }
127
105
  }
128
- }
129
106
  }
130
-
131
107
  /**
132
108
  * Command Validator - Validates commands for hook safety
133
- */
134
- export class HookCommandValidator {
135
- /**
109
+ */ export class HookCommandValidator {
110
+ /**
136
111
  * Validate if a command is safe to execute from a hook
137
- */
138
- static validateCommand(command, hookType) {
139
- const context = HookContextManager.getContext();
140
- const warnings = [];
141
- const errors = [];
142
-
143
- // Critical check: Claude commands in Stop hooks
144
- if (hookType === 'Stop' && this.isClaudeCommand(command)) {
145
- errors.push({
146
- type: 'CRITICAL_RECURSION_RISK',
147
- message:
148
- '🚨 CRITICAL ERROR: Claude command detected in Stop hook!\n' +
149
- 'This creates an INFINITE LOOP that can cost THOUSANDS OF DOLLARS.\n' +
150
- 'Stop hooks that call "claude" commands bypass rate limits and\n' +
151
- 'can result in massive unexpected API charges.\n\n' +
152
- 'BLOCKED FOR SAFETY - Use alternative patterns instead.',
153
- });
112
+ */ static validateCommand(command, hookType) {
113
+ const context = HookContextManager.getContext();
114
+ const warnings = [];
115
+ const errors = [];
116
+ // Critical check: Claude commands in Stop hooks
117
+ if (hookType === 'Stop' && this.isClaudeCommand(command)) {
118
+ errors.push({
119
+ type: 'CRITICAL_RECURSION_RISK',
120
+ message: '🚨 CRITICAL ERROR: Claude command detected in Stop hook!\n' + 'This creates an INFINITE LOOP that can cost THOUSANDS OF DOLLARS.\n' + 'Stop hooks that call "claude" commands bypass rate limits and\n' + 'can result in massive unexpected API charges.\n\n' + 'BLOCKED FOR SAFETY - Use alternative patterns instead.'
121
+ });
122
+ }
123
+ // General recursion detection
124
+ if (context.type && this.isClaudeCommand(command)) {
125
+ const depth = context.depth;
126
+ if (depth >= HOOK_SAFETY_CONFIG.MAX_HOOK_DEPTH) {
127
+ errors.push({
128
+ type: 'HOOK_RECURSION_LIMIT',
129
+ message: `🚨 Hook recursion limit exceeded! (Depth: ${depth})\n` + `Hook type: ${context.type}\n` + 'Blocking execution to prevent infinite loop.'
130
+ });
131
+ } else {
132
+ warnings.push({
133
+ type: 'POTENTIAL_RECURSION',
134
+ message: `⚠️ WARNING: Claude command in ${context.type} hook (depth: ${depth})\n` + 'This could create recursion. Consider using --skip-hooks flag.'
135
+ });
136
+ }
137
+ }
138
+ // Check for other dangerous patterns
139
+ if (this.isDangerousPattern(command, hookType)) {
140
+ warnings.push({
141
+ type: 'DANGEROUS_PATTERN',
142
+ message: `⚠️ WARNING: Potentially dangerous hook pattern detected.\n` + 'Review the command and consider safer alternatives.'
143
+ });
144
+ }
145
+ return {
146
+ warnings,
147
+ errors,
148
+ safe: errors.length === 0
149
+ };
154
150
  }
155
-
156
- // General recursion detection
157
- if (context.type && this.isClaudeCommand(command)) {
158
- const depth = context.depth;
159
-
160
- if (depth >= HOOK_SAFETY_CONFIG.MAX_HOOK_DEPTH) {
161
- errors.push({
162
- type: 'HOOK_RECURSION_LIMIT',
163
- message:
164
- `🚨 Hook recursion limit exceeded! (Depth: ${depth})\n` +
165
- `Hook type: ${context.type}\n` +
166
- 'Blocking execution to prevent infinite loop.',
167
- });
168
- } else {
169
- warnings.push({
170
- type: 'POTENTIAL_RECURSION',
171
- message:
172
- `⚠️ WARNING: Claude command in ${context.type} hook (depth: ${depth})\n` +
173
- 'This could create recursion. Consider using --skip-hooks flag.',
174
- });
175
- }
151
+ static isClaudeCommand(command) {
152
+ // Match various forms of claude command invocation
153
+ const claudePatterns = [
154
+ /\bclaude\b/,
155
+ /claude-code\b/,
156
+ /npx\s+claude\b/,
157
+ /\.\/claude\b/,
158
+ /claude\.exe\b/
159
+ ];
160
+ return claudePatterns.some((pattern)=>pattern.test(command));
176
161
  }
177
-
178
- // Check for other dangerous patterns
179
- if (this.isDangerousPattern(command, hookType)) {
180
- warnings.push({
181
- type: 'DANGEROUS_PATTERN',
182
- message:
183
- `⚠️ WARNING: Potentially dangerous hook pattern detected.\n` +
184
- 'Review the command and consider safer alternatives.',
185
- });
162
+ static isDangerousPattern(command, hookType) {
163
+ const dangerousPatterns = [
164
+ // Commands that could trigger more hooks
165
+ /git\s+commit.*--all/,
166
+ /git\s+add\s+\./,
167
+ // File operations that might trigger watchers
168
+ /watch\s+.*claude/,
169
+ /nodemon.*claude/,
170
+ // Recursive script execution
171
+ /bash.*hook/,
172
+ /sh.*hook/
173
+ ];
174
+ return dangerousPatterns.some((pattern)=>pattern.test(command));
186
175
  }
187
-
188
- return { warnings, errors, safe: errors.length === 0 };
189
- }
190
-
191
- static isClaudeCommand(command) {
192
- // Match various forms of claude command invocation
193
- const claudePatterns = [
194
- /\bclaude\b/, // Direct claude command
195
- /claude-code\b/, // claude-code command
196
- /npx\s+claude\b/, // NPX claude
197
- /\.\/claude\b/, // Local claude wrapper
198
- /claude\.exe\b/, // Windows executable
199
- ];
200
-
201
- return claudePatterns.some((pattern) => pattern.test(command));
202
- }
203
-
204
- static isDangerousPattern(command, hookType) {
205
- const dangerousPatterns = [
206
- // Commands that could trigger more hooks
207
- /git\s+commit.*--all/,
208
- /git\s+add\s+\./,
209
- // File operations that might trigger watchers
210
- /watch\s+.*claude/,
211
- /nodemon.*claude/,
212
- // Recursive script execution
213
- /bash.*hook/,
214
- /sh.*hook/,
215
- ];
216
-
217
- return dangerousPatterns.some((pattern) => pattern.test(command));
218
- }
219
176
  }
220
-
221
177
  /**
222
178
  * Circuit Breaker - Prevents runaway hook execution
223
- */
224
- export class HookCircuitBreaker {
225
- /**
179
+ */ export class HookCircuitBreaker {
180
+ /**
226
181
  * Check if hook execution should be allowed
227
- */
228
- static checkExecution(hookType) {
229
- const executionCount = executionTracker.track(hookType);
230
-
231
- // Stop hook protection - maximum 2 executions per session
232
- if (hookType === 'Stop' && executionCount > HOOK_SAFETY_CONFIG.MAX_STOP_HOOK_EXECUTIONS) {
233
- throw new Error(
234
- `🚨 CIRCUIT BREAKER ACTIVATED!\n` +
235
- `Stop hook has executed ${executionCount} times in this session.\n` +
236
- `This indicates a potential infinite loop that could cost thousands of dollars.\n` +
237
- `Execution blocked for financial protection.\n\n` +
238
- `To reset: Use --reset-circuit-breaker flag or restart your session.`,
239
- );
182
+ */ static checkExecution(hookType) {
183
+ const executionCount = executionTracker.track(hookType);
184
+ // Stop hook protection - maximum 2 executions per session
185
+ if (hookType === 'Stop' && executionCount > HOOK_SAFETY_CONFIG.MAX_STOP_HOOK_EXECUTIONS) {
186
+ throw new Error(`🚨 CIRCUIT BREAKER ACTIVATED!\n` + `Stop hook has executed ${executionCount} times in this session.\n` + `This indicates a potential infinite loop that could cost thousands of dollars.\n` + `Execution blocked for financial protection.\n\n` + `To reset: Use --reset-circuit-breaker flag or restart your session.`);
187
+ }
188
+ // General protection for any hook type
189
+ if (executionCount > 20) {
190
+ throw new Error(`🚨 CIRCUIT BREAKER: ${hookType} hook executed ${executionCount} times!\n` + `This is highly unusual and indicates a potential problem.\n` + `Execution blocked to prevent system overload.`);
191
+ }
192
+ // Log warnings for concerning patterns
193
+ if (hookType === 'Stop' && executionCount > 1) {
194
+ printWarning(`⚠️ Stop hook execution #${executionCount} detected. Monitor for recursion.`);
195
+ }
196
+ return true;
240
197
  }
241
-
242
- // General protection for any hook type
243
- if (executionCount > 20) {
244
- throw new Error(
245
- `🚨 CIRCUIT BREAKER: ${hookType} hook executed ${executionCount} times!\n` +
246
- `This is highly unusual and indicates a potential problem.\n` +
247
- `Execution blocked to prevent system overload.`,
248
- );
198
+ static reset() {
199
+ executionTracker.reset();
200
+ printSuccess('Circuit breaker reset successfully.');
249
201
  }
250
-
251
- // Log warnings for concerning patterns
252
- if (hookType === 'Stop' && executionCount > 1) {
253
- printWarning(`⚠️ Stop hook execution #${executionCount} detected. Monitor for recursion.`);
202
+ static getStatus() {
203
+ return {
204
+ sessionId: executionTracker.sessionId,
205
+ executions: Array.from(executionTracker.executions.entries()).map(([key, count])=>{
206
+ const [sessionId, hookType] = key.split(':');
207
+ return {
208
+ hookType,
209
+ count
210
+ };
211
+ })
212
+ };
254
213
  }
255
-
256
- return true;
257
- }
258
-
259
- static reset() {
260
- executionTracker.reset();
261
- printSuccess('Circuit breaker reset successfully.');
262
- }
263
-
264
- static getStatus() {
265
- return {
266
- sessionId: executionTracker.sessionId,
267
- executions: Array.from(executionTracker.executions.entries()).map(([key, count]) => {
268
- const [sessionId, hookType] = key.split(':');
269
- return { hookType, count };
270
- }),
271
- };
272
- }
273
214
  }
274
-
275
215
  /**
276
216
  * Configuration Validator - Validates hook configurations for safety
277
- */
278
- export class HookConfigValidator {
279
- /**
217
+ */ export class HookConfigValidator {
218
+ /**
280
219
  * Validate Claude Code settings.json for dangerous hook configurations
281
- */
282
- static validateClaudeCodeConfig(configPath = null) {
283
- if (!configPath) {
284
- // Try to find Claude Code settings
285
- const possiblePaths = [
286
- path.join(process.env.HOME || '.', '.claude', 'settings.json'),
287
- path.join(process.cwd(), '.claude', 'settings.json'),
288
- path.join(process.cwd(), 'settings.json'),
289
- ];
290
-
291
- configPath = possiblePaths.find((p) => existsSync(p));
292
-
293
- if (!configPath) {
294
- return { safe: true, message: 'No Claude Code configuration found.' };
295
- }
296
- }
297
-
298
- try {
299
- const config = JSON.parse(readFileSync(configPath, 'utf8'));
300
- const validation = this.validateHooksConfig(config.hooks || {});
301
-
302
- return {
303
- safe: validation.errors.length === 0,
304
- configPath,
305
- ...validation,
306
- };
307
- } catch (err) {
308
- return {
309
- safe: false,
310
- error: `Failed to validate configuration: ${err.message}`,
311
- configPath,
312
- };
220
+ */ static validateClaudeCodeConfig(configPath = null) {
221
+ if (!configPath) {
222
+ // Try to find Claude Code settings
223
+ const possiblePaths = [
224
+ path.join(process.env.HOME || '.', '.claude', 'settings.json'),
225
+ path.join(process.cwd(), '.claude', 'settings.json'),
226
+ path.join(process.cwd(), 'settings.json')
227
+ ];
228
+ configPath = possiblePaths.find((p)=>existsSync(p));
229
+ if (!configPath) {
230
+ return {
231
+ safe: true,
232
+ message: 'No Claude Code configuration found.'
233
+ };
234
+ }
235
+ }
236
+ try {
237
+ const config = JSON.parse(readFileSync(configPath, 'utf8'));
238
+ const validation = this.validateHooksConfig(config.hooks || {});
239
+ return {
240
+ safe: validation.errors.length === 0,
241
+ configPath,
242
+ ...validation
243
+ };
244
+ } catch (err) {
245
+ return {
246
+ safe: false,
247
+ error: `Failed to validate configuration: ${err.message}`,
248
+ configPath
249
+ };
250
+ }
313
251
  }
314
- }
315
-
316
- /**
252
+ /**
317
253
  * Validate hooks configuration object
318
- */
319
- static validateHooksConfig(hooksConfig) {
320
- const warnings = [];
321
- const errors = [];
322
-
323
- // Check Stop hooks specifically
324
- if (hooksConfig.Stop) {
325
- for (const hookGroup of hooksConfig.Stop) {
326
- for (const hook of hookGroup.hooks || []) {
327
- if (hook.type === 'command' && hook.command) {
328
- const result = HookCommandValidator.validateCommand(hook.command, 'Stop');
329
- warnings.push(...result.warnings);
330
- errors.push(...result.errors);
331
- }
254
+ */ static validateHooksConfig(hooksConfig) {
255
+ const warnings = [];
256
+ const errors = [];
257
+ // Check Stop hooks specifically
258
+ if (hooksConfig.Stop) {
259
+ for (const hookGroup of hooksConfig.Stop){
260
+ for (const hook of hookGroup.hooks || []){
261
+ if (hook.type === 'command' && hook.command) {
262
+ const result = HookCommandValidator.validateCommand(hook.command, 'Stop');
263
+ warnings.push(...result.warnings);
264
+ errors.push(...result.errors);
265
+ }
266
+ }
267
+ }
332
268
  }
333
- }
334
- }
335
-
336
- // Check other dangerous hook types
337
- const dangerousHookTypes = ['SubagentStop', 'PostToolUse'];
338
- for (const hookType of dangerousHookTypes) {
339
- if (hooksConfig[hookType]) {
340
- for (const hookGroup of hooksConfig[hookType]) {
341
- for (const hook of hookGroup.hooks || []) {
342
- if (hook.type === 'command' && hook.command) {
343
- const result = HookCommandValidator.validateCommand(hook.command, hookType);
344
- warnings.push(...result.warnings);
345
- errors.push(...result.errors);
269
+ // Check other dangerous hook types
270
+ const dangerousHookTypes = [
271
+ 'SubagentStop',
272
+ 'PostToolUse'
273
+ ];
274
+ for (const hookType of dangerousHookTypes){
275
+ if (hooksConfig[hookType]) {
276
+ for (const hookGroup of hooksConfig[hookType]){
277
+ for (const hook of hookGroup.hooks || []){
278
+ if (hook.type === 'command' && hook.command) {
279
+ const result = HookCommandValidator.validateCommand(hook.command, hookType);
280
+ warnings.push(...result.warnings);
281
+ errors.push(...result.errors);
282
+ }
283
+ }
284
+ }
346
285
  }
347
- }
348
286
  }
349
- }
287
+ return {
288
+ warnings,
289
+ errors
290
+ };
350
291
  }
351
-
352
- return { warnings, errors };
353
- }
354
-
355
- /**
292
+ /**
356
293
  * Generate safe configuration recommendations
357
- */
358
- static generateSafeAlternatives(dangerousConfig) {
359
- const alternatives = [];
360
-
361
- // Example: Stop hook calling claude
362
- if (dangerousConfig.includes('claude')) {
363
- alternatives.push({
364
- pattern: 'Stop hook with claude command',
365
- problem: 'Creates infinite recursion loop',
366
- solution: 'Use flag-based approach instead',
367
- example: `
294
+ */ static generateSafeAlternatives(dangerousConfig) {
295
+ const alternatives = [];
296
+ // Example: Stop hook calling claude
297
+ if (dangerousConfig.includes('claude')) {
298
+ alternatives.push({
299
+ pattern: 'Stop hook with claude command',
300
+ problem: 'Creates infinite recursion loop',
301
+ solution: 'Use flag-based approach instead',
302
+ example: `
368
303
  // Instead of this DANGEROUS pattern:
369
304
  {
370
305
  "Stop": [{
@@ -380,14 +315,13 @@ export class HookConfigValidator {
380
315
  }
381
316
 
382
317
  // Then manually run: claude -c -p "Update history" when needed
383
- `,
384
- });
385
-
386
- alternatives.push({
387
- pattern: 'PostToolUse hook alternative',
388
- problem: 'Stop hooks execute too frequently',
389
- solution: 'Use PostToolUse for specific tools',
390
- example: `
318
+ `
319
+ });
320
+ alternatives.push({
321
+ pattern: 'PostToolUse hook alternative',
322
+ problem: 'Stop hooks execute too frequently',
323
+ solution: 'Use PostToolUse for specific tools',
324
+ example: `
391
325
  // SAFER: Use PostToolUse for specific operations
392
326
  {
393
327
  "PostToolUse": [{
@@ -395,195 +329,177 @@ export class HookConfigValidator {
395
329
  "hooks": [{"type": "command", "command": "echo 'File modified' >> ~/.claude/changes.log"}]
396
330
  }]
397
331
  }
398
- `,
399
- });
332
+ `
333
+ });
334
+ }
335
+ return alternatives;
400
336
  }
401
-
402
- return alternatives;
403
- }
404
337
  }
405
-
406
338
  /**
407
339
  * Safe Hook Execution Wrapper
408
- */
409
- export class SafeHookExecutor {
410
- /**
340
+ */ export class SafeHookExecutor {
341
+ /**
411
342
  * Safely execute a hook command with all safety checks
412
- */
413
- static async executeHookCommand(command, hookType, options = {}) {
414
- try {
415
- // Skip if hooks are disabled
416
- if (HookContextManager.getContext().skipHooks) {
417
- console.log(`⏭️ Skipping ${hookType} hook (hooks disabled)`);
418
- return { success: true, skipped: true };
419
- }
420
-
421
- // Circuit breaker check
422
- HookCircuitBreaker.checkExecution(hookType);
423
-
424
- // Command validation
425
- const validation = HookCommandValidator.validateCommand(command, hookType);
426
-
427
- // Show warnings
428
- for (const warning of validation.warnings) {
429
- printWarning(warning.message);
430
- }
431
-
432
- // Block on errors
433
- if (!validation.safe) {
434
- for (const error of validation.errors) {
435
- printError(error.message);
343
+ */ static async executeHookCommand(command, hookType, options = {}) {
344
+ try {
345
+ // Skip if hooks are disabled
346
+ if (HookContextManager.getContext().skipHooks) {
347
+ console.log(`⏭️ Skipping ${hookType} hook (hooks disabled)`);
348
+ return {
349
+ success: true,
350
+ skipped: true
351
+ };
352
+ }
353
+ // Circuit breaker check
354
+ HookCircuitBreaker.checkExecution(hookType);
355
+ // Command validation
356
+ const validation = HookCommandValidator.validateCommand(command, hookType);
357
+ // Show warnings
358
+ for (const warning of validation.warnings){
359
+ printWarning(warning.message);
360
+ }
361
+ // Block on errors
362
+ if (!validation.safe) {
363
+ for (const error of validation.errors){
364
+ printError(error.message);
365
+ }
366
+ return {
367
+ success: false,
368
+ blocked: true,
369
+ errors: validation.errors
370
+ };
371
+ }
372
+ // Set hook context for nested calls
373
+ const currentContext = HookContextManager.getContext();
374
+ const newDepth = currentContext.depth + 1;
375
+ HookContextManager.setContext(hookType, newDepth);
376
+ // Execute the command with safety context
377
+ const result = await this.executeCommand(command, options);
378
+ return {
379
+ success: true,
380
+ result
381
+ };
382
+ } catch (err) {
383
+ printError(`Hook execution failed: ${err.message}`);
384
+ return {
385
+ success: false,
386
+ error: err.message
387
+ };
388
+ } finally{
389
+ // Clear context
390
+ HookContextManager.clearContext();
436
391
  }
437
- return { success: false, blocked: true, errors: validation.errors };
438
- }
439
-
440
- // Set hook context for nested calls
441
- const currentContext = HookContextManager.getContext();
442
- const newDepth = currentContext.depth + 1;
443
- HookContextManager.setContext(hookType, newDepth);
444
-
445
- // Execute the command with safety context
446
- const result = await this.executeCommand(command, options);
447
-
448
- return { success: true, result };
449
- } catch (err) {
450
- printError(`Hook execution failed: ${err.message}`);
451
- return { success: false, error: err.message };
452
- } finally {
453
- // Clear context
454
- HookContextManager.clearContext();
455
392
  }
456
- }
457
-
458
- static async executeCommand(command, options = {}) {
459
- // This would integrate with the actual command execution system
460
- // For now, just log what would be executed
461
- console.log(`🔗 Executing hook command: ${command}`);
462
-
463
- // Here you would actually execute the command
464
- // return await execCommand(command, options);
465
-
466
- return { stdout: '', stderr: '', exitCode: 0 };
467
- }
393
+ static async executeCommand(command, options = {}) {
394
+ // This would integrate with the actual command execution system
395
+ // For now, just log what would be executed
396
+ console.log(`🔗 Executing hook command: ${command}`);
397
+ // Here you would actually execute the command
398
+ // return await execCommand(command, options);
399
+ return {
400
+ stdout: '',
401
+ stderr: '',
402
+ exitCode: 0
403
+ };
404
+ }
468
405
  }
469
-
470
406
  /**
471
407
  * Hook Safety CLI Commands
472
- */
473
- export async function hookSafetyCommand(subArgs, flags) {
474
- const subcommand = subArgs[0];
475
-
476
- switch (subcommand) {
477
- case 'validate':
478
- return await validateConfigCommand(subArgs, flags);
479
- case 'status':
480
- return await statusCommand(subArgs, flags);
481
- case 'reset':
482
- return await resetCommand(subArgs, flags);
483
- case 'safe-mode':
484
- return await safeModeCommand(subArgs, flags);
485
- default:
486
- showHookSafetyHelp();
487
- }
408
+ */ export async function hookSafetyCommand(subArgs, flags) {
409
+ const subcommand = subArgs[0];
410
+ switch(subcommand){
411
+ case 'validate':
412
+ return await validateConfigCommand(subArgs, flags);
413
+ case 'status':
414
+ return await statusCommand(subArgs, flags);
415
+ case 'reset':
416
+ return await resetCommand(subArgs, flags);
417
+ case 'safe-mode':
418
+ return await safeModeCommand(subArgs, flags);
419
+ default:
420
+ showHookSafetyHelp();
421
+ }
488
422
  }
489
-
490
423
  async function validateConfigCommand(subArgs, flags) {
491
- const configPath = flags.config || flags.c;
492
-
493
- console.log('🔍 Validating hook configuration for safety...\n');
494
-
495
- const result = HookConfigValidator.validateClaudeCodeConfig(configPath);
496
-
497
- if (result.safe) {
498
- printSuccess('✅ Hook configuration is safe!');
499
- if (result.configPath) {
500
- console.log(`📄 Validated: ${result.configPath}`);
501
- }
502
- } else {
503
- printError('❌ DANGEROUS hook configuration detected!');
504
-
505
- if (result.errors) {
506
- console.log('\n🚨 CRITICAL ERRORS:');
507
- for (const error of result.errors) {
508
- console.log(`\n${error.message}`);
509
- }
510
- }
511
-
512
- if (result.warnings) {
513
- console.log('\n⚠️ WARNINGS:');
514
- for (const warning of result.warnings) {
515
- console.log(`\n${warning.message}`);
516
- }
424
+ const configPath = flags.config || flags.c;
425
+ console.log('🔍 Validating hook configuration for safety...\n');
426
+ const result = HookConfigValidator.validateClaudeCodeConfig(configPath);
427
+ if (result.safe) {
428
+ printSuccess('✅ Hook configuration is safe!');
429
+ if (result.configPath) {
430
+ console.log(`📄 Validated: ${result.configPath}`);
431
+ }
432
+ } else {
433
+ printError('❌ DANGEROUS hook configuration detected!');
434
+ if (result.errors) {
435
+ console.log('\n🚨 CRITICAL ERRORS:');
436
+ for (const error of result.errors){
437
+ console.log(`\n${error.message}`);
438
+ }
439
+ }
440
+ if (result.warnings) {
441
+ console.log('\n⚠️ WARNINGS:');
442
+ for (const warning of result.warnings){
443
+ console.log(`\n${warning.message}`);
444
+ }
445
+ }
446
+ console.log('\n💡 RECOMMENDATIONS:');
447
+ console.log('1. Remove claude commands from Stop hooks');
448
+ console.log('2. Use PostToolUse hooks for specific tools');
449
+ console.log('3. Implement flag-based update patterns');
450
+ console.log('4. Use claude --skip-hooks for manual updates');
517
451
  }
518
-
519
- console.log('\n💡 RECOMMENDATIONS:');
520
- console.log('1. Remove claude commands from Stop hooks');
521
- console.log('2. Use PostToolUse hooks for specific tools');
522
- console.log('3. Implement flag-based update patterns');
523
- console.log('4. Use claude --skip-hooks for manual updates');
524
- }
525
452
  }
526
-
527
453
  async function statusCommand(subArgs, flags) {
528
- const context = HookContextManager.getContext();
529
- const circuitStatus = HookCircuitBreaker.getStatus();
530
-
531
- console.log('🔗 Hook Safety Status\n');
532
-
533
- console.log('📊 Current Context:');
534
- if (context.type) {
535
- console.log(` 🔄 Hook Type: ${context.type}`);
536
- console.log(` 📏 Depth: ${context.depth}`);
537
- console.log(` 🆔 Session: ${context.sessionId}`);
538
- console.log(` ⏭️ Skip Hooks: ${context.skipHooks ? 'Yes' : 'No'}`);
539
- console.log(` 🛡️ Safe Mode: ${context.safeMode ? 'Yes' : 'No'}`);
540
- } else {
541
- console.log(' Not currently in hook context');
542
- }
543
-
544
- console.log('\n⚡ Circuit Breaker Status:');
545
- console.log(` 🆔 Session: ${circuitStatus.sessionId}`);
546
-
547
- if (circuitStatus.executions.length > 0) {
548
- console.log(' 📊 Hook Executions:');
549
- for (const exec of circuitStatus.executions) {
550
- console.log(` • ${exec.hookType}: ${exec.count} times`);
454
+ const context = HookContextManager.getContext();
455
+ const circuitStatus = HookCircuitBreaker.getStatus();
456
+ console.log('🔗 Hook Safety Status\n');
457
+ console.log('📊 Current Context:');
458
+ if (context.type) {
459
+ console.log(` 🔄 Hook Type: ${context.type}`);
460
+ console.log(` 📏 Depth: ${context.depth}`);
461
+ console.log(` 🆔 Session: ${context.sessionId}`);
462
+ console.log(` ⏭️ Skip Hooks: ${context.skipHooks ? 'Yes' : 'No'}`);
463
+ console.log(` 🛡️ Safe Mode: ${context.safeMode ? 'Yes' : 'No'}`);
464
+ } else {
465
+ console.log(' Not currently in hook context');
466
+ }
467
+ console.log('\n⚡ Circuit Breaker Status:');
468
+ console.log(` 🆔 Session: ${circuitStatus.sessionId}`);
469
+ if (circuitStatus.executions.length > 0) {
470
+ console.log(' 📊 Hook Executions:');
471
+ for (const exec of circuitStatus.executions){
472
+ console.log(` • ${exec.hookType}: ${exec.count} times`);
473
+ }
474
+ } else {
475
+ console.log(' ✅ No hook executions in current session');
551
476
  }
552
- } else {
553
- console.log(' ✅ No hook executions in current session');
554
- }
555
477
  }
556
-
557
478
  async function resetCommand(subArgs, flags) {
558
- console.log('🔄 Resetting hook safety systems...\n');
559
-
560
- HookCircuitBreaker.reset();
561
- HookContextManager.clearContext();
562
-
563
- printSuccess('✅ Hook safety systems reset successfully!');
564
- console.log('All execution counters and context cleared.');
479
+ console.log('🔄 Resetting hook safety systems...\n');
480
+ HookCircuitBreaker.reset();
481
+ HookContextManager.clearContext();
482
+ printSuccess('✅ Hook safety systems reset successfully!');
483
+ console.log('All execution counters and context cleared.');
565
484
  }
566
-
567
485
  async function safeModeCommand(subArgs, flags) {
568
- const enable = !flags.disable && !flags.off;
569
-
570
- if (enable) {
571
- HookContextManager.setSafeMode(true);
572
- HookContextManager.setSkipHooks(true);
573
- printSuccess('🛡️ Safe mode enabled!');
574
- console.log('• All hooks will be skipped');
575
- console.log('• Claude commands will show safety warnings');
576
- console.log('• Additional validation will be performed');
577
- } else {
578
- HookContextManager.setSafeMode(false);
579
- HookContextManager.setSkipHooks(false);
580
- printSuccess(' Safe mode disabled.');
581
- console.log('Normal hook execution restored.');
582
- }
486
+ const enable = !flags.disable && !flags.off;
487
+ if (enable) {
488
+ HookContextManager.setSafeMode(true);
489
+ HookContextManager.setSkipHooks(true);
490
+ printSuccess('🛡️ Safe mode enabled!');
491
+ console.log(' All hooks will be skipped');
492
+ console.log('• Claude commands will show safety warnings');
493
+ console.log('• Additional validation will be performed');
494
+ } else {
495
+ HookContextManager.setSafeMode(false);
496
+ HookContextManager.setSkipHooks(false);
497
+ printSuccess('⚡ Safe mode disabled.');
498
+ console.log('Normal hook execution restored.');
499
+ }
583
500
  }
584
-
585
501
  function showHookSafetyHelp() {
586
- console.log(`
502
+ console.log(`
587
503
  🛡️ Hook Safety System - Prevent Infinite Loops & Financial Damage
588
504
 
589
505
  USAGE:
@@ -635,37 +551,31 @@ SAFE ALTERNATIVES:
635
551
  For more information: https://github.com/ruvnet/claude-flow/issues/166
636
552
  `);
637
553
  }
638
-
639
554
  /**
640
555
  * Emergency CLI flags for Claude commands
641
- */
642
- export function addSafetyFlags(command) {
643
- // Add safety flags to any claude command
644
- const context = HookContextManager.getContext();
645
-
646
- if (context.type) {
647
- // Automatically add --skip-hooks if in hook context
648
- if (!command.includes('--skip-hooks')) {
649
- command += ' --skip-hooks';
556
+ */ export function addSafetyFlags(command) {
557
+ // Add safety flags to any claude command
558
+ const context = HookContextManager.getContext();
559
+ if (context.type) {
560
+ // Automatically add --skip-hooks if in hook context
561
+ if (!command.includes('--skip-hooks')) {
562
+ command += ' --skip-hooks';
563
+ }
650
564
  }
651
- }
652
-
653
- if (context.safeMode) {
654
- // Add additional safety flags in safe mode
655
- if (!command.includes('--dry-run')) {
656
- command += ' --dry-run';
565
+ if (context.safeMode) {
566
+ // Add additional safety flags in safe mode
567
+ if (!command.includes('--dry-run')) {
568
+ command += ' --dry-run';
569
+ }
657
570
  }
658
- }
659
-
660
- return command;
571
+ return command;
661
572
  }
662
-
663
573
  export default {
664
- HookContextManager,
665
- HookCommandValidator,
666
- HookCircuitBreaker,
667
- HookConfigValidator,
668
- SafeHookExecutor,
669
- hookSafetyCommand,
670
- addSafetyFlags,
574
+ HookContextManager,
575
+ HookCommandValidator,
576
+ HookCircuitBreaker,
577
+ HookConfigValidator,
578
+ SafeHookExecutor,
579
+ hookSafetyCommand,
580
+ addSafetyFlags
671
581
  };