@goodfoot/claude-code-hooks 1.2.2 → 1.2.6

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 CHANGED
@@ -107,7 +107,7 @@ npm test # Run tests
107
107
 
108
108
  ### Available Hook Types
109
109
 
110
- The `--hooks` argument accepts a comma-separated list of any of these 13 event types:
110
+ The `--hooks` argument accepts a comma-separated list of any of these 15 event types:
111
111
 
112
112
  | Hook Type | Description |
113
113
  | -------------------- | ------------------------------------------ |
@@ -119,9 +119,11 @@ The `--hooks` argument accepts a comma-separated list of any of these 13 event t
119
119
  | `SessionStart` | When session begins |
120
120
  | `SessionEnd` | When session terminates |
121
121
  | `Stop` | After main agent finishes |
122
+ | `StopFailure` | When session stops due to an error |
122
123
  | `SubagentStart` | When an Agent tool starts |
123
124
  | `SubagentStop` | When an Agent tool completes |
124
125
  | `PreCompact` | Before context compaction |
126
+ | `PostCompact` | After context compaction completes |
125
127
  | `PermissionRequest` | When permission is requested |
126
128
  | `Setup` | On init, install, or update events |
127
129
 
@@ -209,8 +211,11 @@ The Logger is **silent by default** — no output to stdout, stderr, or files un
209
211
  # Option A: Environment Variable
210
212
  export CLAUDE_CODE_HOOKS_LOG_FILE=/tmp/claude-hooks.log
211
213
 
212
- # Option B: CLI Argument (during build)
214
+ # Option B: CLI Argument — hardcodes path into bundle (runtime CLAUDE_CODE_HOOKS_LOG_FILE overrides)
213
215
  npx -y @goodfoot/claude-code-hooks ... --log /tmp/claude-hooks.log
216
+
217
+ # Option C: CLI Argument — embed the env var name instead of a hardcoded path (good for worktrees)
218
+ npx -y @goodfoot/claude-code-hooks ... --log-env-var CLAUDE_CODE_HOOKS_LOG_FILE
214
219
  ```
215
220
 
216
221
  **View logs:**
@@ -229,9 +234,12 @@ import { Logger } from '@goodfoot/claude-code-hooks';
229
234
  // Silent by default — perfect for unit tests
230
235
  const logger = new Logger();
231
236
 
232
- // With file output
237
+ // With file output (hardcoded path)
233
238
  const fileLogger = new Logger({ logFilePath: '/tmp/my-hooks.log' });
234
239
 
240
+ // With dynamic path via env var
241
+ const envLogger = new Logger({ logEnvVar: 'MY_PLUGIN_LOG_FILE' });
242
+
235
243
  // Subscribe to events programmatically
236
244
  const unsubscribe = logger.on('error', (event) => {
237
245
  sendToMonitoring(event);
package/dist/cli.js CHANGED
@@ -68,11 +68,19 @@ Scaffold Mode (create new hook project):
68
68
 
69
69
  Optional Arguments:
70
70
  --log <path>
71
- Path to a log file for runtime hook logging.
72
- If provided, all context.logger calls within your hooks will write to this file.
73
- This is equivalent to setting the CLAUDE_CODE_HOOKS_LOG_FILE environment variable.
71
+ Hardcode a log file path into the compiled bundle.
72
+ All context.logger calls within your hooks will write to this file.
73
+ A runtime CLAUDE_CODE_HOOKS_LOG_FILE env var overrides this hardcoded path.
74
+ Cannot be combined with --log-env-var.
74
75
  Example: "/tmp/claude-hooks.log"
75
76
 
77
+ --log-env-var <var>
78
+ Name of the environment variable that will supply the log file path at runtime.
79
+ The Logger reads process.env[VAR_NAME] at startup instead of a hardcoded path.
80
+ Use this when the log path must be determined dynamically (e.g. across worktrees).
81
+ Cannot be combined with --log.
82
+ Example: --log-env-var MY_PLUGIN_LOG_FILE
83
+
76
84
  --executable <path>
77
85
  Node executable path to use in generated commands (default: "node").
78
86
  Use this to specify a custom node path in the generated hooks.json commands.
@@ -88,9 +96,12 @@ Examples:
88
96
  1. Basic Compilation:
89
97
  npx -y @goodfoot/claude-code-hooks -i "hooks/**/*.ts" -o "dist/hooks.json"
90
98
 
91
- 2. With Runtime Logging:
99
+ 2. With Hardcoded Log Path:
92
100
  npx -y @goodfoot/claude-code-hooks -i "src/hooks/*.ts" -o "bin/hooks.json" --log /tmp/claude-hooks.log
93
101
 
102
+ 2b. With Dynamic Log Path (env var set at runtime):
103
+ npx -y @goodfoot/claude-code-hooks -i "src/hooks/*.ts" -o "bin/hooks.json" --log-env-var CLAUDE_CODE_HOOKS_LOG_FILE
104
+
94
105
  3. Scaffold a New Hook Project:
95
106
  npx -y @goodfoot/claude-code-hooks --scaffold ./my-hooks --hooks Stop,SubagentStop -o dist/hooks.json
96
107
 
@@ -106,7 +117,7 @@ Examples:
106
117
  Troubleshooting:
107
118
  - Ensure your hook files use 'export default'.
108
119
  - Use absolute paths in your glob patterns if relative paths aren't finding files.
109
- - Check the log file specified by --log if hooks don't seem to run.
120
+ - Check the log file specified by --log (or the env var named by --log-env-var) if hooks don't seem to run.
110
121
  `;
111
122
  // ============================================================================
112
123
  // Logging
@@ -182,6 +193,9 @@ function parseArgs(argv) {
182
193
  case "--log":
183
194
  args.log = argv[++i];
184
195
  break;
196
+ case "--log-env-var":
197
+ args.logEnvVar = argv[++i];
198
+ break;
185
199
  case "-h":
186
200
  case "--help":
187
201
  args.help = true;
@@ -227,6 +241,9 @@ function validateArgs(args) {
227
241
  return undefined;
228
242
  }
229
243
  // Normal build mode validation
244
+ if (args.log !== undefined && args.logEnvVar !== undefined) {
245
+ return "Cannot use --log and --log-env-var together: choose one method to configure log output";
246
+ }
230
247
  if (args.input === "") {
231
248
  return "Missing required argument: -i/--input <glob>";
232
249
  }
@@ -386,13 +403,9 @@ async function discoverHookFiles(pattern, cwd) {
386
403
  * @returns Compiled content and stable content hash
387
404
  */
388
405
  async function compileHook(options) {
389
- const { sourcePath, logFilePath } = options;
406
+ const { sourcePath, logFilePath, logEnvVar } = options;
390
407
  // Get the path to the runtime module (absolute, then converted to relative)
391
408
  const runtimePathAbsolute = path.resolve(path.dirname(new URL(import.meta.url).pathname), "./runtime.js");
392
- // Build log file injection code if specified
393
- const logFileInjection = logFilePath !== undefined
394
- ? `process.env['CLAUDE_CODE_HOOKS_CLI_LOG_FILE'] = ${JSON.stringify(logFilePath)};\n`
395
- : "";
396
409
  // Compute relative paths from resolveDir to avoid absolute paths in source maps.
397
410
  // This ensures reproducible builds regardless of checkout directory.
398
411
  const resolveDir = path.dirname(sourcePath);
@@ -400,8 +413,7 @@ async function compileHook(options) {
400
413
  const relativeRuntimePath = path.relative(resolveDir, runtimePathAbsolute);
401
414
  // Create wrapper content that imports the hook and calls execute
402
415
  // Uses relative paths to produce reproducible builds
403
- const wrapperContent = `${logFileInjection}
404
- import hook from '${relativeSourcePath.replace(/\\/g, "/")}';
416
+ const wrapperContent = `import hook from '${relativeSourcePath.replace(/\\/g, "/")}';
405
417
  import { execute } from '${relativeRuntimePath.replace(/\\/g, "/")}';
406
418
 
407
419
  execute(hook);
@@ -419,6 +431,22 @@ execute(hook);
419
431
  // Banner to polyfill CJS globals for dependencies bundled into ESM.
420
432
  // Some packages (e.g. typescript) use require(), __filename, and __dirname
421
433
  // internally, which are unavailable in ESM scope.
434
+ //
435
+ // Log configuration is also embedded here (before all bundled code) so the
436
+ // Logger singleton reads it at construction time.
437
+ //
438
+ // --log PATH: sets CLAUDE_CODE_HOOKS_LOG_FILE if not already present
439
+ // (runtime env var wins over the hardcoded path)
440
+ // --log-env-var NAME: unconditionally sets CLAUDE_CODE_HOOKS_LOG_ENV_VAR
441
+ // (the var name is fixed at build time, no runtime override)
442
+ const logFileLines = logFilePath !== undefined
443
+ ? [
444
+ `if (!process.env['CLAUDE_CODE_HOOKS_LOG_FILE']) {`,
445
+ ` process.env['CLAUDE_CODE_HOOKS_LOG_FILE'] = ${JSON.stringify(logFilePath)};`,
446
+ `}`,
447
+ ]
448
+ : [];
449
+ const logEnvVarLines = logEnvVar !== undefined ? [`process.env['CLAUDE_CODE_HOOKS_LOG_ENV_VAR'] = ${JSON.stringify(logEnvVar)};`] : [];
422
450
  const esmRequireBanner = [
423
451
  `import { createRequire as __createRequire } from "node:module";`,
424
452
  `import { fileURLToPath as __fileURLToPath } from "node:url";`,
@@ -426,6 +454,8 @@ execute(hook);
426
454
  `const require = __createRequire(import.meta.url);`,
427
455
  `const __filename = __fileURLToPath(import.meta.url);`,
428
456
  `const __dirname = __pathDirname(__filename);`,
457
+ ...logFileLines,
458
+ ...logEnvVarLines,
429
459
  ].join("\n");
430
460
  // Common esbuild options
431
461
  const commonOptions = {
@@ -498,7 +528,7 @@ function generateContentHash(content) {
498
528
  * @returns Array of compiled hook information
499
529
  */
500
530
  async function compileAllHooks(options) {
501
- const { hookFiles, outputDir, logFilePath } = options;
531
+ const { hookFiles, outputDir, logFilePath, logEnvVar } = options;
502
532
  const compiledHooks = [];
503
533
  // Ensure output directory exists
504
534
  if (!fs.existsSync(outputDir)) {
@@ -518,7 +548,7 @@ async function compileAllHooks(options) {
518
548
  });
519
549
  // Compile the hook (two-step process for stable content hash)
520
550
  log("info", `Compiling: ${sourcePath}`);
521
- const { content, contentHash } = await compileHook({ sourcePath, outputDir, logFilePath });
551
+ const { content, contentHash } = await compileHook({ sourcePath, outputDir, logFilePath, logEnvVar });
522
552
  // Determine output filename using the stable content hash
523
553
  const baseName = path.basename(sourcePath, path.extname(sourcePath));
524
554
  const outputFilename = `${baseName}.${contentHash}.mjs`;
@@ -803,8 +833,8 @@ function writeHooksJson(hooksJson, outputPath) {
803
833
  try {
804
834
  fs.unlinkSync(tempPath);
805
835
  }
806
- catch {
807
- // Ignore cleanup errors
836
+ catch (cleanupError) {
837
+ log("warn", "Failed to clean up temp file", { path: tempPath, error: cleanupError });
808
838
  }
809
839
  }
810
840
  throw error;
@@ -852,12 +882,16 @@ async function main() {
852
882
  const hooksJsonDir = path.dirname(outputPath);
853
883
  // Compiled hooks go in a 'bin' subdirectory relative to hooks.json
854
884
  const buildDir = path.join(hooksJsonDir, "bin");
855
- // Resolve log file path to absolute if provided
856
- const logFilePath = args.log !== undefined ? path.resolve(cwd, args.log) : undefined;
885
+ // Resolve log file path: --log flag takes priority, then CLAUDE_CODE_HOOKS_LOG_FILE env var
886
+ const logFileRaw = args.log ?? process.env.CLAUDE_CODE_HOOKS_LOG_FILE;
887
+ const logFilePath = logFileRaw !== undefined ? path.resolve(cwd, logFileRaw) : undefined;
888
+ // --log-env-var names the env var the Logger should read at runtime
889
+ const logEnvVar = args.logEnvVar;
857
890
  log("info", "Starting hook compilation", {
858
891
  input: args.input,
859
892
  output: args.output,
860
893
  logFilePath,
894
+ logEnvVar,
861
895
  cwd,
862
896
  });
863
897
  // Discover hook files
@@ -880,7 +914,7 @@ async function main() {
880
914
  log("info", `Preserved ${preservedCount} hooks from other sources`);
881
915
  }
882
916
  // Compile all hooks
883
- const compiledHooks = await compileAllHooks({ hookFiles, outputDir: buildDir, logFilePath });
917
+ const compiledHooks = await compileAllHooks({ hookFiles, outputDir: buildDir, logFilePath, logEnvVar });
884
918
  if (compiledHooks.length === 0 && hookFiles.length > 0) {
885
919
  process.stderr.write("Error: No valid hooks found in discovered files.\n");
886
920
  process.exit(1);
@@ -951,4 +985,4 @@ if (isDirectExecution) {
951
985
  });
952
986
  }
953
987
  // Export for testing
954
- export { parseArgs, validateArgs, analyzeHookFile, discoverHookFiles, compileHook, generateContentHash, detectHookContext, generateCommandPath, generateHooksJson, groupHooksByEventAndMatcher, readExistingHooksJson, removeOldGeneratedFiles, extractPreservedHooks, mergeHooksJson, HOOK_FACTORY_TO_EVENT, };
988
+ export { analyzeHookFile, compileHook, detectHookContext, discoverHookFiles, extractPreservedHooks, generateCommandPath, generateContentHash, generateHooksJson, groupHooksByEventAndMatcher, HOOK_FACTORY_TO_EVENT, mergeHooksJson, parseArgs, readExistingHooksJson, removeOldGeneratedFiles, validateArgs, };
package/dist/constants.js CHANGED
@@ -14,9 +14,11 @@ export const HOOK_FACTORY_TO_EVENT = {
14
14
  sessionStartHook: "SessionStart",
15
15
  sessionEndHook: "SessionEnd",
16
16
  stopHook: "Stop",
17
+ stopFailureHook: "StopFailure",
17
18
  subagentStartHook: "SubagentStart",
18
19
  subagentStopHook: "SubagentStop",
19
20
  preCompactHook: "PreCompact",
21
+ postCompactHook: "PostCompact",
20
22
  permissionRequestHook: "PermissionRequest",
21
23
  setupHook: "Setup",
22
24
  teammateIdleHook: "TeammateIdle",
@@ -27,4 +29,6 @@ export const HOOK_FACTORY_TO_EVENT = {
27
29
  instructionsLoadedHook: "InstructionsLoaded",
28
30
  worktreeCreateHook: "WorktreeCreate",
29
31
  worktreeRemoveHook: "WorktreeRemove",
32
+ cwdChangedHook: "CwdChanged",
33
+ fileChangedHook: "FileChanged",
30
34
  };
package/dist/hooks.js CHANGED
@@ -267,6 +267,39 @@ export function stopHook(config, handler) {
267
267
  return createHookFunction("Stop", config, handler);
268
268
  }
269
269
  // ============================================================================
270
+ // StopFailure Hook Factory
271
+ // ============================================================================
272
+ /**
273
+ * Creates a StopFailure hook handler.
274
+ *
275
+ * StopFailure hooks fire when Claude Code encounters an error while stopping
276
+ * (e.g., API errors, authentication failures, rate limits), allowing you to:
277
+ * - Log stop failure events and error details
278
+ * - Alert on unexpected session termination errors
279
+ * - Observe what error caused the failure
280
+ *
281
+ * **Matcher**: No matcher support - fires on all stop failure events
282
+ * @param config - Hook configuration with optional timeout (matcher is ignored)
283
+ * @param handler - The handler function to execute
284
+ * @returns A hook function that can be exported as the default export
285
+ * @example
286
+ * ```typescript
287
+ * import { stopFailureHook, stopFailureOutput } from '@goodfoot/claude-code-hooks';
288
+ *
289
+ * export default stopFailureHook({}, async (input, { logger }) => {
290
+ * logger.error('Session stopped due to error', {
291
+ * error: input.error,
292
+ * details: input.error_details
293
+ * });
294
+ * return stopFailureOutput({});
295
+ * });
296
+ * ```
297
+ * @see https://code.claude.com/docs/en/hooks#stopfailure
298
+ */
299
+ export function stopFailureHook(config, handler) {
300
+ return createHookFunction("StopFailure", config, handler);
301
+ }
302
+ // ============================================================================
270
303
  // SubagentStart Hook Factory
271
304
  // ============================================================================
272
305
  /**
@@ -385,6 +418,38 @@ export function subagentStopHook(config, handler) {
385
418
  export function preCompactHook(config, handler) {
386
419
  return createHookFunction("PreCompact", config, handler);
387
420
  }
421
+ // ============================================================================
422
+ // PostCompact Hook Factory
423
+ // ============================================================================
424
+ /**
425
+ * Creates a PostCompact hook handler.
426
+ *
427
+ * PostCompact hooks fire after context compaction completes, allowing you to:
428
+ * - Observe the compaction summary and details
429
+ * - Log compaction events
430
+ * - React to the new compacted state
431
+ *
432
+ * **Matcher**: Matches against `trigger` ('manual', 'auto')
433
+ * @param config - Hook configuration with optional matcher and timeout
434
+ * @param handler - The handler function to execute
435
+ * @returns A hook function that can be exported as the default export
436
+ * @example
437
+ * ```typescript
438
+ * import { postCompactHook, postCompactOutput } from '@goodfoot/claude-code-hooks';
439
+ *
440
+ * export default postCompactHook({}, async (input, { logger }) => {
441
+ * logger.info('Context compaction completed', {
442
+ * trigger: input.trigger,
443
+ * summary: input.compact_summary
444
+ * });
445
+ * return postCompactOutput({});
446
+ * });
447
+ * ```
448
+ * @see https://code.claude.com/docs/en/hooks#postcompact
449
+ */
450
+ export function postCompactHook(config, handler) {
451
+ return createHookFunction("PostCompact", config, handler);
452
+ }
388
453
  /** @inheritdoc */
389
454
  export function permissionRequestHook(config, handler) {
390
455
  return createHookFunction("PermissionRequest", config, handler);
@@ -676,3 +741,67 @@ export function worktreeCreateHook(config, handler) {
676
741
  export function worktreeRemoveHook(config, handler) {
677
742
  return createHookFunction("WorktreeRemove", config, handler);
678
743
  }
744
+ // ============================================================================
745
+ // CwdChanged Hook Factory
746
+ // ============================================================================
747
+ /**
748
+ * Creates a CwdChanged hook handler.
749
+ *
750
+ * CwdChanged hooks fire when Claude Code's current working directory changes,
751
+ * allowing you to:
752
+ * - React to directory changes within a session
753
+ * - Update file watchers or environment state
754
+ * - Return `watchPaths` via `hookSpecificOutput` to register paths for FileChanged events
755
+ *
756
+ * **Matcher**: No matcher support - fires on all cwd change events
757
+ * @param config - Hook configuration with optional timeout
758
+ * @param handler - The handler function to execute
759
+ * @returns A hook function that can be exported as the default export
760
+ * @example
761
+ * ```typescript
762
+ * import { cwdChangedHook, cwdChangedOutput } from '@goodfoot/claude-code-hooks';
763
+ *
764
+ * export default cwdChangedHook({}, async (input, { logger }) => {
765
+ * logger.info('Working directory changed', { from: input.old_cwd, to: input.new_cwd });
766
+ * return cwdChangedOutput({});
767
+ * });
768
+ * ```
769
+ * @see https://code.claude.com/docs/en/hooks#cwdchanged
770
+ */
771
+ export function cwdChangedHook(config, handler) {
772
+ return createHookFunction("CwdChanged", config, handler);
773
+ }
774
+ // ============================================================================
775
+ // FileChanged Hook Factory
776
+ // ============================================================================
777
+ /**
778
+ * Creates a FileChanged hook handler.
779
+ *
780
+ * FileChanged hooks fire when a watched file changes on disk, allowing you to:
781
+ * - React to file system changes during a session
782
+ * - Invalidate caches or reload configuration
783
+ * - Return `watchPaths` via `hookSpecificOutput` to update the set of watched paths
784
+ *
785
+ * The input `event` field indicates the type of change:
786
+ * - `'change'` - File contents changed
787
+ * - `'add'` - File was created
788
+ * - `'unlink'` - File was deleted
789
+ *
790
+ * **Matcher**: No matcher support - fires on all file change events
791
+ * @param config - Hook configuration with optional timeout
792
+ * @param handler - The handler function to execute
793
+ * @returns A hook function that can be exported as the default export
794
+ * @example
795
+ * ```typescript
796
+ * import { fileChangedHook, fileChangedOutput } from '@goodfoot/claude-code-hooks';
797
+ *
798
+ * export default fileChangedHook({}, async (input, { logger }) => {
799
+ * logger.info('File changed', { path: input.file_path, event: input.event });
800
+ * return fileChangedOutput({});
801
+ * });
802
+ * ```
803
+ * @see https://code.claude.com/docs/en/hooks#filechanged
804
+ */
805
+ export function fileChangedHook(config, handler) {
806
+ return createHookFunction("FileChanged", config, handler);
807
+ }
package/dist/index.js CHANGED
@@ -11,16 +11,16 @@ export {
11
11
  CLAUDE_ENV_VARS, getEnvFilePath,
12
12
  // Getters
13
13
  getProjectDir, isRemoteEnvironment, } from "./env.js";
14
- // Hook factory functions - all 21 hook types
15
- export { configChangeHook, elicitationHook, elicitationResultHook, instructionsLoadedHook, notificationHook, permissionRequestHook, postToolUseFailureHook, postToolUseHook, preCompactHook, preToolUseHook, sessionEndHook, sessionStartHook, setupHook, stopHook, subagentStartHook, subagentStopHook, taskCompletedHook, teammateIdleHook, userPromptSubmitHook, worktreeCreateHook, worktreeRemoveHook, } from "./hooks.js";
14
+ // Hook factory functions - all 25 hook types
15
+ export { configChangeHook, cwdChangedHook, elicitationHook, elicitationResultHook, fileChangedHook, instructionsLoadedHook, notificationHook, permissionRequestHook, postCompactHook, postToolUseFailureHook, postToolUseHook, preCompactHook, preToolUseHook, sessionEndHook, sessionStartHook, setupHook, stopFailureHook, stopHook, subagentStartHook, subagentStopHook, taskCompletedHook, teammateIdleHook, userPromptSubmitHook, worktreeCreateHook, worktreeRemoveHook, } from "./hooks.js";
16
16
  // Logger exports
17
17
  export { LOG_LEVELS, Logger, logger } from "./logger.js";
18
18
  // Output builder functions
19
- export { configChangeOutput,
19
+ export { configChangeOutput, cwdChangedOutput,
20
20
  // Exit codes
21
- EXIT_CODES, elicitationOutput, elicitationResultOutput, instructionsLoadedOutput, notificationOutput, permissionRequestOutput, postToolUseFailureOutput, postToolUseOutput, preCompactOutput,
22
- // All 21 output builder functions
23
- preToolUseOutput, sessionEndOutput, sessionStartOutput, setupOutput, stopOutput, subagentStartOutput, subagentStopOutput, taskCompletedOutput, teammateIdleOutput, userPromptSubmitOutput, worktreeCreateOutput, worktreeRemoveOutput, } from "./outputs.js";
21
+ EXIT_CODES, elicitationOutput, elicitationResultOutput, fileChangedOutput, instructionsLoadedOutput, notificationOutput, permissionRequestOutput, postCompactOutput, postToolUseFailureOutput, postToolUseOutput, preCompactOutput,
22
+ // All 25 output builder functions
23
+ preToolUseOutput, sessionEndOutput, sessionStartOutput, setupOutput, stopFailureOutput, stopOutput, subagentStartOutput, subagentStopOutput, taskCompletedOutput, teammateIdleOutput, userPromptSubmitOutput, worktreeCreateOutput, worktreeRemoveOutput, } from "./outputs.js";
24
24
  // Runtime exports - execute function
25
25
  export {
26
26
  // Main execute function for compiled hooks
package/dist/logger.js CHANGED
@@ -108,8 +108,8 @@ export class Logger {
108
108
  for (const level of LOG_LEVELS) {
109
109
  this.handlers.set(level, new Set());
110
110
  }
111
- // Set log file path from config or environment
112
- this.logFilePath = config.logFilePath ?? process.env.CLAUDE_CODE_HOOKS_LOG_FILE ?? null;
111
+ // Set log file path from explicit config, or by reading the configured env var
112
+ this.logFilePath = config.logFilePath ?? (config.logEnvVar ? process.env[config.logEnvVar] : undefined) ?? null;
113
113
  }
114
114
  /**
115
115
  * Logs a debug message.
@@ -290,8 +290,8 @@ export class Logger {
290
290
  try {
291
291
  closeSync(this.logFileFd);
292
292
  }
293
- catch {
294
- // Ignore errors on close
293
+ catch (closeError) {
294
+ process.stderr.write(`[claude-code-hooks] Failed to close log file: ${String(closeError)}\n`);
295
295
  }
296
296
  this.logFileFd = null;
297
297
  }
@@ -314,8 +314,8 @@ export class Logger {
314
314
  try {
315
315
  closeSync(this.logFileFd);
316
316
  }
317
- catch {
318
- // Ignore errors on close
317
+ catch (closeError) {
318
+ process.stderr.write(`[claude-code-hooks] Failed to close log file: ${String(closeError)}\n`);
319
319
  }
320
320
  this.logFileFd = null;
321
321
  }
@@ -366,8 +366,8 @@ export class Logger {
366
366
  try {
367
367
  handler(event);
368
368
  }
369
- catch {
370
- // Silently ignore handler errors to not disrupt hook execution
369
+ catch (handlerError) {
370
+ process.stderr.write(`[claude-code-hooks] Log handler error: ${String(handlerError)}\n`);
371
371
  }
372
372
  }
373
373
  }
@@ -391,10 +391,11 @@ export class Logger {
391
391
  const line = `${JSON.stringify(event)}\n`;
392
392
  writeSync(this.logFileFd, line);
393
393
  }
394
- catch {
395
- // Silently ignore file write errors to not disrupt hook execution
396
- // This follows the risk mitigation: "Graceful degradation - log write
397
- // failures are silently ignored to not disrupt hook execution"
394
+ catch (writeError) {
395
+ // Disable file logging after a write failure to avoid repeated errors
396
+ this.logFileFd = null;
397
+ this.fileInitialized = false;
398
+ process.stderr.write(`[claude-code-hooks] Log file write failed: ${String(writeError)}\n`);
398
399
  }
399
400
  }
400
401
  /**
@@ -500,4 +501,8 @@ export class Logger {
500
501
  * }
501
502
  * ```
502
503
  */
503
- export const logger = new Logger();
504
+ // CLAUDE_CODE_HOOKS_LOG_ENV_VAR is set unconditionally by the --log-env-var banner
505
+ // before this module initialises. If absent, fall back to the default env var name.
506
+ export const logger = new Logger({
507
+ logEnvVar: process.env.CLAUDE_CODE_HOOKS_LOG_ENV_VAR ?? "CLAUDE_CODE_HOOKS_LOG_FILE",
508
+ });
package/dist/outputs.js CHANGED
@@ -199,6 +199,16 @@ export const sessionEndOutput = /* @__PURE__ */ createSimpleOutputBuilder("Sessi
199
199
  * ```
200
200
  */
201
201
  export const stopOutput = /* @__PURE__ */ createDecisionOutputBuilder("Stop");
202
+ /**
203
+ * Creates an output for StopFailure hooks.
204
+ * @param options - Configuration options for the hook output
205
+ * @returns A StopFailureOutput object ready for the runtime
206
+ * @example
207
+ * ```typescript
208
+ * stopFailureOutput({});
209
+ * ```
210
+ */
211
+ export const stopFailureOutput = /* @__PURE__ */ createSimpleOutputBuilder("StopFailure");
202
212
  /**
203
213
  * Creates an output for SubagentStart hooks.
204
214
  * @param options - Configuration options for the hook output
@@ -257,6 +267,16 @@ export const notificationOutput = /* @__PURE__ */ createHookSpecificOutputBuilde
257
267
  * ```
258
268
  */
259
269
  export const preCompactOutput = /* @__PURE__ */ createSimpleOutputBuilder("PreCompact");
270
+ /**
271
+ * Creates an output for PostCompact hooks.
272
+ * @param options - Configuration options for the hook output
273
+ * @returns A PostCompactOutput object ready for the runtime
274
+ * @example
275
+ * ```typescript
276
+ * postCompactOutput({});
277
+ * ```
278
+ */
279
+ export const postCompactOutput = /* @__PURE__ */ createSimpleOutputBuilder("PostCompact");
260
280
  /**
261
281
  * Creates an output for PermissionRequest hooks.
262
282
  * @param options - Configuration options for the hook output
@@ -411,3 +431,39 @@ export const worktreeCreateOutput = /* @__PURE__ */ createSimpleOutputBuilder("W
411
431
  * ```
412
432
  */
413
433
  export const worktreeRemoveOutput = /* @__PURE__ */ createSimpleOutputBuilder("WorktreeRemove");
434
+ /**
435
+ * Creates an output for CwdChanged hooks.
436
+ * @param options - Configuration options for the hook output
437
+ * @returns A CwdChangedOutput object ready for the runtime
438
+ * @example
439
+ * ```typescript
440
+ * // Return additional paths to watch after the cwd change
441
+ * cwdChangedOutput({
442
+ * hookSpecificOutput: {
443
+ * watchPaths: ['/new/path/to/watch']
444
+ * }
445
+ * });
446
+ *
447
+ * // Simple passthrough
448
+ * cwdChangedOutput({});
449
+ * ```
450
+ */
451
+ export const cwdChangedOutput = /* @__PURE__ */ createHookSpecificOutputBuilder("CwdChanged");
452
+ /**
453
+ * Creates an output for FileChanged hooks.
454
+ * @param options - Configuration options for the hook output
455
+ * @returns A FileChangedOutput object ready for the runtime
456
+ * @example
457
+ * ```typescript
458
+ * // Update the set of watched paths
459
+ * fileChangedOutput({
460
+ * hookSpecificOutput: {
461
+ * watchPaths: ['/path/to/watch', '/another/path']
462
+ * }
463
+ * });
464
+ *
465
+ * // Simple passthrough
466
+ * fileChangedOutput({});
467
+ * ```
468
+ */
469
+ export const fileChangedOutput = /* @__PURE__ */ createHookSpecificOutputBuilder("FileChanged");
package/dist/runtime.js CHANGED
@@ -161,21 +161,6 @@ export function convertToHookOutput(specificOutput) {
161
161
  export async function execute(hookFn) {
162
162
  let output;
163
163
  try {
164
- // Check for log file configuration conflicts
165
- // CLAUDE_CODE_HOOKS_CLI_LOG_FILE is injected by the CLI --log parameter
166
- // CLAUDE_CODE_HOOKS_LOG_FILE is the user's environment variable
167
- const cliLogFile = process.env.CLAUDE_CODE_HOOKS_CLI_LOG_FILE;
168
- const envLogFile = process.env.CLAUDE_CODE_HOOKS_LOG_FILE;
169
- if (cliLogFile !== undefined && envLogFile !== undefined && cliLogFile !== envLogFile) {
170
- // Write error to stderr and exit with error code
171
- process.stderr.write(`Log file configuration conflict: CLI --log="${cliLogFile}" vs CLAUDE_CODE_HOOKS_LOG_FILE="${envLogFile}". ` +
172
- "Use only one method to configure hook logging.\n");
173
- process.exit(EXIT_CODES.ERROR);
174
- }
175
- // If CLI log file is set, configure the logger
176
- if (cliLogFile !== undefined) {
177
- logger.setLogFile(cliLogFile);
178
- }
179
164
  // Read and parse stdin
180
165
  let stdinContent;
181
166
  try {
package/dist/scaffold.js CHANGED
@@ -45,9 +45,11 @@ const EVENT_TO_OUTPUT_FUNCTION = {
45
45
  SessionStart: "sessionStartOutput",
46
46
  SessionEnd: "sessionEndOutput",
47
47
  Stop: "stopOutput",
48
+ StopFailure: "stopFailureOutput",
48
49
  SubagentStart: "subagentStartOutput",
49
50
  SubagentStop: "subagentStopOutput",
50
51
  PreCompact: "preCompactOutput",
52
+ PostCompact: "postCompactOutput",
51
53
  PermissionRequest: "permissionRequestOutput",
52
54
  Setup: "setupOutput",
53
55
  TeammateIdle: "teammateIdleOutput",
@@ -58,6 +60,8 @@ const EVENT_TO_OUTPUT_FUNCTION = {
58
60
  InstructionsLoaded: "instructionsLoadedOutput",
59
61
  WorktreeCreate: "worktreeCreateOutput",
60
62
  WorktreeRemove: "worktreeRemoveOutput",
63
+ CwdChanged: "cwdChangedOutput",
64
+ FileChanged: "fileChangedOutput",
61
65
  };
62
66
  // ============================================================================
63
67
  // Validation
@@ -125,7 +129,7 @@ function generatePackageJson(projectName, outputPath) {
125
129
  "@goodfoot/claude-code-hooks": "^1.0.9",
126
130
  },
127
131
  devDependencies: {
128
- "@biomejs/biome": "2.4.6",
132
+ "@biomejs/biome": "2.4.9",
129
133
  "@types/node": "^22.0.0",
130
134
  typescript: "^5.9.3",
131
135
  vitest: "^4.0.16",
@@ -168,7 +172,7 @@ function generateTsConfig() {
168
172
  */
169
173
  function generateBiomeConfig() {
170
174
  return `{
171
- "$schema": "https://biomejs.dev/schemas/2.4.6/schema.json",
175
+ "$schema": "https://biomejs.dev/schemas/2.4.9/schema.json",
172
176
  "formatter": {
173
177
  "enabled": true,
174
178
  "indentStyle": "space",
package/dist/types.js CHANGED
@@ -28,9 +28,11 @@ export const HOOK_EVENT_NAMES = [
28
28
  "SessionStart",
29
29
  "SessionEnd",
30
30
  "Stop",
31
+ "StopFailure",
31
32
  "SubagentStart",
32
33
  "SubagentStop",
33
34
  "PreCompact",
35
+ "PostCompact",
34
36
  "PermissionRequest",
35
37
  "Setup",
36
38
  "TeammateIdle",
@@ -41,4 +43,6 @@ export const HOOK_EVENT_NAMES = [
41
43
  "InstructionsLoaded",
42
44
  "WorktreeCreate",
43
45
  "WorktreeRemove",
46
+ "CwdChanged",
47
+ "FileChanged",
44
48
  ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goodfoot/claude-code-hooks",
3
- "version": "1.2.2",
3
+ "version": "1.2.6",
4
4
  "description": "Type-safe Claude Code hooks library with camelCase types and output builders",
5
5
  "homepage": "https://github.com/goodfoot-io/marketplace/tree/main/packages/claude-code-hooks",
6
6
  "repository": {
@@ -53,8 +53,8 @@
53
53
  "typescript": "^5.9.3"
54
54
  },
55
55
  "devDependencies": {
56
- "@anthropic-ai/claude-agent-sdk": "^0.2.71",
57
- "@biomejs/biome": "2.4.6",
56
+ "@anthropic-ai/claude-agent-sdk": "^0.2.83",
57
+ "@biomejs/biome": "2.4.9",
58
58
  "@types/node": "^24",
59
59
  "ts-morph": "^25.0.0",
60
60
  "tsx": "^4.20.3",
package/types/cli.d.ts CHANGED
@@ -31,8 +31,10 @@ interface CliArgs {
31
31
  input: string;
32
32
  /** Path for hooks.json output file. */
33
33
  output: string;
34
- /** Optional log file path. */
34
+ /** Optional log file path (hardcoded into bundle). */
35
35
  log?: string;
36
+ /** Optional env var name whose value supplies the log file path at runtime. */
37
+ logEnvVar?: string;
36
38
  /** Show help. */
37
39
  help: boolean;
38
40
  /** Show version. */
@@ -148,8 +150,10 @@ interface CompileHookOptions {
148
150
  sourcePath: string;
149
151
  /** Directory for compiled output. */
150
152
  outputDir: string;
151
- /** Optional log file path to inject into compiled hook. */
153
+ /** Optional log file path to hardcode into the bundle via the banner. */
152
154
  logFilePath?: string;
155
+ /** Optional env var name the Logger should read for the log file path at runtime. */
156
+ logEnvVar?: string;
153
157
  }
154
158
  /**
155
159
  * Result of compiling a hook.
@@ -262,5 +266,5 @@ declare function extractPreservedHooks(existingHooksJson: HooksJson): Partial<Re
262
266
  * @returns Merged HooksJson
263
267
  */
264
268
  declare function mergeHooksJson(newHooksJson: HooksJson, preservedHooks: Partial<Record<HookEventName, MatcherEntry[]>>): HooksJson;
265
- export { parseArgs, validateArgs, analyzeHookFile, discoverHookFiles, compileHook, generateContentHash, detectHookContext, generateCommandPath, generateHooksJson, groupHooksByEventAndMatcher, readExistingHooksJson, removeOldGeneratedFiles, extractPreservedHooks, mergeHooksJson, HOOK_FACTORY_TO_EVENT, };
266
- export type { CliArgs, HookMetadata, CompiledHook, HookConfig, MatcherEntry, HooksJson };
269
+ export type { CliArgs, CompiledHook, HookConfig, HookMetadata, HooksJson, MatcherEntry };
270
+ export { analyzeHookFile, compileHook, detectHookContext, discoverHookFiles, extractPreservedHooks, generateCommandPath, generateContentHash, generateHooksJson, groupHooksByEventAndMatcher, HOOK_FACTORY_TO_EVENT, mergeHooksJson, parseArgs, readExistingHooksJson, removeOldGeneratedFiles, validateArgs, };
package/types/hooks.d.ts CHANGED
@@ -22,8 +22,8 @@
22
22
  * @see https://code.claude.com/docs/en/hooks
23
23
  */
24
24
  import type { Logger } from "./logger.js";
25
- import type { ConfigChangeOutput, ElicitationOutput, ElicitationResultOutput, InstructionsLoadedOutput, NotificationOutput, PermissionRequestOutput, PostToolUseFailureOutput, PostToolUseOutput, PreCompactOutput, PreToolUseOutput, SessionEndOutput, SessionStartOutput, SetupOutput, SpecificHookOutput, StopOutput, SubagentStartOutput, SubagentStopOutput, TaskCompletedOutput, TeammateIdleOutput, UserPromptSubmitOutput, WorktreeCreateOutput, WorktreeRemoveOutput } from "./outputs.js";
26
- import type { ConfigChangeInput, ElicitationInput, ElicitationResultInput, HookEventName, InstructionsLoadedInput, KnownToolName, NotificationInput, PermissionRequestInput, PostToolUseFailureInput, PostToolUseInput, PreCompactInput, PreToolUseInput, SessionEndInput, SessionStartInput, SetupInput, StopInput, SubagentStartInput, SubagentStopInput, TaskCompletedInput, TeammateIdleInput, ToolInputMap, UserPromptSubmitInput, WorktreeCreateInput, WorktreeRemoveInput } from "./types.js";
25
+ import type { ConfigChangeOutput, CwdChangedOutput, ElicitationOutput, ElicitationResultOutput, FileChangedOutput, InstructionsLoadedOutput, NotificationOutput, PermissionRequestOutput, PostCompactOutput, PostToolUseFailureOutput, PostToolUseOutput, PreCompactOutput, PreToolUseOutput, SessionEndOutput, SessionStartOutput, SetupOutput, SpecificHookOutput, StopFailureOutput, StopOutput, SubagentStartOutput, SubagentStopOutput, TaskCompletedOutput, TeammateIdleOutput, UserPromptSubmitOutput, WorktreeCreateOutput, WorktreeRemoveOutput } from "./outputs.js";
26
+ import type { ConfigChangeInput, CwdChangedInput, ElicitationInput, ElicitationResultInput, FileChangedInput, HookEventName, InstructionsLoadedInput, KnownToolName, NotificationInput, PermissionRequestInput, PostCompactInput, PostToolUseFailureInput, PostToolUseInput, PreCompactInput, PreToolUseInput, SessionEndInput, SessionStartInput, SetupInput, StopFailureInput, StopInput, SubagentStartInput, SubagentStopInput, TaskCompletedInput, TeammateIdleInput, ToolInputMap, UserPromptSubmitInput, WorktreeCreateInput, WorktreeRemoveInput } from "./types.js";
27
27
  /**
28
28
  * Configuration options for hook factories.
29
29
  *
@@ -612,6 +612,34 @@ export declare function sessionEndHook(config: HookConfig, handler: HookHandler<
612
612
  * @see https://code.claude.com/docs/en/hooks#stop
613
613
  */
614
614
  export declare function stopHook(config: HookConfig, handler: HookHandler<StopInput, StopOutput>): HookFunction<StopInput, StopOutput>;
615
+ /**
616
+ * Creates a StopFailure hook handler.
617
+ *
618
+ * StopFailure hooks fire when Claude Code encounters an error while stopping
619
+ * (e.g., API errors, authentication failures, rate limits), allowing you to:
620
+ * - Log stop failure events and error details
621
+ * - Alert on unexpected session termination errors
622
+ * - Observe what error caused the failure
623
+ *
624
+ * **Matcher**: No matcher support - fires on all stop failure events
625
+ * @param config - Hook configuration with optional timeout (matcher is ignored)
626
+ * @param handler - The handler function to execute
627
+ * @returns A hook function that can be exported as the default export
628
+ * @example
629
+ * ```typescript
630
+ * import { stopFailureHook, stopFailureOutput } from '@goodfoot/claude-code-hooks';
631
+ *
632
+ * export default stopFailureHook({}, async (input, { logger }) => {
633
+ * logger.error('Session stopped due to error', {
634
+ * error: input.error,
635
+ * details: input.error_details
636
+ * });
637
+ * return stopFailureOutput({});
638
+ * });
639
+ * ```
640
+ * @see https://code.claude.com/docs/en/hooks#stopfailure
641
+ */
642
+ export declare function stopFailureHook(config: HookConfig, handler: HookHandler<StopFailureInput, StopFailureOutput>): HookFunction<StopFailureInput, StopFailureOutput>;
615
643
  /**
616
644
  * Creates a SubagentStart hook handler.
617
645
  *
@@ -716,6 +744,33 @@ export declare function subagentStopHook(config: HookConfig, handler: HookHandle
716
744
  * @see https://code.claude.com/docs/en/hooks#precompact
717
745
  */
718
746
  export declare function preCompactHook(config: HookConfig, handler: HookHandler<PreCompactInput, PreCompactOutput>): HookFunction<PreCompactInput, PreCompactOutput>;
747
+ /**
748
+ * Creates a PostCompact hook handler.
749
+ *
750
+ * PostCompact hooks fire after context compaction completes, allowing you to:
751
+ * - Observe the compaction summary and details
752
+ * - Log compaction events
753
+ * - React to the new compacted state
754
+ *
755
+ * **Matcher**: Matches against `trigger` ('manual', 'auto')
756
+ * @param config - Hook configuration with optional matcher and timeout
757
+ * @param handler - The handler function to execute
758
+ * @returns A hook function that can be exported as the default export
759
+ * @example
760
+ * ```typescript
761
+ * import { postCompactHook, postCompactOutput } from '@goodfoot/claude-code-hooks';
762
+ *
763
+ * export default postCompactHook({}, async (input, { logger }) => {
764
+ * logger.info('Context compaction completed', {
765
+ * trigger: input.trigger,
766
+ * summary: input.compact_summary
767
+ * });
768
+ * return postCompactOutput({});
769
+ * });
770
+ * ```
771
+ * @see https://code.claude.com/docs/en/hooks#postcompact
772
+ */
773
+ export declare function postCompactHook(config: HookConfig, handler: HookHandler<PostCompactInput, PostCompactOutput>): HookFunction<PostCompactInput, PostCompactOutput>;
719
774
  /**
720
775
  * Creates a PermissionRequest hook handler.
721
776
  *
@@ -1017,4 +1072,58 @@ export declare function worktreeCreateHook(config: HookConfig, handler: HookHand
1017
1072
  * @see https://code.claude.com/docs/en/hooks#worktreeremove
1018
1073
  */
1019
1074
  export declare function worktreeRemoveHook(config: HookConfig, handler: HookHandler<WorktreeRemoveInput, WorktreeRemoveOutput>): HookFunction<WorktreeRemoveInput, WorktreeRemoveOutput>;
1075
+ /**
1076
+ * Creates a CwdChanged hook handler.
1077
+ *
1078
+ * CwdChanged hooks fire when Claude Code's current working directory changes,
1079
+ * allowing you to:
1080
+ * - React to directory changes within a session
1081
+ * - Update file watchers or environment state
1082
+ * - Return `watchPaths` via `hookSpecificOutput` to register paths for FileChanged events
1083
+ *
1084
+ * **Matcher**: No matcher support - fires on all cwd change events
1085
+ * @param config - Hook configuration with optional timeout
1086
+ * @param handler - The handler function to execute
1087
+ * @returns A hook function that can be exported as the default export
1088
+ * @example
1089
+ * ```typescript
1090
+ * import { cwdChangedHook, cwdChangedOutput } from '@goodfoot/claude-code-hooks';
1091
+ *
1092
+ * export default cwdChangedHook({}, async (input, { logger }) => {
1093
+ * logger.info('Working directory changed', { from: input.old_cwd, to: input.new_cwd });
1094
+ * return cwdChangedOutput({});
1095
+ * });
1096
+ * ```
1097
+ * @see https://code.claude.com/docs/en/hooks#cwdchanged
1098
+ */
1099
+ export declare function cwdChangedHook(config: HookConfig, handler: HookHandler<CwdChangedInput, CwdChangedOutput>): HookFunction<CwdChangedInput, CwdChangedOutput>;
1100
+ /**
1101
+ * Creates a FileChanged hook handler.
1102
+ *
1103
+ * FileChanged hooks fire when a watched file changes on disk, allowing you to:
1104
+ * - React to file system changes during a session
1105
+ * - Invalidate caches or reload configuration
1106
+ * - Return `watchPaths` via `hookSpecificOutput` to update the set of watched paths
1107
+ *
1108
+ * The input `event` field indicates the type of change:
1109
+ * - `'change'` - File contents changed
1110
+ * - `'add'` - File was created
1111
+ * - `'unlink'` - File was deleted
1112
+ *
1113
+ * **Matcher**: No matcher support - fires on all file change events
1114
+ * @param config - Hook configuration with optional timeout
1115
+ * @param handler - The handler function to execute
1116
+ * @returns A hook function that can be exported as the default export
1117
+ * @example
1118
+ * ```typescript
1119
+ * import { fileChangedHook, fileChangedOutput } from '@goodfoot/claude-code-hooks';
1120
+ *
1121
+ * export default fileChangedHook({}, async (input, { logger }) => {
1122
+ * logger.info('File changed', { path: input.file_path, event: input.event });
1123
+ * return fileChangedOutput({});
1124
+ * });
1125
+ * ```
1126
+ * @see https://code.claude.com/docs/en/hooks#filechanged
1127
+ */
1128
+ export declare function fileChangedHook(config: HookConfig, handler: HookHandler<FileChangedInput, FileChangedOutput>): HookFunction<FileChangedInput, FileChangedOutput>;
1020
1129
  export {};
package/types/index.d.ts CHANGED
@@ -8,15 +8,15 @@
8
8
  export type * from "@anthropic-ai/claude-agent-sdk/sdk-tools.js";
9
9
  export { CLAUDE_ENV_VARS, getEnvFilePath, getProjectDir, isRemoteEnvironment, } from "./env.js";
10
10
  export type { HookConfig, HookContext, HookFunction, HookHandler, SessionStartContext, TypedHookConfig, TypedPermissionRequestInput, TypedPostToolUseFailureHookInput, TypedPostToolUseHookInput, TypedPreToolUseHookInput, } from "./hooks.js";
11
- export { configChangeHook, elicitationHook, elicitationResultHook, instructionsLoadedHook, notificationHook, permissionRequestHook, postToolUseFailureHook, postToolUseHook, preCompactHook, preToolUseHook, sessionEndHook, sessionStartHook, setupHook, stopHook, subagentStartHook, subagentStopHook, taskCompletedHook, teammateIdleHook, userPromptSubmitHook, worktreeCreateHook, worktreeRemoveHook, } from "./hooks.js";
11
+ export { configChangeHook, cwdChangedHook, elicitationHook, elicitationResultHook, fileChangedHook, instructionsLoadedHook, notificationHook, permissionRequestHook, postCompactHook, postToolUseFailureHook, postToolUseHook, preCompactHook, preToolUseHook, sessionEndHook, sessionStartHook, setupHook, stopFailureHook, stopHook, subagentStartHook, subagentStopHook, taskCompletedHook, teammateIdleHook, userPromptSubmitHook, worktreeCreateHook, worktreeRemoveHook, } from "./hooks.js";
12
12
  export type { LogEvent, LogEventError, LogEventHandler, LoggerConfig, LogLevel, Unsubscribe } from "./logger.js";
13
13
  export { LOG_LEVELS, Logger, logger } from "./logger.js";
14
14
  export type {
15
15
  /** @deprecated Use CommonOptions instead */
16
- BaseOptions, CommonOptions, ConfigChangeOptions, ElicitationHookSpecificOutput, ElicitationOptions, ElicitationResultHookSpecificOutput, ElicitationResultOptions, ExitCode, ExitCodeOptions, HookOutput, HookSpecificOutput, InstructionsLoadedOptions, NotificationHookSpecificOutput, NotificationOptions, PermissionRequestAllowDecision, PermissionRequestDecision, PermissionRequestDenyDecision, PermissionRequestHookSpecificOutput, PermissionRequestOptions, PostToolUseFailureHookSpecificOutput, PostToolUseFailureOptions, PostToolUseHookSpecificOutput, PostToolUseOptions, PreCompactOptions, PreToolUseHookSpecificOutput, PreToolUseOptions, SessionEndOptions, SessionStartHookSpecificOutput, SessionStartOptions, SetupHookSpecificOutput, SetupOptions, StopOptions, SubagentStartHookSpecificOutput, SubagentStartOptions, SubagentStopOptions, SyncHookJSONOutput, TaskCompletedOptions, TeammateIdleOptions, UserPromptSubmitHookSpecificOutput, UserPromptSubmitOptions, WorktreeCreateOptions, WorktreeRemoveOptions, } from "./outputs.js";
17
- export { configChangeOutput, EXIT_CODES, elicitationOutput, elicitationResultOutput, instructionsLoadedOutput, notificationOutput, permissionRequestOutput, postToolUseFailureOutput, postToolUseOutput, preCompactOutput, preToolUseOutput, sessionEndOutput, sessionStartOutput, setupOutput, stopOutput, subagentStartOutput, subagentStopOutput, taskCompletedOutput, teammateIdleOutput, userPromptSubmitOutput, worktreeCreateOutput, worktreeRemoveOutput, } from "./outputs.js";
16
+ BaseOptions, CommonOptions, ConfigChangeOptions, CwdChangedHookSpecificOutput, CwdChangedOptions, ElicitationHookSpecificOutput, ElicitationOptions, ElicitationResultHookSpecificOutput, ElicitationResultOptions, ExitCode, ExitCodeOptions, FileChangedHookSpecificOutput, FileChangedOptions, HookOutput, HookSpecificOutput, InstructionsLoadedOptions, NotificationHookSpecificOutput, NotificationOptions, PermissionRequestAllowDecision, PermissionRequestDecision, PermissionRequestDenyDecision, PermissionRequestHookSpecificOutput, PermissionRequestOptions, PostCompactOptions, PostToolUseFailureHookSpecificOutput, PostToolUseFailureOptions, PostToolUseHookSpecificOutput, PostToolUseOptions, PreCompactOptions, PreToolUseHookSpecificOutput, PreToolUseOptions, SessionEndOptions, SessionStartHookSpecificOutput, SessionStartOptions, SetupHookSpecificOutput, SetupOptions, StopFailureOptions, StopOptions, SubagentStartHookSpecificOutput, SubagentStartOptions, SubagentStopOptions, SyncHookJSONOutput, TaskCompletedOptions, TeammateIdleOptions, UserPromptSubmitHookSpecificOutput, UserPromptSubmitOptions, WorktreeCreateOptions, WorktreeRemoveOptions, } from "./outputs.js";
17
+ export { configChangeOutput, cwdChangedOutput, EXIT_CODES, elicitationOutput, elicitationResultOutput, fileChangedOutput, instructionsLoadedOutput, notificationOutput, permissionRequestOutput, postCompactOutput, postToolUseFailureOutput, postToolUseOutput, preCompactOutput, preToolUseOutput, sessionEndOutput, sessionStartOutput, setupOutput, stopFailureOutput, stopOutput, subagentStartOutput, subagentStopOutput, taskCompletedOutput, teammateIdleOutput, userPromptSubmitOutput, worktreeCreateOutput, worktreeRemoveOutput, } from "./outputs.js";
18
18
  export { execute, } from "./runtime.js";
19
19
  export type { ContentContext, PatternCheckResult, ToolUseInput } from "./tool-helpers.js";
20
20
  export { checkContentForPattern, forEachContent, getFilePath, isAskUserQuestionTool, isBashTool, isConfigTool, isEditTool, isExitPlanModeTool, isFileModifyingTool, isGlobTool, isGrepTool, isJsTsFile, isKillShellTool, isListMcpResourcesTool, isMcpTool, isMultiEditTool, isNotebookEditTool, isReadMcpResourceTool, isReadTool, isTaskOutputTool, isTaskTool, isTodoWriteTool, isTsFile, isWebFetchTool, isWebSearchTool, isWriteTool, } from "./tool-helpers.js";
21
- export type { BaseHookInput, ConfigChangeInput, ConfigInput, ElicitationInput, ElicitationResultInput, FileModifyingToolInput, FileModifyingToolName, HookEventName, HookInput, InstructionsLoadedInput, KnownToolInput, KnownToolName, ListMcpResourcesInput, McpInput, MultiEditEntry, MultiEditToolInput, NotificationInput, PermissionMode, PermissionRequestInput, PermissionUpdate, PostToolUseFailureInput, PostToolUseInput, PreCompactInput, PreCompactTrigger, PreToolUseInput, ReadMcpResourceInput, SessionEndInput, SessionEndReason, SessionStartInput, SessionStartSource, SetupInput, SetupTrigger, StopInput, SubagentStartInput, SubagentStopInput, TaskCompletedInput, TeammateIdleInput, ToolInputMap, UserPromptSubmitInput, WorktreeCreateInput, WorktreeRemoveInput, } from "./types.js";
21
+ export type { BaseHookInput, ConfigChangeInput, ConfigInput, CwdChangedInput, ElicitationInput, ElicitationResultInput, FileChangedInput, FileModifyingToolInput, FileModifyingToolName, HookEventName, HookInput, InstructionsLoadedInput, KnownToolInput, KnownToolName, ListMcpResourcesInput, McpInput, MultiEditEntry, MultiEditToolInput, NotificationInput, PermissionMode, PermissionRequestInput, PermissionUpdate, PostCompactInput, PostToolUseFailureInput, PostToolUseInput, PreCompactInput, PreCompactTrigger, PreToolUseInput, ReadMcpResourceInput, SessionEndInput, SessionEndReason, SessionStartInput, SessionStartSource, SetupInput, SetupTrigger, StopFailureInput, StopInput, SubagentStartInput, SubagentStopInput, TaskCompletedInput, TeammateIdleInput, ToolInputMap, UserPromptSubmitInput, WorktreeCreateInput, WorktreeRemoveInput, } from "./types.js";
22
22
  export { HOOK_EVENT_NAMES } from "./types.js";
package/types/logger.d.ts CHANGED
@@ -147,9 +147,15 @@ export interface LoggerConfig {
147
147
  /**
148
148
  * Path to the log file for file output.
149
149
  * If not set, file logging is disabled.
150
- * Can also be set via `CLAUDE_CODE_HOOKS_LOG_FILE` environment variable.
151
150
  */
152
151
  logFilePath?: string;
152
+ /**
153
+ * Name of the environment variable to read for the log file path.
154
+ * When set, the Logger reads `process.env[logEnvVar]` at construction time.
155
+ * Ignored if `logFilePath` is also provided.
156
+ * Defaults to `'CLAUDE_CODE_HOOKS_LOG_FILE'` for the exported singleton.
157
+ */
158
+ logEnvVar?: string;
153
159
  }
154
160
  /**
155
161
  * Logger for Claude Code hooks with event subscription and file output.
@@ -7,7 +7,7 @@
7
7
  * @see https://code.claude.com/docs/en/hooks
8
8
  * @module
9
9
  */
10
- import type { ElicitationHookSpecificOutput as SDKElicitationHookSpecificOutput, ElicitationResultHookSpecificOutput as SDKElicitationResultHookSpecificOutput } from "@anthropic-ai/claude-agent-sdk";
10
+ import type { CwdChangedHookSpecificOutput as SDKCwdChangedHookSpecificOutput, ElicitationHookSpecificOutput as SDKElicitationHookSpecificOutput, ElicitationResultHookSpecificOutput as SDKElicitationResultHookSpecificOutput, FileChangedHookSpecificOutput as SDKFileChangedHookSpecificOutput } from "@anthropic-ai/claude-agent-sdk";
11
11
  import type { NotificationHookSpecificOutput as SDKNotificationHookSpecificOutput, PermissionRequestHookSpecificOutput as SDKPermissionRequestHookSpecificOutput, PostToolUseFailureHookSpecificOutput as SDKPostToolUseFailureHookSpecificOutput, PostToolUseHookSpecificOutput as SDKPostToolUseHookSpecificOutput, PreToolUseHookSpecificOutput as SDKPreToolUseHookSpecificOutput, SessionStartHookSpecificOutput as SDKSessionStartHookSpecificOutput, SetupHookSpecificOutput as SDKSetupHookSpecificOutput, SubagentStartHookSpecificOutput as SDKSubagentStartHookSpecificOutput, SyncHookJSONOutput as SDKSyncHookJSONOutput, UserPromptSubmitHookSpecificOutput as SDKUserPromptSubmitHookSpecificOutput } from "@anthropic-ai/claude-agent-sdk/sdk.js";
12
12
  /**
13
13
  * Exit codes used by Claude Code hooks.
@@ -33,11 +33,10 @@ export type ExitCode = (typeof EXIT_CODES)[keyof typeof EXIT_CODES];
33
33
  /**
34
34
  * Re-export the SDK's SyncHookJSONOutput type.
35
35
  */
36
- export type { SDKSyncHookJSONOutput };
37
36
  /**
38
37
  * Re-export SDK hook-specific output types (includes hookEventName discriminator).
39
38
  */
40
- export type { SDKElicitationHookSpecificOutput, SDKElicitationResultHookSpecificOutput, SDKNotificationHookSpecificOutput, SDKPreToolUseHookSpecificOutput, SDKPostToolUseHookSpecificOutput, SDKPostToolUseFailureHookSpecificOutput, SDKUserPromptSubmitHookSpecificOutput, SDKSessionStartHookSpecificOutput, SDKSetupHookSpecificOutput, SDKSubagentStartHookSpecificOutput, SDKPermissionRequestHookSpecificOutput, };
39
+ export type { SDKCwdChangedHookSpecificOutput, SDKElicitationHookSpecificOutput, SDKElicitationResultHookSpecificOutput, SDKFileChangedHookSpecificOutput, SDKNotificationHookSpecificOutput, SDKPermissionRequestHookSpecificOutput, SDKPostToolUseFailureHookSpecificOutput, SDKPostToolUseHookSpecificOutput, SDKPreToolUseHookSpecificOutput, SDKSessionStartHookSpecificOutput, SDKSetupHookSpecificOutput, SDKSubagentStartHookSpecificOutput, SDKSyncHookJSONOutput, SDKUserPromptSubmitHookSpecificOutput, };
41
40
  /**
42
41
  * PreToolUse hook-specific output fields.
43
42
  * Omits `hookEventName` which is added automatically by the builder.
@@ -112,10 +111,20 @@ export type PermissionRequestDecision = SDKPermissionRequestHookSpecificOutput["
112
111
  * Omits `hookEventName` which is added automatically by the builder.
113
112
  */
114
113
  export type NotificationHookSpecificOutput = Omit<SDKNotificationHookSpecificOutput, "hookEventName">;
114
+ /**
115
+ * CwdChanged hook-specific output fields.
116
+ * Omits `hookEventName` which is added automatically by the builder.
117
+ */
118
+ export type CwdChangedHookSpecificOutput = Omit<SDKCwdChangedHookSpecificOutput, "hookEventName">;
119
+ /**
120
+ * FileChanged hook-specific output fields.
121
+ * Omits `hookEventName` which is added automatically by the builder.
122
+ */
123
+ export type FileChangedHookSpecificOutput = Omit<SDKFileChangedHookSpecificOutput, "hookEventName">;
115
124
  /**
116
125
  * Full hook-specific output with hookEventName discriminator.
117
126
  */
118
- export type HookSpecificOutput = SDKPreToolUseHookSpecificOutput | SDKPostToolUseHookSpecificOutput | SDKPostToolUseFailureHookSpecificOutput | SDKUserPromptSubmitHookSpecificOutput | SDKSessionStartHookSpecificOutput | SDKSetupHookSpecificOutput | SDKSubagentStartHookSpecificOutput | SDKPermissionRequestHookSpecificOutput | SDKNotificationHookSpecificOutput | SDKElicitationHookSpecificOutput | SDKElicitationResultHookSpecificOutput;
127
+ export type HookSpecificOutput = SDKPreToolUseHookSpecificOutput | SDKPostToolUseHookSpecificOutput | SDKPostToolUseFailureHookSpecificOutput | SDKUserPromptSubmitHookSpecificOutput | SDKSessionStartHookSpecificOutput | SDKSetupHookSpecificOutput | SDKSubagentStartHookSpecificOutput | SDKPermissionRequestHookSpecificOutput | SDKNotificationHookSpecificOutput | SDKElicitationHookSpecificOutput | SDKElicitationResultHookSpecificOutput | SDKCwdChangedHookSpecificOutput | SDKFileChangedHookSpecificOutput;
119
128
  /**
120
129
  * The JSON output format expected by Claude Code (sync hooks only).
121
130
  * Extends SDK's SyncHookJSONOutput to include Notification hook support.
@@ -211,6 +220,10 @@ export type SessionEndOutput = BaseSpecificOutput<"SessionEnd">;
211
220
  *
212
221
  */
213
222
  export type StopOutput = BaseSpecificOutput<"Stop">;
223
+ /**
224
+ *
225
+ */
226
+ export type StopFailureOutput = BaseSpecificOutput<"StopFailure">;
214
227
  /**
215
228
  *
216
229
  */
@@ -223,6 +236,10 @@ export type SubagentStopOutput = BaseSpecificOutput<"SubagentStop">;
223
236
  *
224
237
  */
225
238
  export type PreCompactOutput = BaseSpecificOutput<"PreCompact">;
239
+ /**
240
+ *
241
+ */
242
+ export type PostCompactOutput = BaseSpecificOutput<"PostCompact">;
226
243
  /**
227
244
  *
228
245
  */
@@ -263,10 +280,18 @@ export type WorktreeCreateOutput = BaseSpecificOutput<"WorktreeCreate">;
263
280
  *
264
281
  */
265
282
  export type WorktreeRemoveOutput = BaseSpecificOutput<"WorktreeRemove">;
283
+ /**
284
+ *
285
+ */
286
+ export type CwdChangedOutput = BaseSpecificOutput<"CwdChanged">;
287
+ /**
288
+ *
289
+ */
290
+ export type FileChangedOutput = BaseSpecificOutput<"FileChanged">;
266
291
  /**
267
292
  * Union of all specific output types.
268
293
  */
269
- export type SpecificHookOutput = PreToolUseOutput | PostToolUseOutput | PostToolUseFailureOutput | NotificationOutput | UserPromptSubmitOutput | SessionStartOutput | SessionEndOutput | StopOutput | SubagentStartOutput | SubagentStopOutput | PreCompactOutput | PermissionRequestOutput | SetupOutput | TeammateIdleOutput | TaskCompletedOutput | ElicitationOutput | ElicitationResultOutput | ConfigChangeOutput | InstructionsLoadedOutput | WorktreeCreateOutput | WorktreeRemoveOutput;
294
+ export type SpecificHookOutput = PreToolUseOutput | PostToolUseOutput | PostToolUseFailureOutput | NotificationOutput | UserPromptSubmitOutput | SessionStartOutput | SessionEndOutput | StopOutput | StopFailureOutput | SubagentStartOutput | SubagentStopOutput | PreCompactOutput | PostCompactOutput | PermissionRequestOutput | SetupOutput | TeammateIdleOutput | TaskCompletedOutput | ElicitationOutput | ElicitationResultOutput | ConfigChangeOutput | InstructionsLoadedOutput | WorktreeCreateOutput | WorktreeRemoveOutput | CwdChangedOutput | FileChangedOutput;
270
295
  /**
271
296
  * Options for decision-based hooks (Stop, SubagentStop).
272
297
  */
@@ -470,6 +495,24 @@ export declare const stopOutput: (options?: DecisionOptions) => {
470
495
  readonly _type: "Stop";
471
496
  stdout: SyncHookJSONOutput;
472
497
  };
498
+ /**
499
+ * Options for the StopFailure output builder.
500
+ * StopFailure hooks only support common options.
501
+ */
502
+ export type StopFailureOptions = CommonOptions;
503
+ /**
504
+ * Creates an output for StopFailure hooks.
505
+ * @param options - Configuration options for the hook output
506
+ * @returns A StopFailureOutput object ready for the runtime
507
+ * @example
508
+ * ```typescript
509
+ * stopFailureOutput({});
510
+ * ```
511
+ */
512
+ export declare const stopFailureOutput: (options?: CommonOptions) => {
513
+ readonly _type: "StopFailure";
514
+ stdout: SyncHookJSONOutput;
515
+ };
473
516
  /**
474
517
  * Options for the SubagentStart output builder.
475
518
  */
@@ -572,6 +615,24 @@ export declare const preCompactOutput: (options?: CommonOptions) => {
572
615
  readonly _type: "PreCompact";
573
616
  stdout: SyncHookJSONOutput;
574
617
  };
618
+ /**
619
+ * Options for the PostCompact output builder.
620
+ * PostCompact hooks only support common options.
621
+ */
622
+ export type PostCompactOptions = CommonOptions;
623
+ /**
624
+ * Creates an output for PostCompact hooks.
625
+ * @param options - Configuration options for the hook output
626
+ * @returns A PostCompactOutput object ready for the runtime
627
+ * @example
628
+ * ```typescript
629
+ * postCompactOutput({});
630
+ * ```
631
+ */
632
+ export declare const postCompactOutput: (options?: CommonOptions) => {
633
+ readonly _type: "PostCompact";
634
+ stdout: SyncHookJSONOutput;
635
+ };
575
636
  /**
576
637
  * Options for the PermissionRequest output builder.
577
638
  */
@@ -823,6 +884,66 @@ export declare const worktreeRemoveOutput: (options?: CommonOptions) => {
823
884
  readonly _type: "WorktreeRemove";
824
885
  stdout: SyncHookJSONOutput;
825
886
  };
887
+ /**
888
+ * Options for the CwdChanged output builder.
889
+ */
890
+ export type CwdChangedOptions = CommonOptions & {
891
+ /** Hook-specific output matching the wire format. */
892
+ hookSpecificOutput?: CwdChangedHookSpecificOutput;
893
+ };
894
+ /**
895
+ * Creates an output for CwdChanged hooks.
896
+ * @param options - Configuration options for the hook output
897
+ * @returns A CwdChangedOutput object ready for the runtime
898
+ * @example
899
+ * ```typescript
900
+ * // Return additional paths to watch after the cwd change
901
+ * cwdChangedOutput({
902
+ * hookSpecificOutput: {
903
+ * watchPaths: ['/new/path/to/watch']
904
+ * }
905
+ * });
906
+ *
907
+ * // Simple passthrough
908
+ * cwdChangedOutput({});
909
+ * ```
910
+ */
911
+ export declare const cwdChangedOutput: (options?: CommonOptions & {
912
+ hookSpecificOutput?: CwdChangedHookSpecificOutput | undefined;
913
+ }) => {
914
+ readonly _type: "CwdChanged";
915
+ stdout: SyncHookJSONOutput;
916
+ };
917
+ /**
918
+ * Options for the FileChanged output builder.
919
+ */
920
+ export type FileChangedOptions = CommonOptions & {
921
+ /** Hook-specific output matching the wire format. */
922
+ hookSpecificOutput?: FileChangedHookSpecificOutput;
923
+ };
924
+ /**
925
+ * Creates an output for FileChanged hooks.
926
+ * @param options - Configuration options for the hook output
927
+ * @returns A FileChangedOutput object ready for the runtime
928
+ * @example
929
+ * ```typescript
930
+ * // Update the set of watched paths
931
+ * fileChangedOutput({
932
+ * hookSpecificOutput: {
933
+ * watchPaths: ['/path/to/watch', '/another/path']
934
+ * }
935
+ * });
936
+ *
937
+ * // Simple passthrough
938
+ * fileChangedOutput({});
939
+ * ```
940
+ */
941
+ export declare const fileChangedOutput: (options?: CommonOptions & {
942
+ hookSpecificOutput?: FileChangedHookSpecificOutput | undefined;
943
+ }) => {
944
+ readonly _type: "FileChanged";
945
+ stdout: SyncHookJSONOutput;
946
+ };
826
947
  /**
827
948
  * @deprecated Use CommonOptions instead
828
949
  */
package/types/types.d.ts CHANGED
@@ -12,8 +12,8 @@
12
12
  * Re-exports types from @anthropic-ai/claude-agent-sdk with "SDK" prefix.
13
13
  * These are used as base types for extension, ensuring synchronization with the SDK.
14
14
  */
15
- export type { BaseHookInput as SDKBaseHookInput, ConfigChangeHookInput as SDKConfigChangeHookInput, ElicitationHookInput as SDKElicitationHookInput, ElicitationResultHookInput as SDKElicitationResultHookInput, HookEvent as SDKHookEvent, HookInput as SDKHookInput, InstructionsLoadedHookInput as SDKInstructionsLoadedHookInput, NotificationHookInput as SDKNotificationHookInput, PermissionMode as SDKPermissionMode, PermissionRequestHookInput as SDKPermissionRequestHookInput, PermissionUpdate as SDKPermissionUpdate, PostToolUseFailureHookInput as SDKPostToolUseFailureHookInput, PostToolUseHookInput as SDKPostToolUseHookInput, PreCompactHookInput as SDKPreCompactHookInput, PreToolUseHookInput as SDKPreToolUseHookInput, SessionEndHookInput as SDKSessionEndHookInput, SessionStartHookInput as SDKSessionStartHookInput, SetupHookInput as SDKSetupHookInput, StopHookInput as SDKStopHookInput, SubagentStartHookInput as SDKSubagentStartHookInput, SubagentStopHookInput as SDKSubagentStopHookInput, TaskCompletedHookInput as SDKTaskCompletedHookInput, TeammateIdleHookInput as SDKTeammateIdleHookInput, UserPromptSubmitHookInput as SDKUserPromptSubmitHookInput, WorktreeCreateHookInput as SDKWorktreeCreateHookInput, WorktreeRemoveHookInput as SDKWorktreeRemoveHookInput, } from "@anthropic-ai/claude-agent-sdk";
16
- import type { BaseHookInput as SDKBaseHookInput, ConfigChangeHookInput as SDKConfigChangeHookInput, ElicitationHookInput as SDKElicitationHookInput, ElicitationResultHookInput as SDKElicitationResultHookInput, InstructionsLoadedHookInput as SDKInstructionsLoadedHookInput, NotificationHookInput as SDKNotificationHookInput, PermissionMode as SDKPermissionMode, PermissionRequestHookInput as SDKPermissionRequestHookInput, PermissionUpdate as SDKPermissionUpdate, PostToolUseFailureHookInput as SDKPostToolUseFailureHookInput, PostToolUseHookInput as SDKPostToolUseHookInput, PreCompactHookInput as SDKPreCompactHookInput, PreToolUseHookInput as SDKPreToolUseHookInput, SessionEndHookInput as SDKSessionEndHookInput, SessionStartHookInput as SDKSessionStartHookInput, SetupHookInput as SDKSetupHookInput, StopHookInput as SDKStopHookInput, SubagentStartHookInput as SDKSubagentStartHookInput, SubagentStopHookInput as SDKSubagentStopHookInput, TaskCompletedHookInput as SDKTaskCompletedHookInput, TeammateIdleHookInput as SDKTeammateIdleHookInput, UserPromptSubmitHookInput as SDKUserPromptSubmitHookInput, WorktreeCreateHookInput as SDKWorktreeCreateHookInput, WorktreeRemoveHookInput as SDKWorktreeRemoveHookInput } from "@anthropic-ai/claude-agent-sdk";
15
+ export type { BaseHookInput as SDKBaseHookInput, ConfigChangeHookInput as SDKConfigChangeHookInput, CwdChangedHookInput as SDKCwdChangedHookInput, ElicitationHookInput as SDKElicitationHookInput, ElicitationResultHookInput as SDKElicitationResultHookInput, FileChangedHookInput as SDKFileChangedHookInput, HookEvent as SDKHookEvent, HookInput as SDKHookInput, InstructionsLoadedHookInput as SDKInstructionsLoadedHookInput, NotificationHookInput as SDKNotificationHookInput, PermissionMode as SDKPermissionMode, PermissionRequestHookInput as SDKPermissionRequestHookInput, PermissionUpdate as SDKPermissionUpdate, PostCompactHookInput as SDKPostCompactHookInput, PostToolUseFailureHookInput as SDKPostToolUseFailureHookInput, PostToolUseHookInput as SDKPostToolUseHookInput, PreCompactHookInput as SDKPreCompactHookInput, PreToolUseHookInput as SDKPreToolUseHookInput, SessionEndHookInput as SDKSessionEndHookInput, SessionStartHookInput as SDKSessionStartHookInput, SetupHookInput as SDKSetupHookInput, StopFailureHookInput as SDKStopFailureHookInput, StopHookInput as SDKStopHookInput, SubagentStartHookInput as SDKSubagentStartHookInput, SubagentStopHookInput as SDKSubagentStopHookInput, TaskCompletedHookInput as SDKTaskCompletedHookInput, TeammateIdleHookInput as SDKTeammateIdleHookInput, UserPromptSubmitHookInput as SDKUserPromptSubmitHookInput, WorktreeCreateHookInput as SDKWorktreeCreateHookInput, WorktreeRemoveHookInput as SDKWorktreeRemoveHookInput, } from "@anthropic-ai/claude-agent-sdk";
16
+ import type { BaseHookInput as SDKBaseHookInput, ConfigChangeHookInput as SDKConfigChangeHookInput, CwdChangedHookInput as SDKCwdChangedHookInput, ElicitationHookInput as SDKElicitationHookInput, ElicitationResultHookInput as SDKElicitationResultHookInput, FileChangedHookInput as SDKFileChangedHookInput, InstructionsLoadedHookInput as SDKInstructionsLoadedHookInput, NotificationHookInput as SDKNotificationHookInput, PermissionMode as SDKPermissionMode, PermissionRequestHookInput as SDKPermissionRequestHookInput, PermissionUpdate as SDKPermissionUpdate, PostCompactHookInput as SDKPostCompactHookInput, PostToolUseFailureHookInput as SDKPostToolUseFailureHookInput, PostToolUseHookInput as SDKPostToolUseHookInput, PreCompactHookInput as SDKPreCompactHookInput, PreToolUseHookInput as SDKPreToolUseHookInput, SessionEndHookInput as SDKSessionEndHookInput, SessionStartHookInput as SDKSessionStartHookInput, SetupHookInput as SDKSetupHookInput, StopFailureHookInput as SDKStopFailureHookInput, StopHookInput as SDKStopHookInput, SubagentStartHookInput as SDKSubagentStartHookInput, SubagentStopHookInput as SDKSubagentStopHookInput, TaskCompletedHookInput as SDKTaskCompletedHookInput, TeammateIdleHookInput as SDKTeammateIdleHookInput, UserPromptSubmitHookInput as SDKUserPromptSubmitHookInput, WorktreeCreateHookInput as SDKWorktreeCreateHookInput, WorktreeRemoveHookInput as SDKWorktreeRemoveHookInput } from "@anthropic-ai/claude-agent-sdk";
17
17
  import type { AgentInput, AskUserQuestionInput, BashInput, ConfigInput, ExitPlanModeInput, FileEditInput, FileReadInput, FileWriteInput, GlobInput, GrepInput, TaskStopInput as KillShellInput, ListMcpResourcesInput, McpInput, NotebookEditInput, ReadMcpResourceInput, TaskOutputInput, TodoWriteInput, WebFetchInput, WebSearchInput } from "@anthropic-ai/claude-agent-sdk/sdk-tools.js";
18
18
  /**
19
19
  * Permission mode for controlling how tool executions are handled.
@@ -42,6 +42,7 @@ export type PreCompactTrigger = "manual" | "auto";
42
42
  * Reason for session end events.
43
43
  *
44
44
  * - `'clear'` - Session cleared by user
45
+ * - `'resume'` - Session resumed from a previous session
45
46
  * - `'logout'` - User logged out
46
47
  * - `'prompt_input_exit'` - User exited at prompt input
47
48
  * - `'other'` - Other reasons
@@ -49,7 +50,7 @@ export type PreCompactTrigger = "manual" | "auto";
49
50
  *
50
51
  * Note: SDK's ExitReason resolves to string. This type provides concrete literals for better DX.
51
52
  */
52
- export type SessionEndReason = "clear" | "logout" | "prompt_input_exit" | "other" | "bypass_permissions_disabled";
53
+ export type SessionEndReason = "clear" | "resume" | "logout" | "prompt_input_exit" | "other" | "bypass_permissions_disabled";
53
54
  /**
54
55
  * Common fields present in all hook inputs.
55
56
  *
@@ -123,6 +124,18 @@ export type SessionStartInput = {
123
124
  export type StopInput = {
124
125
  [K in keyof SDKStopHookInput]: SDKStopHookInput[K];
125
126
  } & {};
127
+ /**
128
+ * Input for StopFailure hooks.
129
+ *
130
+ * Fires when Claude Code encounters an error while stopping (e.g., API errors,
131
+ * rate limits, authentication failures), allowing you to:
132
+ * - Log stop failure events and error details
133
+ * - Alert on unexpected session termination errors
134
+ * @see https://code.claude.com/docs/en/hooks#stopfailure
135
+ */
136
+ export type StopFailureInput = {
137
+ [K in keyof SDKStopFailureHookInput]: SDKStopFailureHookInput[K];
138
+ } & {};
126
139
  /**
127
140
  * Input for SubagentStart hooks.
128
141
  * @see https://code.claude.com/docs/en/hooks#subagentstart
@@ -144,6 +157,18 @@ export type SubagentStopInput = {
144
157
  export type PreCompactInput = {
145
158
  [K in keyof SDKPreCompactHookInput]: SDKPreCompactHookInput[K];
146
159
  } & {};
160
+ /**
161
+ * Input for PostCompact hooks.
162
+ *
163
+ * Fires after context compaction completes, allowing you to:
164
+ * - Observe the compaction summary
165
+ * - Log compaction events with context details
166
+ * - React to the new compacted state
167
+ * @see https://code.claude.com/docs/en/hooks#postcompact
168
+ */
169
+ export type PostCompactInput = {
170
+ [K in keyof SDKPostCompactHookInput]: SDKPostCompactHookInput[K];
171
+ } & {};
147
172
  /**
148
173
  * Input for Setup hooks.
149
174
  * @see https://code.claude.com/docs/en/hooks#setup
@@ -233,6 +258,35 @@ export type WorktreeCreateInput = {
233
258
  export type WorktreeRemoveInput = {
234
259
  [K in keyof SDKWorktreeRemoveHookInput]: SDKWorktreeRemoveHookInput[K];
235
260
  } & {};
261
+ /**
262
+ * Input for CwdChanged hooks.
263
+ *
264
+ * Fires when Claude Code's current working directory changes, allowing you to:
265
+ * - React to directory changes within a session
266
+ * - Update file watchers or environment state
267
+ * - Return `watchPaths` to register paths for FileChanged events
268
+ * @see https://code.claude.com/docs/en/hooks#cwdchanged
269
+ */
270
+ export type CwdChangedInput = {
271
+ [K in keyof SDKCwdChangedHookInput]: SDKCwdChangedHookInput[K];
272
+ } & {};
273
+ /**
274
+ * Input for FileChanged hooks.
275
+ *
276
+ * Fires when a watched file changes on disk, allowing you to:
277
+ * - React to file system changes during a session
278
+ * - Invalidate caches or reload configuration
279
+ * - Return `watchPaths` to update the set of watched paths
280
+ *
281
+ * The `event` field indicates the type of change:
282
+ * - `'change'` - File contents changed
283
+ * - `'add'` - File was created
284
+ * - `'unlink'` - File was deleted
285
+ * @see https://code.claude.com/docs/en/hooks#filechanged
286
+ */
287
+ export type FileChangedInput = {
288
+ [K in keyof SDKFileChangedHookInput]: SDKFileChangedHookInput[K];
289
+ } & {};
236
290
  /**
237
291
  * Input for SessionEnd hooks.
238
292
  *
@@ -327,7 +381,7 @@ export type SetupTrigger = "init" | "maintenance";
327
381
  * ```
328
382
  * @see https://code.claude.com/docs/en/hooks
329
383
  */
330
- export type HookInput = PreToolUseInput | PostToolUseInput | PostToolUseFailureInput | NotificationInput | UserPromptSubmitInput | SessionStartInput | SessionEndInput | StopInput | SubagentStartInput | SubagentStopInput | PreCompactInput | PermissionRequestInput | SetupInput | TeammateIdleInput | TaskCompletedInput | ElicitationInput | ElicitationResultInput | ConfigChangeInput | InstructionsLoadedInput | WorktreeCreateInput | WorktreeRemoveInput;
384
+ export type HookInput = PreToolUseInput | PostToolUseInput | PostToolUseFailureInput | NotificationInput | UserPromptSubmitInput | SessionStartInput | SessionEndInput | StopInput | StopFailureInput | SubagentStartInput | SubagentStopInput | PreCompactInput | PostCompactInput | PermissionRequestInput | SetupInput | TeammateIdleInput | TaskCompletedInput | ElicitationInput | ElicitationResultInput | ConfigChangeInput | InstructionsLoadedInput | WorktreeCreateInput | WorktreeRemoveInput | CwdChangedInput | FileChangedInput;
331
385
  /**
332
386
  * Hook event name literal union.
333
387
  *
@@ -345,7 +399,7 @@ export type HookEventName = HookInput["hook_event_name"];
345
399
  * }
346
400
  * ```
347
401
  */
348
- export declare const HOOK_EVENT_NAMES: readonly ["PreToolUse", "PostToolUse", "PostToolUseFailure", "Notification", "UserPromptSubmit", "SessionStart", "SessionEnd", "Stop", "SubagentStart", "SubagentStop", "PreCompact", "PermissionRequest", "Setup", "TeammateIdle", "TaskCompleted", "Elicitation", "ElicitationResult", "ConfigChange", "InstructionsLoaded", "WorktreeCreate", "WorktreeRemove"];
402
+ export declare const HOOK_EVENT_NAMES: readonly ["PreToolUse", "PostToolUse", "PostToolUseFailure", "Notification", "UserPromptSubmit", "SessionStart", "SessionEnd", "Stop", "StopFailure", "SubagentStart", "SubagentStop", "PreCompact", "PostCompact", "PermissionRequest", "Setup", "TeammateIdle", "TaskCompleted", "Elicitation", "ElicitationResult", "ConfigChange", "InstructionsLoaded", "WorktreeCreate", "WorktreeRemove", "CwdChanged", "FileChanged"];
349
403
  export type { SDKPermissionUpdate as PermissionUpdate };
350
404
  /**
351
405
  * Re-export all tool input types from the official Claude Agent SDK.