opencode-command-hooks 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.
Files changed (46) hide show
  1. package/README.md +796 -0
  2. package/dist/config/agent.d.ts +82 -0
  3. package/dist/config/agent.d.ts.map +1 -0
  4. package/dist/config/agent.js +145 -0
  5. package/dist/config/agent.js.map +1 -0
  6. package/dist/config/global.d.ts +36 -0
  7. package/dist/config/global.d.ts.map +1 -0
  8. package/dist/config/global.js +219 -0
  9. package/dist/config/global.js.map +1 -0
  10. package/dist/config/markdown.d.ts +119 -0
  11. package/dist/config/markdown.d.ts.map +1 -0
  12. package/dist/config/markdown.js +373 -0
  13. package/dist/config/markdown.js.map +1 -0
  14. package/dist/config/merge.d.ts +67 -0
  15. package/dist/config/merge.d.ts.map +1 -0
  16. package/dist/config/merge.js +192 -0
  17. package/dist/config/merge.js.map +1 -0
  18. package/dist/execution/shell.d.ts +55 -0
  19. package/dist/execution/shell.d.ts.map +1 -0
  20. package/dist/execution/shell.js +187 -0
  21. package/dist/execution/shell.js.map +1 -0
  22. package/dist/execution/template.d.ts +55 -0
  23. package/dist/execution/template.d.ts.map +1 -0
  24. package/dist/execution/template.js +106 -0
  25. package/dist/execution/template.js.map +1 -0
  26. package/dist/executor.d.ts +54 -0
  27. package/dist/executor.d.ts.map +1 -0
  28. package/dist/executor.js +314 -0
  29. package/dist/executor.js.map +1 -0
  30. package/dist/index.d.ts +22 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +359 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/logging.d.ts +24 -0
  35. package/dist/logging.d.ts.map +1 -0
  36. package/dist/logging.js +57 -0
  37. package/dist/logging.js.map +1 -0
  38. package/dist/schemas.d.ts +425 -0
  39. package/dist/schemas.d.ts.map +1 -0
  40. package/dist/schemas.js +150 -0
  41. package/dist/schemas.js.map +1 -0
  42. package/dist/types/hooks.d.ts +635 -0
  43. package/dist/types/hooks.d.ts.map +1 -0
  44. package/dist/types/hooks.js +12 -0
  45. package/dist/types/hooks.js.map +1 -0
  46. package/package.json +66 -0
@@ -0,0 +1,425 @@
1
+ /**
2
+ * Zod schemas for command hooks configuration
3
+ *
4
+ * Provides runtime validation and type safety for hook configurations.
5
+ * Replaces manual validation with declarative, composable schemas.
6
+ */
7
+ import { z } from "zod";
8
+ /**
9
+ * Matching conditions for tool hooks
10
+ */
11
+ declare const ToolHookWhenSchema: z.ZodObject<{
12
+ phase: z.ZodEnum<["before", "after"]>;
13
+ tool: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
14
+ callingAgent: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
15
+ slashCommand: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
16
+ }, "strip", z.ZodTypeAny, {
17
+ phase: "before" | "after";
18
+ tool?: string | string[] | undefined;
19
+ slashCommand?: string | string[] | undefined;
20
+ callingAgent?: string | string[] | undefined;
21
+ }, {
22
+ phase: "before" | "after";
23
+ tool?: string | string[] | undefined;
24
+ slashCommand?: string | string[] | undefined;
25
+ callingAgent?: string | string[] | undefined;
26
+ }>;
27
+ /**
28
+ * Tool hook configuration
29
+ *
30
+ * Runs shell command(s) before or after a tool execution. Hooks can be filtered
31
+ * by tool name, calling agent, and slash command context. Results can optionally
32
+ * be injected into the session as messages.
33
+ */
34
+ export declare const ToolHookSchema: z.ZodObject<{
35
+ id: z.ZodString;
36
+ when: z.ZodObject<{
37
+ phase: z.ZodEnum<["before", "after"]>;
38
+ tool: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
39
+ callingAgent: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
40
+ slashCommand: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
41
+ }, "strip", z.ZodTypeAny, {
42
+ phase: "before" | "after";
43
+ tool?: string | string[] | undefined;
44
+ slashCommand?: string | string[] | undefined;
45
+ callingAgent?: string | string[] | undefined;
46
+ }, {
47
+ phase: "before" | "after";
48
+ tool?: string | string[] | undefined;
49
+ slashCommand?: string | string[] | undefined;
50
+ callingAgent?: string | string[] | undefined;
51
+ }>;
52
+ run: z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>;
53
+ inject: z.ZodOptional<z.ZodString>;
54
+ toast: z.ZodOptional<z.ZodObject<{
55
+ title: z.ZodOptional<z.ZodString>;
56
+ message: z.ZodString;
57
+ variant: z.ZodOptional<z.ZodEnum<["info", "success", "warning", "error"]>>;
58
+ duration: z.ZodOptional<z.ZodNumber>;
59
+ }, "strip", z.ZodTypeAny, {
60
+ message: string;
61
+ title?: string | undefined;
62
+ variant?: "info" | "success" | "warning" | "error" | undefined;
63
+ duration?: number | undefined;
64
+ }, {
65
+ message: string;
66
+ title?: string | undefined;
67
+ variant?: "info" | "success" | "warning" | "error" | undefined;
68
+ duration?: number | undefined;
69
+ }>>;
70
+ }, "strip", z.ZodTypeAny, {
71
+ id: string;
72
+ when: {
73
+ phase: "before" | "after";
74
+ tool?: string | string[] | undefined;
75
+ slashCommand?: string | string[] | undefined;
76
+ callingAgent?: string | string[] | undefined;
77
+ };
78
+ run: string | string[];
79
+ inject?: string | undefined;
80
+ toast?: {
81
+ message: string;
82
+ title?: string | undefined;
83
+ variant?: "info" | "success" | "warning" | "error" | undefined;
84
+ duration?: number | undefined;
85
+ } | undefined;
86
+ }, {
87
+ id: string;
88
+ when: {
89
+ phase: "before" | "after";
90
+ tool?: string | string[] | undefined;
91
+ slashCommand?: string | string[] | undefined;
92
+ callingAgent?: string | string[] | undefined;
93
+ };
94
+ run: string | string[];
95
+ inject?: string | undefined;
96
+ toast?: {
97
+ message: string;
98
+ title?: string | undefined;
99
+ variant?: "info" | "success" | "warning" | "error" | undefined;
100
+ duration?: number | undefined;
101
+ } | undefined;
102
+ }>;
103
+ /**
104
+ * Matching conditions for session hooks
105
+ */
106
+ declare const SessionHookWhenSchema: z.ZodObject<{
107
+ event: z.ZodEnum<["session.start", "session.idle", "session.end"]>;
108
+ agent: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
109
+ }, "strip", z.ZodTypeAny, {
110
+ event: "session.start" | "session.idle" | "session.end";
111
+ agent?: string | string[] | undefined;
112
+ }, {
113
+ event: "session.start" | "session.idle" | "session.end";
114
+ agent?: string | string[] | undefined;
115
+ }>;
116
+ /**
117
+ * Session hook configuration
118
+ *
119
+ * Runs shell command(s) on session lifecycle events (start, idle, end).
120
+ * Can be filtered by agent name. Results can optionally be injected into
121
+ * the session as messages.
122
+ */
123
+ export declare const SessionHookSchema: z.ZodObject<{
124
+ id: z.ZodString;
125
+ when: z.ZodObject<{
126
+ event: z.ZodEnum<["session.start", "session.idle", "session.end"]>;
127
+ agent: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
128
+ }, "strip", z.ZodTypeAny, {
129
+ event: "session.start" | "session.idle" | "session.end";
130
+ agent?: string | string[] | undefined;
131
+ }, {
132
+ event: "session.start" | "session.idle" | "session.end";
133
+ agent?: string | string[] | undefined;
134
+ }>;
135
+ run: z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>;
136
+ inject: z.ZodOptional<z.ZodString>;
137
+ toast: z.ZodOptional<z.ZodObject<{
138
+ title: z.ZodOptional<z.ZodString>;
139
+ message: z.ZodString;
140
+ variant: z.ZodOptional<z.ZodEnum<["info", "success", "warning", "error"]>>;
141
+ duration: z.ZodOptional<z.ZodNumber>;
142
+ }, "strip", z.ZodTypeAny, {
143
+ message: string;
144
+ title?: string | undefined;
145
+ variant?: "info" | "success" | "warning" | "error" | undefined;
146
+ duration?: number | undefined;
147
+ }, {
148
+ message: string;
149
+ title?: string | undefined;
150
+ variant?: "info" | "success" | "warning" | "error" | undefined;
151
+ duration?: number | undefined;
152
+ }>>;
153
+ }, "strip", z.ZodTypeAny, {
154
+ id: string;
155
+ when: {
156
+ event: "session.start" | "session.idle" | "session.end";
157
+ agent?: string | string[] | undefined;
158
+ };
159
+ run: string | string[];
160
+ inject?: string | undefined;
161
+ toast?: {
162
+ message: string;
163
+ title?: string | undefined;
164
+ variant?: "info" | "success" | "warning" | "error" | undefined;
165
+ duration?: number | undefined;
166
+ } | undefined;
167
+ }, {
168
+ id: string;
169
+ when: {
170
+ event: "session.start" | "session.idle" | "session.end";
171
+ agent?: string | string[] | undefined;
172
+ };
173
+ run: string | string[];
174
+ inject?: string | undefined;
175
+ toast?: {
176
+ message: string;
177
+ title?: string | undefined;
178
+ variant?: "info" | "success" | "warning" | "error" | undefined;
179
+ duration?: number | undefined;
180
+ } | undefined;
181
+ }>;
182
+ /**
183
+ * Top-level command hooks configuration
184
+ *
185
+ * This is the root configuration object that appears in opencode.json/.opencode.jsonc
186
+ * under the "command_hooks" key, or in YAML frontmatter of agent/slash-command markdown.
187
+ */
188
+ export declare const ConfigSchema: z.ZodObject<{
189
+ tool: z.ZodOptional<z.ZodArray<z.ZodObject<{
190
+ id: z.ZodString;
191
+ when: z.ZodObject<{
192
+ phase: z.ZodEnum<["before", "after"]>;
193
+ tool: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
194
+ callingAgent: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
195
+ slashCommand: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
196
+ }, "strip", z.ZodTypeAny, {
197
+ phase: "before" | "after";
198
+ tool?: string | string[] | undefined;
199
+ slashCommand?: string | string[] | undefined;
200
+ callingAgent?: string | string[] | undefined;
201
+ }, {
202
+ phase: "before" | "after";
203
+ tool?: string | string[] | undefined;
204
+ slashCommand?: string | string[] | undefined;
205
+ callingAgent?: string | string[] | undefined;
206
+ }>;
207
+ run: z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>;
208
+ inject: z.ZodOptional<z.ZodString>;
209
+ toast: z.ZodOptional<z.ZodObject<{
210
+ title: z.ZodOptional<z.ZodString>;
211
+ message: z.ZodString;
212
+ variant: z.ZodOptional<z.ZodEnum<["info", "success", "warning", "error"]>>;
213
+ duration: z.ZodOptional<z.ZodNumber>;
214
+ }, "strip", z.ZodTypeAny, {
215
+ message: string;
216
+ title?: string | undefined;
217
+ variant?: "info" | "success" | "warning" | "error" | undefined;
218
+ duration?: number | undefined;
219
+ }, {
220
+ message: string;
221
+ title?: string | undefined;
222
+ variant?: "info" | "success" | "warning" | "error" | undefined;
223
+ duration?: number | undefined;
224
+ }>>;
225
+ }, "strip", z.ZodTypeAny, {
226
+ id: string;
227
+ when: {
228
+ phase: "before" | "after";
229
+ tool?: string | string[] | undefined;
230
+ slashCommand?: string | string[] | undefined;
231
+ callingAgent?: string | string[] | undefined;
232
+ };
233
+ run: string | string[];
234
+ inject?: string | undefined;
235
+ toast?: {
236
+ message: string;
237
+ title?: string | undefined;
238
+ variant?: "info" | "success" | "warning" | "error" | undefined;
239
+ duration?: number | undefined;
240
+ } | undefined;
241
+ }, {
242
+ id: string;
243
+ when: {
244
+ phase: "before" | "after";
245
+ tool?: string | string[] | undefined;
246
+ slashCommand?: string | string[] | undefined;
247
+ callingAgent?: string | string[] | undefined;
248
+ };
249
+ run: string | string[];
250
+ inject?: string | undefined;
251
+ toast?: {
252
+ message: string;
253
+ title?: string | undefined;
254
+ variant?: "info" | "success" | "warning" | "error" | undefined;
255
+ duration?: number | undefined;
256
+ } | undefined;
257
+ }>, "many">>;
258
+ session: z.ZodOptional<z.ZodArray<z.ZodObject<{
259
+ id: z.ZodString;
260
+ when: z.ZodObject<{
261
+ event: z.ZodEnum<["session.start", "session.idle", "session.end"]>;
262
+ agent: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
263
+ }, "strip", z.ZodTypeAny, {
264
+ event: "session.start" | "session.idle" | "session.end";
265
+ agent?: string | string[] | undefined;
266
+ }, {
267
+ event: "session.start" | "session.idle" | "session.end";
268
+ agent?: string | string[] | undefined;
269
+ }>;
270
+ run: z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>;
271
+ inject: z.ZodOptional<z.ZodString>;
272
+ toast: z.ZodOptional<z.ZodObject<{
273
+ title: z.ZodOptional<z.ZodString>;
274
+ message: z.ZodString;
275
+ variant: z.ZodOptional<z.ZodEnum<["info", "success", "warning", "error"]>>;
276
+ duration: z.ZodOptional<z.ZodNumber>;
277
+ }, "strip", z.ZodTypeAny, {
278
+ message: string;
279
+ title?: string | undefined;
280
+ variant?: "info" | "success" | "warning" | "error" | undefined;
281
+ duration?: number | undefined;
282
+ }, {
283
+ message: string;
284
+ title?: string | undefined;
285
+ variant?: "info" | "success" | "warning" | "error" | undefined;
286
+ duration?: number | undefined;
287
+ }>>;
288
+ }, "strip", z.ZodTypeAny, {
289
+ id: string;
290
+ when: {
291
+ event: "session.start" | "session.idle" | "session.end";
292
+ agent?: string | string[] | undefined;
293
+ };
294
+ run: string | string[];
295
+ inject?: string | undefined;
296
+ toast?: {
297
+ message: string;
298
+ title?: string | undefined;
299
+ variant?: "info" | "success" | "warning" | "error" | undefined;
300
+ duration?: number | undefined;
301
+ } | undefined;
302
+ }, {
303
+ id: string;
304
+ when: {
305
+ event: "session.start" | "session.idle" | "session.end";
306
+ agent?: string | string[] | undefined;
307
+ };
308
+ run: string | string[];
309
+ inject?: string | undefined;
310
+ toast?: {
311
+ message: string;
312
+ title?: string | undefined;
313
+ variant?: "info" | "success" | "warning" | "error" | undefined;
314
+ duration?: number | undefined;
315
+ } | undefined;
316
+ }>, "many">>;
317
+ }, "strip", z.ZodTypeAny, {
318
+ tool?: {
319
+ id: string;
320
+ when: {
321
+ phase: "before" | "after";
322
+ tool?: string | string[] | undefined;
323
+ slashCommand?: string | string[] | undefined;
324
+ callingAgent?: string | string[] | undefined;
325
+ };
326
+ run: string | string[];
327
+ inject?: string | undefined;
328
+ toast?: {
329
+ message: string;
330
+ title?: string | undefined;
331
+ variant?: "info" | "success" | "warning" | "error" | undefined;
332
+ duration?: number | undefined;
333
+ } | undefined;
334
+ }[] | undefined;
335
+ session?: {
336
+ id: string;
337
+ when: {
338
+ event: "session.start" | "session.idle" | "session.end";
339
+ agent?: string | string[] | undefined;
340
+ };
341
+ run: string | string[];
342
+ inject?: string | undefined;
343
+ toast?: {
344
+ message: string;
345
+ title?: string | undefined;
346
+ variant?: "info" | "success" | "warning" | "error" | undefined;
347
+ duration?: number | undefined;
348
+ } | undefined;
349
+ }[] | undefined;
350
+ }, {
351
+ tool?: {
352
+ id: string;
353
+ when: {
354
+ phase: "before" | "after";
355
+ tool?: string | string[] | undefined;
356
+ slashCommand?: string | string[] | undefined;
357
+ callingAgent?: string | string[] | undefined;
358
+ };
359
+ run: string | string[];
360
+ inject?: string | undefined;
361
+ toast?: {
362
+ message: string;
363
+ title?: string | undefined;
364
+ variant?: "info" | "success" | "warning" | "error" | undefined;
365
+ duration?: number | undefined;
366
+ } | undefined;
367
+ }[] | undefined;
368
+ session?: {
369
+ id: string;
370
+ when: {
371
+ event: "session.start" | "session.idle" | "session.end";
372
+ agent?: string | string[] | undefined;
373
+ };
374
+ run: string | string[];
375
+ inject?: string | undefined;
376
+ toast?: {
377
+ message: string;
378
+ title?: string | undefined;
379
+ variant?: "info" | "success" | "warning" | "error" | undefined;
380
+ duration?: number | undefined;
381
+ } | undefined;
382
+ }[] | undefined;
383
+ }>;
384
+ /**
385
+ * Inferred TypeScript types from Zod schemas
386
+ * These provide type safety throughout the codebase
387
+ */
388
+ export type ToolHookWhen = z.infer<typeof ToolHookWhenSchema>;
389
+ export type SessionHookWhen = z.infer<typeof SessionHookWhenSchema>;
390
+ export type ToolHook = z.infer<typeof ToolHookSchema>;
391
+ export type SessionHook = z.infer<typeof SessionHookSchema>;
392
+ export type CommandHooksConfig = z.infer<typeof ConfigSchema>;
393
+ /**
394
+ * Safe configuration parser with fallback defaults
395
+ *
396
+ * Parses unknown input and returns a valid CommandHooksConfig.
397
+ * On validation failure, returns safe defaults (empty arrays).
398
+ *
399
+ * @param input - Unknown configuration object to parse
400
+ * @returns Valid CommandHooksConfig with safe defaults on failure
401
+ */
402
+ export declare function parseConfig(input: unknown): CommandHooksConfig;
403
+ /**
404
+ * Parse a single tool hook with error details
405
+ *
406
+ * @param input - Unknown hook object to parse
407
+ * @returns Parsed hook or null if invalid
408
+ */
409
+ export declare function parseToolHook(input: unknown): ToolHook | null;
410
+ /**
411
+ * Parse a single session hook with error details
412
+ *
413
+ * @param input - Unknown hook object to parse
414
+ * @returns Parsed hook or null if invalid
415
+ */
416
+ export declare function parseSessionHook(input: unknown): SessionHook | null;
417
+ /**
418
+ * Get detailed validation errors for debugging
419
+ *
420
+ * @param input - Unknown configuration object to validate
421
+ * @returns Validation errors if any, or null if valid
422
+ */
423
+ export declare function getConfigValidationErrors(input: unknown): z.ZodError | null;
424
+ export {};
425
+ //# sourceMappingURL=schemas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAyBxB;;GAEG;AACH,QAAA,MAAM,kBAAkB;;;;;;;;;;;;;;;EAKtB,CAAC;AAYH;;;;;;GAMG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAMzB,CAAC;AAMH;;GAEG;AACH,QAAA,MAAM,qBAAqB;;;;;;;;;EAGzB,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAM5B,CAAC;AAMH;;;;;GAKG;AACH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAGvB,CAAC;AAMH;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAC9D,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AACpE,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AACtD,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC5D,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAM9D;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,kBAAkB,CAc9D;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,QAAQ,GAAG,IAAI,CAG7D;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,GAAG,IAAI,CAGnE;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,OAAO,GACb,CAAC,CAAC,QAAQ,GAAG,IAAI,CAGnB"}
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Zod schemas for command hooks configuration
3
+ *
4
+ * Provides runtime validation and type safety for hook configurations.
5
+ * Replaces manual validation with declarative, composable schemas.
6
+ */
7
+ import { z } from "zod";
8
+ // ============================================================================
9
+ // PRIMITIVE SCHEMAS
10
+ // ============================================================================
11
+ /**
12
+ * String or array of strings - used for flexible matching fields
13
+ */
14
+ const StringOrArray = z.union([z.string(), z.array(z.string())]);
15
+ /**
16
+ * Phase for tool hooks: "before" or "after"
17
+ */
18
+ const PhaseSchema = z.enum(["before", "after"]);
19
+ /**
20
+ * Session event types
21
+ */
22
+ const SessionEventSchema = z.enum(["session.start", "session.idle", "session.end"]);
23
+ // ============================================================================
24
+ // TOOL HOOK SCHEMAS
25
+ // ============================================================================
26
+ /**
27
+ * Matching conditions for tool hooks
28
+ */
29
+ const ToolHookWhenSchema = z.object({
30
+ phase: PhaseSchema,
31
+ tool: StringOrArray.optional(),
32
+ callingAgent: StringOrArray.optional(),
33
+ slashCommand: StringOrArray.optional(),
34
+ });
35
+ /**
36
+ * Toast notification configuration
37
+ */
38
+ const ToastSchema = z.object({
39
+ title: z.string().optional(),
40
+ message: z.string(),
41
+ variant: z.enum(["info", "success", "warning", "error"]).optional(),
42
+ duration: z.number().optional(),
43
+ }).optional();
44
+ /**
45
+ * Tool hook configuration
46
+ *
47
+ * Runs shell command(s) before or after a tool execution. Hooks can be filtered
48
+ * by tool name, calling agent, and slash command context. Results can optionally
49
+ * be injected into the session as messages.
50
+ */
51
+ export const ToolHookSchema = z.object({
52
+ id: z.string().min(1, "Hook ID must not be empty"),
53
+ when: ToolHookWhenSchema,
54
+ run: z.union([z.string(), z.array(z.string())]),
55
+ inject: z.string().optional(),
56
+ toast: ToastSchema,
57
+ });
58
+ // ============================================================================
59
+ // SESSION HOOK SCHEMAS
60
+ // ============================================================================
61
+ /**
62
+ * Matching conditions for session hooks
63
+ */
64
+ const SessionHookWhenSchema = z.object({
65
+ event: SessionEventSchema,
66
+ agent: StringOrArray.optional(),
67
+ });
68
+ /**
69
+ * Session hook configuration
70
+ *
71
+ * Runs shell command(s) on session lifecycle events (start, idle, end).
72
+ * Can be filtered by agent name. Results can optionally be injected into
73
+ * the session as messages.
74
+ */
75
+ export const SessionHookSchema = z.object({
76
+ id: z.string().min(1, "Hook ID must not be empty"),
77
+ when: SessionHookWhenSchema,
78
+ run: z.union([z.string(), z.array(z.string())]),
79
+ inject: z.string().optional(),
80
+ toast: ToastSchema,
81
+ });
82
+ // ============================================================================
83
+ // CONFIGURATION SCHEMAS
84
+ // ============================================================================
85
+ /**
86
+ * Top-level command hooks configuration
87
+ *
88
+ * This is the root configuration object that appears in opencode.json/.opencode.jsonc
89
+ * under the "command_hooks" key, or in YAML frontmatter of agent/slash-command markdown.
90
+ */
91
+ export const ConfigSchema = z.object({
92
+ tool: z.array(ToolHookSchema).optional(),
93
+ session: z.array(SessionHookSchema).optional(),
94
+ });
95
+ // ============================================================================
96
+ // PARSING FUNCTIONS
97
+ // ============================================================================
98
+ /**
99
+ * Safe configuration parser with fallback defaults
100
+ *
101
+ * Parses unknown input and returns a valid CommandHooksConfig.
102
+ * On validation failure, returns safe defaults (empty arrays).
103
+ *
104
+ * @param input - Unknown configuration object to parse
105
+ * @returns Valid CommandHooksConfig with safe defaults on failure
106
+ */
107
+ export function parseConfig(input) {
108
+ const result = ConfigSchema.safeParse(input);
109
+ if (!result.success) {
110
+ // Return safe defaults on validation failure
111
+ return {
112
+ tool: [],
113
+ session: [],
114
+ };
115
+ }
116
+ // For successful parses, keep undefined fields as-is
117
+ // This allows callers to distinguish between "not provided" vs "provided"
118
+ return result.data;
119
+ }
120
+ /**
121
+ * Parse a single tool hook with error details
122
+ *
123
+ * @param input - Unknown hook object to parse
124
+ * @returns Parsed hook or null if invalid
125
+ */
126
+ export function parseToolHook(input) {
127
+ const result = ToolHookSchema.safeParse(input);
128
+ return result.success ? result.data : null;
129
+ }
130
+ /**
131
+ * Parse a single session hook with error details
132
+ *
133
+ * @param input - Unknown hook object to parse
134
+ * @returns Parsed hook or null if invalid
135
+ */
136
+ export function parseSessionHook(input) {
137
+ const result = SessionHookSchema.safeParse(input);
138
+ return result.success ? result.data : null;
139
+ }
140
+ /**
141
+ * Get detailed validation errors for debugging
142
+ *
143
+ * @param input - Unknown configuration object to validate
144
+ * @returns Validation errors if any, or null if valid
145
+ */
146
+ export function getConfigValidationErrors(input) {
147
+ const result = ConfigSchema.safeParse(input);
148
+ return result.success ? null : result.error;
149
+ }
150
+ //# sourceMappingURL=schemas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"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"}