From 7554503b420cd03a97947929d5f27d4241a54d7f Mon Sep 17 00:00:00 2001 From: Tibsfox Date: Tue, 3 Mar 2026 03:04:27 -0800 Subject: [PATCH] fix(hooks): add stdin timeout guard to prevent hook errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The context monitor and statusline hooks wait for stdin 'end' event before processing. On some platforms (Windows/Git Bash), the stdin pipe may not close cleanly, causing the script to hang until Claude Code's hook timeout kills it — surfacing as "PostToolUse:Read hook error" after every tool call. Add a 3-second timeout that exits silently if stdin doesn't complete, preventing the noisy error messages. Closes #775 Co-Authored-By: Claude Opus 4.6 --- hooks/gsd-context-monitor.js | 5 +++++ hooks/gsd-statusline.js | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/hooks/gsd-context-monitor.js b/hooks/gsd-context-monitor.js index cae8fc930..c3f5630c3 100644 --- a/hooks/gsd-context-monitor.js +++ b/hooks/gsd-context-monitor.js @@ -27,9 +27,14 @@ const STALE_SECONDS = 60; // ignore metrics older than 60s const DEBOUNCE_CALLS = 5; // min tool uses between warnings let input = ''; +// Timeout guard: if stdin doesn't close within 3s (e.g. pipe issues on +// Windows/Git Bash), exit silently instead of hanging until Claude Code +// kills the process and reports "hook error". See #775. +const stdinTimeout = setTimeout(() => process.exit(0), 3000); process.stdin.setEncoding('utf8'); process.stdin.on('data', chunk => input += chunk); process.stdin.on('end', () => { + clearTimeout(stdinTimeout); try { const data = JSON.parse(input); const sessionId = data.session_id; diff --git a/hooks/gsd-statusline.js b/hooks/gsd-statusline.js index dfc03fa3d..9d3fb5b59 100755 --- a/hooks/gsd-statusline.js +++ b/hooks/gsd-statusline.js @@ -8,9 +8,13 @@ const os = require('os'); // Read JSON from stdin let input = ''; +// Timeout guard: if stdin doesn't close within 3s (e.g. pipe issues on +// Windows/Git Bash), exit silently instead of hanging. See #775. +const stdinTimeout = setTimeout(() => process.exit(0), 3000); process.stdin.setEncoding('utf8'); process.stdin.on('data', chunk => input += chunk); process.stdin.on('end', () => { + clearTimeout(stdinTimeout); try { const data = JSON.parse(input); const model = data.model?.display_name || 'Claude';