




















@@ -1,8 +1,26 @@
11import { spawnSync } from "node:child_process";
22import fs from "node:fs";
3+import os from "node:os";
34import path from "node:path";
4556const readJson = (file) => JSON.parse(fs.readFileSync(file, "utf8"));
7+const normalizePathForProbe = (value) => String(value ?? "").replace(/\\/g, "/");
8+const bundledRuntimeFragments = (pluginDir) => [
9+`/dist/extensions/${pluginDir}`,
10+`/dist-runtime/extensions/${pluginDir}`,
11+];
12+13+function resolveStateDir() {
14+if (process.env.OPENCLAW_STATE_DIR) {
15+return process.env.OPENCLAW_STATE_DIR;
16+}
17+return path.join(process.env.HOME || os.homedir(), ".openclaw");
18+}
19+20+function pathReferencesBundledRuntime(value, pluginDir) {
21+const normalized = normalizePathForProbe(value);
22+return bundledRuntimeFragments(pluginDir).some((fragment) => normalized.includes(fragment));
23+}
624725function resolveOpenClawEntry() {
826if (process.env.OPENCLAW_ENTRY) {
@@ -109,8 +127,9 @@ async function selectedManifestEntries() {
109127}
110128111129function assertInstalled(pluginId, pluginDir, requiresConfig) {
112-const configPath = path.join(process.env.HOME, ".openclaw", "openclaw.json");
113-const indexPath = path.join(process.env.HOME, ".openclaw", "plugins", "installs.json");
130+const stateDir = resolveStateDir();
131+const configPath = path.join(stateDir, "openclaw.json");
132+const indexPath = path.join(stateDir, "plugins", "installs.json");
114133const config = readJson(configPath);
115134const index = readJson(indexPath);
116135const records = index.installRecords ?? index.records ?? {};
@@ -125,23 +144,15 @@ function assertInstalled(pluginId, pluginDir, requiresConfig) {
125144}
126145if (
127146typeof record.sourcePath !== "string" ||
128-![`/dist/extensions/${pluginDir}`, `/dist-runtime/extensions/${pluginDir}`].some((fragment) =>
129-record.sourcePath.includes(fragment),
130-)
147+!pathReferencesBundledRuntime(record.sourcePath, pluginDir)
131148) {
132149throw new Error(`unexpected bundled source path for ${pluginId}: ${record.sourcePath}`);
133150}
134-if (record.installPath !== record.sourcePath) {
151+if (normalizePathForProbe(record.installPath) !== normalizePathForProbe(record.sourcePath)) {
135152throw new Error(`bundled install path should equal source path for ${pluginId}`);
136153}
137154const paths = config.plugins?.load?.paths || [];
138-if (
139-paths.some((entry) =>
140-[`/dist/extensions/${pluginDir}`, `/dist-runtime/extensions/${pluginDir}`].some(
141-(fragment) => String(entry).includes(fragment),
142-),
143-)
144-) {
155+if (paths.some((entry) => pathReferencesBundledRuntime(entry, pluginDir))) {
145156throw new Error(`config load paths should not include bundled install path for ${pluginId}`);
146157}
147158if (requiresConfig && config.plugins?.entries?.[pluginId]?.enabled === true) {
@@ -162,22 +173,17 @@ function assertInstalled(pluginId, pluginDir, requiresConfig) {
162173}
163174164175function assertUninstalled(pluginId, pluginDir) {
165-const configPath = path.join(process.env.HOME, ".openclaw", "openclaw.json");
166-const indexPath = path.join(process.env.HOME, ".openclaw", "plugins", "installs.json");
176+const stateDir = resolveStateDir();
177+const configPath = path.join(stateDir, "openclaw.json");
178+const indexPath = path.join(stateDir, "plugins", "installs.json");
167179const config = fs.existsSync(configPath) ? readJson(configPath) : {};
168180const index = fs.existsSync(indexPath) ? readJson(indexPath) : {};
169181const records = index.installRecords ?? index.records ?? {};
170182if (records[pluginId]) {
171183throw new Error(`install record still present after uninstall for ${pluginId}`);
172184}
173185const paths = config.plugins?.load?.paths || [];
174-if (
175-paths.some((entry) =>
176-[`/dist/extensions/${pluginDir}`, `/dist-runtime/extensions/${pluginDir}`].some(
177-(fragment) => String(entry).includes(fragment),
178-),
179-)
180-) {
186+if (paths.some((entry) => pathReferencesBundledRuntime(entry, pluginDir))) {
181187throw new Error(`load path still present after uninstall for ${pluginId}`);
182188}
183189if (config.plugins?.entries?.[pluginId]) {
@@ -189,7 +195,7 @@ function assertUninstalled(pluginId, pluginDir) {
189195if ((config.plugins?.deny || []).includes(pluginId)) {
190196throw new Error(`denylist still contains ${pluginId} after uninstall`);
191197}
192-const managedPath = path.join(process.env.HOME, ".openclaw", "extensions", pluginId);
198+const managedPath = path.join(stateDir, "extensions", pluginId);
193199if (fs.existsSync(managedPath)) {
194200throw new Error(
195201`managed install directory unexpectedly exists for bundled plugin ${pluginId}: ${managedPath}`,
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。