cc-hooks-ts 0.0.5 → 0.1.0
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 +3 -0
- package/dist/index.d.mts +212 -30
- package/dist/index.mjs +16 -21
- package/package.json +15 -13
package/README.md
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import * as v from "valibot";
|
|
2
|
+
import { BashInput, FileEditInput, FileReadInput, FileWriteInput, GlobInput, GrepInput, NotebookEditInput, TodoWriteInput, WebFetchInput, WebSearchInput } from "@anthropic-ai/claude-code/sdk-tools.js";
|
|
2
3
|
|
|
4
|
+
//#region src/utils/types.d.ts
|
|
5
|
+
type Awaitable<T> = Promise<T> | T;
|
|
6
|
+
type AutoComplete<T extends string> = Record<string, never> & T;
|
|
7
|
+
//#endregion
|
|
3
8
|
//#region src/event.d.ts
|
|
4
|
-
declare const SUPPORTED_HOOK_EVENTS: readonly ["PreToolUse", "PostToolUse", "Notification", "UserPromptSubmit", "
|
|
9
|
+
declare const SUPPORTED_HOOK_EVENTS: readonly ["PreToolUse", "PostToolUse", "Notification", "UserPromptSubmit", "SessionStart", "SessionEnd", "Stop", "SubagentStop", "PreCompact"];
|
|
5
10
|
/**
|
|
6
11
|
* @see {@link https://docs.anthropic.com/en/docs/claude-code/hooks#hook-events}
|
|
7
12
|
*/
|
|
@@ -19,7 +24,7 @@ type HookOutput = {
|
|
|
19
24
|
PreCompact: CommonHookOutputs;
|
|
20
25
|
SessionEnd: CommonHookOutputs;
|
|
21
26
|
};
|
|
22
|
-
type ExtractHookOutput<TEvent extends SupportedHookEvent> = HookOutput extends Record<SupportedHookEvent, unknown> ? HookOutput[TEvent] : never;
|
|
27
|
+
type ExtractHookOutput<TEvent$1 extends SupportedHookEvent> = HookOutput extends Record<SupportedHookEvent, unknown> ? HookOutput[TEvent$1] : never;
|
|
23
28
|
/**
|
|
24
29
|
* Common fields of hook outputs
|
|
25
30
|
*
|
|
@@ -49,6 +54,18 @@ type CommonHookOutputs = {
|
|
|
49
54
|
* Optional warning message shown to the user
|
|
50
55
|
*/
|
|
51
56
|
systemMessage?: string;
|
|
57
|
+
/**
|
|
58
|
+
* Use `hookSpecificOutput` in appropriate hook events instead.
|
|
59
|
+
*
|
|
60
|
+
* @deprecated
|
|
61
|
+
*/
|
|
62
|
+
reason?: string;
|
|
63
|
+
/**
|
|
64
|
+
* Use `hookSpecificOutput` in appropriate hook events instead.
|
|
65
|
+
*
|
|
66
|
+
* @deprecated
|
|
67
|
+
*/
|
|
68
|
+
decision?: "approve" | "block";
|
|
52
69
|
};
|
|
53
70
|
/**
|
|
54
71
|
* @see {@link https://docs.anthropic.com/en/docs/claude-code/hooks#pretooluse-decision-control}
|
|
@@ -61,8 +78,8 @@ interface PreToolUseHookOutput extends CommonHookOutputs {
|
|
|
61
78
|
* - `deny` prevents the tool call from executing. `permissionDecisionReason` is shown to Claude.
|
|
62
79
|
* - `ask` asks the user to confirm the tool call in the UI. `permissionDecisionReason` is shown to the user but not to Claude.
|
|
63
80
|
*/
|
|
64
|
-
permissionDecision
|
|
65
|
-
permissionDecisionReason
|
|
81
|
+
permissionDecision?: "allow" | "ask" | "deny";
|
|
82
|
+
permissionDecisionReason?: string;
|
|
66
83
|
};
|
|
67
84
|
}
|
|
68
85
|
/**
|
|
@@ -70,10 +87,10 @@ interface PreToolUseHookOutput extends CommonHookOutputs {
|
|
|
70
87
|
*/
|
|
71
88
|
interface PostToolUseHookOutput extends CommonHookOutputs {
|
|
72
89
|
/**
|
|
90
|
+
* - `approve` has no effect; the tool response is processed normally.
|
|
73
91
|
* - `block` automatically prompts Claude with `reason`.
|
|
74
|
-
* - `undefined` does nothing. `reason` is ignored.
|
|
75
92
|
*/
|
|
76
|
-
decision
|
|
93
|
+
decision?: "approve" | "block";
|
|
77
94
|
hookSpecificOutput?: {
|
|
78
95
|
hookEventName: "PostToolUse";
|
|
79
96
|
/**
|
|
@@ -88,12 +105,11 @@ interface PostToolUseHookOutput extends CommonHookOutputs {
|
|
|
88
105
|
*/
|
|
89
106
|
interface UserPromptSubmitHookOutput extends CommonHookOutputs {
|
|
90
107
|
/**
|
|
108
|
+
* - `approve` has no effect; the tool response is processed normally.
|
|
91
109
|
* - `block` prevents the prompt from being processed.
|
|
92
110
|
* The submitted prompt is erased from context. `reason` is shown to the user but not added to context.
|
|
93
|
-
*
|
|
94
|
-
* - `undefined` allows the prompt to proceed normally. `reason` is ignored.
|
|
95
111
|
*/
|
|
96
|
-
decision?: "
|
|
112
|
+
decision?: "approve" | "block";
|
|
97
113
|
hookSpecificOutput?: {
|
|
98
114
|
hookEventName: "UserPromptSubmit";
|
|
99
115
|
/**
|
|
@@ -108,11 +124,10 @@ interface UserPromptSubmitHookOutput extends CommonHookOutputs {
|
|
|
108
124
|
*/
|
|
109
125
|
interface StopHookOutput extends CommonHookOutputs {
|
|
110
126
|
/**
|
|
127
|
+
* - `approve` has no effect; the tool response is processed normally.
|
|
111
128
|
* - `block` prevents Claude from stopping. You must populate `reason` for Claude to know how to proceed.
|
|
112
|
-
*
|
|
113
|
-
* - `undefined` allows Claude to stop. `reason` is ignored.
|
|
114
129
|
*/
|
|
115
|
-
decision
|
|
130
|
+
decision?: "approve" | "block";
|
|
116
131
|
/**
|
|
117
132
|
* Reason for the decision.
|
|
118
133
|
*/
|
|
@@ -123,11 +138,9 @@ interface StopHookOutput extends CommonHookOutputs {
|
|
|
123
138
|
*/
|
|
124
139
|
interface SubagentStopHookOutput extends CommonHookOutputs {
|
|
125
140
|
/**
|
|
141
|
+
* - `approve` has no effect; the tool response is processed normally.
|
|
126
142
|
* - `block` prevents Claude from stopping. You must populate `reason` for Claude to know how to proceed.
|
|
127
|
-
*
|
|
128
|
-
* - `undefined` allows Claude to stop. `reason` is ignored.
|
|
129
143
|
*/
|
|
130
|
-
decision: "block" | undefined;
|
|
131
144
|
/**
|
|
132
145
|
* Reason for the decision.
|
|
133
146
|
*/
|
|
@@ -143,10 +156,6 @@ interface SessionStartHookOutput extends CommonHookOutputs {
|
|
|
143
156
|
};
|
|
144
157
|
}
|
|
145
158
|
//#endregion
|
|
146
|
-
//#region src/utils/types.d.ts
|
|
147
|
-
type Awaitable<T> = Promise<T> | T;
|
|
148
|
-
type AutoComplete<T extends string> = Record<string, never> & T;
|
|
149
|
-
//#endregion
|
|
150
159
|
//#region src/input/schemas.d.ts
|
|
151
160
|
/**
|
|
152
161
|
* @package
|
|
@@ -155,6 +164,7 @@ declare const HookInputSchemas: {
|
|
|
155
164
|
readonly PreToolUse: v.ObjectSchema<{
|
|
156
165
|
readonly hook_event_name: v.LiteralSchema<"PreToolUse", undefined>;
|
|
157
166
|
readonly cwd: v.StringSchema<undefined>;
|
|
167
|
+
readonly permission_mode: v.ExactOptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
158
168
|
readonly session_id: v.StringSchema<undefined>;
|
|
159
169
|
readonly transcript_path: v.StringSchema<undefined>;
|
|
160
170
|
} & {
|
|
@@ -164,6 +174,7 @@ declare const HookInputSchemas: {
|
|
|
164
174
|
readonly PostToolUse: v.ObjectSchema<{
|
|
165
175
|
readonly hook_event_name: v.LiteralSchema<"PostToolUse", undefined>;
|
|
166
176
|
readonly cwd: v.StringSchema<undefined>;
|
|
177
|
+
readonly permission_mode: v.ExactOptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
167
178
|
readonly session_id: v.StringSchema<undefined>;
|
|
168
179
|
readonly transcript_path: v.StringSchema<undefined>;
|
|
169
180
|
} & {
|
|
@@ -174,14 +185,17 @@ declare const HookInputSchemas: {
|
|
|
174
185
|
readonly Notification: v.ObjectSchema<{
|
|
175
186
|
readonly hook_event_name: v.LiteralSchema<"Notification", undefined>;
|
|
176
187
|
readonly cwd: v.StringSchema<undefined>;
|
|
188
|
+
readonly permission_mode: v.ExactOptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
177
189
|
readonly session_id: v.StringSchema<undefined>;
|
|
178
190
|
readonly transcript_path: v.StringSchema<undefined>;
|
|
179
191
|
} & {
|
|
180
|
-
message: v.
|
|
192
|
+
message: v.StringSchema<undefined>;
|
|
193
|
+
title: v.ExactOptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
181
194
|
}, undefined>;
|
|
182
195
|
readonly UserPromptSubmit: v.ObjectSchema<{
|
|
183
196
|
readonly hook_event_name: v.LiteralSchema<"UserPromptSubmit", undefined>;
|
|
184
197
|
readonly cwd: v.StringSchema<undefined>;
|
|
198
|
+
readonly permission_mode: v.ExactOptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
185
199
|
readonly session_id: v.StringSchema<undefined>;
|
|
186
200
|
readonly transcript_path: v.StringSchema<undefined>;
|
|
187
201
|
} & {
|
|
@@ -190,39 +204,44 @@ declare const HookInputSchemas: {
|
|
|
190
204
|
readonly Stop: v.ObjectSchema<{
|
|
191
205
|
readonly hook_event_name: v.LiteralSchema<"Stop", undefined>;
|
|
192
206
|
readonly cwd: v.StringSchema<undefined>;
|
|
207
|
+
readonly permission_mode: v.ExactOptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
193
208
|
readonly session_id: v.StringSchema<undefined>;
|
|
194
209
|
readonly transcript_path: v.StringSchema<undefined>;
|
|
195
210
|
} & {
|
|
196
|
-
stop_hook_active: v.
|
|
211
|
+
stop_hook_active: v.BooleanSchema<undefined>;
|
|
197
212
|
}, undefined>;
|
|
198
213
|
readonly SubagentStop: v.ObjectSchema<{
|
|
199
214
|
readonly hook_event_name: v.LiteralSchema<"SubagentStop", undefined>;
|
|
200
215
|
readonly cwd: v.StringSchema<undefined>;
|
|
216
|
+
readonly permission_mode: v.ExactOptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
201
217
|
readonly session_id: v.StringSchema<undefined>;
|
|
202
218
|
readonly transcript_path: v.StringSchema<undefined>;
|
|
203
219
|
} & {
|
|
204
|
-
stop_hook_active: v.
|
|
220
|
+
stop_hook_active: v.BooleanSchema<undefined>;
|
|
205
221
|
}, undefined>;
|
|
206
222
|
readonly PreCompact: v.ObjectSchema<{
|
|
207
223
|
readonly hook_event_name: v.LiteralSchema<"PreCompact", undefined>;
|
|
208
224
|
readonly cwd: v.StringSchema<undefined>;
|
|
225
|
+
readonly permission_mode: v.ExactOptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
209
226
|
readonly session_id: v.StringSchema<undefined>;
|
|
210
227
|
readonly transcript_path: v.StringSchema<undefined>;
|
|
211
228
|
} & {
|
|
212
|
-
custom_instructions: v.StringSchema<undefined>;
|
|
229
|
+
custom_instructions: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
213
230
|
trigger: v.UnionSchema<[v.LiteralSchema<"manual", undefined>, v.LiteralSchema<"auto", undefined>], undefined>;
|
|
214
231
|
}, undefined>;
|
|
215
232
|
readonly SessionStart: v.ObjectSchema<{
|
|
216
233
|
readonly hook_event_name: v.LiteralSchema<"SessionStart", undefined>;
|
|
217
234
|
readonly cwd: v.StringSchema<undefined>;
|
|
235
|
+
readonly permission_mode: v.ExactOptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
218
236
|
readonly session_id: v.StringSchema<undefined>;
|
|
219
237
|
readonly transcript_path: v.StringSchema<undefined>;
|
|
220
238
|
} & {
|
|
221
|
-
source: v.
|
|
239
|
+
source: v.UnionSchema<[v.LiteralSchema<"startup", undefined>, v.LiteralSchema<"resume", undefined>, v.LiteralSchema<"clear", undefined>, v.LiteralSchema<"compact", undefined>], undefined>;
|
|
222
240
|
}, undefined>;
|
|
223
241
|
readonly SessionEnd: v.ObjectSchema<{
|
|
224
242
|
readonly hook_event_name: v.LiteralSchema<"SessionEnd", undefined>;
|
|
225
243
|
readonly cwd: v.StringSchema<undefined>;
|
|
244
|
+
readonly permission_mode: v.ExactOptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
226
245
|
readonly session_id: v.StringSchema<undefined>;
|
|
227
246
|
readonly transcript_path: v.StringSchema<undefined>;
|
|
228
247
|
} & {
|
|
@@ -266,7 +285,7 @@ type HookInputs = { [EventKey in SupportedHookEvent]: EventKey extends "PreToolU
|
|
|
266
285
|
* ```
|
|
267
286
|
* @package
|
|
268
287
|
*/
|
|
269
|
-
type ExtractAllHookInputsForEvent<TEvent extends SupportedHookEvent> = { [K in keyof HookInputs[TEvent]]: HookInputs[TEvent][K] }[keyof HookInputs[TEvent]];
|
|
288
|
+
type ExtractAllHookInputsForEvent<TEvent$1 extends SupportedHookEvent> = { [K in keyof HookInputs[TEvent$1]]: HookInputs[TEvent$1][K] }[keyof HookInputs[TEvent$1]];
|
|
270
289
|
/**
|
|
271
290
|
* Extracts the hook input type for a specific tool within a given event type.
|
|
272
291
|
* This type utility is used to get strongly-typed inputs for tool-specific hook handlers.
|
|
@@ -287,11 +306,11 @@ type ExtractAllHookInputsForEvent<TEvent extends SupportedHookEvent> = { [K in k
|
|
|
287
306
|
* ```
|
|
288
307
|
* @package
|
|
289
308
|
*/
|
|
290
|
-
type ExtractSpecificHookInputForEvent<TEvent extends SupportedHookEvent, TSpecificKey extends ExtractExtendedSpecificKeys<TEvent>> = { [K in keyof HookInputs[TEvent]]: K extends TSpecificKey ? HookInputs[TEvent][K] : never }[keyof HookInputs[TEvent]];
|
|
309
|
+
type ExtractSpecificHookInputForEvent<TEvent$1 extends SupportedHookEvent, TSpecificKey extends ExtractExtendedSpecificKeys<TEvent$1>> = { [K in keyof HookInputs[TEvent$1]]: K extends TSpecificKey ? HookInputs[TEvent$1][K] : never }[keyof HookInputs[TEvent$1]];
|
|
291
310
|
/**
|
|
292
311
|
* @package
|
|
293
312
|
*/
|
|
294
|
-
type ExtractExtendedSpecificKeys<TEvent extends SupportedHookEvent> = Exclude<keyof HookInputs[TEvent], "default">;
|
|
313
|
+
type ExtractExtendedSpecificKeys<TEvent$1 extends SupportedHookEvent> = Exclude<keyof HookInputs[TEvent$1], "default">;
|
|
295
314
|
type BaseHookInputs = { [EventKey in SupportedHookEvent]: v.InferOutput<(typeof HookInputSchemas)[EventKey]> };
|
|
296
315
|
type ToolSpecificPreToolUseInput = { [K in keyof ToolSchema]: Omit<BaseHookInputs["PreToolUse"], "tool_input" | "tool_name"> & {
|
|
297
316
|
tool_input: ToolSchema[K]["input"];
|
|
@@ -542,19 +561,182 @@ declare function runHook<THookTrigger extends HookTrigger = HookTrigger>(def: Ho
|
|
|
542
561
|
* ```
|
|
543
562
|
*/
|
|
544
563
|
interface ToolSchema {
|
|
545
|
-
|
|
564
|
+
Bash: {
|
|
565
|
+
input: BashInput;
|
|
566
|
+
response: {
|
|
567
|
+
interrupted: boolean;
|
|
568
|
+
isImage: boolean;
|
|
569
|
+
stderr: string;
|
|
570
|
+
stdout: string;
|
|
571
|
+
};
|
|
572
|
+
};
|
|
573
|
+
Edit: {
|
|
574
|
+
input: FileEditInput;
|
|
575
|
+
response: {
|
|
576
|
+
filePath: string;
|
|
577
|
+
newString: string;
|
|
578
|
+
oldString: string;
|
|
579
|
+
originalFile: string;
|
|
580
|
+
replaceAll: boolean;
|
|
581
|
+
structuredPatch: Array<{
|
|
582
|
+
lines: string[];
|
|
583
|
+
newLines: number;
|
|
584
|
+
newStart: number;
|
|
585
|
+
oldLines: number;
|
|
586
|
+
oldStart: number;
|
|
587
|
+
}>;
|
|
588
|
+
userModified: boolean;
|
|
589
|
+
};
|
|
590
|
+
};
|
|
591
|
+
Glob: {
|
|
592
|
+
input: GlobInput;
|
|
593
|
+
response: {
|
|
594
|
+
durationMs: number;
|
|
595
|
+
filenames: string[];
|
|
596
|
+
numFiles: number;
|
|
597
|
+
truncated: boolean;
|
|
598
|
+
};
|
|
599
|
+
};
|
|
600
|
+
Grep: {
|
|
601
|
+
input: GrepInput;
|
|
602
|
+
response: {
|
|
603
|
+
content: string;
|
|
604
|
+
mode: "content" | "count" | "files_with_matches";
|
|
605
|
+
numFiles: number;
|
|
606
|
+
numLines: number;
|
|
607
|
+
};
|
|
608
|
+
};
|
|
609
|
+
LS: {
|
|
610
|
+
input: {
|
|
611
|
+
path: string;
|
|
612
|
+
};
|
|
613
|
+
response: string;
|
|
614
|
+
};
|
|
615
|
+
MultiEdit: {
|
|
546
616
|
input: {
|
|
617
|
+
edits: Array<{
|
|
618
|
+
new_string: string;
|
|
619
|
+
old_string: string;
|
|
620
|
+
/**
|
|
621
|
+
* @default false
|
|
622
|
+
*/
|
|
623
|
+
replace_all?: boolean;
|
|
624
|
+
}>;
|
|
547
625
|
file_path: string;
|
|
548
626
|
};
|
|
549
|
-
response:
|
|
627
|
+
response: {
|
|
628
|
+
edits: Array<{
|
|
629
|
+
new_string: string;
|
|
630
|
+
old_string: string;
|
|
631
|
+
/**
|
|
632
|
+
* @default false
|
|
633
|
+
*/
|
|
634
|
+
replace_all?: boolean;
|
|
635
|
+
}>;
|
|
636
|
+
filePath: string;
|
|
637
|
+
originalFileContents: string;
|
|
638
|
+
structuredPatch: Array<{
|
|
639
|
+
lines: string[];
|
|
640
|
+
newLines: number;
|
|
641
|
+
newStart: number;
|
|
642
|
+
oldLines: number;
|
|
643
|
+
oldStart: number;
|
|
644
|
+
}>;
|
|
645
|
+
userModified: boolean;
|
|
646
|
+
};
|
|
550
647
|
};
|
|
551
|
-
|
|
648
|
+
NotebookEdit: {
|
|
649
|
+
input: NotebookEditInput;
|
|
650
|
+
response: {
|
|
651
|
+
cell_type: "code" | "markdown";
|
|
652
|
+
edit_mode: "delete" | "insert" | "replace";
|
|
653
|
+
error: string;
|
|
654
|
+
language: string;
|
|
655
|
+
new_source: string;
|
|
656
|
+
};
|
|
657
|
+
};
|
|
658
|
+
Read: {
|
|
659
|
+
input: FileReadInput;
|
|
660
|
+
response: {
|
|
661
|
+
file: {
|
|
662
|
+
cells: Array<{
|
|
663
|
+
cell_id: string;
|
|
664
|
+
cellType: "code";
|
|
665
|
+
language: string;
|
|
666
|
+
source: string;
|
|
667
|
+
} | {
|
|
668
|
+
cell_id: string;
|
|
669
|
+
cellType: "markdown";
|
|
670
|
+
source: string;
|
|
671
|
+
}>;
|
|
672
|
+
filePath: string;
|
|
673
|
+
};
|
|
674
|
+
type: "notebook";
|
|
675
|
+
} | {
|
|
676
|
+
file: {
|
|
677
|
+
content: string;
|
|
678
|
+
filePath: string;
|
|
679
|
+
numLines: number;
|
|
680
|
+
startLine: number;
|
|
681
|
+
totalLines: number;
|
|
682
|
+
};
|
|
683
|
+
type: "text";
|
|
684
|
+
};
|
|
685
|
+
};
|
|
686
|
+
Task: {
|
|
552
687
|
input: {
|
|
688
|
+
description: string;
|
|
553
689
|
prompt: string;
|
|
690
|
+
subagent_type: AutoComplete<"general-purpose" | "output-style-setup" | "statusline-setup">;
|
|
691
|
+
};
|
|
692
|
+
response: {
|
|
693
|
+
content: Array<{
|
|
694
|
+
text: string;
|
|
695
|
+
type: "text";
|
|
696
|
+
}>;
|
|
697
|
+
totalDurationMs: number;
|
|
698
|
+
totalTokens: number;
|
|
699
|
+
totalToolUseCount: number;
|
|
700
|
+
usage: {
|
|
701
|
+
cache_creation: {
|
|
702
|
+
ephemeral_1h_input_tokens: number;
|
|
703
|
+
ephemeral_5m_input_tokens: number;
|
|
704
|
+
};
|
|
705
|
+
cache_creation_input_tokens: number;
|
|
706
|
+
cache_read_input_tokens: number;
|
|
707
|
+
input_tokens: number;
|
|
708
|
+
output_tokens: number;
|
|
709
|
+
};
|
|
710
|
+
};
|
|
711
|
+
};
|
|
712
|
+
TodoWrite: {
|
|
713
|
+
input: TodoWriteInput;
|
|
714
|
+
response: unknown;
|
|
715
|
+
};
|
|
716
|
+
WebFetch: {
|
|
717
|
+
input: WebFetchInput;
|
|
718
|
+
response: {
|
|
719
|
+
bytes: number;
|
|
720
|
+
code: number;
|
|
721
|
+
codeText: string;
|
|
722
|
+
durationMs: number;
|
|
723
|
+
result: string;
|
|
554
724
|
url: string;
|
|
555
725
|
};
|
|
726
|
+
};
|
|
727
|
+
WebSearch: {
|
|
728
|
+
input: WebSearchInput;
|
|
556
729
|
response: unknown;
|
|
557
730
|
};
|
|
731
|
+
Write: {
|
|
732
|
+
input: FileWriteInput;
|
|
733
|
+
response: {
|
|
734
|
+
content: string;
|
|
735
|
+
filePath: string;
|
|
736
|
+
structuredPatch: unknown[];
|
|
737
|
+
type: "create";
|
|
738
|
+
};
|
|
739
|
+
};
|
|
558
740
|
}
|
|
559
741
|
//#endregion
|
|
560
742
|
export { type ExtractAllHookInputsForEvent, type ExtractSpecificHookInputForEvent, ToolSchema, defineHook, runHook };
|
package/dist/index.mjs
CHANGED
|
@@ -28,20 +28,9 @@ function createContext(input) {
|
|
|
28
28
|
})
|
|
29
29
|
};
|
|
30
30
|
}
|
|
31
|
-
const SUPPORTED_HOOK_EVENTS = [
|
|
32
|
-
"PreToolUse",
|
|
33
|
-
"PostToolUse",
|
|
34
|
-
"Notification",
|
|
35
|
-
"UserPromptSubmit",
|
|
36
|
-
"Stop",
|
|
37
|
-
"SubagentStop",
|
|
38
|
-
"PreCompact",
|
|
39
|
-
"SessionStart",
|
|
40
|
-
"SessionEnd"
|
|
41
|
-
];
|
|
42
31
|
const baseHookInputSchema = v.object({
|
|
43
32
|
cwd: v.string(),
|
|
44
|
-
|
|
33
|
+
permission_mode: v.exactOptional(v.string()),
|
|
45
34
|
session_id: v.string(),
|
|
46
35
|
transcript_path: v.string()
|
|
47
36
|
});
|
|
@@ -62,15 +51,23 @@ const HookInputSchemas = {
|
|
|
62
51
|
tool_input: v.unknown(),
|
|
63
52
|
tool_response: v.unknown()
|
|
64
53
|
}),
|
|
65
|
-
Notification: buildHookInputSchema("Notification", {
|
|
54
|
+
Notification: buildHookInputSchema("Notification", {
|
|
55
|
+
message: v.string(),
|
|
56
|
+
title: v.exactOptional(v.string())
|
|
57
|
+
}),
|
|
66
58
|
UserPromptSubmit: buildHookInputSchema("UserPromptSubmit", { prompt: v.string() }),
|
|
67
|
-
Stop: buildHookInputSchema("Stop", { stop_hook_active: v.
|
|
68
|
-
SubagentStop: buildHookInputSchema("SubagentStop", { stop_hook_active: v.
|
|
59
|
+
Stop: buildHookInputSchema("Stop", { stop_hook_active: v.boolean() }),
|
|
60
|
+
SubagentStop: buildHookInputSchema("SubagentStop", { stop_hook_active: v.boolean() }),
|
|
69
61
|
PreCompact: buildHookInputSchema("PreCompact", {
|
|
70
|
-
custom_instructions: v.string(),
|
|
62
|
+
custom_instructions: v.nullable(v.string()),
|
|
71
63
|
trigger: v.union([v.literal("manual"), v.literal("auto")])
|
|
72
64
|
}),
|
|
73
|
-
SessionStart: buildHookInputSchema("SessionStart", { source: v.
|
|
65
|
+
SessionStart: buildHookInputSchema("SessionStart", { source: v.union([
|
|
66
|
+
v.literal("startup"),
|
|
67
|
+
v.literal("resume"),
|
|
68
|
+
v.literal("clear"),
|
|
69
|
+
v.literal("compact")
|
|
70
|
+
]) }),
|
|
74
71
|
SessionEnd: buildHookInputSchema("SessionEnd", { reason: v.string() })
|
|
75
72
|
};
|
|
76
73
|
function isNonEmptyString(value) {
|
|
@@ -80,8 +77,7 @@ async function runHook(def) {
|
|
|
80
77
|
const { run, shouldRun = true, trigger } = def;
|
|
81
78
|
let eventName = null;
|
|
82
79
|
try {
|
|
83
|
-
|
|
84
|
-
if (!proceed) return handleHookResult(eventName, {
|
|
80
|
+
if (!(typeof shouldRun === "function" ? await shouldRun() : shouldRun)) return handleHookResult(eventName, {
|
|
85
81
|
kind: "success",
|
|
86
82
|
payload: {}
|
|
87
83
|
});
|
|
@@ -89,8 +85,7 @@ async function runHook(def) {
|
|
|
89
85
|
const rawInput = readFileSync(process.stdin.fd, "utf-8");
|
|
90
86
|
const parsed = v.parse(inputSchema, JSON.parse(rawInput));
|
|
91
87
|
eventName = parsed.hook_event_name;
|
|
92
|
-
const
|
|
93
|
-
const result = await run(context);
|
|
88
|
+
const result = await run(createContext(parsed));
|
|
94
89
|
handleHookResult(eventName, result);
|
|
95
90
|
} catch (error) {
|
|
96
91
|
handleHookResult(eventName, {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cc-hooks-ts",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Write claude code hooks with type safety",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -42,22 +42,24 @@
|
|
|
42
42
|
}
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
+
"@anthropic-ai/claude-code": "2.0.0",
|
|
45
46
|
"@arethetypeswrong/core": "0.18.2",
|
|
46
|
-
"@biomejs/biome": "2.
|
|
47
|
-
"@types/node": "24.
|
|
48
|
-
"@virtual-live-lab/eslint-config": "2.
|
|
47
|
+
"@biomejs/biome": "2.3.4",
|
|
48
|
+
"@types/node": "24.10.0",
|
|
49
|
+
"@virtual-live-lab/eslint-config": "2.3.1",
|
|
49
50
|
"@virtual-live-lab/tsconfig": "2.1.21",
|
|
50
|
-
"eslint": "9.
|
|
51
|
+
"eslint": "9.39.1",
|
|
51
52
|
"eslint-plugin-import-access": "3.0.0",
|
|
52
|
-
"pkg-pr-new": "0.0.
|
|
53
|
-
"publint": "0.3.
|
|
54
|
-
"release-it": "19.0.
|
|
53
|
+
"pkg-pr-new": "0.0.60",
|
|
54
|
+
"publint": "0.3.15",
|
|
55
|
+
"release-it": "19.0.6",
|
|
55
56
|
"release-it-pnpm": "4.6.6",
|
|
56
|
-
"tsdown": "0.
|
|
57
|
-
"
|
|
58
|
-
"typescript
|
|
59
|
-
"
|
|
60
|
-
"
|
|
57
|
+
"tsdown": "0.16.0",
|
|
58
|
+
"type-fest": "5.2.0",
|
|
59
|
+
"typescript": "5.9.3",
|
|
60
|
+
"typescript-eslint": "8.46.3",
|
|
61
|
+
"unplugin-unused": "0.5.5",
|
|
62
|
+
"vitest": "4.0.7"
|
|
61
63
|
},
|
|
62
64
|
"dependencies": {
|
|
63
65
|
"valibot": "^1.1.0"
|