From 1dc789e83aca356d1ea119ae09444c653ec1b8f3 Mon Sep 17 00:00:00 2001 From: 1395490241lhj-code <1395490241lhj-code@users.noreply.github.com> Date: Tue, 20 Oct 2026 20:56:00 -0400 Subject: [PATCH 1/2] fix(deps): patch follow-redirects security advisories Update the transitive follow-redirects dependency (via axios@1.20.0, range ^1.16.0) from 1.16.0 to 1.16.1 in package-lock.json only, to clear the high-severity advisories GHSA-q3jh-wrc6-jgq8 and GHSA-8r9p-f939-6h3c reported by the production npm audit gate. Only the version, resolved and integrity fields of that one entry change. package.json, overrides and every other locked package are unchanged. Co-Authored-By: Claude Opus 5.5 --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 30635b56..a4b5154f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -748,9 +748,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", - "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.1.tgz", + "integrity": "sha512-FNvFGzoMLWmE6Yj9spb/zjd7yiNCHiAW9/Tg9CXrQ8wuu32HtlJOwWO11OJafl5FfY3DxTdQ0vj42zU1kvv5jg==", "funding": [ { "type": "individual", From f533d6d339025966fefd79e5590f51df6456d416 Mon Sep 17 00:00:00 2001 From: 1395490241lhj-code <1395490241lhj-code@users.noreply.github.com> Date: Tue, 20 Oct 2026 21:34:02 -0400 Subject: [PATCH 2/2] test(node22): avoid startup log deserialization failure The Node 22 test runner (v22.23.3) reads the 4 bytes after a consumed v8 frame as the next frame length without re-checking for the frame header (nodejs/node#64061). The fix, nodejs/node#64706, is in v24+ but has not been backported to v22.x (nodejs/node#65934). server.js prints its startup line starting with an emoji. When that stdout line lands in the same pipe read right after a frame, Node 22 computes a negative length and fails the whole lifecycle test file with "Unable to deserialize cloned data due to invalid or unsupported version", even though every subtest passed. In the real-HTTP lifecycle tests only, prefix that one startup line with "[server] " so it starts with ASCII. Every other console.log call passes through unchanged, and afterEach restores the original console.log. No production code, assertion, CI matrix or concurrency setting changes. Co-Authored-By: Claude Opus 5.5 --- test/ai-conversation-lifecycle.test.mjs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/ai-conversation-lifecycle.test.mjs b/test/ai-conversation-lifecycle.test.mjs index ac1bce0c..b0974c19 100644 --- a/test/ai-conversation-lifecycle.test.mjs +++ b/test/ai-conversation-lifecycle.test.mjs @@ -14,6 +14,7 @@ const Module = require('node:module'); const realExpress = require('express'); const originalLoad = Module._load; const originalWrite = http.ServerResponse.prototype.write; +const originalConsoleLog = console.log; const root = process.cwd(); const serverPath = path.resolve(root, 'server.js'); const serverModulesDir = path.resolve(root, 'src/server') + path.sep; @@ -49,6 +50,17 @@ function spyOnResponseWrites() { }; } +// Node 22 的 node:test 父进程读完一帧之后不再找帧头,直接把紧跟的 4 个字节当下一帧长度 +// (nodejs/node#64061;修复 #64706 只进了 v24+,v22.x 未回移,见 #65934)。server.js 的 +// 启动日志以 emoji 开头,恰好落在一帧后面时会被算成负长度,整个测试文件当场崩溃。 +// 只给这一行补 ASCII 前缀,日志内容和其余输出原样保留;afterEach 负责还原。 +function prefixStartupLog() { + console.log = (first, ...rest) => { + const line = typeof first === 'string' && first.startsWith('🍳 Kitchen Manager') ? `[server] ${first}` : first; + return originalConsoleLog.call(console, line, ...rest); + }; +} + // 真 express,只在 listen 上挂一个钩子拿到 http.Server(server.js 不导出它), // 端口用 0 由内核分配。 async function startRealServer({ streams = [], env = {} } = {}) { @@ -99,6 +111,8 @@ async function startRealServer({ streams = [], env = {} } = {}) { ...env }; spyOnResponseWrites(); + // 启动日志在 listen 回调里打印,比 require 返回更晚,所以要在 require 之前装上。 + prefixStartupLog(); clearServerRequireCache(); require(serverPath); @@ -117,6 +131,7 @@ afterEach(async () => { while (pendingGates.length) pendingGates.pop()(); await new Promise((r) => setTimeout(r, 10)); http.ServerResponse.prototype.write = originalWrite; + console.log = originalConsoleLog; if (runningServer) { runningServer.closeAllConnections?.(); await new Promise((resolveClose) => runningServer.close(resolveClose));