@codemieai/code 0.0.31 → 0.0.32

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 (71) hide show
  1. package/dist/agents/codemie-code/agent.d.ts +6 -0
  2. package/dist/agents/codemie-code/agent.d.ts.map +1 -1
  3. package/dist/agents/codemie-code/agent.js +239 -3
  4. package/dist/agents/codemie-code/agent.js.map +1 -1
  5. package/dist/agents/codemie-code/config.d.ts.map +1 -1
  6. package/dist/agents/codemie-code/config.js +3 -1
  7. package/dist/agents/codemie-code/config.js.map +1 -1
  8. package/dist/agents/codemie-code/types.d.ts +13 -0
  9. package/dist/agents/codemie-code/types.d.ts.map +1 -1
  10. package/dist/agents/codemie-code/types.js.map +1 -1
  11. package/dist/agents/core/BaseAgentAdapter.d.ts +9 -1
  12. package/dist/agents/core/BaseAgentAdapter.d.ts.map +1 -1
  13. package/dist/agents/core/BaseAgentAdapter.js +11 -0
  14. package/dist/agents/core/BaseAgentAdapter.js.map +1 -1
  15. package/dist/agents/core/types.d.ts +74 -0
  16. package/dist/agents/core/types.d.ts.map +1 -1
  17. package/dist/agents/plugins/claude/claude.plugin.d.ts.map +1 -1
  18. package/dist/agents/plugins/claude/claude.plugin.js +18 -0
  19. package/dist/agents/plugins/claude/claude.plugin.js.map +1 -1
  20. package/dist/agents/plugins/claude/plugin/.claude-plugin/plugin.json +1 -1
  21. package/dist/agents/plugins/claude/plugin/claude-templates/templates/agents/code-review-agent-template.md.template +466 -0
  22. package/dist/agents/plugins/claude/plugin/claude-templates/templates/agents/solution-architect-agent.md.template +487 -0
  23. package/dist/agents/plugins/claude/plugin/claude-templates/templates/agents/unit-tester-agent.md.template +805 -0
  24. package/dist/agents/plugins/claude/plugin/commands/codemie-commit.md +31 -0
  25. package/dist/agents/plugins/claude/plugin/commands/codemie-init.md +1 -1
  26. package/dist/agents/plugins/claude/plugin/commands/codemie-pr.md +25 -0
  27. package/dist/agents/plugins/claude/plugin/commands/codemie-subagents.md +616 -0
  28. package/dist/agents/plugins/gemini/gemini.plugin.d.ts.map +1 -1
  29. package/dist/agents/plugins/gemini/gemini.plugin.js +14 -0
  30. package/dist/agents/plugins/gemini/gemini.plugin.js.map +1 -1
  31. package/dist/cli/commands/hook.d.ts.map +1 -1
  32. package/dist/cli/commands/hook.js +15 -1
  33. package/dist/cli/commands/hook.js.map +1 -1
  34. package/dist/env/types.d.ts +2 -0
  35. package/dist/env/types.d.ts.map +1 -1
  36. package/dist/env/types.js.map +1 -1
  37. package/dist/hooks/decision.d.ts +53 -0
  38. package/dist/hooks/decision.d.ts.map +1 -0
  39. package/dist/hooks/decision.js +201 -0
  40. package/dist/hooks/decision.js.map +1 -0
  41. package/dist/hooks/executor.d.ts +154 -0
  42. package/dist/hooks/executor.d.ts.map +1 -0
  43. package/dist/hooks/executor.js +415 -0
  44. package/dist/hooks/executor.js.map +1 -0
  45. package/dist/hooks/matcher.d.ts +41 -0
  46. package/dist/hooks/matcher.d.ts.map +1 -0
  47. package/dist/hooks/matcher.js +93 -0
  48. package/dist/hooks/matcher.js.map +1 -0
  49. package/dist/hooks/prompt-executor.d.ts +57 -0
  50. package/dist/hooks/prompt-executor.d.ts.map +1 -0
  51. package/dist/hooks/prompt-executor.js +141 -0
  52. package/dist/hooks/prompt-executor.js.map +1 -0
  53. package/dist/hooks/types.d.ts +153 -0
  54. package/dist/hooks/types.d.ts.map +1 -0
  55. package/dist/hooks/types.js +9 -0
  56. package/dist/hooks/types.js.map +1 -0
  57. package/dist/providers/plugins/sso/session/processors/metrics/metrics-api-client.d.ts +3 -1
  58. package/dist/providers/plugins/sso/session/processors/metrics/metrics-api-client.d.ts.map +1 -1
  59. package/dist/providers/plugins/sso/session/processors/metrics/metrics-api-client.js +14 -2
  60. package/dist/providers/plugins/sso/session/processors/metrics/metrics-api-client.js.map +1 -1
  61. package/dist/providers/plugins/sso/session/processors/metrics/metrics-types.d.ts +8 -0
  62. package/dist/providers/plugins/sso/session/processors/metrics/metrics-types.d.ts.map +1 -1
  63. package/dist/utils/config.d.ts +5 -0
  64. package/dist/utils/config.d.ts.map +1 -1
  65. package/dist/utils/config.js +73 -0
  66. package/dist/utils/config.js.map +1 -1
  67. package/dist/utils/mcp-config.d.ts +25 -0
  68. package/dist/utils/mcp-config.d.ts.map +1 -0
  69. package/dist/utils/mcp-config.js +197 -0
  70. package/dist/utils/mcp-config.js.map +1 -0
  71. package/package.json +1 -1
@@ -0,0 +1,415 @@
1
+ /**
2
+ * Hook Executor
3
+ *
4
+ * Orchestrates execution of hooks at various lifecycle points.
5
+ * Handles pattern matching, deduplication, parallel execution, and timeout management.
6
+ */
7
+ import crypto from 'crypto';
8
+ import { exec } from '../utils/exec.js';
9
+ import { logger } from '../utils/logger.js';
10
+ import { sanitizeValue } from '../utils/security.js';
11
+ import { HookMatcher } from './matcher.js';
12
+ import { DecisionParser } from './decision.js';
13
+ import { PromptHookExecutor } from './prompt-executor.js';
14
+ /**
15
+ * Default timeout for hook execution (60 seconds)
16
+ */
17
+ const DEFAULT_HOOK_TIMEOUT = 60000;
18
+ /**
19
+ * Hook execution engine
20
+ * Manages lifecycle hook execution with pattern matching, deduplication, and aggregation
21
+ */
22
+ export class HookExecutor {
23
+ /** Hooks configuration */
24
+ config;
25
+ /** Execution context (session ID, working directory, etc.) */
26
+ context;
27
+ /** Cache of executed hooks (for deduplication) */
28
+ executedHooks = new Set();
29
+ /** Prompt hook executor (for LLM-based hooks) */
30
+ promptExecutor = null;
31
+ constructor(config, context, llmConfig) {
32
+ this.config = config;
33
+ this.context = context;
34
+ // Initialize prompt executor if LLM config provided
35
+ if (llmConfig) {
36
+ this.promptExecutor = new PromptHookExecutor(llmConfig);
37
+ }
38
+ }
39
+ /**
40
+ * Execute PreToolUse hooks
41
+ * Runs before tool execution, can block or modify tool input
42
+ *
43
+ * @param toolName - Name of tool being executed
44
+ * @param toolInput - Tool input arguments
45
+ * @param toolUseId - Unique identifier for this tool use
46
+ * @returns Aggregated result from all matching hooks
47
+ */
48
+ async executePreToolUse(toolName, toolInput, toolUseId) {
49
+ logger.debug(`Executing PreToolUse hooks for tool: ${toolName}`);
50
+ const matchers = this.config.PreToolUse || [];
51
+ const matchingHooks = this.findMatchingHooks(matchers, toolName);
52
+ if (matchingHooks.length === 0) {
53
+ logger.debug(`No PreToolUse hooks matched for: ${toolName}`);
54
+ return this.createEmptyResult();
55
+ }
56
+ const input = {
57
+ hook_event_name: 'PreToolUse',
58
+ session_id: this.context.sessionId,
59
+ transcript_path: this.context.transcriptPath,
60
+ cwd: this.context.workingDir,
61
+ permission_mode: this.context.permissionMode,
62
+ tool_name: toolName,
63
+ tool_input: toolInput,
64
+ tool_use_id: toolUseId,
65
+ agent_name: this.context.agentName,
66
+ profile_name: this.context.profileName,
67
+ };
68
+ return this.executeHooks(matchingHooks, input);
69
+ }
70
+ /**
71
+ * Execute PostToolUse hooks
72
+ * Runs after tool completes, informational only (cannot block)
73
+ *
74
+ * @param toolName - Name of tool that was executed
75
+ * @param toolInput - Tool input arguments
76
+ * @param toolOutput - Tool output/result
77
+ * @param toolMetadata - Additional tool metadata
78
+ * @returns Aggregated result from all matching hooks
79
+ */
80
+ async executePostToolUse(toolName, toolInput, toolOutput, toolMetadata) {
81
+ logger.debug(`Executing PostToolUse hooks for tool: ${toolName}`);
82
+ const matchers = this.config.PostToolUse || [];
83
+ const matchingHooks = this.findMatchingHooks(matchers, toolName);
84
+ if (matchingHooks.length === 0) {
85
+ logger.debug(`No PostToolUse hooks matched for: ${toolName}`);
86
+ return this.createEmptyResult();
87
+ }
88
+ const input = {
89
+ hook_event_name: 'PostToolUse',
90
+ session_id: this.context.sessionId,
91
+ transcript_path: this.context.transcriptPath,
92
+ cwd: this.context.workingDir,
93
+ permission_mode: this.context.permissionMode,
94
+ tool_name: toolName,
95
+ tool_input: toolInput,
96
+ tool_output: toolOutput,
97
+ tool_metadata: toolMetadata,
98
+ agent_name: this.context.agentName,
99
+ profile_name: this.context.profileName,
100
+ };
101
+ return this.executeHooks(matchingHooks, input);
102
+ }
103
+ /**
104
+ * Execute UserPromptSubmit hooks
105
+ * Runs before processing user input, can block or add context
106
+ *
107
+ * @param prompt - User's prompt text
108
+ * @returns Aggregated result from all hooks
109
+ */
110
+ async executeUserPromptSubmit(prompt) {
111
+ logger.debug('Executing UserPromptSubmit hooks');
112
+ const matchers = this.config.UserPromptSubmit || [];
113
+ // UserPromptSubmit hooks don't use matchers (always run)
114
+ const allHooks = matchers.flatMap((m) => m.hooks);
115
+ if (allHooks.length === 0) {
116
+ logger.debug('No UserPromptSubmit hooks configured');
117
+ return this.createEmptyResult();
118
+ }
119
+ const input = {
120
+ hook_event_name: 'UserPromptSubmit',
121
+ session_id: this.context.sessionId,
122
+ transcript_path: this.context.transcriptPath,
123
+ cwd: this.context.workingDir,
124
+ permission_mode: this.context.permissionMode,
125
+ prompt,
126
+ agent_name: this.context.agentName,
127
+ profile_name: this.context.profileName,
128
+ };
129
+ return this.executeHooks(allHooks, input);
130
+ }
131
+ /**
132
+ * Execute Stop hooks
133
+ * Runs when agent completes, can prevent stopping and continue execution
134
+ *
135
+ * @param executionSteps - Optional array of execution steps with tool history
136
+ * @param stats - Optional execution statistics
137
+ * @returns Aggregated result from all hooks
138
+ */
139
+ async executeStop(executionSteps, stats) {
140
+ logger.debug('Executing Stop hooks');
141
+ const matchers = this.config.Stop || [];
142
+ // Stop hooks don't use matchers (always run)
143
+ const allHooks = matchers.flatMap((m) => m.hooks);
144
+ if (allHooks.length === 0) {
145
+ logger.debug('No Stop hooks configured');
146
+ return this.createEmptyResult();
147
+ }
148
+ // Format tool execution history from execution steps
149
+ const toolExecutionHistory = executionSteps
150
+ ?.filter((step) => step.type === 'tool_execution')
151
+ .map((step) => ({
152
+ toolName: step.toolName || 'unknown',
153
+ success: step.toolSuccess ?? false,
154
+ exitCode: step.toolMetadata?.exitCode,
155
+ duration: step.duration,
156
+ errorMessage: step.error || step.toolMetadata?.errorMessage,
157
+ })) || [];
158
+ const input = {
159
+ hook_event_name: 'Stop',
160
+ session_id: this.context.sessionId,
161
+ transcript_path: this.context.transcriptPath,
162
+ cwd: this.context.workingDir,
163
+ permission_mode: this.context.permissionMode,
164
+ agent_name: this.context.agentName,
165
+ profile_name: this.context.profileName,
166
+ tool_execution_history: toolExecutionHistory.length > 0 ? toolExecutionHistory : undefined,
167
+ execution_stats: stats
168
+ ? {
169
+ totalToolCalls: stats.toolCalls,
170
+ successfulTools: stats.successfulTools,
171
+ failedTools: stats.failedTools,
172
+ }
173
+ : undefined,
174
+ };
175
+ return this.executeHooks(allHooks, input);
176
+ }
177
+ /**
178
+ * Execute SessionStart hooks
179
+ * Runs at the beginning of a session, can block session start and inject context
180
+ *
181
+ * @returns Aggregated result from all hooks
182
+ */
183
+ async executeSessionStart() {
184
+ logger.debug('Executing SessionStart hooks');
185
+ const matchers = this.config.SessionStart || [];
186
+ // SessionStart hooks don't use matchers (always run)
187
+ const allHooks = matchers.flatMap((m) => m.hooks);
188
+ if (allHooks.length === 0) {
189
+ logger.debug('No SessionStart hooks configured');
190
+ return this.createEmptyResult();
191
+ }
192
+ const input = {
193
+ hook_event_name: 'SessionStart',
194
+ session_id: this.context.sessionId,
195
+ transcript_path: this.context.transcriptPath,
196
+ cwd: this.context.workingDir,
197
+ permission_mode: this.context.permissionMode,
198
+ agent_name: this.context.agentName,
199
+ profile_name: this.context.profileName,
200
+ };
201
+ return this.executeHooks(allHooks, input);
202
+ }
203
+ /**
204
+ * Find hooks that match a tool name
205
+ *
206
+ * @param matchers - Array of hook matchers with patterns
207
+ * @param toolName - Tool name to match against
208
+ * @returns Array of matching hook configurations
209
+ */
210
+ findMatchingHooks(matchers, toolName) {
211
+ const matchingHooks = [];
212
+ for (const matcher of matchers) {
213
+ const pattern = matcher.matcher || '*';
214
+ if (HookMatcher.matches(pattern, toolName)) {
215
+ logger.debug(`Pattern "${pattern}" matched tool: ${toolName}`);
216
+ matchingHooks.push(...matcher.hooks);
217
+ }
218
+ }
219
+ return matchingHooks;
220
+ }
221
+ /**
222
+ * Execute multiple hooks in parallel with deduplication
223
+ *
224
+ * @param hooks - Hooks to execute
225
+ * @param input - Input data to pass to hooks
226
+ * @returns Aggregated result from all hooks
227
+ */
228
+ async executeHooks(hooks, input) {
229
+ // Deduplicate hooks by hash
230
+ const uniqueHooks = this.deduplicateHooks(hooks);
231
+ logger.debug(`Executing ${uniqueHooks.length} unique hooks (${hooks.length} total after deduplication)`);
232
+ // Execute hooks in parallel
233
+ const results = await Promise.allSettled(uniqueHooks.map((hook) => this.executeSingleHook(hook, input)));
234
+ // Merge results according to priority rules
235
+ return DecisionParser.merge(results);
236
+ }
237
+ /**
238
+ * Deduplicate hooks by computing hash of configuration
239
+ * Identical hooks (same command/prompt/timeout) run only once per event
240
+ *
241
+ * @param hooks - Hooks to deduplicate
242
+ * @returns Unique hooks
243
+ */
244
+ deduplicateHooks(hooks) {
245
+ const uniqueHooks = [];
246
+ const seenHashes = new Set();
247
+ for (const hook of hooks) {
248
+ const hash = this.hashHook(hook);
249
+ // Check if already executed in this event cycle
250
+ if (this.executedHooks.has(hash)) {
251
+ logger.debug('Skipping hook (already executed this event)');
252
+ continue;
253
+ }
254
+ // Check if duplicate in current batch
255
+ if (seenHashes.has(hash)) {
256
+ logger.debug('Skipping duplicate hook in batch');
257
+ continue;
258
+ }
259
+ seenHashes.add(hash);
260
+ this.executedHooks.add(hash);
261
+ uniqueHooks.push(hook);
262
+ }
263
+ return uniqueHooks;
264
+ }
265
+ /**
266
+ * Compute hash of hook configuration for deduplication
267
+ *
268
+ * @param hook - Hook configuration
269
+ * @returns SHA-256 hash of hook config
270
+ */
271
+ hashHook(hook) {
272
+ const data = JSON.stringify({
273
+ type: hook.type,
274
+ command: hook.command,
275
+ prompt: hook.prompt,
276
+ timeout: hook.timeout || DEFAULT_HOOK_TIMEOUT,
277
+ });
278
+ return crypto.createHash('sha256').update(data).digest('hex');
279
+ }
280
+ /**
281
+ * Execute a single hook (command or prompt)
282
+ *
283
+ * @param hook - Hook configuration
284
+ * @param input - Input data for hook
285
+ * @returns Hook result
286
+ */
287
+ async executeSingleHook(hook, input) {
288
+ try {
289
+ if (hook.type === 'command') {
290
+ return await this.executeCommandHook(hook, input);
291
+ }
292
+ else if (hook.type === 'prompt') {
293
+ return await this.executePromptHook(hook, input);
294
+ }
295
+ else {
296
+ logger.warn(`Unknown hook type: ${hook.type}`);
297
+ return { decision: 'allow', reason: `Unknown hook type: ${hook.type}` };
298
+ }
299
+ }
300
+ catch (error) {
301
+ logger.error(`Hook execution failed: ${error}`);
302
+ // Fail open (allow execution to continue)
303
+ return {
304
+ decision: 'allow',
305
+ reason: `Hook failed: ${error instanceof Error ? error.message : String(error)}`,
306
+ };
307
+ }
308
+ }
309
+ /**
310
+ * Execute a command hook (shell script)
311
+ *
312
+ * @param hook - Hook configuration
313
+ * @param input - Input data (passed as JSON via stdin)
314
+ * @returns Hook result parsed from stdout
315
+ */
316
+ async executeCommandHook(hook, input) {
317
+ if (!hook.command) {
318
+ throw new Error('Command hook missing required field: command');
319
+ }
320
+ logger.debug(`Executing command hook: ${hook.command}`);
321
+ // Build environment variables
322
+ const env = this.buildEnvironment(input);
323
+ // Sanitize input before passing to hook
324
+ const sanitizedInput = {
325
+ ...input,
326
+ tool_input: input.tool_input ? sanitizeValue(input.tool_input) : undefined,
327
+ tool_output: input.tool_output ? sanitizeValue(input.tool_output) : undefined,
328
+ };
329
+ // Prepare stdin (JSON)
330
+ const stdin = JSON.stringify(sanitizedInput, null, 2);
331
+ // Execute command with timeout
332
+ // Note: We're passing stdin via environment variable for now
333
+ // In production, we'd use a proper stdin pipe
334
+ const result = await exec(hook.command, [], {
335
+ timeout: hook.timeout || DEFAULT_HOOK_TIMEOUT,
336
+ env: {
337
+ ...env,
338
+ CODEMIE_HOOK_INPUT: stdin, // Pass input via env for now
339
+ },
340
+ cwd: this.context.workingDir,
341
+ shell: true, // Enable shell execution for proper command parsing
342
+ });
343
+ // Log raw output for debugging
344
+ if (result.stdout) {
345
+ logger.debug(`Hook stdout: ${result.stdout}`);
346
+ }
347
+ if (result.stderr) {
348
+ logger.debug(`Hook stderr: ${result.stderr}`);
349
+ }
350
+ // Parse result based on exit code and output
351
+ return DecisionParser.parse(result.stdout, result.stderr, result.code);
352
+ }
353
+ /**
354
+ * Execute a prompt hook (LLM-based)
355
+ *
356
+ * @param hook - Hook configuration
357
+ * @param input - Input data
358
+ * @returns Hook result
359
+ */
360
+ async executePromptHook(hook, input) {
361
+ if (!hook.prompt) {
362
+ throw new Error('Prompt hook missing required field: prompt');
363
+ }
364
+ // Check if prompt executor is available
365
+ if (!this.promptExecutor) {
366
+ logger.warn('Prompt hook requested but no LLM configuration provided, allowing by default');
367
+ return {
368
+ decision: 'allow',
369
+ reason: 'Prompt hooks require LLM configuration',
370
+ };
371
+ }
372
+ logger.debug('Executing prompt hook');
373
+ // Execute prompt hook via LLM
374
+ return this.promptExecutor.execute(hook.prompt, input);
375
+ }
376
+ /**
377
+ * Build environment variables for hook execution
378
+ *
379
+ * @param input - Hook input data
380
+ * @returns Environment variables object
381
+ */
382
+ buildEnvironment(input) {
383
+ return {
384
+ ...process.env,
385
+ CODEMIE_PROJECT_DIR: this.context.workingDir,
386
+ CODEMIE_SESSION_ID: this.context.sessionId,
387
+ CODEMIE_HOOK_EVENT: input.hook_event_name,
388
+ CODEMIE_TOOL_NAME: input.tool_name || '',
389
+ CODEMIE_AGENT_NAME: this.context.agentName || '',
390
+ CODEMIE_PROFILE_NAME: this.context.profileName || '',
391
+ CODEMIE_TRANSCRIPT_PATH: this.context.transcriptPath,
392
+ CODEMIE_PERMISSION_MODE: this.context.permissionMode,
393
+ };
394
+ }
395
+ /**
396
+ * Create empty result (no hooks executed)
397
+ *
398
+ * @returns Empty aggregated result
399
+ */
400
+ createEmptyResult() {
401
+ return {
402
+ decision: 'allow',
403
+ hooksExecuted: 0,
404
+ hooksSucceeded: 0,
405
+ hooksFailed: 0,
406
+ };
407
+ }
408
+ /**
409
+ * Clear executed hooks cache (for new event cycle)
410
+ */
411
+ clearCache() {
412
+ this.executedHooks.clear();
413
+ }
414
+ }
415
+ //# sourceMappingURL=executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../src/hooks/executor.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAW1D;;GAEG;AACH,MAAM,oBAAoB,GAAG,KAAK,CAAC;AAanC;;;GAGG;AACH,MAAM,OAAO,YAAY;IACxB,0BAA0B;IAClB,MAAM,CAAqB;IAEnC,8DAA8D;IACtD,OAAO,CAAuB;IAEtC,kDAAkD;IAC1C,aAAa,GAAgB,IAAI,GAAG,EAAE,CAAC;IAE/C,iDAAiD;IACzC,cAAc,GAA8B,IAAI,CAAC;IAEzD,YACC,MAA0B,EAC1B,OAA6B,EAC7B,SAA+B;QAE/B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QAEvB,oDAAoD;QACpD,IAAI,SAAS,EAAE,CAAC;YACf,IAAI,CAAC,cAAc,GAAG,IAAI,kBAAkB,CAAC,SAAS,CAAC,CAAC;QACzD,CAAC;IACF,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,iBAAiB,CACtB,QAAgB,EAChB,SAAkC,EAClC,SAAkB;QAElB,MAAM,CAAC,KAAK,CAAC,wCAAwC,QAAQ,EAAE,CAAC,CAAC;QAEjE,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC;QAC9C,MAAM,aAAa,GAAG,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAEjE,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChC,MAAM,CAAC,KAAK,CAAC,oCAAoC,QAAQ,EAAE,CAAC,CAAC;YAC7D,OAAO,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACjC,CAAC;QAED,MAAM,KAAK,GAAc;YACxB,eAAe,EAAE,YAAY;YAC7B,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS;YAClC,eAAe,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc;YAC5C,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU;YAC5B,eAAe,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc;YAC5C,SAAS,EAAE,QAAQ;YACnB,UAAU,EAAE,SAAS;YACrB,WAAW,EAAE,SAAS;YACtB,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS;YAClC,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW;SACtC,CAAC;QAEF,OAAO,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;IAChD,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,kBAAkB,CACvB,QAAgB,EAChB,SAAkC,EAClC,UAAkB,EAClB,YAAsC;QAEtC,MAAM,CAAC,KAAK,CAAC,yCAAyC,QAAQ,EAAE,CAAC,CAAC;QAElE,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC;QAC/C,MAAM,aAAa,GAAG,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAEjE,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChC,MAAM,CAAC,KAAK,CAAC,qCAAqC,QAAQ,EAAE,CAAC,CAAC;YAC9D,OAAO,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACjC,CAAC;QAED,MAAM,KAAK,GAAc;YACxB,eAAe,EAAE,aAAa;YAC9B,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS;YAClC,eAAe,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc;YAC5C,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU;YAC5B,eAAe,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc;YAC5C,SAAS,EAAE,QAAQ;YACnB,UAAU,EAAE,SAAS;YACrB,WAAW,EAAE,UAAU;YACvB,aAAa,EAAE,YAAY;YAC3B,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS;YAClC,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW;SACtC,CAAC;QAEF,OAAO,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;IAChD,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,uBAAuB,CAAC,MAAc;QAC3C,MAAM,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;QAEjD,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,gBAAgB,IAAI,EAAE,CAAC;QACpD,yDAAyD;QACzD,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAElD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,MAAM,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;YACrD,OAAO,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACjC,CAAC;QAED,MAAM,KAAK,GAAc;YACxB,eAAe,EAAE,kBAAkB;YACnC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS;YAClC,eAAe,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc;YAC5C,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU;YAC5B,eAAe,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc;YAC5C,MAAM;YACN,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS;YAClC,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW;SACtC,CAAC;QAEF,OAAO,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC3C,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,WAAW,CAChB,cAA2B,EAC3B,KAA2E;QAE3E,MAAM,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;QAErC,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACxC,6CAA6C;QAC7C,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAElD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,MAAM,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;YACzC,OAAO,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACjC,CAAC;QAED,qDAAqD;QACrD,MAAM,oBAAoB,GACzB,cAAc;YACb,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,gBAAgB,CAAC;aACjD,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACf,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,SAAS;YACpC,OAAO,EAAE,IAAI,CAAC,WAAW,IAAI,KAAK;YAClC,QAAQ,EAAE,IAAI,CAAC,YAAY,EAAE,QAAQ;YACrC,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,YAAY,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,YAAY,EAAE,YAAY;SAC3D,CAAC,CAAC,IAAI,EAAE,CAAC;QAEZ,MAAM,KAAK,GAAc;YACxB,eAAe,EAAE,MAAM;YACvB,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS;YAClC,eAAe,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc;YAC5C,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU;YAC5B,eAAe,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc;YAC5C,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS;YAClC,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW;YACtC,sBAAsB,EAAE,oBAAoB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,SAAS;YAC1F,eAAe,EAAE,KAAK;gBACrB,CAAC,CAAC;oBACA,cAAc,EAAE,KAAK,CAAC,SAAS;oBAC/B,eAAe,EAAE,KAAK,CAAC,eAAe;oBACtC,WAAW,EAAE,KAAK,CAAC,WAAW;iBAC9B;gBACF,CAAC,CAAC,SAAS;SACZ,CAAC;QAEF,OAAO,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC3C,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,mBAAmB;QACxB,MAAM,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;QAE7C,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,IAAI,EAAE,CAAC;QAChD,qDAAqD;QACrD,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAElD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,MAAM,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;YACjD,OAAO,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACjC,CAAC;QAED,MAAM,KAAK,GAAc;YACxB,eAAe,EAAE,cAAc;YAC/B,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS;YAClC,eAAe,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc;YAC5C,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU;YAC5B,eAAe,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc;YAC5C,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS;YAClC,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW;SACtC,CAAC;QAEF,OAAO,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC3C,CAAC;IAED;;;;;;OAMG;IACK,iBAAiB,CACxB,QAA6B,EAC7B,QAAgB;QAEhB,MAAM,aAAa,GAAiB,EAAE,CAAC;QAEvC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAChC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,GAAG,CAAC;YACvC,IAAI,WAAW,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,CAAC;gBAC5C,MAAM,CAAC,KAAK,CAAC,YAAY,OAAO,mBAAmB,QAAQ,EAAE,CAAC,CAAC;gBAC/D,aAAa,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;YACtC,CAAC;QACF,CAAC;QAED,OAAO,aAAa,CAAC;IACtB,CAAC;IAED;;;;;;OAMG;IACK,KAAK,CAAC,YAAY,CACzB,KAAmB,EACnB,KAAgB;QAEhB,4BAA4B;QAC5B,MAAM,WAAW,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAEjD,MAAM,CAAC,KAAK,CACX,aAAa,WAAW,CAAC,MAAM,kBAAkB,KAAK,CAAC,MAAM,6BAA6B,CAC1F,CAAC;QAEF,4BAA4B;QAC5B,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CACvC,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAC9D,CAAC;QAEF,4CAA4C;QAC5C,OAAO,cAAc,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC;IAED;;;;;;OAMG;IACK,gBAAgB,CAAC,KAAmB;QAC3C,MAAM,WAAW,GAAiB,EAAE,CAAC;QACrC,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;QAErC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAEjC,gDAAgD;YAChD,IAAI,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBAClC,MAAM,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;gBAC5D,SAAS;YACV,CAAC;YAED,sCAAsC;YACtC,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC1B,MAAM,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;gBACjD,SAAS;YACV,CAAC;YAED,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACrB,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC7B,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxB,CAAC;QAED,OAAO,WAAW,CAAC;IACpB,CAAC;IAED;;;;;OAKG;IACK,QAAQ,CAAC,IAAgB;QAChC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;YAC3B,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,oBAAoB;SAC7C,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC/D,CAAC;IAED;;;;;;OAMG;IACK,KAAK,CAAC,iBAAiB,CAC9B,IAAgB,EAChB,KAAgB;QAEhB,IAAI,CAAC;YACJ,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC7B,OAAO,MAAM,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YACnD,CAAC;iBAAM,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACnC,OAAO,MAAM,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YAClD,CAAC;iBAAM,CAAC;gBACP,MAAM,CAAC,IAAI,CAAC,sBAAsB,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;gBAC/C,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,sBAAsB,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;YACzE,CAAC;QACF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,CAAC,KAAK,CAAC,0BAA0B,KAAK,EAAE,CAAC,CAAC;YAChD,0CAA0C;YAC1C,OAAO;gBACN,QAAQ,EAAE,OAAO;gBACjB,MAAM,EAAE,gBAAgB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;aAChF,CAAC;QACH,CAAC;IACF,CAAC;IAED;;;;;;OAMG;IACK,KAAK,CAAC,kBAAkB,CAC/B,IAAgB,EAChB,KAAgB;QAEhB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;QACjE,CAAC;QAED,MAAM,CAAC,KAAK,CAAC,2BAA2B,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QAExD,8BAA8B;QAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAEzC,wCAAwC;QACxC,MAAM,cAAc,GAAG;YACtB,GAAG,KAAK;YACR,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS;YAC1E,WAAW,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS;SAC7E,CAAC;QAEF,uBAAuB;QACvB,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAEtD,+BAA+B;QAC/B,6DAA6D;QAC7D,8CAA8C;QAC9C,MAAM,MAAM,GAAG,MAAM,IAAI,CACxB,IAAI,CAAC,OAAO,EACZ,EAAE,EACF;YACC,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,oBAAoB;YAC7C,GAAG,EAAE;gBACJ,GAAG,GAAG;gBACN,kBAAkB,EAAE,KAAK,EAAE,6BAA6B;aACxD;YACD,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU;YAC5B,KAAK,EAAE,IAAI,EAAE,oDAAoD;SACjE,CACD,CAAC;QAEF,+BAA+B;QAC/B,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YACnB,MAAM,CAAC,KAAK,CAAC,gBAAgB,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QAC/C,CAAC;QACD,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YACnB,MAAM,CAAC,KAAK,CAAC,gBAAgB,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QAC/C,CAAC;QAED,6CAA6C;QAC7C,OAAO,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IACxE,CAAC;IAED;;;;;;OAMG;IACK,KAAK,CAAC,iBAAiB,CAC9B,IAAgB,EAChB,KAAgB;QAEhB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAC/D,CAAC;QAED,wCAAwC;QACxC,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YAC1B,MAAM,CAAC,IAAI,CAAC,8EAA8E,CAAC,CAAC;YAC5F,OAAO;gBACN,QAAQ,EAAE,OAAO;gBACjB,MAAM,EAAE,wCAAwC;aAChD,CAAC;QACH,CAAC;QAED,MAAM,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;QAEtC,8BAA8B;QAC9B,OAAO,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACxD,CAAC;IAED;;;;;OAKG;IACK,gBAAgB,CAAC,KAAgB;QACxC,OAAO;YACN,GAAG,OAAO,CAAC,GAAG;YACd,mBAAmB,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU;YAC5C,kBAAkB,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS;YAC1C,kBAAkB,EAAE,KAAK,CAAC,eAAe;YACzC,iBAAiB,EAAE,KAAK,CAAC,SAAS,IAAI,EAAE;YACxC,kBAAkB,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,EAAE;YAChD,oBAAoB,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,EAAE;YACpD,uBAAuB,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc;YACpD,uBAAuB,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc;SACpD,CAAC;IACH,CAAC;IAED;;;;OAIG;IACK,iBAAiB;QACxB,OAAO;YACN,QAAQ,EAAE,OAAO;YACjB,aAAa,EAAE,CAAC;YAChB,cAAc,EAAE,CAAC;YACjB,WAAW,EAAE,CAAC;SACd,CAAC;IACH,CAAC;IAED;;OAEG;IACH,UAAU;QACT,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;IAC5B,CAAC;CACD"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Hook Matcher
3
+ *
4
+ * Provides pattern matching logic for determining which hooks should execute
5
+ * for a given tool name. Supports literal matches, wildcards, and regex patterns.
6
+ */
7
+ export declare class HookMatcher {
8
+ /**
9
+ * Check if a pattern matches a tool name
10
+ *
11
+ * @param pattern - Pattern to match (regex, wildcard *, or literal string)
12
+ * @param toolName - Tool name to test against pattern
13
+ * @returns true if pattern matches tool name
14
+ *
15
+ * @example
16
+ * HookMatcher.matches('*', 'Bash') // true (wildcard)
17
+ * HookMatcher.matches('Bash|Write', 'Bash') // true (regex)
18
+ * HookMatcher.matches('Bash', 'Bash') // true (literal)
19
+ * HookMatcher.matches('Bash', 'Read') // false
20
+ */
21
+ static matches(pattern: string, toolName: string): boolean;
22
+ /**
23
+ * Find all patterns that match a tool name
24
+ *
25
+ * @param patterns - Array of patterns to test
26
+ * @param toolName - Tool name to match against
27
+ * @returns Array of matching patterns
28
+ */
29
+ static findMatches(patterns: string[], toolName: string): string[];
30
+ /**
31
+ * Validate a pattern for common mistakes
32
+ *
33
+ * @param pattern - Pattern to validate
34
+ * @returns Validation result with any warnings
35
+ */
36
+ static validate(pattern: string): {
37
+ valid: boolean;
38
+ warnings: string[];
39
+ };
40
+ }
41
+ //# sourceMappingURL=matcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matcher.d.ts","sourceRoot":"","sources":["../../src/hooks/matcher.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,qBAAa,WAAW;IACvB;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO;IA6B1D;;;;;;OAMG;IACH,MAAM,CAAC,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE;IAIlE;;;;;OAKG;IACH,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;KAAE;CA8BxE"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Hook Matcher
3
+ *
4
+ * Provides pattern matching logic for determining which hooks should execute
5
+ * for a given tool name. Supports literal matches, wildcards, and regex patterns.
6
+ */
7
+ import { logger } from '../utils/logger.js';
8
+ export class HookMatcher {
9
+ /**
10
+ * Check if a pattern matches a tool name
11
+ *
12
+ * @param pattern - Pattern to match (regex, wildcard *, or literal string)
13
+ * @param toolName - Tool name to test against pattern
14
+ * @returns true if pattern matches tool name
15
+ *
16
+ * @example
17
+ * HookMatcher.matches('*', 'Bash') // true (wildcard)
18
+ * HookMatcher.matches('Bash|Write', 'Bash') // true (regex)
19
+ * HookMatcher.matches('Bash', 'Bash') // true (literal)
20
+ * HookMatcher.matches('Bash', 'Read') // false
21
+ */
22
+ static matches(pattern, toolName) {
23
+ try {
24
+ // Handle wildcard - matches everything
25
+ if (pattern === '*') {
26
+ return true;
27
+ }
28
+ // Handle regex patterns (contains special regex characters)
29
+ // Common regex chars: | (alternation), [] (character class), {} (quantifier), () (group)
30
+ if (/[|[\]{}()]/.test(pattern)) {
31
+ try {
32
+ // Wrap pattern with anchors to match full tool name
33
+ const regex = new RegExp(`^(${pattern})$`);
34
+ return regex.test(toolName);
35
+ }
36
+ catch (error) {
37
+ // Invalid regex, treat as literal string
38
+ logger.warn(`Invalid regex pattern "${pattern}", treating as literal: ${error}`);
39
+ return pattern === toolName;
40
+ }
41
+ }
42
+ // Literal string match
43
+ return pattern === toolName;
44
+ }
45
+ catch (error) {
46
+ logger.error(`Error matching pattern "${pattern}" against "${toolName}": ${error}`);
47
+ return false;
48
+ }
49
+ }
50
+ /**
51
+ * Find all patterns that match a tool name
52
+ *
53
+ * @param patterns - Array of patterns to test
54
+ * @param toolName - Tool name to match against
55
+ * @returns Array of matching patterns
56
+ */
57
+ static findMatches(patterns, toolName) {
58
+ return patterns.filter((pattern) => this.matches(pattern, toolName));
59
+ }
60
+ /**
61
+ * Validate a pattern for common mistakes
62
+ *
63
+ * @param pattern - Pattern to validate
64
+ * @returns Validation result with any warnings
65
+ */
66
+ static validate(pattern) {
67
+ const warnings = [];
68
+ // Check for empty pattern
69
+ if (!pattern || pattern.trim() === '') {
70
+ return { valid: false, warnings: ['Pattern cannot be empty'] };
71
+ }
72
+ // Check for potential regex mistakes
73
+ if (/[|[\]{}()]/.test(pattern)) {
74
+ try {
75
+ new RegExp(`^(${pattern})$`);
76
+ }
77
+ catch (error) {
78
+ warnings.push(`Pattern appears to be regex but is invalid: ${error}`);
79
+ return { valid: false, warnings };
80
+ }
81
+ // Warn about unescaped dots (likely mistake)
82
+ if (/(?<!\\)\./.test(pattern)) {
83
+ warnings.push('Pattern contains unescaped dots (.) which match any character in regex');
84
+ }
85
+ }
86
+ // Warn about trailing/leading spaces
87
+ if (pattern !== pattern.trim()) {
88
+ warnings.push('Pattern contains leading/trailing spaces');
89
+ }
90
+ return { valid: true, warnings };
91
+ }
92
+ }
93
+ //# sourceMappingURL=matcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matcher.js","sourceRoot":"","sources":["../../src/hooks/matcher.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,MAAM,OAAO,WAAW;IACvB;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,OAAO,CAAC,OAAe,EAAE,QAAgB;QAC/C,IAAI,CAAC;YACJ,uCAAuC;YACvC,IAAI,OAAO,KAAK,GAAG,EAAE,CAAC;gBACrB,OAAO,IAAI,CAAC;YACb,CAAC;YAED,4DAA4D;YAC5D,yFAAyF;YACzF,IAAI,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;gBAChC,IAAI,CAAC;oBACJ,oDAAoD;oBACpD,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,KAAK,OAAO,IAAI,CAAC,CAAC;oBAC3C,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAC7B,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBAChB,yCAAyC;oBACzC,MAAM,CAAC,IAAI,CAAC,0BAA0B,OAAO,2BAA2B,KAAK,EAAE,CAAC,CAAC;oBACjF,OAAO,OAAO,KAAK,QAAQ,CAAC;gBAC7B,CAAC;YACF,CAAC;YAED,uBAAuB;YACvB,OAAO,OAAO,KAAK,QAAQ,CAAC;QAC7B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,CAAC,KAAK,CAAC,2BAA2B,OAAO,cAAc,QAAQ,MAAM,KAAK,EAAE,CAAC,CAAC;YACpF,OAAO,KAAK,CAAC;QACd,CAAC;IACF,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,WAAW,CAAC,QAAkB,EAAE,QAAgB;QACtD,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;IACtE,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,QAAQ,CAAC,OAAe;QAC9B,MAAM,QAAQ,GAAa,EAAE,CAAC;QAE9B,0BAA0B;QAC1B,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACvC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,yBAAyB,CAAC,EAAE,CAAC;QAChE,CAAC;QAED,qCAAqC;QACrC,IAAI,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAChC,IAAI,CAAC;gBACJ,IAAI,MAAM,CAAC,KAAK,OAAO,IAAI,CAAC,CAAC;YAC9B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,QAAQ,CAAC,IAAI,CAAC,+CAA+C,KAAK,EAAE,CAAC,CAAC;gBACtE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;YACnC,CAAC;YAED,6CAA6C;YAC7C,IAAI,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC/B,QAAQ,CAAC,IAAI,CAAC,wEAAwE,CAAC,CAAC;YACzF,CAAC;QACF,CAAC;QAED,qCAAqC;QACrC,IAAI,OAAO,KAAK,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;YAChC,QAAQ,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC;QAC3D,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IAClC,CAAC;CACD"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Prompt Hook Executor
3
+ *
4
+ * Executes LLM-based hooks using prompt templates.
5
+ * Allows users to define hooks that call an LLM to make decisions
6
+ * about tool execution, user prompts, etc.
7
+ */
8
+ import type { HookInput, HookResult } from './types.js';
9
+ /**
10
+ * Configuration for prompt hook executor
11
+ */
12
+ export interface PromptHookConfig {
13
+ /** LLM API key */
14
+ apiKey: string;
15
+ /** LLM base URL */
16
+ baseUrl?: string;
17
+ /** Model name (default: gpt-3.5-turbo for speed) */
18
+ model?: string;
19
+ /** Request timeout in milliseconds */
20
+ timeout?: number;
21
+ /** Debug mode */
22
+ debug?: boolean;
23
+ }
24
+ /**
25
+ * Prompt hook executor
26
+ * Uses LLM to evaluate hooks based on prompt templates
27
+ */
28
+ export declare class PromptHookExecutor {
29
+ private llm;
30
+ private config;
31
+ constructor(config: PromptHookConfig);
32
+ /**
33
+ * Execute a prompt hook
34
+ *
35
+ * @param prompt - Prompt template (can contain $ARGUMENTS placeholder)
36
+ * @param input - Hook input data
37
+ * @returns Hook result from LLM
38
+ */
39
+ execute(prompt: string, input: HookInput): Promise<HookResult>;
40
+ /**
41
+ * Resolve prompt template by replacing placeholders
42
+ *
43
+ * @param prompt - Prompt template
44
+ * @param input - Hook input data
45
+ * @returns Resolved prompt
46
+ */
47
+ private resolvePrompt;
48
+ /**
49
+ * Parse LLM response into hook result
50
+ * Expects JSON response, but handles plain text gracefully
51
+ *
52
+ * @param content - LLM response content
53
+ * @returns Parsed hook result
54
+ */
55
+ private parseResponse;
56
+ }
57
+ //# sourceMappingURL=prompt-executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-executor.d.ts","sourceRoot":"","sources":["../../src/hooks/prompt-executor.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAChC,kBAAkB;IAClB,MAAM,EAAE,MAAM,CAAC;IAEf,mBAAmB;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,oDAAoD;IACpD,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,sCAAsC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,iBAAiB;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;;GAGG;AACH,qBAAa,kBAAkB;IAC9B,OAAO,CAAC,GAAG,CAAa;IACxB,OAAO,CAAC,MAAM,CAAmB;gBAErB,MAAM,EAAE,gBAAgB;IAmBpC;;;;;;OAMG;IACG,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC;IAyBpE;;;;;;OAMG;IACH,OAAO,CAAC,aAAa;IAsCrB;;;;;;OAMG;IACH,OAAO,CAAC,aAAa;CAsCrB"}