From 9a523996300de4efb6387ab67a4bc19d4a0dbd42 Mon Sep 17 00:00:00 2001 From: shahyashish <95119920+shahyashish@users.noreply.github.com> Date: Wed, 15 Apr 2026 08:40:12 +0530 Subject: [PATCH] =?UTF-8?q?Fix=20issue=20#1435:=20fix(hooks):=20GateGuard?= =?UTF-8?q?=20permanently=20blocks=20all=20operations=20on=20Windows=20?= =?UTF-8?q?=E2=80=94=20fs.renameSync=20EEXIST=20not=20handled?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/hooks/gateguard-fact-force.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/scripts/hooks/gateguard-fact-force.js b/scripts/hooks/gateguard-fact-force.js index b8a0fcc8e2..1d982b2be0 100644 --- a/scripts/hooks/gateguard-fact-force.js +++ b/scripts/hooks/gateguard-fact-force.js @@ -27,9 +27,9 @@ const fs = require('fs'); const path = require('path'); // Session state — scoped per session to avoid cross-session races. -// Uses CLAUDE_SESSION_ID (set by Claude Code) or falls back to PID-based isolation. +// Uses CLAUDE_SESSION_ID (set by Claude Code) or falls back to stable CWD-based isolation. const STATE_DIR = process.env.GATEGUARD_STATE_DIR || path.join(process.env.HOME || process.env.USERPROFILE || '/tmp', '.gateguard'); -const SESSION_ID = process.env.CLAUDE_SESSION_ID || process.env.ECC_SESSION_ID || `pid-${process.ppid || process.pid}`; +const SESSION_ID = process.env.CLAUDE_SESSION_ID || process.env.ECC_SESSION_ID || `cwd-${crypto.createHash('sha256').update(process.cwd()).digest('hex').slice(0, 16)}`; const STATE_FILE = path.join(STATE_DIR, `state-${SESSION_ID.replace(/[^a-zA-Z0-9_-]/g, '_')}.json`); // State expires after 30 minutes of inactivity @@ -82,6 +82,9 @@ function saveState(state) { // Atomic write: temp file + rename prevents partial reads const tmpFile = STATE_FILE + '.tmp.' + process.pid; fs.writeFileSync(tmpFile, JSON.stringify(state, null, 2), 'utf8'); + // On Windows, fs.renameSync throws EEXIST if the destination exists. + // Unlink first to ensure cross-platform replacement. + try { fs.unlinkSync(STATE_FILE); } catch (_) { /* ignore if not exists */ } fs.renameSync(tmpFile, STATE_FILE); } catch (_) { /* ignore */ } }