From a4828ba644a96a3acfdf3c6354b9e95cdcc3889d Mon Sep 17 00:00:00 2001 From: i-trytoohard <193449657+i-trytoohard@users.noreply.github.com> Date: Thu, 21 May 2026 07:24:07 +0530 Subject: [PATCH] fix(agent-kimicode): close wire stream on interrupted summary reads --- eslint.config.js | 15 +++++++++++++++ packages/plugins/agent-kimicode/src/index.ts | 11 ++++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/eslint.config.js b/eslint.config.js index c6dcc531e..47a9e06ba 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -57,6 +57,21 @@ export default tseslint.config( "no-debugger": "error", "no-duplicate-imports": "error", "no-template-curly-in-string": "warn", + "no-restricted-syntax": [ + "error", + { + selector: + "CallExpression[callee.name='createInterface'] Property[key.name='input'] > CallExpression[callee.name='createReadStream']", + message: + "Do not pass createReadStream() inline to createInterface(); keep the stream in a variable and close/destroy it in a finally block.", + }, + { + selector: + "CallExpression[callee.name='createInterface'] Property[key.name='input'] > CallExpression[callee.property.name='createReadStream']", + message: + "Do not pass createReadStream() inline to createInterface(); keep the stream in a variable and close/destroy it in a finally block.", + }, + ], "prefer-const": "error", "no-var": "error", eqeqeq: ["error", "always"], diff --git a/packages/plugins/agent-kimicode/src/index.ts b/packages/plugins/agent-kimicode/src/index.ts index a0b26b9f6..2711bafa4 100644 --- a/packages/plugins/agent-kimicode/src/index.ts +++ b/packages/plugins/agent-kimicode/src/index.ts @@ -52,9 +52,12 @@ async function extractKimiSummary(sessionDir: string): Promise { // still be planted as symlinks pointing at /etc/passwd or /dev/zero. if (!(await isKimiSessionFile(wirePath))) return null; let summary: string | null = null; + let stream: ReturnType | null = null; + let rl: ReturnType | null = null; try { - const rl = createInterface({ - input: createReadStream(wirePath, { encoding: "utf-8" }), + stream = createReadStream(wirePath, { encoding: "utf-8" }); + rl = createInterface({ + input: stream, crlfDelay: Infinity, }); let bytes = 0; @@ -85,9 +88,11 @@ async function extractKimiSummary(sessionDir: string): Promise { // Skip malformed line } } - rl.close(); } catch { return null; + } finally { + rl?.close(); + stream?.destroy(); } return summary; }