@agiflowai/hooks-adapter 0.0.0 → 0.0.2
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.
- package/README.md +8 -8
- package/dist/index.cjs +337 -210
- package/dist/index.d.cts +316 -123
- package/dist/index.d.mts +316 -123
- package/dist/index.mjs +329 -208
- package/package.json +4 -2
package/dist/index.d.cts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
//#region src/constants/
|
|
1
|
+
//#region src/constants/hookTypes.d.ts
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Hook Types Constants
|
|
4
4
|
*
|
|
5
5
|
* DESIGN PATTERNS:
|
|
6
6
|
* - Strongly-typed constant exports for compile-time safety
|
|
7
7
|
* - Immutable by default (as const assertions)
|
|
8
8
|
*
|
|
9
9
|
* CODING STANDARDS:
|
|
10
|
-
* - Primitive constants: UPPER_SNAKE_CASE
|
|
10
|
+
* - Primitive constants: UPPER_SNAKE_CASE or PascalCase for event names
|
|
11
11
|
* - Always include JSDoc with purpose and usage
|
|
12
12
|
*
|
|
13
13
|
* AVOID:
|
|
@@ -15,14 +15,19 @@
|
|
|
15
15
|
* - Magic strings without explanation
|
|
16
16
|
*/
|
|
17
17
|
/**
|
|
18
|
-
* Hook type identifiers for
|
|
18
|
+
* Hook type identifiers for Claude Code hook events
|
|
19
19
|
*/
|
|
20
20
|
declare const PRE_TOOL_USE = "PreToolUse";
|
|
21
21
|
declare const POST_TOOL_USE = "PostToolUse";
|
|
22
|
+
/**
|
|
23
|
+
* Hook type identifiers for Gemini CLI hook events
|
|
24
|
+
*/
|
|
25
|
+
declare const BEFORE_TOOL_USE = "BeforeTool";
|
|
26
|
+
declare const AFTER_TOOL_USE = "AfterTool";
|
|
22
27
|
/**
|
|
23
28
|
* Union type of all supported hook types
|
|
24
29
|
*/
|
|
25
|
-
type HookType = typeof PRE_TOOL_USE | typeof POST_TOOL_USE;
|
|
30
|
+
type HookType = typeof PRE_TOOL_USE | typeof POST_TOOL_USE | typeof BEFORE_TOOL_USE | typeof AFTER_TOOL_USE;
|
|
26
31
|
//#endregion
|
|
27
32
|
//#region src/types/index.d.ts
|
|
28
33
|
/**
|
|
@@ -45,55 +50,134 @@ type HookType = typeof PRE_TOOL_USE | typeof POST_TOOL_USE;
|
|
|
45
50
|
* - Coupling types to implementation details
|
|
46
51
|
*/
|
|
47
52
|
/**
|
|
48
|
-
*
|
|
53
|
+
* Decision types for hook responses
|
|
54
|
+
*/
|
|
55
|
+
type Decision = 'allow' | 'deny' | 'ask' | 'skip';
|
|
56
|
+
/**
|
|
57
|
+
* Normalized hook context passed to hook callbacks
|
|
58
|
+
* Provides a common interface for hooks regardless of the underlying AI agent format
|
|
49
59
|
*/
|
|
50
60
|
interface HookContext {
|
|
51
|
-
/** Name of the tool being
|
|
61
|
+
/** Name of the tool being executed (e.g., 'Read', 'Write', 'Edit') */
|
|
52
62
|
toolName: string;
|
|
53
|
-
/** Input parameters
|
|
54
|
-
toolInput: Record<string,
|
|
55
|
-
/** File path
|
|
63
|
+
/** Input parameters for the tool */
|
|
64
|
+
toolInput: Record<string, unknown>;
|
|
65
|
+
/** File path for file operations (extracted from tool input if applicable) */
|
|
56
66
|
filePath?: string;
|
|
57
|
-
/**
|
|
67
|
+
/** Operation type for file operations */
|
|
58
68
|
operation?: 'read' | 'write' | 'edit';
|
|
59
69
|
/** Current working directory */
|
|
60
70
|
cwd: string;
|
|
61
71
|
/** Unique session identifier */
|
|
62
72
|
sessionId: string;
|
|
63
|
-
/** Optional LLM tool
|
|
73
|
+
/** Optional LLM tool identifier (e.g., 'claude-code') */
|
|
64
74
|
llmTool?: string;
|
|
65
75
|
}
|
|
66
76
|
/**
|
|
67
|
-
*
|
|
77
|
+
* Response from hook callback function
|
|
68
78
|
*/
|
|
69
79
|
interface HookResponse {
|
|
70
80
|
/** Permission decision for the tool execution */
|
|
71
|
-
decision:
|
|
81
|
+
decision: Decision;
|
|
72
82
|
/** Message shown to the LLM (e.g., design patterns, warnings) */
|
|
73
83
|
message: string;
|
|
74
84
|
/** Optional message shown only to the user (not the LLM) */
|
|
75
85
|
userMessage?: string;
|
|
76
86
|
/** Optional updated input parameters for the tool */
|
|
77
|
-
updatedInput?: Record<string,
|
|
87
|
+
updatedInput?: Record<string, unknown>;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Content item in tool result from Claude Code
|
|
91
|
+
*/
|
|
92
|
+
interface ToolResultContentItem {
|
|
93
|
+
/** Content type (e.g., 'text', 'image') */
|
|
94
|
+
readonly type: string;
|
|
95
|
+
/** Text content if type is 'text' */
|
|
96
|
+
readonly text?: string;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Tool result structure from Claude Code PostToolUse hook
|
|
100
|
+
*/
|
|
101
|
+
interface ToolResult {
|
|
102
|
+
/** Array of content items returned by the tool */
|
|
103
|
+
readonly content?: readonly ToolResultContentItem[];
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Scaffold execution data from execution log
|
|
107
|
+
*/
|
|
108
|
+
interface ScaffoldExecution {
|
|
109
|
+
/** Unique scaffold execution ID */
|
|
110
|
+
readonly scaffoldId: string;
|
|
111
|
+
/** List of files generated by the scaffold */
|
|
112
|
+
readonly generatedFiles: readonly string[];
|
|
113
|
+
/** Name of the scaffold feature/method */
|
|
114
|
+
readonly featureName?: string;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Log entry structure from ExecutionLogService
|
|
118
|
+
*/
|
|
119
|
+
interface LogEntry {
|
|
120
|
+
/** Timestamp of the log entry */
|
|
121
|
+
readonly timestamp?: number;
|
|
122
|
+
/** Session ID */
|
|
123
|
+
readonly sessionId?: string;
|
|
124
|
+
/** Operation type */
|
|
125
|
+
readonly operation: string;
|
|
126
|
+
/** Scaffold execution ID */
|
|
127
|
+
readonly scaffoldId?: string;
|
|
128
|
+
/** Files generated by scaffold */
|
|
129
|
+
readonly generatedFiles?: readonly string[];
|
|
130
|
+
/** Scaffold feature name */
|
|
131
|
+
readonly featureName?: string;
|
|
132
|
+
/** File path */
|
|
133
|
+
readonly filePath: string;
|
|
134
|
+
/** Decision made */
|
|
135
|
+
readonly decision?: string;
|
|
136
|
+
/** File pattern matched */
|
|
137
|
+
readonly filePattern?: string;
|
|
138
|
+
/** File modification timestamp */
|
|
139
|
+
readonly fileMtime?: number;
|
|
140
|
+
/** File content checksum */
|
|
141
|
+
readonly fileChecksum?: string;
|
|
142
|
+
/** Project path */
|
|
143
|
+
readonly projectPath?: string;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Pending scaffold log entry for temp file storage
|
|
147
|
+
*/
|
|
148
|
+
interface PendingScaffoldLogEntry {
|
|
149
|
+
/** Unique scaffold execution ID */
|
|
150
|
+
readonly scaffoldId: string;
|
|
151
|
+
/** List of files generated */
|
|
152
|
+
readonly generatedFiles: readonly string[];
|
|
153
|
+
/** Project path where scaffold was executed */
|
|
154
|
+
readonly projectPath: string;
|
|
155
|
+
/** Scaffold feature name */
|
|
156
|
+
readonly featureName?: string;
|
|
78
157
|
}
|
|
158
|
+
//#endregion
|
|
159
|
+
//#region src/constants/decisions.d.ts
|
|
79
160
|
/**
|
|
80
|
-
*
|
|
81
|
-
*
|
|
161
|
+
* Normalized hook decision types used across all adapters
|
|
162
|
+
* Adapters convert platform-specific formats to these normalized values
|
|
82
163
|
*/
|
|
83
|
-
|
|
164
|
+
declare const DECISION_ALLOW: Decision;
|
|
165
|
+
declare const DECISION_DENY: Decision;
|
|
166
|
+
declare const DECISION_SKIP: Decision;
|
|
167
|
+
declare const DECISION_ASK: Decision;
|
|
84
168
|
//#endregion
|
|
85
169
|
//#region src/adapters/BaseAdapter.d.ts
|
|
86
|
-
|
|
87
170
|
/**
|
|
88
|
-
* Abstract base adapter for
|
|
171
|
+
* Abstract base adapter for AI agent hook formats
|
|
172
|
+
* @template TContext - The adapter-specific input context type
|
|
89
173
|
*/
|
|
90
|
-
declare abstract class BaseAdapter {
|
|
174
|
+
declare abstract class BaseAdapter<TContext = any> {
|
|
91
175
|
/**
|
|
92
|
-
* Parse stdin from AI agent into
|
|
176
|
+
* Parse stdin from AI agent into context (specific to each adapter)
|
|
93
177
|
* @param stdin - Raw stdin string from AI agent
|
|
94
|
-
* @returns
|
|
178
|
+
* @returns Context object (can be adapter-specific or normalized)
|
|
95
179
|
*/
|
|
96
|
-
abstract parseInput(stdin: string):
|
|
180
|
+
abstract parseInput(stdin: string): TContext;
|
|
97
181
|
/**
|
|
98
182
|
* Format normalized HookResponse into AI agent-specific output
|
|
99
183
|
* @param response - Normalized hook response
|
|
@@ -101,12 +185,18 @@ declare abstract class BaseAdapter {
|
|
|
101
185
|
*/
|
|
102
186
|
abstract formatOutput(response: HookResponse): string;
|
|
103
187
|
/**
|
|
104
|
-
* Execute hook callback with
|
|
188
|
+
* Execute hook callback with context
|
|
105
189
|
* Template method that orchestrates the hook execution flow
|
|
106
190
|
*
|
|
107
191
|
* @param callback - Hook callback function to execute
|
|
108
192
|
*/
|
|
109
|
-
execute(callback:
|
|
193
|
+
execute(callback: (context: TContext) => Promise<HookResponse>): Promise<void>;
|
|
194
|
+
/**
|
|
195
|
+
* Execute multiple hooks with shared stdin (read once, execute all)
|
|
196
|
+
* This is useful when multiple hooks need to process the same input
|
|
197
|
+
* @param callbacks - Array of callback functions to execute
|
|
198
|
+
*/
|
|
199
|
+
executeMultiple(callbacks: Array<(context: TContext) => Promise<HookResponse>>): Promise<void>;
|
|
110
200
|
/**
|
|
111
201
|
* Read stdin from AI agent
|
|
112
202
|
* @returns Promise resolving to stdin content
|
|
@@ -123,96 +213,108 @@ declare abstract class BaseAdapter {
|
|
|
123
213
|
//#endregion
|
|
124
214
|
//#region src/adapters/ClaudeCodeAdapter.d.ts
|
|
125
215
|
/**
|
|
126
|
-
*
|
|
216
|
+
* Claude Code hook input format (PreToolUse)
|
|
127
217
|
*/
|
|
128
|
-
|
|
218
|
+
interface ClaudeCodePreToolUseInput {
|
|
219
|
+
tool_name: string;
|
|
220
|
+
tool_input: Record<string, any>;
|
|
221
|
+
cwd: string;
|
|
222
|
+
session_id: string;
|
|
223
|
+
hook_event_name: 'PreToolUse';
|
|
224
|
+
tool_use_id: string;
|
|
225
|
+
transcript_path: string;
|
|
226
|
+
permission_mode: string;
|
|
227
|
+
llm_tool?: string;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Claude Code hook input format (PostToolUse)
|
|
231
|
+
*/
|
|
232
|
+
interface ClaudeCodePostToolUseInput {
|
|
233
|
+
tool_name: string;
|
|
234
|
+
tool_input: Record<string, any>;
|
|
235
|
+
tool_response: Record<string, any>;
|
|
236
|
+
cwd: string;
|
|
237
|
+
session_id: string;
|
|
238
|
+
hook_event_name: 'PostToolUse';
|
|
239
|
+
tool_use_id: string;
|
|
240
|
+
transcript_path: string;
|
|
241
|
+
permission_mode: string;
|
|
242
|
+
llm_tool?: string;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Union type for both hook input formats
|
|
246
|
+
*/
|
|
247
|
+
type ClaudeCodeHookInput = ClaudeCodePreToolUseInput | ClaudeCodePostToolUseInput;
|
|
248
|
+
/**
|
|
249
|
+
* Unified adapter for Claude Code hook format (PreToolUse & PostToolUse)
|
|
250
|
+
*/
|
|
251
|
+
declare class ClaudeCodeAdapter extends BaseAdapter<ClaudeCodeHookInput> {
|
|
252
|
+
private hookEventName;
|
|
129
253
|
/**
|
|
130
|
-
* Parse Claude Code stdin into
|
|
254
|
+
* Parse Claude Code stdin into ClaudeCodeHookInput
|
|
131
255
|
*
|
|
132
256
|
* @param stdin - Raw JSON string from Claude Code
|
|
133
|
-
* @returns
|
|
257
|
+
* @returns ClaudeCodeHookInput
|
|
134
258
|
*/
|
|
135
|
-
parseInput(stdin: string):
|
|
259
|
+
parseInput(stdin: string): ClaudeCodeHookInput;
|
|
136
260
|
/**
|
|
137
261
|
* Format normalized HookResponse into Claude Code output
|
|
262
|
+
* Morphs output based on hook event type (PreToolUse vs PostToolUse)
|
|
138
263
|
*
|
|
139
264
|
* @param response - Normalized hook response
|
|
140
265
|
* @returns JSON string for Claude Code
|
|
141
266
|
*/
|
|
142
267
|
formatOutput(response: HookResponse): string;
|
|
143
268
|
/**
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
* @param toolName - Name of the tool
|
|
147
|
-
* @param toolInput - Tool input parameters
|
|
148
|
-
* @returns File path if this is a file operation
|
|
269
|
+
* Format PreToolUse output
|
|
149
270
|
*/
|
|
150
|
-
private
|
|
271
|
+
private formatPreToolUseOutput;
|
|
151
272
|
/**
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
* @param toolName - Name of the tool
|
|
155
|
-
* @returns Operation type if this is a file operation
|
|
273
|
+
* Format PostToolUse output
|
|
156
274
|
*/
|
|
157
|
-
private
|
|
275
|
+
private formatPostToolUseOutput;
|
|
158
276
|
}
|
|
159
277
|
//#endregion
|
|
160
|
-
//#region src/adapters/
|
|
278
|
+
//#region src/adapters/GeminiCliAdapter.d.ts
|
|
161
279
|
/**
|
|
162
|
-
*
|
|
280
|
+
* Gemini CLI hook input format (BeforeTool/AfterTool)
|
|
163
281
|
*/
|
|
164
|
-
|
|
282
|
+
interface GeminiCliHookInput {
|
|
283
|
+
tool_name: string;
|
|
284
|
+
tool_input: Record<string, any>;
|
|
285
|
+
cwd: string;
|
|
286
|
+
session_id: string;
|
|
287
|
+
event: 'BeforeTool' | 'AfterTool' | 'BeforeModel' | 'AfterModel';
|
|
288
|
+
llm_tool?: string;
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Adapter for Gemini CLI hook format
|
|
292
|
+
*/
|
|
293
|
+
declare class GeminiCliAdapter extends BaseAdapter<GeminiCliHookInput> {
|
|
165
294
|
/**
|
|
166
|
-
* Parse
|
|
295
|
+
* Parse Gemini CLI stdin into full hook input (preserves all fields)
|
|
167
296
|
*
|
|
168
|
-
* @param stdin - Raw JSON string from
|
|
169
|
-
* @returns
|
|
297
|
+
* @param stdin - Raw JSON string from Gemini CLI
|
|
298
|
+
* @returns Full Gemini CLI hook input
|
|
170
299
|
*/
|
|
171
|
-
parseInput(stdin: string):
|
|
300
|
+
parseInput(stdin: string): GeminiCliHookInput;
|
|
172
301
|
/**
|
|
173
|
-
* Format normalized HookResponse into
|
|
302
|
+
* Format normalized HookResponse into Gemini CLI output
|
|
174
303
|
*
|
|
175
304
|
* @param response - Normalized hook response
|
|
176
|
-
* @returns JSON string for
|
|
305
|
+
* @returns JSON string for Gemini CLI
|
|
177
306
|
*/
|
|
178
307
|
formatOutput(response: HookResponse): string;
|
|
179
|
-
/**
|
|
180
|
-
* Extract file path from tool input or response
|
|
181
|
-
*
|
|
182
|
-
* @param toolName - Name of the tool
|
|
183
|
-
* @param toolInput - Tool input parameters
|
|
184
|
-
* @param toolResponse - Tool response data
|
|
185
|
-
* @returns File path if this is a file operation
|
|
186
|
-
*/
|
|
187
|
-
private extractFilePath;
|
|
188
|
-
/**
|
|
189
|
-
* Extract operation type from tool name
|
|
190
|
-
*
|
|
191
|
-
* @param toolName - Name of the tool
|
|
192
|
-
* @returns Operation type if this is a file operation
|
|
193
|
-
*/
|
|
194
|
-
private extractOperation;
|
|
195
308
|
}
|
|
196
309
|
//#endregion
|
|
197
310
|
//#region src/services/ExecutionLogService.d.ts
|
|
198
311
|
/**
|
|
199
|
-
*
|
|
200
|
-
*
|
|
201
|
-
* DESIGN PATTERNS:
|
|
202
|
-
* - Repository pattern: Abstracts data access to execution log
|
|
203
|
-
* - Query pattern: Provides efficient lookups for hook execution history
|
|
204
|
-
* - Singleton cache: In-memory cache for performance
|
|
205
|
-
*
|
|
206
|
-
* CODING STANDARDS:
|
|
207
|
-
* - Use static methods for stateless operations
|
|
208
|
-
* - Handle file system errors gracefully
|
|
209
|
-
* - Optimize for performance with efficient data structures
|
|
210
|
-
*
|
|
211
|
-
* AVOID:
|
|
212
|
-
* - Loading entire log file into memory
|
|
213
|
-
* - Blocking I/O operations
|
|
214
|
-
* - Complex parsing logic (keep it simple)
|
|
312
|
+
* Log statistics returned by getStats method
|
|
215
313
|
*/
|
|
314
|
+
interface LogStats {
|
|
315
|
+
totalEntries: number;
|
|
316
|
+
uniqueFiles: number;
|
|
317
|
+
}
|
|
216
318
|
/**
|
|
217
319
|
* Input parameters for logging a hook execution
|
|
218
320
|
*/
|
|
@@ -226,57 +328,99 @@ interface LogExecutionParams {
|
|
|
226
328
|
fileMtime?: number;
|
|
227
329
|
/** MD5 checksum of file content at time of execution */
|
|
228
330
|
fileChecksum?: string;
|
|
331
|
+
/** List of files generated by scaffold method execution */
|
|
332
|
+
generatedFiles?: readonly string[] | string[];
|
|
333
|
+
/** Unique scaffold execution ID (for tracking specific scaffold operations) */
|
|
334
|
+
scaffoldId?: string;
|
|
335
|
+
/** Project path where scaffold was executed */
|
|
336
|
+
projectPath?: string;
|
|
337
|
+
/** Name of the scaffold feature/method that was used */
|
|
338
|
+
featureName?: string;
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Input parameters for checking if a hook execution has occurred
|
|
342
|
+
*/
|
|
343
|
+
interface HasExecutedParams {
|
|
344
|
+
/** File path to check */
|
|
345
|
+
filePath: string;
|
|
346
|
+
/** Decision to check for (e.g., 'deny' means we already showed patterns) */
|
|
347
|
+
decision: string;
|
|
348
|
+
/** Optional file pattern to match */
|
|
349
|
+
filePattern?: string;
|
|
350
|
+
/** Optional project path to distinguish same patterns in different projects */
|
|
351
|
+
projectPath?: string;
|
|
229
352
|
}
|
|
230
353
|
/**
|
|
231
354
|
* Service for tracking hook executions using an append-only log
|
|
232
355
|
* Prevents duplicate hook actions (e.g., showing design patterns twice for same file)
|
|
356
|
+
* Each session has its own log file for isolation
|
|
233
357
|
*/
|
|
234
358
|
declare class ExecutionLogService {
|
|
235
|
-
/** Log file path - stored in system temp directory */
|
|
236
|
-
private
|
|
359
|
+
/** Log file path for this session - stored in system temp directory */
|
|
360
|
+
private readonly logFile;
|
|
237
361
|
/** In-memory cache of recent executions (last 1000 entries) */
|
|
238
|
-
private
|
|
362
|
+
private cache;
|
|
239
363
|
/** Max cache size to prevent memory bloat */
|
|
240
364
|
private static readonly MAX_CACHE_SIZE;
|
|
365
|
+
/** Session ID for this service instance */
|
|
366
|
+
private readonly sessionId;
|
|
367
|
+
/**
|
|
368
|
+
* Create a new ExecutionLogService instance for a specific session
|
|
369
|
+
* @param sessionId - Unique session identifier
|
|
370
|
+
*/
|
|
371
|
+
constructor(sessionId: string);
|
|
241
372
|
/**
|
|
242
373
|
* Check if a specific action was already taken for this file in this session
|
|
243
374
|
*
|
|
244
|
-
*
|
|
245
|
-
*
|
|
246
|
-
*
|
|
247
|
-
* @
|
|
375
|
+
* NOTE: Uses fail-open strategy - on error, returns false to allow action.
|
|
376
|
+
* This ensures hooks can still provide guidance even if log access fails.
|
|
377
|
+
*
|
|
378
|
+
* @param params - Parameters for checking execution
|
|
379
|
+
* @returns true if the action was already taken, false on error (fail-open)
|
|
248
380
|
*/
|
|
249
|
-
|
|
381
|
+
hasExecuted(params: HasExecutedParams): Promise<boolean>;
|
|
250
382
|
/**
|
|
251
383
|
* Log a hook execution
|
|
252
384
|
*
|
|
253
|
-
*
|
|
385
|
+
* NOTE: This method uses fail-silent strategy. Logging failures should never
|
|
386
|
+
* break hook execution since the hook's primary purpose is to provide guidance,
|
|
387
|
+
* not to persist data. The log is used for optimization (preventing duplicate
|
|
388
|
+
* guidance) rather than critical functionality.
|
|
389
|
+
*
|
|
390
|
+
* @param params - Log execution parameters (sessionId will be set automatically)
|
|
254
391
|
*/
|
|
255
|
-
|
|
392
|
+
logExecution(params: Omit<LogExecutionParams, 'sessionId'>): Promise<void>;
|
|
256
393
|
/**
|
|
257
394
|
* Load execution log from file
|
|
258
395
|
* Uses in-memory cache for performance
|
|
396
|
+
*
|
|
397
|
+
* NOTE: Uses fail-silent strategy for non-ENOENT errors. The log is used for
|
|
398
|
+
* optimization (deduplication) rather than critical functionality. If the log
|
|
399
|
+
* cannot be read, returning empty allows hooks to continue with potentially
|
|
400
|
+
* duplicate guidance rather than failing entirely.
|
|
259
401
|
*/
|
|
260
|
-
|
|
402
|
+
loadLog(): Promise<LogEntry[]>;
|
|
261
403
|
/**
|
|
262
404
|
* Clear the execution log (for testing)
|
|
405
|
+
* @throws Error if deletion fails for reasons other than file not existing
|
|
263
406
|
*/
|
|
264
|
-
|
|
407
|
+
clearLog(): Promise<void>;
|
|
265
408
|
/**
|
|
266
409
|
* Get log statistics (for debugging)
|
|
410
|
+
*
|
|
411
|
+
* NOTE: Uses fail-open strategy - on error, returns zero counts.
|
|
412
|
+
* This is acceptable for debugging statistics which are non-critical.
|
|
413
|
+
*
|
|
414
|
+
* @returns Log statistics, or zeros on error (fail-open)
|
|
267
415
|
*/
|
|
268
|
-
|
|
269
|
-
totalEntries: number;
|
|
270
|
-
uniqueSessions: number;
|
|
271
|
-
uniqueFiles: number;
|
|
272
|
-
}>;
|
|
416
|
+
getStats(): Promise<LogStats>;
|
|
273
417
|
/**
|
|
274
418
|
* Get file metadata (mtime and checksum) for a file
|
|
275
419
|
*
|
|
276
420
|
* @param filePath - Path to the file
|
|
277
421
|
* @returns File metadata or null if file doesn't exist
|
|
278
422
|
*/
|
|
279
|
-
|
|
423
|
+
getFileMetadata(filePath: string): Promise<{
|
|
280
424
|
mtime: number;
|
|
281
425
|
checksum: string;
|
|
282
426
|
} | null>;
|
|
@@ -284,36 +428,85 @@ declare class ExecutionLogService {
|
|
|
284
428
|
* Check if a file has changed since the last execution for this session
|
|
285
429
|
* Returns true if the file should be reviewed (new file or content changed)
|
|
286
430
|
*
|
|
287
|
-
*
|
|
431
|
+
* NOTE: Uses fail-open strategy - on error, returns true to allow review.
|
|
432
|
+
* This ensures hooks can still provide value even if log access fails.
|
|
433
|
+
*
|
|
288
434
|
* @param filePath - File path to check
|
|
289
435
|
* @param decision - Decision type to check for
|
|
290
|
-
* @returns true if file has changed or no previous execution found
|
|
436
|
+
* @returns true if file has changed or no previous execution found, true on error (fail-open)
|
|
291
437
|
*/
|
|
292
|
-
|
|
293
|
-
}
|
|
294
|
-
//#endregion
|
|
295
|
-
//#region src/services/AdapterProxyService.d.ts
|
|
296
|
-
/**
|
|
297
|
-
* Proxy service for routing hook execution
|
|
298
|
-
* Eliminates duplication across commands by centralizing hook routing logic
|
|
299
|
-
*/
|
|
300
|
-
declare class AdapterProxyService {
|
|
438
|
+
hasFileChanged(filePath: string, decision: string): Promise<boolean>;
|
|
301
439
|
/**
|
|
302
|
-
*
|
|
440
|
+
* Check if file was recently reviewed (within debounce window)
|
|
441
|
+
* Prevents noisy feedback during rapid successive edits
|
|
303
442
|
*
|
|
304
|
-
*
|
|
305
|
-
*
|
|
306
|
-
*
|
|
443
|
+
* NOTE: Uses fail-open strategy - on error, returns false to allow review.
|
|
444
|
+
* This ensures hooks can still provide value even if log access fails.
|
|
445
|
+
*
|
|
446
|
+
* @param filePath - File path to check
|
|
447
|
+
* @param debounceMs - Debounce window in milliseconds (default: 3000ms = 3 seconds)
|
|
448
|
+
* @returns true if file was reviewed within debounce window, false on error (fail-open)
|
|
307
449
|
*/
|
|
308
|
-
|
|
450
|
+
wasRecentlyReviewed(filePath: string, debounceMs?: number): Promise<boolean>;
|
|
309
451
|
/**
|
|
310
|
-
*
|
|
452
|
+
* Check if a file was generated by a scaffold method
|
|
453
|
+
* Useful for hooks to avoid suggesting scaffold for files already created by scaffold
|
|
454
|
+
*
|
|
455
|
+
* NOTE: Uses fail-open strategy - on error, returns false to allow scaffold suggestion.
|
|
456
|
+
* Worst case: user sees scaffold suggestion for an already-scaffolded file.
|
|
311
457
|
*
|
|
312
|
-
* @param
|
|
313
|
-
* @
|
|
314
|
-
* @returns Adapter instance
|
|
458
|
+
* @param filePath - File path to check
|
|
459
|
+
* @returns true if file was generated by scaffold in this session, false on error (fail-open)
|
|
315
460
|
*/
|
|
316
|
-
|
|
461
|
+
wasGeneratedByScaffold(filePath: string): Promise<boolean>;
|
|
317
462
|
}
|
|
318
463
|
//#endregion
|
|
319
|
-
|
|
464
|
+
//#region src/utils/parseHookType.d.ts
|
|
465
|
+
/**
|
|
466
|
+
* parseHookType Utilities
|
|
467
|
+
*
|
|
468
|
+
* DESIGN PATTERNS:
|
|
469
|
+
* - Pure function pattern: No side effects, deterministic output
|
|
470
|
+
* - Single domain focus: All functions related to hook type parsing
|
|
471
|
+
* - Early validation with descriptive error messages
|
|
472
|
+
*
|
|
473
|
+
* CODING STANDARDS:
|
|
474
|
+
* - Function names use camelCase with descriptive verbs (validate, format, parse, transform)
|
|
475
|
+
* - All functions should be pure (same input = same output, no side effects)
|
|
476
|
+
* - Use explicit return types
|
|
477
|
+
* - Document complex logic with JSDoc comments
|
|
478
|
+
* - Keep functions small and focused on single responsibility
|
|
479
|
+
*
|
|
480
|
+
* AVOID:
|
|
481
|
+
* - Side effects (mutations, I/O, random values, Date.now(), etc.)
|
|
482
|
+
* - Stateful behavior or closures with mutable state
|
|
483
|
+
* - Dependencies on external services or global variables
|
|
484
|
+
* - Classes (use pure functions instead)
|
|
485
|
+
*/
|
|
486
|
+
/**
|
|
487
|
+
* Parsed hook type result containing agent and hook method
|
|
488
|
+
*/
|
|
489
|
+
interface ParsedHookType {
|
|
490
|
+
/** Agent identifier (e.g., 'claude-code', 'gemini-cli') */
|
|
491
|
+
agent: string;
|
|
492
|
+
/** Hook method name (e.g., 'preToolUse', 'afterTool') */
|
|
493
|
+
hookMethod: string;
|
|
494
|
+
}
|
|
495
|
+
/**
|
|
496
|
+
* Parse hook type option in format: agent.hookMethod
|
|
497
|
+
*
|
|
498
|
+
* @param hookType - Hook type string in format '<agent>.<hookMethod>'
|
|
499
|
+
* @returns Parsed hook type with agent and hookMethod
|
|
500
|
+
* @throws Error if hook type format is invalid
|
|
501
|
+
*
|
|
502
|
+
* @example
|
|
503
|
+
* parseHookType('claude-code.preToolUse')
|
|
504
|
+
* // Returns: { agent: 'claude-code', hookMethod: 'preToolUse' }
|
|
505
|
+
*
|
|
506
|
+
* @example
|
|
507
|
+
* parseHookType('gemini-cli.afterTool')
|
|
508
|
+
* // Returns: { agent: 'gemini-cli', hookMethod: 'afterTool' }
|
|
509
|
+
*/
|
|
510
|
+
declare function parseHookType(hookType: string): ParsedHookType;
|
|
511
|
+
//#endregion
|
|
512
|
+
export { AFTER_TOOL_USE, BEFORE_TOOL_USE, BaseAdapter, ClaudeCodeAdapter, ClaudeCodeHookInput, ClaudeCodePostToolUseInput, ClaudeCodePreToolUseInput, DECISION_ALLOW, DECISION_ASK, DECISION_DENY, DECISION_SKIP, Decision, ExecutionLogService, GeminiCliAdapter, GeminiCliHookInput, HasExecutedParams, HookContext, HookResponse, HookType, LogEntry, LogExecutionParams, LogStats, POST_TOOL_USE, PRE_TOOL_USE, ParsedHookType, PendingScaffoldLogEntry, ScaffoldExecution, ToolResult, ToolResultContentItem, parseHookType };
|