fix(upgrade): unlink stale plugin runtime symlinks · openclaw/openclaw@990f931
vincentkoc
·
2026-05-04
·
via Recent Commits to openclaw:main
| Original file line number | Diff line number | Diff line change |
|---|
@@ -38,7 +38,7 @@ Docs: https://docs.openclaw.ai
|
38 | 38 | - Agents/network: allow trusted web-search providers and configured model-provider hosts to work behind Surge/Clash/sing-box fake-IP DNS by accepting RFC 2544 and IPv6 ULA synthetic answers only for the request's scoped hostname, without broad private-network access. Refs #76530 and #76549. Thanks @zqchris. |
39 | 39 | - Providers: honor env-proxy settings for guarded provider model fetches when no explicit dispatcher policy is configured, preserving explicit transport overrides. Fixes #70453. (#72480) Thanks @mjamiv. |
40 | 40 | - Feishu: accept and honor `channels.feishu.blockStreaming` at the top level and per account, while keeping the legacy default off so Feishu cards no longer reject documented config or silently drop block replies. Fixes #75555. Thanks @vincentkoc. |
41 | | -- Gateway/update: avoid `launchctl kickstart -k` immediately after fresh macOS update bootstraps, and remove dangling global plugin-runtime symlinks during packaged postinstall and `doctor --fix` so upgrades no longer SIGTERM the newly booted Gateway or leave bundled plugin imports pointed at pruned `plugin-runtime-deps` trees. Completes #76261 and fixes #76466. (#76929) |
| 41 | +- Gateway/update: avoid `launchctl kickstart -k` immediately after fresh macOS update bootstraps, and unlink dangling global plugin-runtime symlinks during packaged postinstall and `doctor --fix` so upgrades no longer SIGTERM the newly booted Gateway or leave bundled plugin imports pointed at pruned `plugin-runtime-deps` trees. Completes #76261 and fixes #76466. (#76929) |
42 | 42 | - Google Chat: normalize custom Google auth transport headers before google-auth/gaxios interceptors run, restoring webhook token verification when certificate retrieval expects Fetch `Headers`. Fixes #76742. Thanks @donbowman. |
43 | 43 | - Doctor/plugins: reset stale `plugins.slots.memory` and `plugins.slots.contextEngine` references during `doctor --fix`, so cleanup of missing plugin config does not leave unrecoverable slot owners behind. Fixes #76550 and #76551. Thanks @vincentkoc. |
44 | 44 | - Docs/WhatsApp: merge the duplicate top-level `web` objects in the gateway channel config example so copy-pasted WhatsApp config keeps both `web.whatsapp` and reconnect settings. Fixes #76619. Thanks @WadydX. |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -445,14 +445,15 @@ function collectLegacyPluginRuntimeDepsSymlinkPaths(roots, params = {}) {
|
445 | 445 | export function pruneLegacyPluginRuntimeDepsState(params = {}) { |
446 | 446 | const pathExists = params.existsSync ?? existsSync; |
447 | 447 | const removePath = params.rmSync ?? rmSync; |
| 448 | +const unlinkPath = params.unlinkSync ?? unlinkSync; |
448 | 449 | const log = params.log ?? console; |
449 | 450 | const removed = []; |
450 | 451 | const removedSymlinks = []; |
451 | 452 | const roots = collectLegacyPluginRuntimeDepsStateRoots(params); |
452 | 453 | |
453 | 454 | for (const linkPath of collectLegacyPluginRuntimeDepsSymlinkPaths(roots, params)) { |
454 | 455 | try { |
455 | | -removePath(linkPath, { force: true }); |
| 456 | +unlinkPath(linkPath); |
456 | 457 | removedSymlinks.push(linkPath); |
457 | 458 | } catch (error) { |
458 | 459 | log.warn?.( |
@@ -889,7 +890,10 @@ export function runBundledPluginPostinstall(params = {}) {
|
889 | 890 | env, |
890 | 891 | packageRoot, |
891 | 892 | existsSync: pathExists, |
| 893 | +lstatSync: params.lstatSync, |
| 894 | +readlinkSync: params.readlinkSync, |
892 | 895 | rmSync: params.rmSync, |
| 896 | +unlinkSync: params.unlinkSync, |
893 | 897 | log, |
894 | 898 | homedir: params.homedir, |
895 | 899 | }); |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -12,6 +12,7 @@ interface FsLike {
|
12 | 12 | readlink(file: string): Promise<string>; |
13 | 13 | stat(file: string): Promise<unknown>; |
14 | 14 | rm(file: string, options: { force: true }): Promise<void>; |
| 15 | +unlink?(file: string): Promise<void>; |
15 | 16 | } |
16 | 17 | |
17 | 18 | interface DirentLike { |
@@ -41,6 +42,7 @@ const DEFAULT_FS: FsLike = {
|
41 | 42 | readlink: (file) => fs.readlink(file), |
42 | 43 | stat: (file) => fs.stat(file), |
43 | 44 | rm: (file, options) => fs.rm(file, options), |
| 45 | +unlink: (file) => fs.unlink(file), |
44 | 46 | }; |
45 | 47 | |
46 | 48 | export async function collectStalePluginRuntimeSymlinks( |
@@ -126,7 +128,11 @@ export async function removeStalePluginRuntimeSymlinks(
|
126 | 128 | const warnings: string[] = []; |
127 | 129 | for (const item of await collectStalePluginRuntimeSymlinks(packageRoot, options)) { |
128 | 130 | try { |
129 | | -await fsApi.rm(item.path, { force: true }); |
| 131 | +if (fsApi.unlink) { |
| 132 | +await fsApi.unlink(item.path); |
| 133 | +} else { |
| 134 | +await fsApi.rm(item.path, { force: true }); |
| 135 | +} |
130 | 136 | changes.push(`Removed stale plugin-runtime symlink: ${item.path}`); |
131 | 137 | } catch (error) { |
132 | 138 | warnings.push(`Failed to remove stale plugin-runtime symlink ${item.path}: ${String(error)}`); |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。