From 00bc7f30beb9e71e3f3eea831fa7ca0dc526e52e Mon Sep 17 00:00:00 2001 From: Affaan Mustafa Date: Wed, 25 Mar 2026 01:34:29 -0400 Subject: [PATCH] fix: resolve blocker PR validation regressions --- hooks/hooks.json | 2 +- scripts/lib/utils.js | 2 +- tests/hooks/governance-capture.test.js | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hooks/hooks.json b/hooks/hooks.json index c66a9f4c..56da376b 100644 --- a/hooks/hooks.json +++ b/hooks/hooks.json @@ -136,7 +136,7 @@ "hooks": [ { "type": "command", - "command": "node -e \"const fs=require('fs');const path=require('path');const {spawnSync}=require('child_process');const raw=fs.readFileSync(0,'utf8');const root=(()=>{const envRoot=process.env.CLAUDE_PLUGIN_ROOT||'';if(envRoot.trim())return envRoot.trim();const home=require('os').homedir();const claudeDir=path.join(home,'.claude');const probe=path.join('scripts','lib','utils.js');if(fs.existsSync(path.join(claudeDir,probe)))return claudeDir;for(const candidate of [path.join(claudeDir,'plugins','everything-claude-code'),path.join(claudeDir,'plugins','everything-claude-code@everything-claude-code'),path.join(claudeDir,'plugins','marketplace','everything-claude-code')]){if(fs.existsSync(path.join(candidate,probe)))return candidate;}try{const cacheBase=path.join(claudeDir,'plugins','cache','everything-claude-code');for(const org of fs.readdirSync(cacheBase,{withFileTypes:true})){if(!org.isDirectory())continue;for(const version of fs.readdirSync(path.join(cacheBase,org.name),{withFileTypes:true})){if(!version.isDirectory())continue;const candidate=path.join(cacheBase,org.name,version.name);if(fs.existsSync(path.join(candidate,probe)))return candidate;}}}catch{}return claudeDir;})();const script=path.join(root,'scripts','hooks','run-with-flags.js');if(fs.existsSync(script)){const result=spawnSync(process.execPath,[script,'session:start','scripts/hooks/session-start.js','minimal,standard,strict'],{input:raw,encoding:'utf8',env:process.env,cwd:process.cwd(),timeout:30000});if(result.stdout)process.stdout.write(result.stdout);if(result.stderr)process.stderr.write(result.stderr);process.exit(Number.isInteger(result.status)?result.status:0);}process.stderr.write('[SessionStart] WARNING: could not resolve ECC plugin root; skipping session-start hook\\n');process.stdout.write(raw);\"" + "command": "node -e \"const fs=require('fs');const path=require('path');const {spawnSync}=require('child_process');const raw=fs.readFileSync(0,'utf8');const root=(()=>{const envRoot=process.env.CLAUDE_PLUGIN_ROOT||'';if(envRoot.trim())return envRoot.trim();const home=require('os').homedir();const claudeDir=path.join(home,'.claude');const probe=path.join('scripts','lib','utils.js');if(fs.existsSync(path.join(claudeDir,probe)))return claudeDir;for(const candidate of [path.join(claudeDir,'plugins','everything-claude-code'),path.join(claudeDir,'plugins','everything-claude-code@everything-claude-code'),path.join(claudeDir,'plugins','marketplace','everything-claude-code')]){if(fs.existsSync(path.join(candidate,probe)))return candidate;}try{const cacheBase=path.join(claudeDir,'plugins','cache','everything-claude-code');for(const org of fs.readdirSync(cacheBase,{withFileTypes:true})){if(!org.isDirectory())continue;for(const version of fs.readdirSync(path.join(cacheBase,org.name),{withFileTypes:true})){if(!version.isDirectory())continue;const candidate=path.join(cacheBase,org.name,version.name);if(fs.existsSync(path.join(candidate,probe)))return candidate;}}}catch{}return claudeDir;})();const script=path.join(root,'scripts','hooks','run-with-flags.js');if(fs.existsSync(script)){const result=spawnSync(process.execPath,[script,'session:start','scripts/hooks/session-start.js','minimal,standard,strict'],{input:raw,encoding:'utf8',env:process.env,cwd:process.cwd(),timeout:30000});if(result.stdout)process.stdout.write(result.stdout);if(result.stderr)process.stderr.write(result.stderr);process.exit(Number.isInteger(result.status)?result.status:0);}process.stderr.write('[SessionStart] WARNING: could not resolve ECC plugin root; skipping session-start hook'+String.fromCharCode(10));process.stdout.write(raw);\"" } ], "description": "Load previous context and detect package manager on new session" diff --git a/scripts/lib/utils.js b/scripts/lib/utils.js index e41b244c..9f0b175e 100644 --- a/scripts/lib/utils.js +++ b/scripts/lib/utils.js @@ -135,7 +135,7 @@ function getProjectName() { function sanitizeSessionId(raw) { if (!raw || typeof raw !== 'string') return null; - const hasNonAscii = /[^\x00-\x7F]/.test(raw); + const hasNonAscii = Array.from(raw).some(char => char.codePointAt(0) > 0x7f); const normalized = raw.replace(/^\.+/, ''); const sanitized = normalized .replace(/[^a-zA-Z0-9_-]/g, '-') diff --git a/tests/hooks/governance-capture.test.js b/tests/hooks/governance-capture.test.js index 1618e594..df118594 100644 --- a/tests/hooks/governance-capture.test.js +++ b/tests/hooks/governance-capture.test.js @@ -335,8 +335,8 @@ async function runTests() { } const combined = stderr.join(''); - assert.ok(combined.includes('\"eventType\":\"hook_input_truncated\"'), 'Should emit truncation event'); - assert.ok(combined.includes('\"sizeLimitBytes\":1024'), 'Should record the truncation limit'); + assert.ok(combined.includes('"eventType":"hook_input_truncated"'), 'Should emit truncation event'); + assert.ok(combined.includes('"sizeLimitBytes":1024'), 'Should record the truncation limit'); assert.ok(!combined.includes('rm -rf /tmp/important'), 'Should not leak raw command text to governance logs'); })) passed += 1; else failed += 1; if (await test('run() can detect multiple event types in one input', async () => {