perf(#317): collapse redundant existsSync+readFileSync in context-monitor hook (#400)

Per-PostToolUse hot path did stat-then-read ×3 (config.json, metrics bridge,
warn sentinel); collapsed to read-with-ENOENT-catch (fewer blocking syscalls,
no TOCTOU), behavior identical. Fixes #317.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Tom Boucher
2026-05-27 20:21:55 -04:00
committed by GitHub
parent 1868947088
commit ee820442e6
3 changed files with 311 additions and 23 deletions

View File

@@ -54,30 +54,33 @@ process.stdin.on('end', () => {
}
// Check if context warnings are disabled via config.
// Quick sentinel check: skip config read entirely for non-GSD projects (#P2.5).
// Collapsed existsSync+readFileSync into a single read guarded by try/catch
// (ENOENT or parse error → use defaults, same as old "planningDir absent" branch).
const cwd = data.cwd || process.cwd();
const planningDir = path.join(cwd, '.planning');
if (fs.existsSync(planningDir)) {
try {
const configPath = path.join(planningDir, 'config.json');
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
if (config.hooks?.context_warnings === false) {
process.exit(0);
}
} catch (e) {
// Ignore config read/parse errors (config may not exist in .planning/)
try {
const configPath = path.join(cwd, '.planning', 'config.json');
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
if (config.hooks?.context_warnings === false) {
process.exit(0);
}
} catch (e) {
// Missing or unparseable config → proceed with defaults (context warnings enabled)
}
const tmpDir = os.tmpdir();
const metricsPath = path.join(tmpDir, `claude-ctx-${sessionId}.json`);
// If no metrics file, this is a subagent or fresh session -- exit silently
if (!fs.existsSync(metricsPath)) {
process.exit(0);
// If no metrics file, this is a subagent or fresh session -- exit silently.
// Collapsed existsSync+readFileSync: ENOENT → exit 0 (identical to old !existsSync branch),
// other errors rethrow to the outer catch (swallowed → exit 0, as before).
let metricsRaw;
try {
metricsRaw = fs.readFileSync(metricsPath, 'utf8');
} catch (e) {
if (e && e.code === 'ENOENT') process.exit(0);
throw e;
}
const metrics = JSON.parse(fs.readFileSync(metricsPath, 'utf8'));
const metrics = JSON.parse(metricsRaw);
const now = Math.floor(Date.now() / 1000);
// Ignore stale metrics
@@ -98,13 +101,13 @@ process.stdin.on('end', () => {
let warnData = { callsSinceWarn: 0, lastLevel: null };
let firstWarn = true;
if (fs.existsSync(warnPath)) {
try {
warnData = JSON.parse(fs.readFileSync(warnPath, 'utf8'));
firstWarn = false;
} catch (e) {
// Corrupted file, reset
}
// Collapsed existsSync+readFileSync: ENOENT or parse error → keep default warnData
// (same as old "file absent" branch). firstWarn tracks whether we read a valid sentinel.
try {
warnData = JSON.parse(fs.readFileSync(warnPath, 'utf8'));
firstWarn = false;
} catch (e) {
// Missing or corrupted sentinel → firstWarn stays true, warnData stays at defaults
}
warnData.callsSinceWarn = (warnData.callsSinceWarn || 0) + 1;