

























@@ -10,6 +10,7 @@ import {
1010existsSync,
1111mkdirSync,
1212readFileSync,
13+realpathSync,
1314rmSync,
1415writeFileSync,
1516} from "node:fs";
@@ -1302,7 +1303,9 @@ export function resolveInstalledPrefixDirFromCliPath(cliPath, platform = process
13021303}
1303130413041305function readInstalledMetadataFromCliPath(cliPath, platform = process.platform) {
1305-return readInstalledMetadata(resolveInstalledPrefixDirFromCliPath(cliPath, platform));
1306+return readInstalledMetadataFromPackageRoot(
1307+resolveInstalledPackageRootFromCliPath(cliPath, platform),
1308+);
13061309}
1307131013081311function resolveInstalledCliInvocation(cliPath, platform = process.platform) {
@@ -2781,6 +2784,10 @@ async function runOpenClaw(params) {
2781278427822785function readInstalledPackageManifest(prefixDir) {
27832786const packageRoot = installedPackageRoot(prefixDir);
2787+return readInstalledPackageManifestFromPackageRoot(packageRoot);
2788+}
2789+2790+function readInstalledPackageManifestFromPackageRoot(packageRoot) {
27842791const packageJsonPath = join(packageRoot, "package.json");
27852792if (!existsSync(packageJsonPath)) {
27862793throw new Error(`Installed package manifest missing: ${packageJsonPath}`);
@@ -2798,6 +2805,15 @@ export function readInstalledVersion(prefixDir) {
2798280527992806function readInstalledMetadata(prefixDir) {
28002807const { packageJson, packageRoot } = readInstalledPackageManifest(prefixDir);
2808+return readInstalledMetadataFromManifest(packageJson, packageRoot);
2809+}
2810+2811+function readInstalledMetadataFromPackageRoot(packageRoot) {
2812+const { packageJson } = readInstalledPackageManifestFromPackageRoot(packageRoot);
2813+return readInstalledMetadataFromManifest(packageJson, packageRoot);
2814+}
2815+2816+function readInstalledMetadataFromManifest(packageJson, packageRoot) {
28012817const buildInfoPath = join(packageRoot, "dist", "build-info.json");
28022818if (!existsSync(buildInfoPath)) {
28032819throw new Error(`Installed build info missing: ${buildInfoPath}`);
@@ -2824,8 +2840,55 @@ function verifyInstalledCandidate(installed, build) {
28242840}
28252841}
282628422827-function installedPackageRoot(prefixDir) {
2828-return process.platform === "win32"
2843+export function resolveInstalledPackageRootFromCliPath(
2844+cliPath,
2845+platform = process.platform,
2846+env = process.env,
2847+) {
2848+const prefixDir = resolveInstalledPrefixDirFromCliPath(cliPath, platform);
2849+const candidates = [installedPackageRoot(prefixDir, platform)];
2850+2851+if (platform !== "win32") {
2852+const resolvedCliPath = String(cliPath ?? "").trim();
2853+if (resolvedCliPath) {
2854+try {
2855+const realCliPath = realpathSync(resolvedCliPath);
2856+candidates.push(dirname(realCliPath));
2857+candidates.push(dirname(dirname(realCliPath)));
2858+} catch {
2859+// Some installer shims are shell wrappers, not symlinks. Fall through to
2860+// common user-local npm prefixes below.
2861+}
2862+}
2863+2864+for (const prefix of [
2865+env.NPM_CONFIG_PREFIX,
2866+env.npm_config_prefix,
2867+env.HOME && join(env.HOME, ".npm-global"),
2868+env.HOME && join(env.HOME, ".local"),
2869+]) {
2870+if (typeof prefix === "string" && prefix.trim()) {
2871+candidates.push(installedPackageRoot(prefix, platform));
2872+}
2873+}
2874+}
2875+2876+const checked: string[] = [];
2877+for (const candidate of candidates) {
2878+if (!candidate || checked.includes(candidate)) {
2879+continue;
2880+}
2881+checked.push(candidate);
2882+if (existsSync(join(candidate, "package.json"))) {
2883+return candidate;
2884+}
2885+}
2886+2887+throw new Error(`Installed package manifest missing. Checked: ${checked.join(", ")}`);
2888+}
2889+2890+function installedPackageRoot(prefixDir, platform = process.platform) {
2891+return platform === "win32"
28292892 ? join(prefixDir, "node_modules", "openclaw")
28302893 : join(prefixDir, "lib", "node_modules", "openclaw");
28312894}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。