@goodfoot/claude-code-hooks 1.0.1
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/LICENSE +21 -0
- package/README.md +317 -0
- package/dist/cli.js +914 -0
- package/dist/constants.js +21 -0
- package/dist/env.js +188 -0
- package/dist/hooks.js +391 -0
- package/dist/index.js +77 -0
- package/dist/inputs.js +35 -0
- package/dist/logger.js +494 -0
- package/dist/outputs.js +282 -0
- package/dist/runtime.js +222 -0
- package/dist/scaffold.js +466 -0
- package/dist/tool-helpers.js +366 -0
- package/dist/tool-inputs.js +21 -0
- package/package.json +68 -0
- package/types/cli.d.ts +281 -0
- package/types/constants.d.ts +9 -0
- package/types/env.d.ts +150 -0
- package/types/hooks.d.ts +851 -0
- package/types/index.d.ts +137 -0
- package/types/inputs.d.ts +601 -0
- package/types/logger.d.ts +471 -0
- package/types/outputs.d.ts +643 -0
- package/types/runtime.d.ts +75 -0
- package/types/scaffold.d.ts +46 -0
- package/types/tool-helpers.d.ts +336 -0
- package/types/tool-inputs.d.ts +228 -0
|
@@ -0,0 +1,643 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Output types and builders for Claude Code hooks.
|
|
3
|
+
*
|
|
4
|
+
* Provides type-safe output builder functions for all 12 hook types. Each builder
|
|
5
|
+
* accepts options that match the wire format expected by Claude Code, with types
|
|
6
|
+
* derived from the Claude Agent SDK's `SyncHookJSONOutput` type.
|
|
7
|
+
* @see https://code.claude.com/docs/en/hooks
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
import type {
|
|
11
|
+
PermissionUpdate,
|
|
12
|
+
SyncHookJSONOutput as SDKSyncHookJSONOutput
|
|
13
|
+
} from '@anthropic-ai/claude-agent-sdk/entrypoints/agentSdkTypes.js';
|
|
14
|
+
/**
|
|
15
|
+
* Exit codes used by Claude Code hooks.
|
|
16
|
+
*
|
|
17
|
+
* | Exit Code | Name | When Used | Claude Code Behavior |
|
|
18
|
+
* |-----------|------|-----------|---------------------|
|
|
19
|
+
* | 0 | Success | Handler returns normally | Continue, parse stdout as JSON |
|
|
20
|
+
* | 1 | Error | Invalid input, non-blocking error | Non-blocking, stderr to user only |
|
|
21
|
+
* | 2 | Block | Handler throws OR `stopReason` set | Blocking, stderr shown to Claude |
|
|
22
|
+
*/
|
|
23
|
+
export declare const EXIT_CODES: {
|
|
24
|
+
/** Handler completed successfully. Claude Code parses stdout as JSON. */
|
|
25
|
+
readonly SUCCESS: 0;
|
|
26
|
+
/** Non-blocking error occurred (e.g., invalid input). stderr shown to user only. */
|
|
27
|
+
readonly ERROR: 1;
|
|
28
|
+
/** Handler threw exception OR blocking action requested. stderr shown to Claude. */
|
|
29
|
+
readonly BLOCK: 2;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Exit code type.
|
|
33
|
+
*/
|
|
34
|
+
export type ExitCode = (typeof EXIT_CODES)[keyof typeof EXIT_CODES];
|
|
35
|
+
/**
|
|
36
|
+
* Re-export the SDK's SyncHookJSONOutput type for reference.
|
|
37
|
+
* Our types are derived from this to ensure wire format compatibility.
|
|
38
|
+
*/
|
|
39
|
+
export type { SDKSyncHookJSONOutput };
|
|
40
|
+
/**
|
|
41
|
+
* PreToolUse hook-specific output fields.
|
|
42
|
+
* Omits `hookEventName` which is added automatically.
|
|
43
|
+
*/
|
|
44
|
+
export interface PreToolUseHookSpecificOutput {
|
|
45
|
+
/** Permission decision: 'allow', 'deny', or 'ask' */
|
|
46
|
+
permissionDecision?: 'allow' | 'deny' | 'ask';
|
|
47
|
+
/** Reason for the permission decision. */
|
|
48
|
+
permissionDecisionReason?: string;
|
|
49
|
+
/** Modified tool input to use instead of original. */
|
|
50
|
+
updatedInput?: Record<string, unknown>;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* PostToolUse hook-specific output fields.
|
|
54
|
+
*/
|
|
55
|
+
export interface PostToolUseHookSpecificOutput {
|
|
56
|
+
/** Additional context to add to the transcript. */
|
|
57
|
+
additionalContext?: string;
|
|
58
|
+
/** Updated MCP tool output to replace the original. */
|
|
59
|
+
updatedMCPToolOutput?: unknown;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* PostToolUseFailure hook-specific output fields.
|
|
63
|
+
*/
|
|
64
|
+
export interface PostToolUseFailureHookSpecificOutput {
|
|
65
|
+
/** Additional context to add after the failure. */
|
|
66
|
+
additionalContext?: string;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* UserPromptSubmit hook-specific output fields.
|
|
70
|
+
*/
|
|
71
|
+
export interface UserPromptSubmitHookSpecificOutput {
|
|
72
|
+
/** Additional context to inject into the conversation. */
|
|
73
|
+
additionalContext?: string;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* SessionStart hook-specific output fields.
|
|
77
|
+
*/
|
|
78
|
+
export interface SessionStartHookSpecificOutput {
|
|
79
|
+
/** Additional context to inject at session start. */
|
|
80
|
+
additionalContext?: string;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* SubagentStart hook-specific output fields.
|
|
84
|
+
*/
|
|
85
|
+
export interface SubagentStartHookSpecificOutput {
|
|
86
|
+
/** Additional context to inject for the subagent. */
|
|
87
|
+
additionalContext?: string;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Notification hook-specific output fields.
|
|
91
|
+
*/
|
|
92
|
+
export interface NotificationHookSpecificOutput {
|
|
93
|
+
/** Additional context to add about the notification. */
|
|
94
|
+
additionalContext?: string;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Allow decision for permission requests.
|
|
98
|
+
*/
|
|
99
|
+
export interface PermissionRequestAllowDecision {
|
|
100
|
+
behavior: 'allow';
|
|
101
|
+
/** Updated tool input to use. */
|
|
102
|
+
updatedInput?: Record<string, unknown>;
|
|
103
|
+
/** Permission updates to apply. */
|
|
104
|
+
updatedPermissions?: PermissionUpdate[];
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Deny decision for permission requests.
|
|
108
|
+
*/
|
|
109
|
+
export interface PermissionRequestDenyDecision {
|
|
110
|
+
behavior: 'deny';
|
|
111
|
+
/** Message explaining the denial. */
|
|
112
|
+
message?: string;
|
|
113
|
+
/** Whether to interrupt the current operation. */
|
|
114
|
+
interrupt?: boolean;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Permission request decision - either allow or deny.
|
|
118
|
+
*/
|
|
119
|
+
export type PermissionRequestDecision = PermissionRequestAllowDecision | PermissionRequestDenyDecision;
|
|
120
|
+
/**
|
|
121
|
+
* PermissionRequest hook-specific output fields.
|
|
122
|
+
*/
|
|
123
|
+
export interface PermissionRequestHookSpecificOutput {
|
|
124
|
+
/** Permission decision details. */
|
|
125
|
+
decision: PermissionRequestDecision;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Full hook-specific output with hookEventName discriminator.
|
|
129
|
+
*/
|
|
130
|
+
export type HookSpecificOutput =
|
|
131
|
+
| ({
|
|
132
|
+
hookEventName: 'PreToolUse';
|
|
133
|
+
} & PreToolUseHookSpecificOutput)
|
|
134
|
+
| ({
|
|
135
|
+
hookEventName: 'PostToolUse';
|
|
136
|
+
} & PostToolUseHookSpecificOutput)
|
|
137
|
+
| ({
|
|
138
|
+
hookEventName: 'PostToolUseFailure';
|
|
139
|
+
} & PostToolUseFailureHookSpecificOutput)
|
|
140
|
+
| ({
|
|
141
|
+
hookEventName: 'UserPromptSubmit';
|
|
142
|
+
} & UserPromptSubmitHookSpecificOutput)
|
|
143
|
+
| ({
|
|
144
|
+
hookEventName: 'SessionStart';
|
|
145
|
+
} & SessionStartHookSpecificOutput)
|
|
146
|
+
| ({
|
|
147
|
+
hookEventName: 'SubagentStart';
|
|
148
|
+
} & SubagentStartHookSpecificOutput)
|
|
149
|
+
| ({
|
|
150
|
+
hookEventName: 'Notification';
|
|
151
|
+
} & NotificationHookSpecificOutput)
|
|
152
|
+
| ({
|
|
153
|
+
hookEventName: 'PermissionRequest';
|
|
154
|
+
} & PermissionRequestHookSpecificOutput);
|
|
155
|
+
/**
|
|
156
|
+
* The JSON output format expected by Claude Code (sync hooks only).
|
|
157
|
+
* Matches the SDK's SyncHookJSONOutput type.
|
|
158
|
+
*/
|
|
159
|
+
export interface SyncHookJSONOutput {
|
|
160
|
+
/** If true, continue processing even after errors. */
|
|
161
|
+
continue?: boolean;
|
|
162
|
+
/** If true, suppress the hook's output from being displayed. */
|
|
163
|
+
suppressOutput?: boolean;
|
|
164
|
+
/** Reason for stopping the session (when blocking). */
|
|
165
|
+
stopReason?: string;
|
|
166
|
+
/** Decision for Stop/SubagentStop hooks: 'approve' allows stop, 'block' prevents it. */
|
|
167
|
+
decision?: 'approve' | 'block';
|
|
168
|
+
/** System message to inject into Claude's context. */
|
|
169
|
+
systemMessage?: string;
|
|
170
|
+
/** Reason shown to Claude when blocking. */
|
|
171
|
+
reason?: string;
|
|
172
|
+
/** Hook-specific output based on the hook type. */
|
|
173
|
+
hookSpecificOutput?: HookSpecificOutput;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* The result of a hook handler, ready for the runtime to process.
|
|
177
|
+
* Exit code is always SUCCESS (0) - blocking behavior is communicated via stdout fields.
|
|
178
|
+
*/
|
|
179
|
+
export interface HookOutput {
|
|
180
|
+
/** JSON-serializable output to write to stdout. */
|
|
181
|
+
stdout: SyncHookJSONOutput;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Common options available to all output builders.
|
|
185
|
+
* These map directly to the wire format fields.
|
|
186
|
+
*/
|
|
187
|
+
export interface CommonOptions {
|
|
188
|
+
/** If true, continue processing even after errors. */
|
|
189
|
+
continue?: boolean;
|
|
190
|
+
/** If true, suppress the hook's output from being displayed. */
|
|
191
|
+
suppressOutput?: boolean;
|
|
192
|
+
/** System message to inject into Claude's context. */
|
|
193
|
+
systemMessage?: string;
|
|
194
|
+
/** Reason for stopping/blocking (sets exit code to BLOCK). */
|
|
195
|
+
stopReason?: string;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Base structure for all specific outputs.
|
|
199
|
+
*/
|
|
200
|
+
interface BaseSpecificOutput<T extends string> {
|
|
201
|
+
readonly _type: T;
|
|
202
|
+
stdout: SyncHookJSONOutput;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
*
|
|
206
|
+
*/
|
|
207
|
+
export type PreToolUseOutput = BaseSpecificOutput<'PreToolUse'>;
|
|
208
|
+
/**
|
|
209
|
+
*
|
|
210
|
+
*/
|
|
211
|
+
export type PostToolUseOutput = BaseSpecificOutput<'PostToolUse'>;
|
|
212
|
+
/**
|
|
213
|
+
*
|
|
214
|
+
*/
|
|
215
|
+
export type PostToolUseFailureOutput = BaseSpecificOutput<'PostToolUseFailure'>;
|
|
216
|
+
/**
|
|
217
|
+
*
|
|
218
|
+
*/
|
|
219
|
+
export type NotificationOutput = BaseSpecificOutput<'Notification'>;
|
|
220
|
+
/**
|
|
221
|
+
*
|
|
222
|
+
*/
|
|
223
|
+
export type UserPromptSubmitOutput = BaseSpecificOutput<'UserPromptSubmit'>;
|
|
224
|
+
/**
|
|
225
|
+
*
|
|
226
|
+
*/
|
|
227
|
+
export type SessionStartOutput = BaseSpecificOutput<'SessionStart'>;
|
|
228
|
+
/**
|
|
229
|
+
*
|
|
230
|
+
*/
|
|
231
|
+
export type SessionEndOutput = BaseSpecificOutput<'SessionEnd'>;
|
|
232
|
+
/**
|
|
233
|
+
*
|
|
234
|
+
*/
|
|
235
|
+
export type StopOutput = BaseSpecificOutput<'Stop'>;
|
|
236
|
+
/**
|
|
237
|
+
*
|
|
238
|
+
*/
|
|
239
|
+
export type SubagentStartOutput = BaseSpecificOutput<'SubagentStart'>;
|
|
240
|
+
/**
|
|
241
|
+
*
|
|
242
|
+
*/
|
|
243
|
+
export type SubagentStopOutput = BaseSpecificOutput<'SubagentStop'>;
|
|
244
|
+
/**
|
|
245
|
+
*
|
|
246
|
+
*/
|
|
247
|
+
export type PreCompactOutput = BaseSpecificOutput<'PreCompact'>;
|
|
248
|
+
/**
|
|
249
|
+
*
|
|
250
|
+
*/
|
|
251
|
+
export type PermissionRequestOutput = BaseSpecificOutput<'PermissionRequest'>;
|
|
252
|
+
/**
|
|
253
|
+
* Union of all specific output types.
|
|
254
|
+
*/
|
|
255
|
+
export type SpecificHookOutput =
|
|
256
|
+
| PreToolUseOutput
|
|
257
|
+
| PostToolUseOutput
|
|
258
|
+
| PostToolUseFailureOutput
|
|
259
|
+
| NotificationOutput
|
|
260
|
+
| UserPromptSubmitOutput
|
|
261
|
+
| SessionStartOutput
|
|
262
|
+
| SessionEndOutput
|
|
263
|
+
| StopOutput
|
|
264
|
+
| SubagentStartOutput
|
|
265
|
+
| SubagentStopOutput
|
|
266
|
+
| PreCompactOutput
|
|
267
|
+
| PermissionRequestOutput;
|
|
268
|
+
/**
|
|
269
|
+
* Options for decision-based hooks (Stop, SubagentStop).
|
|
270
|
+
*/
|
|
271
|
+
interface DecisionOptions extends CommonOptions {
|
|
272
|
+
/** Decision: 'approve' allows the action, 'block' prevents it. */
|
|
273
|
+
decision?: 'approve' | 'block';
|
|
274
|
+
/** Reason for the decision (shown to Claude when blocking). */
|
|
275
|
+
reason?: string;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Options for the PreToolUse output builder.
|
|
279
|
+
* Uses wire format: hookSpecificOutput with permissionDecision.
|
|
280
|
+
*/
|
|
281
|
+
export type PreToolUseOptions = CommonOptions & {
|
|
282
|
+
/** Hook-specific output matching the wire format. */
|
|
283
|
+
hookSpecificOutput?: PreToolUseHookSpecificOutput;
|
|
284
|
+
};
|
|
285
|
+
/**
|
|
286
|
+
* Creates an output for PreToolUse hooks.
|
|
287
|
+
* @param options - Configuration options for the hook output
|
|
288
|
+
* @returns A PreToolUseOutput object ready for the runtime
|
|
289
|
+
* @example
|
|
290
|
+
* ```typescript
|
|
291
|
+
* // Allow tool execution
|
|
292
|
+
* preToolUseOutput({
|
|
293
|
+
* hookSpecificOutput: { permissionDecision: 'allow' }
|
|
294
|
+
* });
|
|
295
|
+
*
|
|
296
|
+
* // Deny with reason
|
|
297
|
+
* preToolUseOutput({
|
|
298
|
+
* hookSpecificOutput: {
|
|
299
|
+
* permissionDecision: 'deny',
|
|
300
|
+
* permissionDecisionReason: 'Dangerous command detected'
|
|
301
|
+
* }
|
|
302
|
+
* });
|
|
303
|
+
*
|
|
304
|
+
* // Allow with modified input
|
|
305
|
+
* preToolUseOutput({
|
|
306
|
+
* hookSpecificOutput: {
|
|
307
|
+
* permissionDecision: 'allow',
|
|
308
|
+
* updatedInput: { command: 'ls -la' }
|
|
309
|
+
* }
|
|
310
|
+
* });
|
|
311
|
+
* ```
|
|
312
|
+
*/
|
|
313
|
+
export declare const preToolUseOutput: (
|
|
314
|
+
options?: CommonOptions & {
|
|
315
|
+
hookSpecificOutput?: PreToolUseHookSpecificOutput | undefined;
|
|
316
|
+
}
|
|
317
|
+
) => {
|
|
318
|
+
readonly _type: 'PreToolUse';
|
|
319
|
+
stdout: SyncHookJSONOutput;
|
|
320
|
+
};
|
|
321
|
+
/**
|
|
322
|
+
* Options for the PostToolUse output builder.
|
|
323
|
+
*/
|
|
324
|
+
export type PostToolUseOptions = CommonOptions & {
|
|
325
|
+
/** Hook-specific output matching the wire format. */
|
|
326
|
+
hookSpecificOutput?: PostToolUseHookSpecificOutput;
|
|
327
|
+
};
|
|
328
|
+
/**
|
|
329
|
+
* Creates an output for PostToolUse hooks.
|
|
330
|
+
* @param options - Configuration options for the hook output
|
|
331
|
+
* @returns A PostToolUseOutput object ready for the runtime
|
|
332
|
+
* @example
|
|
333
|
+
* ```typescript
|
|
334
|
+
* // Add context after a file read
|
|
335
|
+
* postToolUseOutput({
|
|
336
|
+
* hookSpecificOutput: {
|
|
337
|
+
* additionalContext: 'File contains sensitive data'
|
|
338
|
+
* }
|
|
339
|
+
* });
|
|
340
|
+
* ```
|
|
341
|
+
*/
|
|
342
|
+
export declare const postToolUseOutput: (
|
|
343
|
+
options?: CommonOptions & {
|
|
344
|
+
hookSpecificOutput?: PostToolUseHookSpecificOutput | undefined;
|
|
345
|
+
}
|
|
346
|
+
) => {
|
|
347
|
+
readonly _type: 'PostToolUse';
|
|
348
|
+
stdout: SyncHookJSONOutput;
|
|
349
|
+
};
|
|
350
|
+
/**
|
|
351
|
+
* Options for the PostToolUseFailure output builder.
|
|
352
|
+
*/
|
|
353
|
+
export type PostToolUseFailureOptions = CommonOptions & {
|
|
354
|
+
/** Hook-specific output matching the wire format. */
|
|
355
|
+
hookSpecificOutput?: PostToolUseFailureHookSpecificOutput;
|
|
356
|
+
};
|
|
357
|
+
/**
|
|
358
|
+
* Creates an output for PostToolUseFailure hooks.
|
|
359
|
+
* @param options - Configuration options for the hook output
|
|
360
|
+
* @returns A PostToolUseFailureOutput object ready for the runtime
|
|
361
|
+
* @example
|
|
362
|
+
* ```typescript
|
|
363
|
+
* postToolUseFailureOutput({
|
|
364
|
+
* hookSpecificOutput: {
|
|
365
|
+
* additionalContext: 'Try using a different approach'
|
|
366
|
+
* }
|
|
367
|
+
* });
|
|
368
|
+
* ```
|
|
369
|
+
*/
|
|
370
|
+
export declare const postToolUseFailureOutput: (
|
|
371
|
+
options?: CommonOptions & {
|
|
372
|
+
hookSpecificOutput?: PostToolUseFailureHookSpecificOutput | undefined;
|
|
373
|
+
}
|
|
374
|
+
) => {
|
|
375
|
+
readonly _type: 'PostToolUseFailure';
|
|
376
|
+
stdout: SyncHookJSONOutput;
|
|
377
|
+
};
|
|
378
|
+
/**
|
|
379
|
+
* Options for the UserPromptSubmit output builder.
|
|
380
|
+
*/
|
|
381
|
+
export type UserPromptSubmitOptions = CommonOptions & {
|
|
382
|
+
/** Hook-specific output matching the wire format. */
|
|
383
|
+
hookSpecificOutput?: UserPromptSubmitHookSpecificOutput;
|
|
384
|
+
};
|
|
385
|
+
/**
|
|
386
|
+
* Creates an output for UserPromptSubmit hooks.
|
|
387
|
+
* @param options - Configuration options for the hook output
|
|
388
|
+
* @returns A UserPromptSubmitOutput object ready for the runtime
|
|
389
|
+
* @example
|
|
390
|
+
* ```typescript
|
|
391
|
+
* userPromptSubmitOutput({
|
|
392
|
+
* hookSpecificOutput: {
|
|
393
|
+
* additionalContext: 'This project uses TypeScript strict mode'
|
|
394
|
+
* }
|
|
395
|
+
* });
|
|
396
|
+
* ```
|
|
397
|
+
*/
|
|
398
|
+
export declare const userPromptSubmitOutput: (
|
|
399
|
+
options?: CommonOptions & {
|
|
400
|
+
hookSpecificOutput?: UserPromptSubmitHookSpecificOutput | undefined;
|
|
401
|
+
}
|
|
402
|
+
) => {
|
|
403
|
+
readonly _type: 'UserPromptSubmit';
|
|
404
|
+
stdout: SyncHookJSONOutput;
|
|
405
|
+
};
|
|
406
|
+
/**
|
|
407
|
+
* Options for the SessionStart output builder.
|
|
408
|
+
*/
|
|
409
|
+
export type SessionStartOptions = CommonOptions & {
|
|
410
|
+
/** Hook-specific output matching the wire format. */
|
|
411
|
+
hookSpecificOutput?: SessionStartHookSpecificOutput;
|
|
412
|
+
};
|
|
413
|
+
/**
|
|
414
|
+
* Creates an output for SessionStart hooks.
|
|
415
|
+
* @param options - Configuration options for the hook output
|
|
416
|
+
* @returns A SessionStartOutput object ready for the runtime
|
|
417
|
+
* @example
|
|
418
|
+
* ```typescript
|
|
419
|
+
* sessionStartOutput({
|
|
420
|
+
* hookSpecificOutput: {
|
|
421
|
+
* additionalContext: JSON.stringify({ project: 'my-project' })
|
|
422
|
+
* }
|
|
423
|
+
* });
|
|
424
|
+
* ```
|
|
425
|
+
*/
|
|
426
|
+
export declare const sessionStartOutput: (
|
|
427
|
+
options?: CommonOptions & {
|
|
428
|
+
hookSpecificOutput?: SessionStartHookSpecificOutput | undefined;
|
|
429
|
+
}
|
|
430
|
+
) => {
|
|
431
|
+
readonly _type: 'SessionStart';
|
|
432
|
+
stdout: SyncHookJSONOutput;
|
|
433
|
+
};
|
|
434
|
+
/**
|
|
435
|
+
* Options for the SessionEnd output builder.
|
|
436
|
+
* SessionEnd hooks only support common options.
|
|
437
|
+
*/
|
|
438
|
+
export type SessionEndOptions = CommonOptions;
|
|
439
|
+
/**
|
|
440
|
+
* Creates an output for SessionEnd hooks.
|
|
441
|
+
* @param options - Configuration options for the hook output
|
|
442
|
+
* @returns A SessionEndOutput object ready for the runtime
|
|
443
|
+
* @example
|
|
444
|
+
* ```typescript
|
|
445
|
+
* sessionEndOutput({});
|
|
446
|
+
* ```
|
|
447
|
+
*/
|
|
448
|
+
export declare const sessionEndOutput: (options?: CommonOptions) => {
|
|
449
|
+
readonly _type: 'SessionEnd';
|
|
450
|
+
stdout: SyncHookJSONOutput;
|
|
451
|
+
};
|
|
452
|
+
/**
|
|
453
|
+
* Options for the Stop output builder.
|
|
454
|
+
*/
|
|
455
|
+
export interface StopOptions extends CommonOptions {
|
|
456
|
+
/** Decision: 'approve' allows stop, 'block' prevents it. */
|
|
457
|
+
decision?: 'approve' | 'block';
|
|
458
|
+
/** Reason for the decision (shown to Claude when blocking). */
|
|
459
|
+
reason?: string;
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* Creates an output for Stop hooks.
|
|
463
|
+
* @param options - Configuration options for the hook output
|
|
464
|
+
* @returns A StopOutput object ready for the runtime
|
|
465
|
+
* @example
|
|
466
|
+
* ```typescript
|
|
467
|
+
* // Allow the stop
|
|
468
|
+
* stopOutput({ decision: 'approve' });
|
|
469
|
+
*
|
|
470
|
+
* // Block with reason
|
|
471
|
+
* stopOutput({
|
|
472
|
+
* decision: 'block',
|
|
473
|
+
* reason: 'There are uncommitted changes'
|
|
474
|
+
* });
|
|
475
|
+
* ```
|
|
476
|
+
*/
|
|
477
|
+
export declare const stopOutput: (options?: DecisionOptions) => {
|
|
478
|
+
readonly _type: 'Stop';
|
|
479
|
+
stdout: SyncHookJSONOutput;
|
|
480
|
+
};
|
|
481
|
+
/**
|
|
482
|
+
* Options for the SubagentStart output builder.
|
|
483
|
+
*/
|
|
484
|
+
export type SubagentStartOptions = CommonOptions & {
|
|
485
|
+
/** Hook-specific output matching the wire format. */
|
|
486
|
+
hookSpecificOutput?: SubagentStartHookSpecificOutput;
|
|
487
|
+
};
|
|
488
|
+
/**
|
|
489
|
+
* Creates an output for SubagentStart hooks.
|
|
490
|
+
* @param options - Configuration options for the hook output
|
|
491
|
+
* @returns A SubagentStartOutput object ready for the runtime
|
|
492
|
+
* @example
|
|
493
|
+
* ```typescript
|
|
494
|
+
* subagentStartOutput({
|
|
495
|
+
* hookSpecificOutput: {
|
|
496
|
+
* additionalContext: 'Focus on finding patterns'
|
|
497
|
+
* }
|
|
498
|
+
* });
|
|
499
|
+
* ```
|
|
500
|
+
*/
|
|
501
|
+
export declare const subagentStartOutput: (
|
|
502
|
+
options?: CommonOptions & {
|
|
503
|
+
hookSpecificOutput?: SubagentStartHookSpecificOutput | undefined;
|
|
504
|
+
}
|
|
505
|
+
) => {
|
|
506
|
+
readonly _type: 'SubagentStart';
|
|
507
|
+
stdout: SyncHookJSONOutput;
|
|
508
|
+
};
|
|
509
|
+
/**
|
|
510
|
+
* Options for the SubagentStop output builder.
|
|
511
|
+
*/
|
|
512
|
+
export interface SubagentStopOptions extends CommonOptions {
|
|
513
|
+
/** Decision: 'approve' allows stop, 'block' prevents it. */
|
|
514
|
+
decision?: 'approve' | 'block';
|
|
515
|
+
/** Reason for the decision (shown to subagent when blocking). */
|
|
516
|
+
reason?: string;
|
|
517
|
+
}
|
|
518
|
+
/**
|
|
519
|
+
* Creates an output for SubagentStop hooks.
|
|
520
|
+
* @param options - Configuration options for the hook output
|
|
521
|
+
* @returns A SubagentStopOutput object ready for the runtime
|
|
522
|
+
* @example
|
|
523
|
+
* ```typescript
|
|
524
|
+
* // Block with reason
|
|
525
|
+
* subagentStopOutput({
|
|
526
|
+
* decision: 'block',
|
|
527
|
+
* reason: 'Task not complete'
|
|
528
|
+
* });
|
|
529
|
+
* ```
|
|
530
|
+
*/
|
|
531
|
+
export declare const subagentStopOutput: (options?: DecisionOptions) => {
|
|
532
|
+
readonly _type: 'SubagentStop';
|
|
533
|
+
stdout: SyncHookJSONOutput;
|
|
534
|
+
};
|
|
535
|
+
/**
|
|
536
|
+
* Options for the Notification output builder.
|
|
537
|
+
*/
|
|
538
|
+
export type NotificationOptions = CommonOptions & {
|
|
539
|
+
/** Hook-specific output matching the wire format. */
|
|
540
|
+
hookSpecificOutput?: NotificationHookSpecificOutput;
|
|
541
|
+
};
|
|
542
|
+
/**
|
|
543
|
+
* Creates an output for Notification hooks.
|
|
544
|
+
* @param options - Configuration options for the hook output
|
|
545
|
+
* @returns A NotificationOutput object ready for the runtime
|
|
546
|
+
* @example
|
|
547
|
+
* ```typescript
|
|
548
|
+
* // Add context about the notification
|
|
549
|
+
* notificationOutput({
|
|
550
|
+
* hookSpecificOutput: {
|
|
551
|
+
* additionalContext: 'Notification forwarded to Slack #alerts channel'
|
|
552
|
+
* }
|
|
553
|
+
* });
|
|
554
|
+
*
|
|
555
|
+
* // Suppress the notification
|
|
556
|
+
* notificationOutput({ suppressOutput: true });
|
|
557
|
+
* ```
|
|
558
|
+
*/
|
|
559
|
+
export declare const notificationOutput: (
|
|
560
|
+
options?: CommonOptions & {
|
|
561
|
+
hookSpecificOutput?: NotificationHookSpecificOutput | undefined;
|
|
562
|
+
}
|
|
563
|
+
) => {
|
|
564
|
+
readonly _type: 'Notification';
|
|
565
|
+
stdout: SyncHookJSONOutput;
|
|
566
|
+
};
|
|
567
|
+
/**
|
|
568
|
+
* Options for the PreCompact output builder.
|
|
569
|
+
* PreCompact hooks only support common options.
|
|
570
|
+
*/
|
|
571
|
+
export type PreCompactOptions = CommonOptions;
|
|
572
|
+
/**
|
|
573
|
+
* Creates an output for PreCompact hooks.
|
|
574
|
+
* @param options - Configuration options for the hook output
|
|
575
|
+
* @returns A PreCompactOutput object ready for the runtime
|
|
576
|
+
* @example
|
|
577
|
+
* ```typescript
|
|
578
|
+
* preCompactOutput({
|
|
579
|
+
* systemMessage: 'Remember: strict mode is enabled'
|
|
580
|
+
* });
|
|
581
|
+
* ```
|
|
582
|
+
*/
|
|
583
|
+
export declare const preCompactOutput: (options?: CommonOptions) => {
|
|
584
|
+
readonly _type: 'PreCompact';
|
|
585
|
+
stdout: SyncHookJSONOutput;
|
|
586
|
+
};
|
|
587
|
+
/**
|
|
588
|
+
* Options for the PermissionRequest output builder.
|
|
589
|
+
*/
|
|
590
|
+
export type PermissionRequestOptions = CommonOptions & {
|
|
591
|
+
/** Hook-specific output matching the wire format. */
|
|
592
|
+
hookSpecificOutput?: PermissionRequestHookSpecificOutput;
|
|
593
|
+
};
|
|
594
|
+
/**
|
|
595
|
+
* Creates an output for PermissionRequest hooks.
|
|
596
|
+
* @param options - Configuration options for the hook output
|
|
597
|
+
* @returns A PermissionRequestOutput object ready for the runtime
|
|
598
|
+
* @example
|
|
599
|
+
* ```typescript
|
|
600
|
+
* // Auto-approve
|
|
601
|
+
* permissionRequestOutput({
|
|
602
|
+
* hookSpecificOutput: {
|
|
603
|
+
* decision: { behavior: 'allow' }
|
|
604
|
+
* }
|
|
605
|
+
* });
|
|
606
|
+
*
|
|
607
|
+
* // Auto-approve with modified input
|
|
608
|
+
* permissionRequestOutput({
|
|
609
|
+
* hookSpecificOutput: {
|
|
610
|
+
* decision: {
|
|
611
|
+
* behavior: 'allow',
|
|
612
|
+
* updatedInput: { file_path: '/safe/path' }
|
|
613
|
+
* }
|
|
614
|
+
* }
|
|
615
|
+
* });
|
|
616
|
+
*
|
|
617
|
+
* // Auto-deny
|
|
618
|
+
* permissionRequestOutput({
|
|
619
|
+
* hookSpecificOutput: {
|
|
620
|
+
* decision: {
|
|
621
|
+
* behavior: 'deny',
|
|
622
|
+
* message: 'Not allowed',
|
|
623
|
+
* interrupt: true
|
|
624
|
+
* }
|
|
625
|
+
* }
|
|
626
|
+
* });
|
|
627
|
+
*
|
|
628
|
+
* // Fall through to normal prompt
|
|
629
|
+
* permissionRequestOutput({});
|
|
630
|
+
* ```
|
|
631
|
+
*/
|
|
632
|
+
export declare const permissionRequestOutput: (
|
|
633
|
+
options?: CommonOptions & {
|
|
634
|
+
hookSpecificOutput?: PermissionRequestHookSpecificOutput | undefined;
|
|
635
|
+
}
|
|
636
|
+
) => {
|
|
637
|
+
readonly _type: 'PermissionRequest';
|
|
638
|
+
stdout: SyncHookJSONOutput;
|
|
639
|
+
};
|
|
640
|
+
/**
|
|
641
|
+
* @deprecated Use CommonOptions instead
|
|
642
|
+
*/
|
|
643
|
+
export type BaseOptions = CommonOptions;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime module for Claude Code hooks.
|
|
3
|
+
*
|
|
4
|
+
* Handles stdin/stdout/exit code semantics for compiled hook execution.
|
|
5
|
+
* This module is the core orchestrator that:
|
|
6
|
+
* - Reads JSON from stdin (wire format with snake_case properties)
|
|
7
|
+
* - Invokes the hook handler
|
|
8
|
+
* - Writes output to stdout
|
|
9
|
+
* - Manages exit codes
|
|
10
|
+
* @module
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* // In a compiled hook file
|
|
14
|
+
* import { execute } from '@goodfoot/claude-code-hooks/runtime';
|
|
15
|
+
* import myHook from './my-hook.js';
|
|
16
|
+
*
|
|
17
|
+
* execute(myHook);
|
|
18
|
+
* ```
|
|
19
|
+
* @see https://code.claude.com/docs/en/hooks
|
|
20
|
+
*/
|
|
21
|
+
import type { HookFunction } from './hooks.js';
|
|
22
|
+
import type { HookInput } from './inputs.js';
|
|
23
|
+
import type { HookOutput, SpecificHookOutput } from './outputs.js';
|
|
24
|
+
/**
|
|
25
|
+
* Converts a SpecificHookOutput to HookOutput for wire format.
|
|
26
|
+
*
|
|
27
|
+
* SpecificHookOutput types have: { _type, exitCode, stdout, stderr? }
|
|
28
|
+
* HookOutput has: { exitCode, stdout, stderr? }
|
|
29
|
+
*
|
|
30
|
+
* Since output builders now produce wire-format directly, this function
|
|
31
|
+
* simply strips the `_type` discriminator field.
|
|
32
|
+
* @param specificOutput - The specific output from a hook handler
|
|
33
|
+
* @returns HookOutput ready for serialization
|
|
34
|
+
* @see https://code.claude.com/docs/en/hooks#hook-output-structure
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* const specificOutput = preToolUseOutput({ hookSpecificOutput: { permissionDecision: 'allow' } });
|
|
38
|
+
* const hookOutput = convertToHookOutput(specificOutput);
|
|
39
|
+
* // hookOutput: { exitCode: 0, stdout: { hookSpecificOutput: { ... } } }
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export declare function convertToHookOutput(specificOutput: SpecificHookOutput): HookOutput;
|
|
43
|
+
/**
|
|
44
|
+
* Executes a hook handler with full runtime orchestration.
|
|
45
|
+
*
|
|
46
|
+
* This is the main entry point that compiled hooks use. When a compiled hook
|
|
47
|
+
* runs as a CLI:
|
|
48
|
+
*
|
|
49
|
+
* 1. Reads all stdin
|
|
50
|
+
* 2. Parses JSON (wire format with snake_case properties)
|
|
51
|
+
* 3. Sets up logger context (hookType, input)
|
|
52
|
+
* 4. Calls handler with input and context (logger)
|
|
53
|
+
* 5. Handles any errors, logs them
|
|
54
|
+
* 6. Writes JSON to stdout
|
|
55
|
+
* 7. Closes logger
|
|
56
|
+
* 8. Exits with appropriate code
|
|
57
|
+
* @param hookFn - The hook function to execute (from hook factory)
|
|
58
|
+
* @example
|
|
59
|
+
* ```typescript
|
|
60
|
+
* // In compiled hook file
|
|
61
|
+
* import { execute } from '@goodfoot/claude-code-hooks/runtime';
|
|
62
|
+
* import { preToolUseHook, preToolUseOutput } from '@goodfoot/claude-code-hooks';
|
|
63
|
+
*
|
|
64
|
+
* const myHook = preToolUseHook({ matcher: 'Bash' }, async (input, { logger }) => {
|
|
65
|
+
* logger.info('Processing Bash command');
|
|
66
|
+
* return preToolUseOutput({ allow: true });
|
|
67
|
+
* });
|
|
68
|
+
*
|
|
69
|
+
* execute(myHook);
|
|
70
|
+
* ```
|
|
71
|
+
* @see https://code.claude.com/docs/en/hooks
|
|
72
|
+
*/
|
|
73
|
+
export declare function execute<TInput extends HookInput, TOutput extends SpecificHookOutput>(
|
|
74
|
+
hookFn: HookFunction<TInput, TOutput>
|
|
75
|
+
): Promise<void>;
|