From 1bdbac49270880d241952c13801cceedbd81f786 Mon Sep 17 00:00:00 2001 From: Ninym Date: Fri, 17 Apr 2026 08:09:25 +0200 Subject: [PATCH] fix(context-budget): use bounded readSessionFile helper Config JSON, CLAUDE.md scans, and session-discovery reads now pass through the 128 MB-capped helper. JSON.parse remains wrapped in try/catch to preserve the previous 'null on malformed JSON' contract. MEDIUM-1 coverage for the context-budget module. --- src/context-budget.ts | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/src/context-budget.ts b/src/context-budget.ts index 3db8e95..b5c72d6 100644 --- a/src/context-budget.ts +++ b/src/context-budget.ts @@ -1,8 +1,10 @@ -import { readdir, readFile } from 'fs/promises' +import { readdir } from 'fs/promises' import { existsSync } from 'fs' import { join } from 'path' import { homedir } from 'os' +import { readSessionFile } from './fs-utils.js' + const CHARS_PER_TOKEN = 4 const SYSTEM_BASE_TOKENS = 10400 const TOOL_TOKENS_OVERHEAD = 400 @@ -23,9 +25,9 @@ function estimateTokens(text: string): number { async function readConfigFile(path: string): Promise | null> { if (!existsSync(path)) return null - try { - return JSON.parse(await readFile(path, 'utf-8')) - } catch { return null } + const raw = await readSessionFile(path) + if (raw === null) return null + try { return JSON.parse(raw) } catch { return null } } async function countMcpTools(projectPath?: string): Promise { @@ -91,10 +93,9 @@ async function scanMemoryFiles(projectPath?: string): Promise } export async function discoverProjectCwd(sessionDir: string): Promise { + let files: string[] try { - const files = (await readdir(sessionDir)).filter(f => f.endsWith('.jsonl')) - if (files.length === 0) return null - const content = await readFile(join(sessionDir, files[0]), 'utf-8') - for (const line of content.split('\n')) { - if (!line.trim()) continue - try { - const entry = JSON.parse(line) - if (entry.cwd && typeof entry.cwd === 'string') return entry.cwd - } catch { continue } - } + files = (await readdir(sessionDir)).filter(f => f.endsWith('.jsonl')) } catch { return null } + if (files.length === 0) return null + const content = await readSessionFile(join(sessionDir, files[0])) + if (content === null) return null + for (const line of content.split('\n')) { + if (!line.trim()) continue + try { + const entry = JSON.parse(line) + if (entry.cwd && typeof entry.cwd === 'string') return entry.cwd + } catch { continue } + } return null }