@openclaw/openshell-sandbox 2026.7.2-beta.4 → 2026.7.2-beta.7
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.
- package/README.md +8 -0
- package/dist/index.js +130 -11
- package/node_modules/p-limit/index.d.ts +1 -1
- package/node_modules/p-limit/index.js +1 -1
- package/node_modules/p-limit/package.json +1 -1
- package/node_modules/p-limit/readme.md +1 -1
- package/openclaw.plugin.json +10 -0
- package/package.json +5 -6
- package/npm-shrinkwrap.json +0 -52
- /package/node_modules/{yocto-queue → p-limit/node_modules/yocto-queue}/index.d.ts +0 -0
- /package/node_modules/{yocto-queue → p-limit/node_modules/yocto-queue}/index.js +0 -0
- /package/node_modules/{yocto-queue → p-limit/node_modules/yocto-queue}/license +0 -0
- /package/node_modules/{yocto-queue → p-limit/node_modules/yocto-queue}/package.json +0 -0
- /package/node_modules/{yocto-queue → p-limit/node_modules/yocto-queue}/readme.md +0 -0
package/README.md
CHANGED
|
@@ -4,6 +4,14 @@ Official NVIDIA OpenShell sandbox backend for OpenClaw.
|
|
|
4
4
|
|
|
5
5
|
This plugin lets OpenClaw use OpenShell-managed sandboxes with mirrored local workspaces and SSH command execution.
|
|
6
6
|
|
|
7
|
+
Configuring an OpenShell workspace requires OpenShell `v0.0.88` or newer. The
|
|
8
|
+
plugin supports OpenShell control-plane workspaces through
|
|
9
|
+
`plugins.entries.openshell.config.workspace`; this is separate from OpenClaw's
|
|
10
|
+
local/remote filesystem workspace mode. The setting applies to the whole plugin
|
|
11
|
+
instance, not individual agents or sessions. When unset, the plugin preserves
|
|
12
|
+
the OpenShell CLI's ambient `OPENSHELL_WORKSPACE` selection, or its `default`
|
|
13
|
+
fallback when no ambient selection exists.
|
|
14
|
+
|
|
7
15
|
## Install
|
|
8
16
|
|
|
9
17
|
```bash
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
|
|
2
2
|
import { buildRemoteWorkdirValidationCommand, buildValidatedExecRemoteCommand, createRemoteShellSandboxFsBridge, createSshSandboxSessionFromConfigText, createWritableRenameTargetResolver, disposeSshSandboxSession, registerSandboxBackend, resolvePreferredOpenClawTmpDir, runPluginCommandWithTimeout, runSshSandboxCommand, sanitizeEnvVars, shellEscape, withTempWorkspace } from "openclaw/plugin-sdk/sandbox";
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
3
4
|
import fsPromises from "node:fs/promises";
|
|
4
5
|
import path from "node:path";
|
|
5
6
|
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
@@ -15,6 +16,7 @@ function buildOpenShellBaseArgv(config) {
|
|
|
15
16
|
const argv = [config.command];
|
|
16
17
|
if (config.gateway) argv.push("--gateway", config.gateway);
|
|
17
18
|
if (config.gatewayEndpoint) argv.push("--gateway-endpoint", config.gatewayEndpoint);
|
|
19
|
+
if (config.workspace) argv.push("--workspace", config.workspace);
|
|
18
20
|
return argv;
|
|
19
21
|
}
|
|
20
22
|
function buildRemoteCommand(argv) {
|
|
@@ -73,11 +75,13 @@ function normalizeProviders(value) {
|
|
|
73
75
|
return providers;
|
|
74
76
|
}
|
|
75
77
|
const nonEmptyTrimmedString = (message) => z.string({ error: message }).trim().min(1, { error: message });
|
|
78
|
+
const openShellWorkspaceName = z.string({ error: "workspace must be a valid OpenShell workspace name" }).trim().min(1, { error: "workspace must be a valid OpenShell workspace name" }).max(19, { error: "workspace must be at most 19 characters" }).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, { error: "workspace must contain lowercase alphanumeric characters or single hyphens and must not start or end with a hyphen" });
|
|
76
79
|
const OpenShellPluginConfigSchema = z.strictObject({
|
|
77
80
|
mode: z.enum(["mirror", "remote"], { error: "mode must be one of mirror, remote" }).optional(),
|
|
78
81
|
command: nonEmptyTrimmedString("command must be a non-empty string").optional(),
|
|
79
82
|
gateway: nonEmptyTrimmedString("gateway must be a non-empty string").optional(),
|
|
80
83
|
gatewayEndpoint: nonEmptyTrimmedString("gatewayEndpoint must be a non-empty string").optional(),
|
|
84
|
+
workspace: openShellWorkspaceName.optional(),
|
|
81
85
|
from: nonEmptyTrimmedString("from must be a non-empty string").optional(),
|
|
82
86
|
policy: nonEmptyTrimmedString("policy must be a non-empty string").optional(),
|
|
83
87
|
providers: z.array(z.string({ error: "providers must be an array of strings" }).trim().min(1, { error: "providers must be an array of strings" }), { error: "providers must be an array of strings" }).optional(),
|
|
@@ -120,6 +124,7 @@ function resolveOpenShellPluginConfig(value) {
|
|
|
120
124
|
command: DEFAULT_COMMAND,
|
|
121
125
|
gateway: void 0,
|
|
122
126
|
gatewayEndpoint: void 0,
|
|
127
|
+
workspace: void 0,
|
|
123
128
|
from: DEFAULT_SOURCE,
|
|
124
129
|
policy: void 0,
|
|
125
130
|
providers: [],
|
|
@@ -140,6 +145,7 @@ function resolveOpenShellPluginConfig(value) {
|
|
|
140
145
|
command: cfg.command ?? DEFAULT_COMMAND,
|
|
141
146
|
gateway: cfg.gateway,
|
|
142
147
|
gatewayEndpoint: cfg.gatewayEndpoint,
|
|
148
|
+
workspace: cfg.workspace,
|
|
143
149
|
from: cfg.from ?? DEFAULT_SOURCE,
|
|
144
150
|
policy: cfg.policy,
|
|
145
151
|
providers: normalizeProviders(cfg.providers),
|
|
@@ -185,7 +191,12 @@ var OpenShellFsBridge = class {
|
|
|
185
191
|
allowMissingLeaf: false,
|
|
186
192
|
allowFinalSymlinkForUnlink: false
|
|
187
193
|
});
|
|
188
|
-
|
|
194
|
+
const root$1 = await root(target.mountHostRoot);
|
|
195
|
+
if (params.maxBytes !== void 0) return (await root$1.read(path.relative(target.mountHostRoot, hostPath), {
|
|
196
|
+
hardlinks: "reject",
|
|
197
|
+
maxBytes: params.maxBytes
|
|
198
|
+
})).buffer;
|
|
199
|
+
opened = await root$1.open(path.relative(target.mountHostRoot, hostPath), { hardlinks: "reject" });
|
|
189
200
|
try {
|
|
190
201
|
return await opened.handle.readFile();
|
|
191
202
|
} finally {
|
|
@@ -209,6 +220,27 @@ var OpenShellFsBridge = class {
|
|
|
209
220
|
await (await root(target.mountHostRoot)).write(path.relative(target.mountHostRoot, hostPath), buffer, { mkdir: params.mkdir });
|
|
210
221
|
await this.backend.syncLocalPathToRemote(hostPath, target.containerPath);
|
|
211
222
|
}
|
|
223
|
+
async createFileExclusive(params) {
|
|
224
|
+
const target = this.resolveTarget(params);
|
|
225
|
+
const hostPath = this.requireHostPath(target);
|
|
226
|
+
this.ensureWritable(target, "create files");
|
|
227
|
+
await assertLocalPathSafety({
|
|
228
|
+
target,
|
|
229
|
+
root: target.mountHostRoot,
|
|
230
|
+
allowMissingLeaf: true,
|
|
231
|
+
allowFinalSymlinkForUnlink: false
|
|
232
|
+
});
|
|
233
|
+
const buffer = Buffer.isBuffer(params.data) ? params.data : Buffer.from(params.data, params.encoding ?? "utf8");
|
|
234
|
+
const root$2 = await root(target.mountHostRoot);
|
|
235
|
+
try {
|
|
236
|
+
await root$2.create(path.relative(target.mountHostRoot, hostPath), buffer, { mkdir: params.mkdir !== false });
|
|
237
|
+
} catch (error) {
|
|
238
|
+
if (error instanceof FsSafeError && error.code === "already-exists") return "exists";
|
|
239
|
+
throw error;
|
|
240
|
+
}
|
|
241
|
+
await this.backend.syncLocalPathToRemote(hostPath, target.containerPath);
|
|
242
|
+
return "created";
|
|
243
|
+
}
|
|
212
244
|
async mkdirp(params) {
|
|
213
245
|
const target = this.resolveTarget(params);
|
|
214
246
|
const hostPath = this.requireHostPath(target);
|
|
@@ -395,7 +427,7 @@ async function mkdirLocalRootPath(params) {
|
|
|
395
427
|
await (await root(params.target.mountHostRoot)).mkdir(relativePath);
|
|
396
428
|
}
|
|
397
429
|
async function removeLocalRootPath(params) {
|
|
398
|
-
const root$
|
|
430
|
+
const root$3 = await root(params.target.mountHostRoot);
|
|
399
431
|
const relativePath = relativeToRoot(params.target, params.hostPath);
|
|
400
432
|
try {
|
|
401
433
|
if (params.force === false) await fsPromises.lstat(params.hostPath);
|
|
@@ -404,13 +436,13 @@ async function removeLocalRootPath(params) {
|
|
|
404
436
|
if (isNotFoundError(err)) return null;
|
|
405
437
|
throw err;
|
|
406
438
|
}))?.isSymbolicLink()) {
|
|
407
|
-
await root$
|
|
439
|
+
await root$3.remove(relativePath);
|
|
408
440
|
return;
|
|
409
441
|
}
|
|
410
|
-
await removeRootTree(root$
|
|
442
|
+
await removeRootTree(root$3, relativePath);
|
|
411
443
|
return;
|
|
412
444
|
}
|
|
413
|
-
await root$
|
|
445
|
+
await root$3.remove(relativePath);
|
|
414
446
|
} catch (err) {
|
|
415
447
|
if (params.force !== false && isNotFoundError(err)) return;
|
|
416
448
|
throw err;
|
|
@@ -426,11 +458,11 @@ async function removeRootTree(root, relativePath, knownStats) {
|
|
|
426
458
|
await root.remove(relativePath);
|
|
427
459
|
}
|
|
428
460
|
async function moveLocalRootPath(params) {
|
|
429
|
-
const root$
|
|
461
|
+
const root$4 = await root(params.from.mountHostRoot);
|
|
430
462
|
const fromRelativePath = relativeToRoot(params.from, params.fromHostPath);
|
|
431
463
|
const toRelativePath = relativeToRoot(params.to, params.toHostPath);
|
|
432
|
-
await mkdirParentPath(root$
|
|
433
|
-
await root$
|
|
464
|
+
await mkdirParentPath(root$4, toRelativePath);
|
|
465
|
+
await root$4.move(fromRelativePath, toRelativePath, { overwrite: true });
|
|
434
466
|
}
|
|
435
467
|
async function mkdirParentPath(root, relativePath) {
|
|
436
468
|
const parentPath = path.dirname(relativePath);
|
|
@@ -813,7 +845,11 @@ function createOpenShellSandboxBackendManager(params) {
|
|
|
813
845
|
}
|
|
814
846
|
async function createOpenShellSandboxBackend(params) {
|
|
815
847
|
if ((params.createParams.cfg.docker.binds?.length ?? 0) > 0) throw new Error("OpenShell sandbox backend does not support sandbox.docker.binds.");
|
|
816
|
-
const
|
|
848
|
+
const resolvedSandboxName = resolveOpenShellSandboxName({
|
|
849
|
+
scopeKey: params.createParams.scopeKey,
|
|
850
|
+
registeredRuntimeIds: params.createParams.registeredRuntimeIds
|
|
851
|
+
});
|
|
852
|
+
const sandboxName = resolvedSandboxName.sandboxName;
|
|
817
853
|
const execContext = {
|
|
818
854
|
config: params.pluginConfig,
|
|
819
855
|
sandboxName
|
|
@@ -821,6 +857,7 @@ async function createOpenShellSandboxBackend(params) {
|
|
|
821
857
|
const impl = new OpenShellSandboxBackendImpl({
|
|
822
858
|
createParams: params.createParams,
|
|
823
859
|
execContext,
|
|
860
|
+
legacyRuntimeAdopted: resolvedSandboxName.legacyRuntimeAdopted,
|
|
824
861
|
remoteWorkspaceDir: params.pluginConfig.remoteWorkspaceDir,
|
|
825
862
|
remoteAgentWorkspaceDir: params.pluginConfig.remoteAgentWorkspaceDir
|
|
826
863
|
});
|
|
@@ -1169,7 +1206,7 @@ var OpenShellSandboxBackendImpl = class {
|
|
|
1169
1206
|
}
|
|
1170
1207
|
}
|
|
1171
1208
|
async ensureSandboxExistsInner() {
|
|
1172
|
-
|
|
1209
|
+
const getResult = await runOpenShellCli({
|
|
1173
1210
|
context: this.params.execContext,
|
|
1174
1211
|
args: [
|
|
1175
1212
|
"sandbox",
|
|
@@ -1177,7 +1214,16 @@ var OpenShellSandboxBackendImpl = class {
|
|
|
1177
1214
|
this.params.execContext.sandboxName
|
|
1178
1215
|
],
|
|
1179
1216
|
cwd: this.params.createParams.workspaceDir
|
|
1180
|
-
})
|
|
1217
|
+
});
|
|
1218
|
+
if (getResult.code === 0) {
|
|
1219
|
+
if (this.params.legacyRuntimeAdopted) {
|
|
1220
|
+
const phase = await this.resolveLegacyRuntimePhase();
|
|
1221
|
+
if (!phase) throw this.buildLegacyRuntimeUnavailableError("OpenShell did not report a lifecycle phase for this sandbox.");
|
|
1222
|
+
if (phase !== "Ready") throw this.buildLegacyRuntimeUnavailableError(`OpenShell reports phase "${phase}".`);
|
|
1223
|
+
}
|
|
1224
|
+
return;
|
|
1225
|
+
}
|
|
1226
|
+
if (this.params.legacyRuntimeAdopted) throw this.buildLegacyRuntimeUnavailableError(getResult.stderr.trim());
|
|
1181
1227
|
const createArgs = [
|
|
1182
1228
|
"sandbox",
|
|
1183
1229
|
"create",
|
|
@@ -1201,6 +1247,38 @@ var OpenShellSandboxBackendImpl = class {
|
|
|
1201
1247
|
if (createResult.code !== 0) throw new Error(createResult.stderr.trim() || "openshell sandbox create failed");
|
|
1202
1248
|
this.remoteSeedPending = true;
|
|
1203
1249
|
}
|
|
1250
|
+
async resolveLegacyRuntimePhase() {
|
|
1251
|
+
const pageSize = 100;
|
|
1252
|
+
for (let offset = 0;; offset += pageSize) {
|
|
1253
|
+
const listResult = await runOpenShellCli({
|
|
1254
|
+
context: this.params.execContext,
|
|
1255
|
+
args: [
|
|
1256
|
+
"sandbox",
|
|
1257
|
+
"list",
|
|
1258
|
+
"--limit",
|
|
1259
|
+
String(pageSize),
|
|
1260
|
+
"--offset",
|
|
1261
|
+
String(offset),
|
|
1262
|
+
"--output",
|
|
1263
|
+
"json"
|
|
1264
|
+
],
|
|
1265
|
+
cwd: this.params.createParams.workspaceDir
|
|
1266
|
+
});
|
|
1267
|
+
if (listResult.code !== 0) throw this.buildLegacyRuntimeUnavailableError(listResult.stderr.trim());
|
|
1268
|
+
const page = parseOpenShellSandboxPhasePage(listResult.stdout, this.params.execContext.sandboxName);
|
|
1269
|
+
if (!page) throw this.buildLegacyRuntimeUnavailableError("OpenShell returned malformed sandbox lifecycle data.");
|
|
1270
|
+
if (page.phase) return page.phase;
|
|
1271
|
+
if (page.count < pageSize) return;
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
buildLegacyRuntimeUnavailableError(detail) {
|
|
1275
|
+
const recreateCommand = `openclaw sandbox recreate --session ${shellEscape(this.params.createParams.scopeKey)}`;
|
|
1276
|
+
return new Error([
|
|
1277
|
+
`Registered legacy OpenShell sandbox "${this.params.execContext.sandboxName}" is not usable.`,
|
|
1278
|
+
detail,
|
|
1279
|
+
`OpenClaw will not recreate this retired runtime name. Run \`${recreateCommand}\` to migrate this scope to the current naming format.`
|
|
1280
|
+
].filter(Boolean).join(" "));
|
|
1281
|
+
}
|
|
1204
1282
|
async syncWorkspaceToRemote() {
|
|
1205
1283
|
await this.runRemoteShellScriptInternal({
|
|
1206
1284
|
script: "mkdir -p -- \"$1\" && find \"$1\" -mindepth 1 -maxdepth 1 -exec rm -rf -- {} +",
|
|
@@ -1307,11 +1385,52 @@ function resolveOpenShellPluginConfigFromConfig(config, fallback) {
|
|
|
1307
1385
|
return resolveOpenShellPluginConfig(pluginConfig);
|
|
1308
1386
|
}
|
|
1309
1387
|
function buildOpenShellSandboxName(scopeKey) {
|
|
1388
|
+
const trimmed = scopeKey.trim() || "session";
|
|
1389
|
+
if (/:workspace:[a-f0-9]{32}$/i.test(trimmed)) {
|
|
1390
|
+
const hash = createHash("sha256").update(trimmed).digest("hex").slice(0, 20);
|
|
1391
|
+
return `oc-${BigInt(`0x${hash}`).toString(36).padStart(16, "0")}`;
|
|
1392
|
+
}
|
|
1393
|
+
return `oc-${createHash("sha256").update(trimmed).digest("hex").slice(0, 16)}`;
|
|
1394
|
+
}
|
|
1395
|
+
function buildLegacyOpenShellSandboxName(scopeKey) {
|
|
1310
1396
|
const trimmed = scopeKey.trim() || "session";
|
|
1311
1397
|
const safe = normalizeLowercaseStringOrEmpty(trimmed).replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 32);
|
|
1312
1398
|
const hash = Array.from(trimmed).reduce((acc, char) => (acc * 33 ^ char.charCodeAt(0)) >>> 0, 5381);
|
|
1313
1399
|
return `openclaw-${safe || "session"}-${hash.toString(16).slice(0, 8)}`;
|
|
1314
1400
|
}
|
|
1401
|
+
function resolveOpenShellSandboxName(params) {
|
|
1402
|
+
const sandboxName = buildOpenShellSandboxName(params.scopeKey);
|
|
1403
|
+
if (params.registeredRuntimeIds?.includes(sandboxName)) return {
|
|
1404
|
+
sandboxName,
|
|
1405
|
+
legacyRuntimeAdopted: false
|
|
1406
|
+
};
|
|
1407
|
+
const legacySandboxName = buildLegacyOpenShellSandboxName(params.scopeKey);
|
|
1408
|
+
if (params.registeredRuntimeIds?.includes(legacySandboxName)) return {
|
|
1409
|
+
sandboxName: legacySandboxName,
|
|
1410
|
+
legacyRuntimeAdopted: true
|
|
1411
|
+
};
|
|
1412
|
+
return {
|
|
1413
|
+
sandboxName,
|
|
1414
|
+
legacyRuntimeAdopted: false
|
|
1415
|
+
};
|
|
1416
|
+
}
|
|
1417
|
+
function parseOpenShellSandboxPhasePage(stdout, sandboxName) {
|
|
1418
|
+
try {
|
|
1419
|
+
const parsed = JSON.parse(stdout);
|
|
1420
|
+
if (!Array.isArray(parsed)) return;
|
|
1421
|
+
for (const entry of parsed) {
|
|
1422
|
+
if (!entry || typeof entry !== "object") continue;
|
|
1423
|
+
const record = entry;
|
|
1424
|
+
if (record.name === sandboxName && typeof record.phase === "string") return {
|
|
1425
|
+
count: parsed.length,
|
|
1426
|
+
phase: record.phase
|
|
1427
|
+
};
|
|
1428
|
+
}
|
|
1429
|
+
return { count: parsed.length };
|
|
1430
|
+
} catch {
|
|
1431
|
+
return;
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1315
1434
|
function resolveRemoteMaterializedSkillsWorkspaceDir(remoteWorkspaceDir) {
|
|
1316
1435
|
const root = remoteWorkspaceDir.replace(/\\/g, "/").replace(/\/+$/, "") || "/";
|
|
1317
1436
|
return path.posix.join(root, ...MATERIALIZED_SKILLS_REMOTE_PARTS);
|
|
@@ -17,7 +17,7 @@ export type LimitFunction = {
|
|
|
17
17
|
/**
|
|
18
18
|
Discard pending promises that are waiting to run.
|
|
19
19
|
|
|
20
|
-
This might be useful if you want to
|
|
20
|
+
This might be useful if you want to tear down the queue at the end of your program's lifecycle or discard any function calls referencing an intermediary state of your app.
|
|
21
21
|
|
|
22
22
|
Note: This does not cancel promises that are already running.
|
|
23
23
|
|
|
@@ -105,7 +105,7 @@ export default function pLimit(concurrency) {
|
|
|
105
105
|
},
|
|
106
106
|
map: {
|
|
107
107
|
async value(iterable, function_) {
|
|
108
|
-
const promises = Array.from(iterable, (value, index) =>
|
|
108
|
+
const promises = Array.from(iterable, (value, index) => generator(function_, value, index));
|
|
109
109
|
return Promise.all(promises);
|
|
110
110
|
},
|
|
111
111
|
},
|
|
@@ -97,7 +97,7 @@ The number of promises that are waiting to run (i.e. their internal `fn` was not
|
|
|
97
97
|
|
|
98
98
|
Discard pending promises that are waiting to run.
|
|
99
99
|
|
|
100
|
-
This might be useful if you want to
|
|
100
|
+
This might be useful if you want to tear down the queue at the end of your program's lifecycle or discard any function calls referencing an intermediary state of your app.
|
|
101
101
|
|
|
102
102
|
Note: This does not cancel promises that are already running.
|
|
103
103
|
|
package/openclaw.plugin.json
CHANGED
|
@@ -25,6 +25,12 @@
|
|
|
25
25
|
"type": "string",
|
|
26
26
|
"minLength": 1
|
|
27
27
|
},
|
|
28
|
+
"workspace": {
|
|
29
|
+
"type": "string",
|
|
30
|
+
"minLength": 1,
|
|
31
|
+
"maxLength": 19,
|
|
32
|
+
"pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
|
|
33
|
+
},
|
|
28
34
|
"from": {
|
|
29
35
|
"type": "string",
|
|
30
36
|
"minLength": 1
|
|
@@ -78,6 +84,10 @@
|
|
|
78
84
|
"label": "Gateway Endpoint",
|
|
79
85
|
"help": "Optional OpenShell gateway endpoint passed as --gateway-endpoint."
|
|
80
86
|
},
|
|
87
|
+
"workspace": {
|
|
88
|
+
"label": "OpenShell Workspace",
|
|
89
|
+
"help": "Existing OpenShell control-plane workspace for sandboxes, providers, policies, and inference routes. When unset, preserves the OpenShell CLI's ambient workspace selection."
|
|
90
|
+
},
|
|
81
91
|
"from": {
|
|
82
92
|
"label": "Sandbox Source",
|
|
83
93
|
"help": "OpenShell sandbox source for first-time create. Defaults to openclaw."
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/openshell-sandbox",
|
|
3
|
-
"version": "2026.7.2-beta.
|
|
3
|
+
"version": "2026.7.2-beta.7",
|
|
4
4
|
"description": "OpenClaw sandbox backend for the NVIDIA OpenShell CLI with mirrored local workspaces and SSH command execution.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
},
|
|
9
9
|
"type": "module",
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"p-limit": "7.3.
|
|
11
|
+
"p-limit": "7.3.1",
|
|
12
12
|
"zod": "4.4.3"
|
|
13
13
|
},
|
|
14
14
|
"openclaw": {
|
|
@@ -21,10 +21,10 @@
|
|
|
21
21
|
"minHostVersion": ">=2026.5.12-beta.1"
|
|
22
22
|
},
|
|
23
23
|
"compat": {
|
|
24
|
-
"pluginApi": ">=2026.7.2-beta.
|
|
24
|
+
"pluginApi": ">=2026.7.2-beta.7"
|
|
25
25
|
},
|
|
26
26
|
"build": {
|
|
27
|
-
"openclawVersion": "2026.7.2-beta.
|
|
27
|
+
"openclawVersion": "2026.7.2-beta.7",
|
|
28
28
|
"bundledDist": false
|
|
29
29
|
},
|
|
30
30
|
"release": {
|
|
@@ -38,11 +38,10 @@
|
|
|
38
38
|
"files": [
|
|
39
39
|
"dist/**",
|
|
40
40
|
"openclaw.plugin.json",
|
|
41
|
-
"npm-shrinkwrap.json",
|
|
42
41
|
"README.md"
|
|
43
42
|
],
|
|
44
43
|
"peerDependencies": {
|
|
45
|
-
"openclaw": ">=2026.7.2-beta.
|
|
44
|
+
"openclaw": ">=2026.7.2-beta.7"
|
|
46
45
|
},
|
|
47
46
|
"peerDependenciesMeta": {
|
|
48
47
|
"openclaw": {
|
package/npm-shrinkwrap.json
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@openclaw/openshell-sandbox",
|
|
3
|
-
"version": "2026.7.2-beta.4",
|
|
4
|
-
"lockfileVersion": 3,
|
|
5
|
-
"requires": true,
|
|
6
|
-
"packages": {
|
|
7
|
-
"": {
|
|
8
|
-
"name": "@openclaw/openshell-sandbox",
|
|
9
|
-
"version": "2026.7.2-beta.4",
|
|
10
|
-
"dependencies": {
|
|
11
|
-
"p-limit": "7.3.0",
|
|
12
|
-
"zod": "4.4.3"
|
|
13
|
-
}
|
|
14
|
-
},
|
|
15
|
-
"node_modules/p-limit": {
|
|
16
|
-
"version": "7.3.0",
|
|
17
|
-
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-7.3.0.tgz",
|
|
18
|
-
"integrity": "sha512-7cIXg/Z0M5WZRblrsOla88S4wAK+zOQQWeBYfV3qJuJXMr+LnbYjaadrFaS0JILfEDPVqHyKnZ1Z/1d6J9VVUw==",
|
|
19
|
-
"license": "MIT",
|
|
20
|
-
"dependencies": {
|
|
21
|
-
"yocto-queue": "^1.2.1"
|
|
22
|
-
},
|
|
23
|
-
"engines": {
|
|
24
|
-
"node": ">=20"
|
|
25
|
-
},
|
|
26
|
-
"funding": {
|
|
27
|
-
"url": "https://github.com/sponsors/sindresorhus"
|
|
28
|
-
}
|
|
29
|
-
},
|
|
30
|
-
"node_modules/yocto-queue": {
|
|
31
|
-
"version": "1.2.2",
|
|
32
|
-
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz",
|
|
33
|
-
"integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==",
|
|
34
|
-
"license": "MIT",
|
|
35
|
-
"engines": {
|
|
36
|
-
"node": ">=12.20"
|
|
37
|
-
},
|
|
38
|
-
"funding": {
|
|
39
|
-
"url": "https://github.com/sponsors/sindresorhus"
|
|
40
|
-
}
|
|
41
|
-
},
|
|
42
|
-
"node_modules/zod": {
|
|
43
|
-
"version": "4.4.3",
|
|
44
|
-
"resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz",
|
|
45
|
-
"integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==",
|
|
46
|
-
"license": "MIT",
|
|
47
|
-
"funding": {
|
|
48
|
-
"url": "https://github.com/sponsors/colinhacks"
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|