* Validate hooks configuration
(hooks: HooksConfiguration)
| 107 | * Validate hooks configuration |
| 108 | */ |
| 109 | static async validateConfig(hooks: HooksConfiguration): Promise<HookValidationResult> { |
| 110 | const errors: HookValidationError[] = []; |
| 111 | const warnings: HookValidationWarning[] = []; |
| 112 | |
| 113 | // Guard against undefined or null hooks |
| 114 | if (!hooks) { |
| 115 | return { valid: true, errors, warnings }; |
| 116 | } |
| 117 | |
| 118 | // Events with matchers |
| 119 | const matcherEvents = ['PreToolUse', 'PostToolUse'] as const; |
| 120 | |
| 121 | // Events without matchers |
| 122 | const directEvents = ['Notification', 'Stop', 'SubagentStop'] as const; |
| 123 | |
| 124 | // Validate events with matchers |
| 125 | for (const event of matcherEvents) { |
| 126 | const matchers = hooks[event]; |
| 127 | if (!matchers || !Array.isArray(matchers)) continue; |
| 128 | |
| 129 | for (const matcher of matchers) { |
| 130 | // Validate regex pattern if provided |
| 131 | if (matcher.matcher) { |
| 132 | try { |
| 133 | new RegExp(matcher.matcher); |
| 134 | } catch (e) { |
| 135 | errors.push({ |
| 136 | event, |
| 137 | matcher: matcher.matcher, |
| 138 | message: `Invalid regex pattern: ${e instanceof Error ? e.message : 'Unknown error'}` |
| 139 | }); |
| 140 | } |
| 141 | } |
| 142 | |
| 143 | // Validate commands |
| 144 | if (matcher.hooks && Array.isArray(matcher.hooks)) { |
| 145 | for (const hook of matcher.hooks) { |
| 146 | if (!hook.command || !hook.command.trim()) { |
| 147 | errors.push({ |
| 148 | event, |
| 149 | matcher: matcher.matcher, |
| 150 | message: 'Empty command' |
| 151 | }); |
| 152 | } |
| 153 | |
| 154 | // Check for dangerous patterns |
| 155 | const dangers = this.checkDangerousPatterns(hook.command || ''); |
| 156 | warnings.push(...dangers.map(d => ({ |
| 157 | event, |
| 158 | matcher: matcher.matcher, |
| 159 | command: hook.command || '', |
| 160 | message: d |
| 161 | }))); |
| 162 | } |
| 163 | } |
| 164 | } |
| 165 | } |
| 166 |
no test coverage detected