惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

雷峰网
雷峰网
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 三生石上(FineUI控件)
博客园 - 聂微东
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Hugging Face - Blog
Hugging Face - Blog
Apple Machine Learning Research
Apple Machine Learning Research
博客园 - Franky
MyScale Blog
MyScale Blog
A
About on SuperTechFans
博客园_首页
B
Blog RSS Feed
Martin Fowler
Martin Fowler
大猫的无限游戏
大猫的无限游戏
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Vercel News
Vercel News
C
Check Point Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
博客园 - 【当耐特】
M
MIT News - Artificial intelligence
宝玉的分享
宝玉的分享
T
Tailwind CSS Blog
I
InfoQ
罗磊的独立博客

Recent Commits to openclaw:main

test: merge chat side-result checks · openclaw/openclaw@ddd2c2a test: merge cron history checks · openclaw/openclaw@f7eb746 test: merge responsive navigation shell checks · openclaw/openclaw@c2e4b47 docs(changelog): add codex oauth fixes · openclaw/openclaw@628e6cd test: merge navigation routing cases · openclaw/openclaw@5d8cecb Tests: mock channel registry bundled fallback · openclaw/openclaw@2b08233 Secrets: avoid broad web search discovery for single plugin config · openclaw/openclaw@a464f59 test: merge config view browser checks · openclaw/openclaw@20cf511 fix(status): align oauth health with runtime · openclaw/openclaw@eed7116 feat: add macOS screen snapshots for monitor preview (#67954) thanks … · openclaw/openclaw@f377db1 fix: report shared auth scopes in hello-ok (#67810) thanks @BunsDev · openclaw/openclaw@0b6c39b Auto-reply: avoid eager bundled route fallback · openclaw/openclaw@3ea1bf4 Tests: narrow session binding contract setup · openclaw/openclaw@54e4e16 fix(macOS): enable undo/redo in webchat composer text input (#34962) · openclaw/openclaw@00951dc Tests: speed up channel setup promotion · openclaw/openclaw@82b529a Docs: refresh agent instructions · openclaw/openclaw@5775fe2 fix(auth): serialize OAuth refresh across agents to fix #26322 (#67876) · openclaw/openclaw@8e79080 test: allow ollama public surface boundary test · openclaw/openclaw@7d4f1a6 Docs: add test performance guardrails · openclaw/openclaw@89706d3 Tests: restore context-engine usage proof · openclaw/openclaw@e4c4f95 Tests: slim context engine runtime coverage · openclaw/openclaw@74c198f ci: retry failed custom checkouts · openclaw/openclaw@0ee5baf test: trim duplicate provider auth onboarding cases · openclaw/openclaw@1ffc02e matrix: fix sessions_spawn --thread subagent session spawning (#67643) · openclaw/openclaw@1ce2596 test: reduce auth choice fixture churn · openclaw/openclaw@857b9cd test: mock health status config boundaries · openclaw/openclaw@9d5ab4a test: mock onboard config io boundary · openclaw/openclaw@299694d test: mock legacy state plugin boundaries · openclaw/openclaw@2713089 test: mock channel install boundaries · openclaw/openclaw@b945248 test: mock doctor preview channel boundaries · openclaw/openclaw@b1a3ad4
fix(ci): bound deadcode knip scan · openclaw/openclaw@270...
vincentkoc · 2026-06-01 · via Recent Commits to openclaw:main
Original file line numberDiff line numberDiff line change

@@ -7,6 +7,8 @@ import {

77

} from "./deadcode-unused-files.allowlist.mjs";

88
99

const KNIP_VERSION = "6.8.0";

10+

export const KNIP_TIMEOUT_MS = 10 * 60 * 1000;

11+

export const KNIP_MAX_BUFFER_BYTES = 16 * 1024 * 1024;

1012

const KNIP_ARGS = [

1113

"--config",

1214

"config/knip.config.ts",

@@ -108,18 +110,28 @@ export function formatUnusedFileComparison(comparison) {

108110

return lines.join("\n");

109111

}

110112
111-

export function runKnipUnusedFiles() {

112-

const result = spawnSync(

113+

function spawnErrorCode(error) {

114+

return error && typeof error === "object" && "code" in error ? String(error.code) : undefined;

115+

}

116+
117+

export function runKnipUnusedFiles(params = {}) {

118+

const run = params.spawnSyncCommand ?? spawnSync;

119+

const result = run(

113120

"pnpm",

114121

["--config.minimum-release-age=0", "dlx", `knip@${KNIP_VERSION}`, ...KNIP_ARGS],

115122

{

116123

encoding: "utf8",

124+

killSignal: "SIGTERM",

125+

maxBuffer: params.maxBufferBytes ?? KNIP_MAX_BUFFER_BYTES,

117126

stdio: ["ignore", "pipe", "pipe"],

127+

timeout: params.timeoutMs ?? KNIP_TIMEOUT_MS,

118128

},

119129

);

120130

return {

121131

status: result.status,

122132

signal: result.signal,

133+

errorCode: spawnErrorCode(result.error),

134+

errorMessage: result.error?.message,

123135

output: `${result.stdout ?? ""}${result.stderr ?? ""}`,

124136

};

125137

}

@@ -144,6 +156,18 @@ export function checkUnusedFiles(

144156
145157

function main() {

146158

const result = runKnipUnusedFiles();

159+

if (result.errorCode || result.status === null) {

160+

console.error(

161+

`deadcode unused-file scan failed: ${result.errorCode ?? result.signal ?? "unknown"}${

162+

result.errorMessage ? `: ${result.errorMessage}` : ""

163+

}`,

164+

);

165+

if (result.output) {

166+

console.error(result.output);

167+

}

168+

process.exitCode = 1;

169+

return;

170+

}

147171

const check = checkUnusedFiles(result.output);

148172

if (!check.ok) {

149173

if (check.message) {

Original file line numberDiff line numberDiff line change

@@ -2,7 +2,10 @@ import { describe, expect, it } from "vitest";

22

import {

33

checkUnusedFiles,

44

compareUnusedFilesToAllowlist,

5+

KNIP_MAX_BUFFER_BYTES,

6+

KNIP_TIMEOUT_MS,

57

parseKnipCompactUnusedFiles,

8+

runKnipUnusedFiles,

69

} from "../../scripts/check-deadcode-unused-files.mjs";

710
811

describe("check-deadcode-unused-files", () => {

@@ -107,4 +110,54 @@ src/a.ts: src/a.ts

107110

unexpected: [],

108111

});

109112

});

113+
114+

it("bounds Knip execution and reports spawn errors", () => {

115+

const calls: unknown[] = [];

116+

const timeoutError = Object.assign(new Error("spawnSync pnpm ETIMEDOUT"), {

117+

code: "ETIMEDOUT",

118+

});

119+
120+

const result = runKnipUnusedFiles({

121+

spawnSyncCommand(command: string, args: string[], options: unknown) {

122+

calls.push({ args, command, options });

123+

return {

124+

error: timeoutError,

125+

signal: "SIGTERM",

126+

status: null,

127+

stderr: "partial stderr",

128+

stdout: "partial stdout",

129+

};

130+

},

131+

});

132+
133+

expect(calls).toHaveLength(1);

134+

expect(calls[0]).toMatchObject({

135+

args: [

136+

"--config.minimum-release-age=0",

137+

"dlx",

138+

"knip@6.8.0",

139+

"--config",

140+

"config/knip.config.ts",

141+

"--production",

142+

"--no-progress",

143+

"--reporter",

144+

"compact",

145+

"--files",

146+

"--no-config-hints",

147+

],

148+

command: "pnpm",

149+

options: {

150+

killSignal: "SIGTERM",

151+

maxBuffer: KNIP_MAX_BUFFER_BYTES,

152+

timeout: KNIP_TIMEOUT_MS,

153+

},

154+

});

155+

expect(result).toStrictEqual({

156+

errorCode: "ETIMEDOUT",

157+

errorMessage: "spawnSync pnpm ETIMEDOUT",

158+

output: "partial stdoutpartial stderr",

159+

signal: "SIGTERM",

160+

status: null,

161+

});

162+

});

110163

});