@remnic/plugin-openclaw 9.50.1 → 9.50.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,22 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
18
+
19
+ export {
20
+ __export,
21
+ __reExport
22
+ };
package/dist/index.js CHANGED
@@ -1,20 +1,7 @@
1
- var __defProp = Object.defineProperty;
2
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
- var __getOwnPropNames = Object.getOwnPropertyNames;
4
- var __hasOwnProp = Object.prototype.hasOwnProperty;
5
- var __export = (target, all) => {
6
- for (var name in all)
7
- __defProp(target, name, { get: all[name], enumerable: true });
8
- };
9
- var __copyProps = (to, from, except, desc) => {
10
- if (from && typeof from === "object" || typeof from === "function") {
11
- for (let key of __getOwnPropNames(from))
12
- if (!__hasOwnProp.call(to, key) && key !== except)
13
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
- }
15
- return to;
16
- };
17
- var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
1
+ import {
2
+ __export,
3
+ __reExport
4
+ } from "./chunk-I2KLQ2HA.js";
18
5
 
19
6
  // ../../src/day-summary.ts
20
7
  var day_summary_exports = {};
@@ -0,0 +1,35 @@
1
+ declare const REMNIC_OPENCLAW_PLUGIN_ID = "openclaw-remnic";
2
+ interface OpenclawCommandOptions {
3
+ timeoutMs: number;
4
+ }
5
+ type OpenclawCommandRunner = (args: readonly string[], options: OpenclawCommandOptions) => string;
6
+ declare function assertDirectoryPathOrMissing(targetPath: string, label: string): void;
7
+ declare function describeErrorWithCause(error: unknown): string;
8
+ declare class PublishedOpenclawPluginInstallError extends Error {
9
+ readonly managedRestoreNote?: string;
10
+ readonly managedRollbackDir?: string;
11
+ readonly managedRollbackTargetDir?: string;
12
+ readonly requiresHostManagedRestore: boolean;
13
+ readonly rollbackDir?: string;
14
+ readonly shouldRestoreBackup: boolean;
15
+ readonly shouldRestoreConfig: boolean;
16
+ constructor(message: string, options?: ErrorOptions & {
17
+ managedRestoreNote?: string;
18
+ managedRollbackDir?: string;
19
+ managedRollbackTargetDir?: string;
20
+ requiresHostManagedRestore?: boolean;
21
+ rollbackDir?: string;
22
+ shouldRestoreBackup?: boolean;
23
+ shouldRestoreConfig?: boolean;
24
+ });
25
+ }
26
+ declare function installPublishedOpenclawPlugin(spec: string, pluginDir: string, managedTargetDir: string, runOpenclaw: OpenclawCommandRunner): {
27
+ managedRollbackDir?: string;
28
+ managedRollbackTargetDir?: string;
29
+ requiresHostManagedRestore: boolean;
30
+ rollbackDir?: string;
31
+ rollbackManagedInstall: () => string | undefined;
32
+ version?: string;
33
+ };
34
+
35
+ export { type OpenclawCommandOptions, type OpenclawCommandRunner, PublishedOpenclawPluginInstallError, REMNIC_OPENCLAW_PLUGIN_ID, assertDirectoryPathOrMissing, describeErrorWithCause, installPublishedOpenclawPlugin };
@@ -0,0 +1,382 @@
1
+ import "./chunk-I2KLQ2HA.js";
2
+
3
+ // src/managed-upgrade.ts
4
+ import fs from "fs";
5
+ import path from "path";
6
+ var REMNIC_OPENCLAW_PLUGIN_ID = "openclaw-remnic";
7
+ var OPENCLAW_EXEC_TIMEOUT_MS = 12e4;
8
+ var OPENCLAW_PLUGIN_PACKAGE = "@remnic/plugin-openclaw";
9
+ var DIST_TAG_SELECTOR = /^[A-Za-z][0-9A-Za-z._-]*$/;
10
+ function semanticVersionCoreLength(selector) {
11
+ let cursor = selector.startsWith("v") ? 1 : 0;
12
+ for (let part = 0; part < 3; part += 1) {
13
+ const partStart = cursor;
14
+ while (cursor < selector.length) {
15
+ const code = selector.charCodeAt(cursor);
16
+ if (code < 48 || code > 57) break;
17
+ cursor += 1;
18
+ }
19
+ if (cursor === partStart || cursor - partStart > 1 && selector.charCodeAt(partStart) === 48) return -1;
20
+ if (part < 2) {
21
+ if (selector.charCodeAt(cursor) !== 46) return -1;
22
+ cursor += 1;
23
+ }
24
+ }
25
+ return cursor;
26
+ }
27
+ function areSemverIdentifiersValid(value, start, end, rejectLeadingZeroes) {
28
+ if (start >= end) return false;
29
+ let identifierStart = start;
30
+ let numeric = true;
31
+ for (let cursor = start; cursor <= end; cursor += 1) {
32
+ const code = value.charCodeAt(cursor);
33
+ if (cursor === end || code === 46) {
34
+ if (cursor === identifierStart) return false;
35
+ if (rejectLeadingZeroes && numeric && cursor - identifierStart > 1 && value.charCodeAt(identifierStart) === 48) {
36
+ return false;
37
+ }
38
+ identifierStart = cursor + 1;
39
+ numeric = true;
40
+ continue;
41
+ }
42
+ const alphanumeric = code >= 48 && code <= 57 || code >= 65 && code <= 90 || code >= 97 && code <= 122;
43
+ if (!alphanumeric && code !== 45) return false;
44
+ if (code < 48 || code > 57) numeric = false;
45
+ }
46
+ return true;
47
+ }
48
+ function isExactSemverSelector(selector) {
49
+ const coreLength = semanticVersionCoreLength(selector);
50
+ if (coreLength < 0) return false;
51
+ if (coreLength === selector.length) return true;
52
+ const suffixMarker = selector[coreLength];
53
+ if (suffixMarker === "-") {
54
+ const plusIndex = selector.indexOf("+", coreLength + 1);
55
+ const prereleaseEnd = plusIndex < 0 ? selector.length : plusIndex;
56
+ if (!areSemverIdentifiersValid(selector, coreLength + 1, prereleaseEnd, true)) return false;
57
+ return plusIndex < 0 || areSemverIdentifiersValid(selector, plusIndex + 1, selector.length, false);
58
+ }
59
+ return suffixMarker === "+" && areSemverIdentifiersValid(selector, coreLength + 1, selector.length, false);
60
+ }
61
+ function assertRegistryPackageSpec(spec) {
62
+ const prefix = `${OPENCLAW_PLUGIN_PACKAGE}@`;
63
+ const selector = spec.startsWith(prefix) ? spec.slice(prefix.length) : "";
64
+ const lowerSelector = selector.toLowerCase();
65
+ const archiveSelector = lowerSelector.endsWith(".tgz") || lowerSelector.endsWith(".tar.gz");
66
+ if (!selector || !isExactSemverSelector(selector) && !DIST_TAG_SELECTOR.test(selector) || archiveSelector) {
67
+ const renderedSpec = JSON.stringify(spec);
68
+ throw new Error(
69
+ `Invalid OpenClaw plugin package spec ${renderedSpec}. Use an exact semantic version or npm dist-tag.`
70
+ );
71
+ }
72
+ return selector;
73
+ }
74
+ function isInstalledPluginStatus(status, allowDisabled) {
75
+ return status === "loaded" || allowDisabled && status === "disabled";
76
+ }
77
+ function assertDirectoryPathOrMissing(targetPath, label) {
78
+ let stat;
79
+ try {
80
+ stat = fs.lstatSync(targetPath);
81
+ } catch (error) {
82
+ if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") return;
83
+ throw error;
84
+ }
85
+ if (stat.isSymbolicLink()) {
86
+ throw new Error(`${label} must not be a symlink: ${targetPath}`);
87
+ }
88
+ if (!stat.isDirectory()) {
89
+ throw new Error(`${label} must be a directory when it already exists: ${targetPath}`);
90
+ }
91
+ }
92
+ function describeErrorWithCause(error) {
93
+ const message = error instanceof Error ? error.message : String(error);
94
+ if (!(error instanceof Error) || !("cause" in error)) return message;
95
+ const cause = error.cause;
96
+ if (cause === void 0 || cause === null) return message;
97
+ const causeText = cause instanceof Error ? cause.message : String(cause);
98
+ if (!causeText || causeText === message) return message;
99
+ return `${message} Cause: ${causeText}`;
100
+ }
101
+ var PublishedOpenclawPluginInstallError = class extends Error {
102
+ managedRestoreNote;
103
+ managedRollbackDir;
104
+ managedRollbackTargetDir;
105
+ requiresHostManagedRestore;
106
+ rollbackDir;
107
+ shouldRestoreBackup;
108
+ shouldRestoreConfig;
109
+ constructor(message, options = {}) {
110
+ super(message, options);
111
+ this.name = "PublishedOpenclawPluginInstallError";
112
+ this.managedRestoreNote = options.managedRestoreNote;
113
+ this.managedRollbackDir = options.managedRollbackDir;
114
+ this.managedRollbackTargetDir = options.managedRollbackTargetDir;
115
+ this.requiresHostManagedRestore = options.requiresHostManagedRestore ?? false;
116
+ this.rollbackDir = options.rollbackDir;
117
+ this.shouldRestoreBackup = options.shouldRestoreBackup ?? false;
118
+ this.shouldRestoreConfig = options.shouldRestoreConfig ?? false;
119
+ }
120
+ };
121
+ function installPublishedOpenclawPlugin(spec, pluginDir, managedTargetDir, runOpenclaw) {
122
+ const requestedSelector = assertRegistryPackageSpec(spec);
123
+ assertDirectoryPathOrMissing(pluginDir, "OpenClaw plugin dir");
124
+ assertDirectoryPathOrMissing(managedTargetDir, "Managed OpenClaw plugin dir");
125
+ const rollbackSuffix = `${process.pid}-${Date.now()}`;
126
+ const rollbackDir = `${pluginDir}.rollback-${rollbackSuffix}`;
127
+ const managedRollbackDir = `${managedTargetDir}.rollback-${rollbackSuffix}`;
128
+ const runOpenclawCommand = (args) => runOpenclaw(args, { timeoutMs: OPENCLAW_EXEC_TIMEOUT_MS });
129
+ let activeRollbackDir;
130
+ let activeManagedRollbackDir;
131
+ let activeManagedRollbackTargetDir;
132
+ let managedInstallStarted = false;
133
+ let shouldRestoreBackup = false;
134
+ let managedRestoreNote;
135
+ const readOpenclawHelp = (subcommand) => runOpenclawCommand(["plugins", subcommand, "--help"]);
136
+ const inspectManagedPlugin = (inspectArgs) => {
137
+ const inspectOutput = runOpenclawCommand(inspectArgs);
138
+ let inspectResult;
139
+ try {
140
+ inspectResult = JSON.parse(inspectOutput);
141
+ } catch (error) {
142
+ throw new Error("OpenClaw returned invalid JSON while inspecting the managed plugin.", {
143
+ cause: error
144
+ });
145
+ }
146
+ const inspected = Array.isArray(inspectResult) ? inspectResult.find((candidate) => {
147
+ if (!candidate || typeof candidate !== "object" || !("plugin" in candidate)) {
148
+ return false;
149
+ }
150
+ const plugin2 = candidate.plugin;
151
+ return Boolean(
152
+ plugin2 && typeof plugin2 === "object" && ("id" in plugin2 && plugin2.id === REMNIC_OPENCLAW_PLUGIN_ID || "name" in plugin2 && plugin2.name === REMNIC_OPENCLAW_PLUGIN_ID)
153
+ );
154
+ }) : inspectResult;
155
+ if (!inspected || typeof inspected !== "object") return {};
156
+ const plugin = "plugin" in inspected ? inspected.plugin : void 0;
157
+ const install = "install" in inspected ? inspected.install : void 0;
158
+ return {
159
+ status: plugin && typeof plugin === "object" && "status" in plugin ? plugin.status : void 0,
160
+ installPath: install && typeof install === "object" && "installPath" in install && typeof install.installPath === "string" ? install.installPath : void 0,
161
+ installPackage: install && typeof install === "object" && "clawhubPackage" in install && typeof install.clawhubPackage === "string" ? install.clawhubPackage : void 0,
162
+ installSource: install && typeof install === "object" && "source" in install && typeof install.source === "string" ? install.source : void 0,
163
+ version: install && typeof install === "object" && "version" in install && typeof install.version === "string" ? install.version : void 0
164
+ };
165
+ };
166
+ const inspectInstalledPlugin = (runtime) => {
167
+ const inspectArgs = ["plugins", "inspect", REMNIC_OPENCLAW_PLUGIN_ID];
168
+ if (runtime) inspectArgs.push("--runtime");
169
+ inspectArgs.push("--json");
170
+ return inspectManagedPlugin(inspectArgs);
171
+ };
172
+ const retireUnmanagedPlugin = () => {
173
+ fs.rmSync(rollbackDir, { recursive: true, force: true });
174
+ if (!fs.existsSync(pluginDir)) return;
175
+ try {
176
+ fs.renameSync(pluginDir, rollbackDir);
177
+ activeRollbackDir = rollbackDir;
178
+ } catch (error) {
179
+ shouldRestoreBackup = true;
180
+ throw error;
181
+ }
182
+ };
183
+ const retireManagedTarget = () => {
184
+ if (path.resolve(managedTargetDir) === path.resolve(pluginDir)) return;
185
+ fs.rmSync(managedRollbackDir, { recursive: true, force: true });
186
+ if (!fs.existsSync(managedTargetDir)) return;
187
+ fs.renameSync(managedTargetDir, managedRollbackDir);
188
+ activeManagedRollbackDir = managedRollbackDir;
189
+ activeManagedRollbackTargetDir = managedTargetDir;
190
+ };
191
+ const preserveManagedTarget = (targetDir = previousManagedInstall?.installPath?.trim() || managedTargetDir) => {
192
+ assertDirectoryPathOrMissing(targetDir, "Tracked managed OpenClaw plugin dir");
193
+ const targetRollbackDir = path.resolve(targetDir) === path.resolve(managedTargetDir) ? managedRollbackDir : `${targetDir}.rollback-${rollbackSuffix}`;
194
+ fs.rmSync(targetRollbackDir, { recursive: true, force: true });
195
+ if (!fs.existsSync(targetDir)) return;
196
+ fs.cpSync(targetDir, targetRollbackDir, { recursive: true });
197
+ activeManagedRollbackDir = targetRollbackDir;
198
+ activeManagedRollbackTargetDir = targetDir;
199
+ };
200
+ let previousManagedInstall;
201
+ let installSupportsForce = false;
202
+ let inspectSupportsRuntime = false;
203
+ const rollbackManagedInstall = () => {
204
+ const previousInstall = previousManagedInstall;
205
+ const previousSource = previousInstall?.installSource;
206
+ if (previousInstall && (previousSource === "npm" || previousSource === "clawhub")) {
207
+ const previousSpec = previousSource === "npm" ? `@remnic/plugin-openclaw@${previousInstall.version}` : `clawhub:${previousInstall.installPackage}@${previousInstall.version}`;
208
+ const previousPackageArg = installSupportsForce && previousSource === "npm" ? `npm:${previousSpec}` : previousSpec;
209
+ try {
210
+ if (!installSupportsForce) {
211
+ const currentInstall = inspectManagedPlugin(["plugins", "inspect", "--all", "--json"]);
212
+ if (currentInstall.installSource) {
213
+ runOpenclawCommand(["plugins", "uninstall", REMNIC_OPENCLAW_PLUGIN_ID, "--force"]);
214
+ }
215
+ }
216
+ const restoreArgs = ["plugins", "install", previousPackageArg];
217
+ if (installSupportsForce) restoreArgs.push("--force");
218
+ runOpenclawCommand(restoreArgs);
219
+ const restoredPlugin = inspectInstalledPlugin(inspectSupportsRuntime);
220
+ if (!isInstalledPluginStatus(restoredPlugin.status, previousInstall.status === "disabled") || restoredPlugin.installSource !== previousSource || restoredPlugin.version !== previousInstall.version) {
221
+ throw new Error("OpenClaw did not restore the previous managed plugin version.");
222
+ }
223
+ return void 0;
224
+ } catch (registryRestoreError) {
225
+ if (!activeManagedRollbackDir) throw registryRestoreError;
226
+ try {
227
+ if (!installSupportsForce) {
228
+ const currentInstall = inspectManagedPlugin(["plugins", "inspect", "--all", "--json"]);
229
+ if (currentInstall.installSource) {
230
+ runOpenclawCommand(["plugins", "uninstall", REMNIC_OPENCLAW_PLUGIN_ID, "--force"]);
231
+ }
232
+ }
233
+ const localRestoreArgs = ["plugins", "install", activeManagedRollbackDir];
234
+ if (installSupportsForce) localRestoreArgs.push("--force");
235
+ runOpenclawCommand(localRestoreArgs);
236
+ const locallyRestoredPlugin = inspectInstalledPlugin(inspectSupportsRuntime);
237
+ if (!isInstalledPluginStatus(locallyRestoredPlugin.status, previousInstall.status === "disabled") || locallyRestoredPlugin.installSource !== "path" || locallyRestoredPlugin.version !== previousInstall.version) {
238
+ throw new Error("OpenClaw did not re-register the preserved plugin copy.");
239
+ }
240
+ managedRestoreNote = "OpenClaw re-registered the preserved plugin copy as a local path because the registry restore failed";
241
+ return managedRestoreNote;
242
+ } catch (localRestoreError) {
243
+ throw new AggregateError(
244
+ [registryRestoreError, localRestoreError],
245
+ "OpenClaw could not restore the previous registry install or re-register the preserved plugin copy."
246
+ );
247
+ }
248
+ }
249
+ }
250
+ const rollbackErrors = [];
251
+ if (managedInstallStarted) {
252
+ try {
253
+ runOpenclawCommand(["plugins", "uninstall", REMNIC_OPENCLAW_PLUGIN_ID, "--force"]);
254
+ } catch (error) {
255
+ rollbackErrors.push(error);
256
+ }
257
+ }
258
+ if (activeManagedRollbackDir && activeManagedRollbackTargetDir) {
259
+ try {
260
+ fs.rmSync(activeManagedRollbackTargetDir, { recursive: true, force: true });
261
+ fs.renameSync(activeManagedRollbackDir, activeManagedRollbackTargetDir);
262
+ activeManagedRollbackDir = void 0;
263
+ activeManagedRollbackTargetDir = void 0;
264
+ } catch (error) {
265
+ rollbackErrors.push(error);
266
+ }
267
+ }
268
+ if (rollbackErrors.length === 1) throw rollbackErrors[0];
269
+ if (rollbackErrors.length > 1) {
270
+ throw new AggregateError(rollbackErrors, "One or more managed plugin rollback steps failed.");
271
+ }
272
+ return void 0;
273
+ };
274
+ try {
275
+ inspectSupportsRuntime = readOpenclawHelp("inspect").includes("--runtime");
276
+ const installHelp = readOpenclawHelp("install");
277
+ installSupportsForce = installHelp.includes("--force");
278
+ previousManagedInstall = inspectManagedPlugin(["plugins", "inspect", "--all", "--json"]);
279
+ const previousSource = previousManagedInstall.installSource;
280
+ if (previousSource && previousSource !== "npm" && previousSource !== "clawhub") {
281
+ throw new Error(
282
+ `OpenClaw tracks ${REMNIC_OPENCLAW_PLUGIN_ID} from ${previousSource}; refusing to replace a non-registry install.`
283
+ );
284
+ }
285
+ if (previousSource && !previousManagedInstall.version) {
286
+ throw new Error(
287
+ "OpenClaw tracked the existing plugin without an installed version; refusing a non-reversible update."
288
+ );
289
+ }
290
+ if (previousSource === "clawhub" && !previousManagedInstall.installPackage) {
291
+ throw new Error(
292
+ "OpenClaw tracked the existing ClawHub plugin without its package name; refusing a non-reversible update."
293
+ );
294
+ }
295
+ if (!previousSource && !installSupportsForce) {
296
+ retireManagedTarget();
297
+ retireUnmanagedPlugin();
298
+ }
299
+ if (previousSource === "npm" || previousSource === "clawhub") {
300
+ preserveManagedTarget();
301
+ }
302
+ if (!previousSource && installSupportsForce && fs.existsSync(managedTargetDir)) {
303
+ preserveManagedTarget(managedTargetDir);
304
+ }
305
+ if ((previousSource === "npm" || previousSource === "clawhub") && !installSupportsForce) {
306
+ managedInstallStarted = true;
307
+ runOpenclawCommand(["plugins", "uninstall", REMNIC_OPENCLAW_PLUGIN_ID, "--force"]);
308
+ }
309
+ const packageArg = installSupportsForce ? `npm:${spec}` : spec;
310
+ const installArgs = ["plugins", "install", packageArg];
311
+ if (installSupportsForce) installArgs.push("--force");
312
+ managedInstallStarted = true;
313
+ runOpenclawCommand(installArgs);
314
+ let inspectedPlugin = inspectInstalledPlugin(inspectSupportsRuntime);
315
+ const installPath = inspectedPlugin.installPath;
316
+ if (!installPath) {
317
+ throw new Error("OpenClaw did not report the managed plugin install path after installation.");
318
+ }
319
+ if (!fs.existsSync(installPath) || !fs.statSync(installPath).isDirectory()) {
320
+ throw new Error(`OpenClaw reported a missing managed plugin install path: ${installPath}`);
321
+ }
322
+ const pluginDirExists = fs.existsSync(pluginDir);
323
+ const installedAtPluginDir = pluginDirExists && fs.realpathSync(installPath) === fs.realpathSync(pluginDir);
324
+ if (!installedAtPluginDir) {
325
+ retireUnmanagedPlugin();
326
+ const verifiedPlugin = inspectInstalledPlugin(inspectSupportsRuntime);
327
+ if (verifiedPlugin.installPath !== installPath) {
328
+ throw new Error("OpenClaw changed the managed plugin install path during verification.");
329
+ }
330
+ inspectedPlugin = verifiedPlugin;
331
+ } else if (!activeRollbackDir) {
332
+ shouldRestoreBackup = true;
333
+ }
334
+ if (!isInstalledPluginStatus(inspectedPlugin.status, previousManagedInstall.status === "disabled")) {
335
+ throw new Error(
336
+ `OpenClaw reported plugin status ${JSON.stringify(inspectedPlugin.status ?? "missing")} for ${REMNIC_OPENCLAW_PLUGIN_ID} after the managed install.`
337
+ );
338
+ }
339
+ if (isExactSemverSelector(requestedSelector) && inspectedPlugin.version !== requestedSelector.replace(/^v/, "")) {
340
+ throw new Error(
341
+ `OpenClaw reported plugin version ${JSON.stringify(inspectedPlugin.version ?? "missing")} after installing requested exact version ${JSON.stringify(requestedSelector)}.`
342
+ );
343
+ }
344
+ return {
345
+ managedRollbackDir: activeManagedRollbackDir,
346
+ managedRollbackTargetDir: activeManagedRollbackTargetDir,
347
+ requiresHostManagedRestore: previousManagedInstall?.installSource === "npm" || previousManagedInstall?.installSource === "clawhub",
348
+ rollbackDir: activeRollbackDir,
349
+ rollbackManagedInstall,
350
+ version: inspectedPlugin.version
351
+ };
352
+ } catch (error) {
353
+ let installFailure = error;
354
+ try {
355
+ if (managedInstallStarted || activeManagedRollbackDir) {
356
+ rollbackManagedInstall();
357
+ }
358
+ } catch (cleanupError) {
359
+ installFailure = new AggregateError(
360
+ [error, cleanupError],
361
+ previousManagedInstall?.installSource === "npm" || previousManagedInstall?.installSource === "clawhub" ? "The managed plugin failed verification, and OpenClaw could not restore the previous managed version." : "The managed plugin failed verification, and OpenClaw could not remove the failed install."
362
+ );
363
+ }
364
+ throw new PublishedOpenclawPluginInstallError(`Failed to install published OpenClaw plugin from ${spec}.`, {
365
+ cause: installFailure,
366
+ managedRestoreNote,
367
+ managedRollbackDir: activeManagedRollbackDir,
368
+ managedRollbackTargetDir: activeManagedRollbackTargetDir,
369
+ requiresHostManagedRestore: previousManagedInstall?.installSource === "npm" || previousManagedInstall?.installSource === "clawhub",
370
+ rollbackDir: activeRollbackDir,
371
+ shouldRestoreBackup,
372
+ shouldRestoreConfig: managedInstallStarted
373
+ });
374
+ }
375
+ }
376
+ export {
377
+ PublishedOpenclawPluginInstallError,
378
+ REMNIC_OPENCLAW_PLUGIN_ID,
379
+ assertDirectoryPathOrMissing,
380
+ describeErrorWithCause,
381
+ installPublishedOpenclawPlugin
382
+ };