@openclaw/openshell-sandbox 2026.6.8 → 2026.6.9-beta.1
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 +216 -47
- package/npm-shrinkwrap.json +2 -2
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -312,12 +312,8 @@ var OpenShellFsBridge = class {
|
|
|
312
312
|
allowMissingLeaf: true,
|
|
313
313
|
allowFinalSymlinkForUnlink: false
|
|
314
314
|
});
|
|
315
|
+
await this.backend.mkdirpRemotePath(target.containerPath, params.signal);
|
|
315
316
|
await fs.mkdir(hostPath, { recursive: true });
|
|
316
|
-
await this.backend.runRemoteShellScript({
|
|
317
|
-
script: "mkdir -p -- \"$1\"",
|
|
318
|
-
args: [target.containerPath],
|
|
319
|
-
signal: params.signal
|
|
320
|
-
});
|
|
321
317
|
}
|
|
322
318
|
async remove(params) {
|
|
323
319
|
const target = this.resolveTarget(params);
|
|
@@ -329,16 +325,15 @@ var OpenShellFsBridge = class {
|
|
|
329
325
|
allowMissingLeaf: params.force !== false,
|
|
330
326
|
allowFinalSymlinkForUnlink: true
|
|
331
327
|
});
|
|
328
|
+
await this.backend.removeRemotePath(target.containerPath, {
|
|
329
|
+
recursive: params.recursive ?? false,
|
|
330
|
+
signal: params.signal,
|
|
331
|
+
ignoreMissing: params.force !== false
|
|
332
|
+
});
|
|
332
333
|
await fs.rm(hostPath, {
|
|
333
334
|
recursive: params.recursive ?? false,
|
|
334
335
|
force: params.force !== false
|
|
335
336
|
});
|
|
336
|
-
await this.backend.runRemoteShellScript({
|
|
337
|
-
script: params.recursive ? "rm -rf -- \"$1\"" : "if [ -d \"$1\" ] && [ ! -L \"$1\" ]; then rmdir -- \"$1\"; elif [ -e \"$1\" ] || [ -L \"$1\" ]; then rm -f -- \"$1\"; fi",
|
|
338
|
-
args: [target.containerPath],
|
|
339
|
-
signal: params.signal,
|
|
340
|
-
allowFailure: params.force !== false
|
|
341
|
-
});
|
|
342
337
|
}
|
|
343
338
|
async rename(params) {
|
|
344
339
|
const { from, to } = this.resolveRenameTargets(params);
|
|
@@ -356,16 +351,12 @@ var OpenShellFsBridge = class {
|
|
|
356
351
|
allowMissingLeaf: true,
|
|
357
352
|
allowFinalSymlinkForUnlink: false
|
|
358
353
|
});
|
|
354
|
+
await this.backend.renameRemotePath(from.containerPath, to.containerPath, params.signal);
|
|
359
355
|
await fs.mkdir(path.dirname(toHostPath), { recursive: true });
|
|
360
356
|
await movePathWithCopyFallback({
|
|
361
357
|
from: fromHostPath,
|
|
362
358
|
to: toHostPath
|
|
363
359
|
});
|
|
364
|
-
await this.backend.runRemoteShellScript({
|
|
365
|
-
script: "mkdir -p -- \"$(dirname -- \"$2\")\" && mv -- \"$1\" \"$2\"",
|
|
366
|
-
args: [from.containerPath, to.containerPath],
|
|
367
|
-
signal: params.signal
|
|
368
|
-
});
|
|
369
360
|
}
|
|
370
361
|
async stat(params) {
|
|
371
362
|
const target = this.resolveTarget(params);
|
|
@@ -544,7 +535,108 @@ async function resolveCanonicalCandidate(targetPath) {
|
|
|
544
535
|
//#endregion
|
|
545
536
|
//#region extensions/openshell/src/backend.ts
|
|
546
537
|
const MATERIALIZED_SKILLS_REMOTE_PARTS = [".openclaw", "sandbox-skills"];
|
|
547
|
-
const
|
|
538
|
+
const PINNED_REMOTE_PATH_MUTATION_SCRIPT = [
|
|
539
|
+
"set -eu",
|
|
540
|
+
"die() { echo \"$1\" >&2; exit 1; }",
|
|
541
|
+
"validate_basename() {",
|
|
542
|
+
" case \"$1\" in \"\"|\".\"|\"..\"|*/*) die \"unsafe remote basename: $1\" ;; esac",
|
|
543
|
+
"}",
|
|
544
|
+
"pin_dir() {",
|
|
545
|
+
" root=\"$1\"",
|
|
546
|
+
" relative=\"$2\"",
|
|
547
|
+
" create=\"$3\"",
|
|
548
|
+
" case \"$root\" in /*) ;; *) die \"remote root must be absolute: $root\" ;; esac",
|
|
549
|
+
" root=\"${root%/}\"",
|
|
550
|
+
" [ -n \"$root\" ] || root=\"/\"",
|
|
551
|
+
" if [ -L \"$root\" ]; then die \"unsafe remote root symlink: $root\"; fi",
|
|
552
|
+
" mkdir -p -- \"$root\"",
|
|
553
|
+
" canonical_root=\"$(cd \"$root\" && pwd -P)\"",
|
|
554
|
+
" current=\"$canonical_root\"",
|
|
555
|
+
" relative=\"${relative#/}\"",
|
|
556
|
+
" while [ -n \"$relative\" ]; do",
|
|
557
|
+
" part=\"${relative%%/*}\"",
|
|
558
|
+
" if [ \"$part\" = \"$relative\" ]; then relative=\"\"; else relative=\"${relative#*/}\"; fi",
|
|
559
|
+
" [ -n \"$part\" ] || continue",
|
|
560
|
+
" case \"$part\" in \".\"|\"..\") die \"unsafe remote directory component: $part\" ;; esac",
|
|
561
|
+
" if [ \"$current\" = \"/\" ]; then next=\"/$part\"; else next=\"$current/$part\"; fi",
|
|
562
|
+
" if [ -L \"$next\" ]; then die \"unsafe remote directory symlink: $next\"; fi",
|
|
563
|
+
" if [ -e \"$next\" ]; then",
|
|
564
|
+
" if [ ! -d \"$next\" ]; then die \"unsafe remote directory component: $next\"; fi",
|
|
565
|
+
" else",
|
|
566
|
+
" if [ \"$create\" != \"1\" ]; then die \"remote directory not found: $next\"; fi",
|
|
567
|
+
" mkdir -- \"$next\"",
|
|
568
|
+
" fi",
|
|
569
|
+
" current=\"$next\"",
|
|
570
|
+
" done",
|
|
571
|
+
" printf \"%s\\n\" \"$current\"",
|
|
572
|
+
"}",
|
|
573
|
+
"pin_dir_or_missing() {",
|
|
574
|
+
" root=\"$1\"",
|
|
575
|
+
" relative=\"$2\"",
|
|
576
|
+
" missing_ok=\"$3\"",
|
|
577
|
+
" case \"$root\" in /*) ;; *) die \"remote root must be absolute: $root\" ;; esac",
|
|
578
|
+
" root=\"${root%/}\"",
|
|
579
|
+
" [ -n \"$root\" ] || root=\"/\"",
|
|
580
|
+
" if [ -L \"$root\" ]; then die \"unsafe remote root symlink: $root\"; fi",
|
|
581
|
+
" if [ ! -d \"$root\" ]; then",
|
|
582
|
+
" if [ -e \"$root\" ]; then die \"unsafe remote root component: $root\"; fi",
|
|
583
|
+
" if [ \"$missing_ok\" = \"1\" ]; then printf \"\\n\"; return 0; fi",
|
|
584
|
+
" die \"remote directory not found: $root\"",
|
|
585
|
+
" fi",
|
|
586
|
+
" canonical_root=\"$(cd \"$root\" && pwd -P)\"",
|
|
587
|
+
" current=\"$canonical_root\"",
|
|
588
|
+
" relative=\"${relative#/}\"",
|
|
589
|
+
" while [ -n \"$relative\" ]; do",
|
|
590
|
+
" part=\"${relative%%/*}\"",
|
|
591
|
+
" if [ \"$part\" = \"$relative\" ]; then relative=\"\"; else relative=\"${relative#*/}\"; fi",
|
|
592
|
+
" [ -n \"$part\" ] || continue",
|
|
593
|
+
" case \"$part\" in \".\"|\"..\") die \"unsafe remote directory component: $part\" ;; esac",
|
|
594
|
+
" if [ \"$current\" = \"/\" ]; then next=\"/$part\"; else next=\"$current/$part\"; fi",
|
|
595
|
+
" if [ -L \"$next\" ]; then die \"unsafe remote directory symlink: $next\"; fi",
|
|
596
|
+
" if [ -e \"$next\" ]; then",
|
|
597
|
+
" if [ ! -d \"$next\" ]; then die \"unsafe remote directory component: $next\"; fi",
|
|
598
|
+
" else",
|
|
599
|
+
" if [ \"$missing_ok\" = \"1\" ]; then printf \"\\n\"; return 0; fi",
|
|
600
|
+
" die \"remote directory not found: $next\"",
|
|
601
|
+
" fi",
|
|
602
|
+
" current=\"$next\"",
|
|
603
|
+
" done",
|
|
604
|
+
" printf \"%s\\n\" \"$current\"",
|
|
605
|
+
"}",
|
|
606
|
+
"operation=\"$1\"",
|
|
607
|
+
"case \"$operation\" in",
|
|
608
|
+
" mkdirp)",
|
|
609
|
+
" pin_dir \"$2\" \"$3\" 1 >/dev/null",
|
|
610
|
+
" ;;",
|
|
611
|
+
" remove)",
|
|
612
|
+
" validate_basename \"$4\"",
|
|
613
|
+
" parent=\"$(pin_dir_or_missing \"$2\" \"$3\" \"${5:-0}\")\"",
|
|
614
|
+
" [ -n \"$parent\" ] || exit 0",
|
|
615
|
+
" target=\"$parent/$4\"",
|
|
616
|
+
" if [ -d \"$target\" ] && [ ! -L \"$target\" ]; then rm -rf -- \"$target\"; elif [ -e \"$target\" ] || [ -L \"$target\" ]; then rm -f -- \"$target\"; fi",
|
|
617
|
+
" ;;",
|
|
618
|
+
" removefile)",
|
|
619
|
+
" validate_basename \"$4\"",
|
|
620
|
+
" parent=\"$(pin_dir_or_missing \"$2\" \"$3\" \"${5:-0}\")\"",
|
|
621
|
+
" [ -n \"$parent\" ] || exit 0",
|
|
622
|
+
" target=\"$parent/$4\"",
|
|
623
|
+
" if [ -d \"$target\" ] && [ ! -L \"$target\" ]; then rmdir -- \"$target\"; elif [ -e \"$target\" ] || [ -L \"$target\" ]; then rm -f -- \"$target\"; fi",
|
|
624
|
+
" ;;",
|
|
625
|
+
" rename)",
|
|
626
|
+
" src_parent=\"$(pin_dir \"$2\" \"$3\" 0)\"",
|
|
627
|
+
" validate_basename \"$4\"",
|
|
628
|
+
" dst_parent=\"$(pin_dir \"$5\" \"$6\" 1)\"",
|
|
629
|
+
" validate_basename \"$7\"",
|
|
630
|
+
" if [ -L \"$dst_parent/$7\" ]; then die \"unsafe remote rename target symlink: $dst_parent/$7\"; fi",
|
|
631
|
+
" if [ -d \"$dst_parent/$7\" ]; then die \"unsafe remote rename target directory: $dst_parent/$7\"; fi",
|
|
632
|
+
" mv -- \"$src_parent/$4\" \"$dst_parent/$7\"",
|
|
633
|
+
" ;;",
|
|
634
|
+
" *)",
|
|
635
|
+
" die \"unknown remote path mutation: $operation\"",
|
|
636
|
+
" ;;",
|
|
637
|
+
"esac"
|
|
638
|
+
].join("\n");
|
|
639
|
+
const ENSURE_OPEN_SHELL_REMOTE_REAL_DIRECTORY_SCRIPT = [
|
|
548
640
|
"set -e",
|
|
549
641
|
"target=\"$1\"",
|
|
550
642
|
"root=\"${2:-$1}\"",
|
|
@@ -555,13 +647,14 @@ const ENSURE_REMOTE_REAL_DIRECTORY_SCRIPT = [
|
|
|
555
647
|
"[ -n \"$target\" ] || target=\"/\"",
|
|
556
648
|
"[ -n \"$root\" ] || root=\"/\"",
|
|
557
649
|
"case \"$target/\" in \"$root\"/*|\"$root/\") ;; *) echo \"remote directory must stay under root: $target\" >&2; exit 1 ;; esac",
|
|
558
|
-
"
|
|
559
|
-
"
|
|
560
|
-
"
|
|
561
|
-
"
|
|
562
|
-
"
|
|
563
|
-
"
|
|
564
|
-
"
|
|
650
|
+
"for path_to_check in \"$target\" \"$root\"; do",
|
|
651
|
+
" relative=\"${path_to_check#/}\"",
|
|
652
|
+
" while [ -n \"$relative\" ]; do",
|
|
653
|
+
" part=\"${relative%%/*}\"",
|
|
654
|
+
" if [ \"$part\" = \"$relative\" ]; then relative=\"\"; else relative=\"${relative#*/}\"; fi",
|
|
655
|
+
" [ -n \"$part\" ] || continue",
|
|
656
|
+
" case \"$part\" in \".\"|\"..\") echo \"unsafe remote directory component: $part\" >&2; exit 1 ;; esac",
|
|
657
|
+
" done",
|
|
565
658
|
"done",
|
|
566
659
|
"if [ -L \"$root\" ]; then echo \"unsafe remote root symlink: $root\" >&2; exit 1; fi",
|
|
567
660
|
"mkdir -p -- \"$root\"",
|
|
@@ -569,10 +662,9 @@ const ENSURE_REMOTE_REAL_DIRECTORY_SCRIPT = [
|
|
|
569
662
|
"relative=\"${target#\"$root\"}\"",
|
|
570
663
|
"relative=\"${relative#/}\"",
|
|
571
664
|
"current=\"$canonical_root\"",
|
|
572
|
-
"
|
|
573
|
-
"
|
|
574
|
-
"
|
|
575
|
-
"for part do",
|
|
665
|
+
"while [ -n \"$relative\" ]; do",
|
|
666
|
+
" part=\"${relative%%/*}\"",
|
|
667
|
+
" if [ \"$part\" = \"$relative\" ]; then relative=\"\"; else relative=\"${relative#*/}\"; fi",
|
|
576
668
|
" [ -n \"$part\" ] || continue",
|
|
577
669
|
" if [ \"$current\" = \"/\" ]; then next=\"/$part\"; else next=\"$current/$part\"; fi",
|
|
578
670
|
" if [ -L \"$next\" ]; then echo \"unsafe remote directory symlink: $next\" >&2; exit 1; fi",
|
|
@@ -680,6 +772,9 @@ async function createOpenShellSandboxBackend(params) {
|
|
|
680
772
|
remoteWorkspaceDir: params.pluginConfig.remoteWorkspaceDir,
|
|
681
773
|
remoteAgentWorkspaceDir: params.pluginConfig.remoteAgentWorkspaceDir,
|
|
682
774
|
runRemoteShellScript: async (command) => await impl.runRemoteShellScript(command),
|
|
775
|
+
mkdirpRemotePath: async (remotePath, signal) => await impl.mkdirpRemotePath(remotePath, signal),
|
|
776
|
+
removeRemotePath: async (remotePath, removeParams) => await impl.removeRemotePath(remotePath, removeParams),
|
|
777
|
+
renameRemotePath: async (fromRemotePath, toRemotePath, signal) => await impl.renameRemotePath(fromRemotePath, toRemotePath, signal),
|
|
683
778
|
syncLocalPathToRemote: async (localPath, remotePath) => await impl.syncLocalPathToRemote(localPath, remotePath)
|
|
684
779
|
};
|
|
685
780
|
}
|
|
@@ -727,6 +822,9 @@ var OpenShellSandboxBackendImpl = class {
|
|
|
727
822
|
backend: this.asHandle()
|
|
728
823
|
}),
|
|
729
824
|
runRemoteShellScript: async (command) => await this.runRemoteShellScript(command),
|
|
825
|
+
mkdirpRemotePath: async (remotePath, signal) => await this.mkdirpRemotePath(remotePath, signal),
|
|
826
|
+
removeRemotePath: async (remotePath, removeParams) => await this.removeRemotePath(remotePath, removeParams),
|
|
827
|
+
renameRemotePath: async (fromRemotePath, toRemotePath, signal) => await this.renameRemotePath(fromRemotePath, toRemotePath, signal),
|
|
730
828
|
syncLocalPathToRemote: async (localPath, remotePath) => await this.syncLocalPathToRemote(localPath, remotePath)
|
|
731
829
|
};
|
|
732
830
|
}
|
|
@@ -774,6 +872,46 @@ var OpenShellSandboxBackendImpl = class {
|
|
|
774
872
|
if (!await this.maybeSeedRemoteWorkspace()) await this.syncSkillsWorkspaceToRemote();
|
|
775
873
|
return await this.runRemoteShellScriptInternal(params);
|
|
776
874
|
}
|
|
875
|
+
async mkdirpRemotePath(remotePath, signal) {
|
|
876
|
+
const target = this.resolveRemoteTarget(remotePath);
|
|
877
|
+
await this.runPinnedRemotePathMutation({
|
|
878
|
+
args: [
|
|
879
|
+
"mkdirp",
|
|
880
|
+
target.root,
|
|
881
|
+
target.relativePath
|
|
882
|
+
],
|
|
883
|
+
signal
|
|
884
|
+
});
|
|
885
|
+
}
|
|
886
|
+
async removeRemotePath(remotePath, params) {
|
|
887
|
+
const target = this.resolveRemoteTarget(remotePath);
|
|
888
|
+
await this.runPinnedRemotePathMutation({
|
|
889
|
+
args: [
|
|
890
|
+
params?.recursive ? "remove" : "removefile",
|
|
891
|
+
target.root,
|
|
892
|
+
path.posix.dirname(target.relativePath) === "." ? "" : path.posix.dirname(target.relativePath),
|
|
893
|
+
path.posix.basename(target.relativePath),
|
|
894
|
+
params?.ignoreMissing ? "1" : "0"
|
|
895
|
+
],
|
|
896
|
+
signal: params?.signal
|
|
897
|
+
});
|
|
898
|
+
}
|
|
899
|
+
async renameRemotePath(fromRemotePath, toRemotePath, signal) {
|
|
900
|
+
const from = this.resolveRemoteTarget(fromRemotePath);
|
|
901
|
+
const to = this.resolveRemoteTarget(toRemotePath);
|
|
902
|
+
await this.runPinnedRemotePathMutation({
|
|
903
|
+
args: [
|
|
904
|
+
"rename",
|
|
905
|
+
from.root,
|
|
906
|
+
path.posix.dirname(from.relativePath) === "." ? "" : path.posix.dirname(from.relativePath),
|
|
907
|
+
path.posix.basename(from.relativePath),
|
|
908
|
+
to.root,
|
|
909
|
+
path.posix.dirname(to.relativePath) === "." ? "" : path.posix.dirname(to.relativePath),
|
|
910
|
+
path.posix.basename(to.relativePath)
|
|
911
|
+
],
|
|
912
|
+
signal
|
|
913
|
+
});
|
|
914
|
+
}
|
|
777
915
|
async runRemoteShellScriptInternal(params) {
|
|
778
916
|
const session = await createOpenShellSshSession({ context: this.params.execContext });
|
|
779
917
|
try {
|
|
@@ -797,34 +935,37 @@ var OpenShellSandboxBackendImpl = class {
|
|
|
797
935
|
async syncLocalPathToRemote(localPath, remotePath) {
|
|
798
936
|
await this.ensureSandboxExists();
|
|
799
937
|
await this.maybeSeedRemoteWorkspace();
|
|
938
|
+
const target = this.resolveRemoteTarget(remotePath);
|
|
800
939
|
const stats = await fs.lstat(localPath).catch(() => null);
|
|
801
940
|
if (!stats) {
|
|
802
|
-
await this.
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
941
|
+
await this.runPinnedRemotePathMutation({ args: [
|
|
942
|
+
"remove",
|
|
943
|
+
target.root,
|
|
944
|
+
path.posix.dirname(target.relativePath) === "." ? "" : path.posix.dirname(target.relativePath),
|
|
945
|
+
path.posix.basename(target.relativePath),
|
|
946
|
+
"1"
|
|
947
|
+
] });
|
|
807
948
|
return;
|
|
808
949
|
}
|
|
809
950
|
if (stats.isSymbolicLink()) {
|
|
810
|
-
await this.
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
951
|
+
await this.runPinnedRemotePathMutation({ args: [
|
|
952
|
+
"remove",
|
|
953
|
+
target.root,
|
|
954
|
+
path.posix.dirname(target.relativePath) === "." ? "" : path.posix.dirname(target.relativePath),
|
|
955
|
+
path.posix.basename(target.relativePath),
|
|
956
|
+
"1"
|
|
957
|
+
] });
|
|
815
958
|
return;
|
|
816
959
|
}
|
|
817
960
|
if (stats.isDirectory()) {
|
|
818
|
-
await this.
|
|
819
|
-
script: "mkdir -p -- \"$1\"",
|
|
820
|
-
args: [remotePath]
|
|
821
|
-
});
|
|
961
|
+
await this.mkdirpRemotePath(remotePath);
|
|
822
962
|
return;
|
|
823
963
|
}
|
|
824
|
-
await this.
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
964
|
+
await this.runPinnedRemotePathMutation({ args: [
|
|
965
|
+
"mkdirp",
|
|
966
|
+
target.root,
|
|
967
|
+
path.posix.dirname(target.relativePath) === "." ? "" : path.posix.dirname(target.relativePath)
|
|
968
|
+
] });
|
|
828
969
|
const result = await runOpenShellCli({
|
|
829
970
|
context: this.params.execContext,
|
|
830
971
|
args: [
|
|
@@ -839,6 +980,25 @@ var OpenShellSandboxBackendImpl = class {
|
|
|
839
980
|
});
|
|
840
981
|
if (result.code !== 0) throw new Error(result.stderr.trim() || "openshell sandbox upload failed");
|
|
841
982
|
}
|
|
983
|
+
async runPinnedRemotePathMutation(params) {
|
|
984
|
+
return await this.runRemoteShellScript({
|
|
985
|
+
script: PINNED_REMOTE_PATH_MUTATION_SCRIPT,
|
|
986
|
+
args: params.args,
|
|
987
|
+
signal: params.signal
|
|
988
|
+
});
|
|
989
|
+
}
|
|
990
|
+
resolveRemoteTarget(remotePath) {
|
|
991
|
+
const normalized = normalizeRemotePath(remotePath);
|
|
992
|
+
const roots = [normalizeRemotePath(this.params.remoteWorkspaceDir), normalizeRemotePath(this.params.remoteAgentWorkspaceDir)].toSorted((a, b) => b.length - a.length);
|
|
993
|
+
for (const root of roots) if (isRemotePathInside(root, normalized)) {
|
|
994
|
+
const relativePath = path.posix.relative(root, normalized);
|
|
995
|
+
return {
|
|
996
|
+
root,
|
|
997
|
+
relativePath: relativePath === "." ? "" : relativePath
|
|
998
|
+
};
|
|
999
|
+
}
|
|
1000
|
+
throw new Error(`Remote path escapes OpenShell managed roots: ${remotePath}`);
|
|
1001
|
+
}
|
|
842
1002
|
async ensureSandboxExists() {
|
|
843
1003
|
if (this.ensurePromise) return await this.ensurePromise;
|
|
844
1004
|
this.ensurePromise = this.ensureSandboxExistsInner();
|
|
@@ -901,7 +1061,7 @@ var OpenShellSandboxBackendImpl = class {
|
|
|
901
1061
|
if (this.params.createParams.cfg.workspaceAccess !== "rw" || !this.params.createParams.skillsWorkspaceDir) return;
|
|
902
1062
|
const remoteSkillsWorkspaceDir = resolveRemoteMaterializedSkillsWorkspaceDir(this.params.remoteWorkspaceDir);
|
|
903
1063
|
await this.runRemoteShellScriptInternal({
|
|
904
|
-
script: `${
|
|
1064
|
+
script: `${ENSURE_OPEN_SHELL_REMOTE_REAL_DIRECTORY_SCRIPT}\nfind "$1" -mindepth 1 -maxdepth 1 -exec rm -rf -- {} +`,
|
|
905
1065
|
args: [remoteSkillsWorkspaceDir, this.params.remoteWorkspaceDir]
|
|
906
1066
|
});
|
|
907
1067
|
const stats = await fs.lstat(this.params.createParams.skillsWorkspaceDir).catch(() => null);
|
|
@@ -1067,6 +1227,15 @@ async function restoreMaterializedSkillsShadow(params) {
|
|
|
1067
1227
|
function resolveOpenShellTmpRoot() {
|
|
1068
1228
|
return path.resolve(resolvePreferredOpenClawTmpDir());
|
|
1069
1229
|
}
|
|
1230
|
+
function normalizeRemotePath(remotePath) {
|
|
1231
|
+
const normalized = path.posix.normalize(remotePath.replace(/\\/g, "/"));
|
|
1232
|
+
if (!path.posix.isAbsolute(normalized)) throw new Error(`OpenShell remote path must be absolute: ${remotePath}`);
|
|
1233
|
+
return normalized;
|
|
1234
|
+
}
|
|
1235
|
+
function isRemotePathInside(root, candidate) {
|
|
1236
|
+
const relative = path.posix.relative(root, candidate);
|
|
1237
|
+
return relative === "" || relative !== ".." && !relative.startsWith("../") && !path.posix.isAbsolute(relative);
|
|
1238
|
+
}
|
|
1070
1239
|
//#endregion
|
|
1071
1240
|
//#region extensions/openshell/index.ts
|
|
1072
1241
|
var openshell_default = definePluginEntry({
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/openshell-sandbox",
|
|
3
|
-
"version": "2026.6.
|
|
3
|
+
"version": "2026.6.9-beta.1",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@openclaw/openshell-sandbox",
|
|
9
|
-
"version": "2026.6.
|
|
9
|
+
"version": "2026.6.9-beta.1",
|
|
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.
|
|
3
|
+
"version": "2026.6.9-beta.1",
|
|
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.
|
|
23
|
+
"pluginApi": ">=2026.6.9-beta.1"
|
|
24
24
|
},
|
|
25
25
|
"build": {
|
|
26
|
-
"openclawVersion": "2026.6.
|
|
26
|
+
"openclawVersion": "2026.6.9-beta.1",
|
|
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.
|
|
44
|
+
"openclaw": ">=2026.6.9-beta.1"
|
|
45
45
|
},
|
|
46
46
|
"peerDependenciesMeta": {
|
|
47
47
|
"openclaw": {
|