@openclaw/openshell-sandbox 2026.6.5-beta.2 → 2026.6.5-beta.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.
- package/dist/index.js +214 -7
- package/npm-shrinkwrap.json +2 -2
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -245,6 +245,11 @@ async function stageDirectoryContents(params) {
|
|
|
245
245
|
}
|
|
246
246
|
//#endregion
|
|
247
247
|
//#region extensions/openshell/src/fs-bridge.ts
|
|
248
|
+
const MATERIALIZED_SKILLS_CONTAINER_PARTS = [
|
|
249
|
+
".openclaw",
|
|
250
|
+
"sandbox-skills",
|
|
251
|
+
"skills"
|
|
252
|
+
];
|
|
248
253
|
function createOpenShellFsBridge(params) {
|
|
249
254
|
return new OpenShellFsBridge(params.sandbox, params.backend);
|
|
250
255
|
}
|
|
@@ -392,7 +397,18 @@ var OpenShellFsBridge = class {
|
|
|
392
397
|
const hasAgentMount = this.sandbox.workspaceAccess !== "none" && workspaceRoot !== agentRoot;
|
|
393
398
|
const agentContainerRoot = (this.backend.remoteAgentWorkspaceDir || "/agent").replace(/\\/g, "/");
|
|
394
399
|
const workspaceContainerRoot = this.sandbox.containerWorkdir.replace(/\\/g, "/");
|
|
400
|
+
const skillsRoot = this.sandbox.skillsWorkspaceDir ? path.resolve(this.sandbox.skillsWorkspaceDir, "skills") : void 0;
|
|
401
|
+
const skillsContainerRoot = path.posix.join(workspaceContainerRoot, ...MATERIALIZED_SKILLS_CONTAINER_PARTS);
|
|
402
|
+
const workspaceSkillsShadowRoot = path.resolve(workspaceRoot, ...MATERIALIZED_SKILLS_CONTAINER_PARTS);
|
|
395
403
|
const input = params.filePath.trim();
|
|
404
|
+
if (skillsRoot && this.sandbox.workspaceAccess === "rw") {
|
|
405
|
+
const protectedSkillTarget = resolveProtectedSkillTarget({
|
|
406
|
+
input,
|
|
407
|
+
skillsRoot,
|
|
408
|
+
skillsContainerRoot
|
|
409
|
+
});
|
|
410
|
+
if (protectedSkillTarget) return protectedSkillTarget;
|
|
411
|
+
}
|
|
396
412
|
if (input.startsWith(`${workspaceContainerRoot}/`) || input === workspaceContainerRoot) {
|
|
397
413
|
const relative = path.posix.relative(workspaceContainerRoot, input) || "";
|
|
398
414
|
return {
|
|
@@ -417,6 +433,15 @@ var OpenShellFsBridge = class {
|
|
|
417
433
|
}
|
|
418
434
|
const cwd = params.cwd ? path.resolve(params.cwd) : workspaceRoot;
|
|
419
435
|
const hostPath = path.isAbsolute(input) ? path.resolve(input) : path.resolve(cwd, input);
|
|
436
|
+
if (skillsRoot && this.sandbox.workspaceAccess === "rw") {
|
|
437
|
+
const protectedSkillShadowTarget = resolveProtectedSkillShadowTarget({
|
|
438
|
+
hostPath,
|
|
439
|
+
workspaceSkillsShadowRoot,
|
|
440
|
+
skillsRoot,
|
|
441
|
+
skillsContainerRoot
|
|
442
|
+
});
|
|
443
|
+
if (protectedSkillShadowTarget) return protectedSkillShadowTarget;
|
|
444
|
+
}
|
|
420
445
|
if (isPathInside(workspaceRoot, hostPath)) {
|
|
421
446
|
const relative = path.relative(workspaceRoot, hostPath).split(path.sep).join(path.posix.sep);
|
|
422
447
|
return {
|
|
@@ -428,6 +453,17 @@ var OpenShellFsBridge = class {
|
|
|
428
453
|
source: "workspace"
|
|
429
454
|
};
|
|
430
455
|
}
|
|
456
|
+
if (skillsRoot && this.sandbox.workspaceAccess === "rw" && isPathInside(skillsRoot, hostPath)) {
|
|
457
|
+
const relative = path.relative(skillsRoot, hostPath).split(path.sep).join(path.posix.sep);
|
|
458
|
+
return {
|
|
459
|
+
hostPath,
|
|
460
|
+
relativePath: relative ? path.posix.join(...MATERIALIZED_SKILLS_CONTAINER_PARTS, relative) : path.posix.join(...MATERIALIZED_SKILLS_CONTAINER_PARTS),
|
|
461
|
+
containerPath: relative ? path.posix.join(skillsContainerRoot, relative) : skillsContainerRoot,
|
|
462
|
+
mountHostRoot: skillsRoot,
|
|
463
|
+
writable: false,
|
|
464
|
+
source: "protectedSkill"
|
|
465
|
+
};
|
|
466
|
+
}
|
|
431
467
|
if (hasAgentMount && isPathInside(agentRoot, hostPath)) {
|
|
432
468
|
const relative = path.relative(agentRoot, hostPath).split(path.sep).join(path.posix.sep);
|
|
433
469
|
return {
|
|
@@ -442,6 +478,38 @@ var OpenShellFsBridge = class {
|
|
|
442
478
|
throw new Error(`Path escapes sandbox root (${workspaceRoot}): ${params.filePath}`);
|
|
443
479
|
}
|
|
444
480
|
};
|
|
481
|
+
function resolveProtectedSkillTarget(params) {
|
|
482
|
+
const relativeRoot = path.posix.join(...MATERIALIZED_SKILLS_CONTAINER_PARTS);
|
|
483
|
+
const normalizedInput = path.posix.normalize(params.input.replace(/\\/g, "/"));
|
|
484
|
+
const isAbsoluteContainer = normalizedInput === params.skillsContainerRoot || normalizedInput.startsWith(`${params.skillsContainerRoot}/`);
|
|
485
|
+
const isRelativeContainer = normalizedInput === relativeRoot || normalizedInput.startsWith(`${relativeRoot}/`);
|
|
486
|
+
if (!isAbsoluteContainer && !isRelativeContainer) return null;
|
|
487
|
+
const relative = isAbsoluteContainer ? path.posix.relative(params.skillsContainerRoot, normalizedInput) : path.posix.relative(relativeRoot, normalizedInput);
|
|
488
|
+
const safeRelative = relative === "." ? "" : relative;
|
|
489
|
+
return {
|
|
490
|
+
hostPath: safeRelative ? path.resolve(params.skillsRoot, ...safeRelative.split("/")) : params.skillsRoot,
|
|
491
|
+
relativePath: safeRelative ? path.posix.join(relativeRoot, safeRelative) : relativeRoot,
|
|
492
|
+
containerPath: safeRelative ? path.posix.join(params.skillsContainerRoot, safeRelative) : params.skillsContainerRoot,
|
|
493
|
+
mountHostRoot: params.skillsRoot,
|
|
494
|
+
writable: false,
|
|
495
|
+
source: "protectedSkill"
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
function resolveProtectedSkillShadowTarget(params) {
|
|
499
|
+
if (!isPathInside(params.workspaceSkillsShadowRoot, params.hostPath)) return null;
|
|
500
|
+
const relative = path.relative(params.workspaceSkillsShadowRoot, params.hostPath).split(path.sep).join(path.posix.sep);
|
|
501
|
+
const safeRelative = relative === "." ? "" : relative;
|
|
502
|
+
const hostPath = safeRelative ? path.resolve(params.skillsRoot, ...safeRelative.split("/")) : params.skillsRoot;
|
|
503
|
+
const relativeRoot = path.posix.join(...MATERIALIZED_SKILLS_CONTAINER_PARTS);
|
|
504
|
+
return {
|
|
505
|
+
hostPath,
|
|
506
|
+
relativePath: safeRelative ? path.posix.join(relativeRoot, safeRelative) : relativeRoot,
|
|
507
|
+
containerPath: safeRelative ? path.posix.join(params.skillsContainerRoot, safeRelative) : params.skillsContainerRoot,
|
|
508
|
+
mountHostRoot: params.skillsRoot,
|
|
509
|
+
writable: false,
|
|
510
|
+
source: "protectedSkill"
|
|
511
|
+
};
|
|
512
|
+
}
|
|
445
513
|
async function assertLocalPathSafety(params) {
|
|
446
514
|
if (!params.target.hostPath) throw new Error(`Missing local host path for ${params.target.containerPath}`);
|
|
447
515
|
if (!isPathInside(await fs.realpath(params.root).catch(() => path.resolve(params.root)), await resolveCanonicalCandidate(params.target.hostPath))) throw new Error(`Sandbox path escapes allowed mounts; cannot access: ${params.target.containerPath}`);
|
|
@@ -475,6 +543,47 @@ async function resolveCanonicalCandidate(targetPath) {
|
|
|
475
543
|
}
|
|
476
544
|
//#endregion
|
|
477
545
|
//#region extensions/openshell/src/backend.ts
|
|
546
|
+
const MATERIALIZED_SKILLS_REMOTE_PARTS = [".openclaw", "sandbox-skills"];
|
|
547
|
+
const ENSURE_REMOTE_REAL_DIRECTORY_SCRIPT = [
|
|
548
|
+
"set -e",
|
|
549
|
+
"target=\"$1\"",
|
|
550
|
+
"root=\"${2:-$1}\"",
|
|
551
|
+
"case \"$target\" in /*) ;; *) echo \"remote directory must be absolute: $target\" >&2; exit 1 ;; esac",
|
|
552
|
+
"case \"$root\" in /*) ;; *) echo \"remote root must be absolute: $root\" >&2; exit 1 ;; esac",
|
|
553
|
+
"target=\"${target%/}\"",
|
|
554
|
+
"root=\"${root%/}\"",
|
|
555
|
+
"[ -n \"$target\" ] || target=\"/\"",
|
|
556
|
+
"[ -n \"$root\" ] || root=\"/\"",
|
|
557
|
+
"case \"$target/\" in \"$root\"/*|\"$root/\") ;; *) echo \"remote directory must stay under root: $target\" >&2; exit 1 ;; esac",
|
|
558
|
+
"old_ifs=\"$IFS\"",
|
|
559
|
+
"IFS=\"/\"",
|
|
560
|
+
"set -- ${target#/} ${root#/}",
|
|
561
|
+
"IFS=\"$old_ifs\"",
|
|
562
|
+
"for part do",
|
|
563
|
+
" [ -n \"$part\" ] || continue",
|
|
564
|
+
" case \"$part\" in \".\"|\"..\") echo \"unsafe remote directory component: $part\" >&2; exit 1 ;; esac",
|
|
565
|
+
"done",
|
|
566
|
+
"if [ -L \"$root\" ]; then echo \"unsafe remote root symlink: $root\" >&2; exit 1; fi",
|
|
567
|
+
"mkdir -p -- \"$root\"",
|
|
568
|
+
"canonical_root=\"$(cd \"$root\" && pwd -P)\"",
|
|
569
|
+
"relative=\"${target#\"$root\"}\"",
|
|
570
|
+
"relative=\"${relative#/}\"",
|
|
571
|
+
"current=\"$canonical_root\"",
|
|
572
|
+
"IFS=\"/\"",
|
|
573
|
+
"set -- $relative",
|
|
574
|
+
"IFS=\"$old_ifs\"",
|
|
575
|
+
"for part do",
|
|
576
|
+
" [ -n \"$part\" ] || continue",
|
|
577
|
+
" if [ \"$current\" = \"/\" ]; then next=\"/$part\"; else next=\"$current/$part\"; fi",
|
|
578
|
+
" if [ -L \"$next\" ]; then echo \"unsafe remote directory symlink: $next\" >&2; exit 1; fi",
|
|
579
|
+
" if [ -e \"$next\" ]; then",
|
|
580
|
+
" if [ ! -d \"$next\" ]; then echo \"unsafe remote directory component: $next\" >&2; exit 1; fi",
|
|
581
|
+
" else",
|
|
582
|
+
" mkdir -- \"$next\"",
|
|
583
|
+
" fi",
|
|
584
|
+
" current=\"$next\"",
|
|
585
|
+
"done"
|
|
586
|
+
].join("\n");
|
|
478
587
|
function buildOpenShellSshExecEnv() {
|
|
479
588
|
return sanitizeEnvVars(process.env).allowed;
|
|
480
589
|
}
|
|
@@ -629,7 +738,7 @@ var OpenShellSandboxBackendImpl = class {
|
|
|
629
738
|
});
|
|
630
739
|
await this.ensureSandboxExists();
|
|
631
740
|
if (this.params.execContext.config.mode === "mirror") await this.syncWorkspaceToRemote();
|
|
632
|
-
else await this.maybeSeedRemoteWorkspace();
|
|
741
|
+
else if (!await this.maybeSeedRemoteWorkspace()) await this.syncSkillsWorkspaceToRemote();
|
|
633
742
|
const sshSession = await createOpenShellSshSession({ context: this.params.execContext });
|
|
634
743
|
return {
|
|
635
744
|
argv: [
|
|
@@ -662,7 +771,7 @@ var OpenShellSandboxBackendImpl = class {
|
|
|
662
771
|
}
|
|
663
772
|
async runRemoteShellScript(params) {
|
|
664
773
|
await this.ensureSandboxExists();
|
|
665
|
-
await this.maybeSeedRemoteWorkspace();
|
|
774
|
+
if (!await this.maybeSeedRemoteWorkspace()) await this.syncSkillsWorkspaceToRemote();
|
|
666
775
|
return await this.runRemoteShellScriptInternal(params);
|
|
667
776
|
}
|
|
668
777
|
async runRemoteShellScriptInternal(params) {
|
|
@@ -786,6 +895,18 @@ var OpenShellSandboxBackendImpl = class {
|
|
|
786
895
|
});
|
|
787
896
|
await this.uploadPathToRemote(this.params.createParams.agentWorkspaceDir, this.params.remoteAgentWorkspaceDir);
|
|
788
897
|
}
|
|
898
|
+
await this.syncSkillsWorkspaceToRemote();
|
|
899
|
+
}
|
|
900
|
+
async syncSkillsWorkspaceToRemote() {
|
|
901
|
+
if (this.params.createParams.cfg.workspaceAccess !== "rw" || !this.params.createParams.skillsWorkspaceDir) return;
|
|
902
|
+
const remoteSkillsWorkspaceDir = resolveRemoteMaterializedSkillsWorkspaceDir(this.params.remoteWorkspaceDir);
|
|
903
|
+
await this.runRemoteShellScriptInternal({
|
|
904
|
+
script: `${ENSURE_REMOTE_REAL_DIRECTORY_SCRIPT}\nfind "$1" -mindepth 1 -maxdepth 1 -exec rm -rf -- {} +`,
|
|
905
|
+
args: [remoteSkillsWorkspaceDir, this.params.remoteWorkspaceDir]
|
|
906
|
+
});
|
|
907
|
+
const stats = await fs.lstat(this.params.createParams.skillsWorkspaceDir).catch(() => null);
|
|
908
|
+
if (!stats?.isDirectory() || stats.isSymbolicLink()) return;
|
|
909
|
+
await this.uploadPathToRemote(this.params.createParams.skillsWorkspaceDir, remoteSkillsWorkspaceDir);
|
|
789
910
|
}
|
|
790
911
|
async syncWorkspaceFromRemote() {
|
|
791
912
|
await withTempWorkspace({
|
|
@@ -804,11 +925,23 @@ var OpenShellSandboxBackendImpl = class {
|
|
|
804
925
|
cwd: this.params.createParams.workspaceDir
|
|
805
926
|
});
|
|
806
927
|
if (result.code !== 0) throw new Error(result.stderr.trim() || "openshell sandbox download failed");
|
|
807
|
-
await
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
928
|
+
await removeMaterializedSkillsFromDownloadedWorkspace(tmpDir);
|
|
929
|
+
const preservedSandboxSkills = await moveMaterializedSkillsShadowAside({
|
|
930
|
+
workspaceDir: this.params.createParams.workspaceDir,
|
|
931
|
+
tmpDir
|
|
811
932
|
});
|
|
933
|
+
try {
|
|
934
|
+
await replaceDirectoryContents({
|
|
935
|
+
sourceDir: tmpDir,
|
|
936
|
+
targetDir: this.params.createParams.workspaceDir,
|
|
937
|
+
excludeDirs: DEFAULT_OPEN_SHELL_MIRROR_EXCLUDE_DIRS
|
|
938
|
+
});
|
|
939
|
+
} finally {
|
|
940
|
+
await restoreMaterializedSkillsShadow({
|
|
941
|
+
workspaceDir: this.params.createParams.workspaceDir,
|
|
942
|
+
preserved: preservedSandboxSkills
|
|
943
|
+
});
|
|
944
|
+
}
|
|
812
945
|
});
|
|
813
946
|
}
|
|
814
947
|
async uploadPathToRemote(localPath, remotePath) {
|
|
@@ -836,10 +969,11 @@ var OpenShellSandboxBackendImpl = class {
|
|
|
836
969
|
});
|
|
837
970
|
}
|
|
838
971
|
async maybeSeedRemoteWorkspace() {
|
|
839
|
-
if (!this.remoteSeedPending) return;
|
|
972
|
+
if (!this.remoteSeedPending) return false;
|
|
840
973
|
this.remoteSeedPending = false;
|
|
841
974
|
try {
|
|
842
975
|
await this.syncWorkspaceToRemote();
|
|
976
|
+
return true;
|
|
843
977
|
} catch (error) {
|
|
844
978
|
this.remoteSeedPending = true;
|
|
845
979
|
throw error;
|
|
@@ -857,6 +991,79 @@ function buildOpenShellSandboxName(scopeKey) {
|
|
|
857
991
|
const hash = Array.from(trimmed).reduce((acc, char) => (acc * 33 ^ char.charCodeAt(0)) >>> 0, 5381);
|
|
858
992
|
return `openclaw-${safe || "session"}-${hash.toString(16).slice(0, 8)}`;
|
|
859
993
|
}
|
|
994
|
+
function resolveRemoteMaterializedSkillsWorkspaceDir(remoteWorkspaceDir) {
|
|
995
|
+
const root = remoteWorkspaceDir.replace(/\\/g, "/").replace(/\/+$/, "") || "/";
|
|
996
|
+
return path.posix.join(root, ...MATERIALIZED_SKILLS_REMOTE_PARTS);
|
|
997
|
+
}
|
|
998
|
+
async function removeMaterializedSkillsFromDownloadedWorkspace(tmpDir) {
|
|
999
|
+
let cursor = tmpDir;
|
|
1000
|
+
for (const [index, part] of MATERIALIZED_SKILLS_REMOTE_PARTS.entries()) {
|
|
1001
|
+
const next = path.join(cursor, part);
|
|
1002
|
+
const stats = await fs.lstat(next).catch(() => null);
|
|
1003
|
+
if (!stats) return;
|
|
1004
|
+
if (index === MATERIALIZED_SKILLS_REMOTE_PARTS.length - 1) {
|
|
1005
|
+
await fs.rm(next, {
|
|
1006
|
+
recursive: true,
|
|
1007
|
+
force: true
|
|
1008
|
+
});
|
|
1009
|
+
return;
|
|
1010
|
+
}
|
|
1011
|
+
if (stats.isSymbolicLink() || !stats.isDirectory()) {
|
|
1012
|
+
await fs.rm(next, {
|
|
1013
|
+
recursive: true,
|
|
1014
|
+
force: true
|
|
1015
|
+
});
|
|
1016
|
+
return;
|
|
1017
|
+
}
|
|
1018
|
+
cursor = next;
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
async function moveMaterializedSkillsShadowAside(params) {
|
|
1022
|
+
const shadowPath = path.join(params.workspaceDir, ...MATERIALIZED_SKILLS_REMOTE_PARTS);
|
|
1023
|
+
const parentStats = await fs.lstat(path.dirname(shadowPath)).catch(() => null);
|
|
1024
|
+
if (!parentStats?.isDirectory() || parentStats.isSymbolicLink()) return;
|
|
1025
|
+
const shadowStats = await fs.lstat(shadowPath).catch(() => null);
|
|
1026
|
+
if (!shadowStats || shadowStats.isSymbolicLink()) return;
|
|
1027
|
+
const preserveRoot = await fs.mkdtemp(path.join(path.dirname(params.tmpDir), "openclaw-openshell-preserve-"));
|
|
1028
|
+
const preservedPath = path.join(preserveRoot, "sandbox-skills");
|
|
1029
|
+
await movePathWithCopyFallback({
|
|
1030
|
+
from: shadowPath,
|
|
1031
|
+
to: preservedPath
|
|
1032
|
+
});
|
|
1033
|
+
return {
|
|
1034
|
+
preservedPath,
|
|
1035
|
+
preserveRoot
|
|
1036
|
+
};
|
|
1037
|
+
}
|
|
1038
|
+
async function restoreMaterializedSkillsShadow(params) {
|
|
1039
|
+
if (!params.preserved) return;
|
|
1040
|
+
let restored = false;
|
|
1041
|
+
try {
|
|
1042
|
+
const shadowPath = path.join(params.workspaceDir, ...MATERIALIZED_SKILLS_REMOTE_PARTS);
|
|
1043
|
+
const parentPath = path.dirname(shadowPath);
|
|
1044
|
+
const parentStats = await fs.lstat(parentPath).catch(() => null);
|
|
1045
|
+
if (parentStats?.isSymbolicLink()) throw new Error(`Refusing to restore sandbox skills through symlink parent: ${parentPath}`);
|
|
1046
|
+
if (parentStats && !parentStats.isDirectory()) await fs.rm(parentPath, {
|
|
1047
|
+
recursive: true,
|
|
1048
|
+
force: true
|
|
1049
|
+
});
|
|
1050
|
+
await fs.mkdir(parentPath, { recursive: true });
|
|
1051
|
+
await fs.rm(shadowPath, {
|
|
1052
|
+
recursive: true,
|
|
1053
|
+
force: true
|
|
1054
|
+
});
|
|
1055
|
+
await movePathWithCopyFallback({
|
|
1056
|
+
from: params.preserved.preservedPath,
|
|
1057
|
+
to: shadowPath
|
|
1058
|
+
});
|
|
1059
|
+
restored = true;
|
|
1060
|
+
} finally {
|
|
1061
|
+
if (restored) await fs.rm(params.preserved.preserveRoot, {
|
|
1062
|
+
recursive: true,
|
|
1063
|
+
force: true
|
|
1064
|
+
});
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
860
1067
|
function resolveOpenShellTmpRoot() {
|
|
861
1068
|
return path.resolve(resolvePreferredOpenClawTmpDir());
|
|
862
1069
|
}
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/openshell-sandbox",
|
|
3
|
-
"version": "2026.6.5-beta.
|
|
3
|
+
"version": "2026.6.5-beta.3",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@openclaw/openshell-sandbox",
|
|
9
|
-
"version": "2026.6.5-beta.
|
|
9
|
+
"version": "2026.6.5-beta.3",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"zod": "4.4.3"
|
|
12
12
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/openshell-sandbox",
|
|
3
|
-
"version": "2026.6.5-beta.
|
|
3
|
+
"version": "2026.6.5-beta.3",
|
|
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",
|
|
@@ -20,10 +20,10 @@
|
|
|
20
20
|
"minHostVersion": ">=2026.5.12-beta.1"
|
|
21
21
|
},
|
|
22
22
|
"compat": {
|
|
23
|
-
"pluginApi": ">=2026.6.5-beta.
|
|
23
|
+
"pluginApi": ">=2026.6.5-beta.3"
|
|
24
24
|
},
|
|
25
25
|
"build": {
|
|
26
|
-
"openclawVersion": "2026.6.5-beta.
|
|
26
|
+
"openclawVersion": "2026.6.5-beta.3",
|
|
27
27
|
"bundledDist": false
|
|
28
28
|
},
|
|
29
29
|
"release": {
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"README.md"
|
|
42
42
|
],
|
|
43
43
|
"peerDependencies": {
|
|
44
|
-
"openclaw": ">=2026.6.5-beta.
|
|
44
|
+
"openclaw": ">=2026.6.5-beta.3"
|
|
45
45
|
},
|
|
46
46
|
"peerDependenciesMeta": {
|
|
47
47
|
"openclaw": {
|