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

推荐订阅源

有赞技术团队
有赞技术团队
G
Google Developers Blog
T
Tailwind CSS Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
人人都是产品经理
人人都是产品经理
J
Java Code Geeks
P
Proofpoint News Feed
V
Visual Studio Blog
爱范儿
爱范儿
The Cloudflare Blog
博客园 - 叶小钗
V
V2EX
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
M
MIT News - Artificial intelligence
Microsoft Security Blog
Microsoft Security Blog
博客园 - 聂微东
H
Help Net Security
B
Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 【当耐特】
量子位
宝玉的分享
宝玉的分享
WordPress大学
WordPress大学
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知

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(plugins): prune legacy runtime deps roots · openclaw/...
vincentkoc · 2026-05-01 · via Recent Commits to openclaw:main

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

1313

const DEFAULT_UNKNOWN_RUNTIME_DEPS_ROOTS_TO_KEEP = 20;

1414

const DEFAULT_UNKNOWN_RUNTIME_DEPS_MIN_AGE_MS = 10 * 60_000;

1515

const PACKAGE_KEY_PATH_HASH_RE = /^openclaw-.+-([0-9a-f]{12})$/u;

16+

const LEGACY_VERSIONED_RUNTIME_DEPS_ROOT_RE =

17+

/^openclaw-\d{4}\.\d+\.\d+(?:-[0-9A-Za-z.]+)*-[A-Za-z][A-Za-z0-9_-]*$/u;

16181719

export type BundledRuntimeDepsInstallRootPlan = {

1820

installRoot: string;

@@ -143,6 +145,19 @@ export function pruneUnknownBundledRuntimeDepsRoots(

143145

let scanned = 0;

144146

let removed = 0;

145147

let skippedLocked = 0;

148+

const removeRoot = (root: string): void => {

149+

const lockDir = path.join(root, BUNDLED_RUNTIME_DEPS_LOCK_DIR);

150+

if (fs.existsSync(lockDir) && !removeRuntimeDepsLockIfStale(lockDir, nowMs)) {

151+

skippedLocked += 1;

152+

return;

153+

}

154+

try {

155+

fs.rmSync(root, { recursive: true, force: true });

156+

removed += 1;

157+

} catch (error) {

158+

params.warn?.(`failed to remove stale bundled runtime deps root ${root}: ${String(error)}`);

159+

}

160+

};

146161147162

for (const baseDir of resolveBundledRuntimeDepsExternalBaseDirs(env)) {

148163

let entries: fs.Dirent[];

@@ -163,32 +178,39 @@ export function pruneUnknownBundledRuntimeDepsRoots(

163178

})

164179

.filter((entry): entry is { root: string; mtimeMs: number } => entry !== null)

165180

.toSorted((left, right) => right.mtimeMs - left.mtimeMs);

181+

const legacyVersionedRoots = entries

182+

.filter(

183+

(entry) => entry.isDirectory() && isLegacyVersionedBundledRuntimeDepsRootName(entry.name),

184+

)

185+

.map((entry) => path.join(baseDir, entry.name))

186+

.toSorted((left, right) => left.localeCompare(right));

166187

scanned += unknownRoots.length;

188+

scanned += legacyVersionedRoots.length;

167189168190

for (const [index, entry] of unknownRoots.entries()) {

169191

const ageMs = nowMs - entry.mtimeMs;

170192

if (index < maxRootsToKeep && ageMs < minAgeMs) {

171193

continue;

172194

}

173-

const lockDir = path.join(entry.root, BUNDLED_RUNTIME_DEPS_LOCK_DIR);

174-

if (fs.existsSync(lockDir) && !removeRuntimeDepsLockIfStale(lockDir, nowMs)) {

175-

skippedLocked += 1;

176-

continue;

177-

}

178-

try {

179-

fs.rmSync(entry.root, { recursive: true, force: true });

180-

removed += 1;

181-

} catch (error) {

182-

params.warn?.(

183-

`failed to remove stale bundled runtime deps root ${entry.root}: ${String(error)}`,

184-

);

185-

}

195+

removeRoot(entry.root);

196+

}

197+198+

for (const root of legacyVersionedRoots) {

199+

removeRoot(root);

186200

}

187201

}

188202189203

return { scanned, removed, skippedLocked };

190204

}

191205206+

function isLegacyVersionedBundledRuntimeDepsRootName(name: string): boolean {

207+

return (

208+

name.startsWith("openclaw-") &&

209+

readPackageKeyPathHash(name) === null &&

210+

LEGACY_VERSIONED_RUNTIME_DEPS_ROOT_RE.test(name)

211+

);

212+

}

213+192214

export function listSiblingExternalBundledRuntimeDepsRoots(params: {

193215

installRoot: string;

194216

env?: NodeJS.ProcessEnv;