






















@@ -1,14 +1,47 @@
1-import { describe, expect, it, vi } from "vitest";
1+import fs from "node:fs/promises";
2+import os from "node:os";
3+import path from "node:path";
4+import { afterAll, beforeAll, describe, expect, it, vi } from "vitest";
25import type { OpenClawConfig } from "../config/config.js";
36import { registerSandboxBackend } from "./sandbox/backend.js";
47import { ensureSandboxWorkspaceForSession, resolveSandboxContext } from "./sandbox/context.js";
5869const updateRegistryMock = vi.hoisted(() => vi.fn());
10+const syncSkillsToWorkspaceMock = vi.hoisted(() => vi.fn(async () => undefined));
711812vi.mock("./sandbox/registry.js", () => ({
913updateRegistry: updateRegistryMock,
1014}));
111516+vi.mock("../infra/skills-remote.js", () => ({
17+getRemoteSkillEligibility: vi.fn(() => ({ note: "test-remote" })),
18+}));
19+20+vi.mock("./exec-defaults.js", () => ({
21+canExecRequestNode: vi.fn(() => false),
22+}));
23+24+vi.mock("./skills.js", () => ({
25+syncSkillsToWorkspace: syncSkillsToWorkspaceMock,
26+}));
27+28+let sandboxFixtureRoot = "";
29+let sandboxFixtureCount = 0;
30+31+async function createSandboxFixtureDir(prefix: string): Promise<string> {
32+const dir = path.join(sandboxFixtureRoot, `${prefix}-${sandboxFixtureCount++}`);
33+await fs.mkdir(dir, { recursive: true });
34+return dir;
35+}
36+37+beforeAll(async () => {
38+sandboxFixtureRoot = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-sandbox-context-"));
39+});
40+41+afterAll(async () => {
42+await fs.rm(sandboxFixtureRoot, { recursive: true, force: true });
43+});
44+1245describe("resolveSandboxContext", () => {
1346it("does not sandbox the agent main session in non-main mode", async () => {
1447const cfg: OpenClawConfig = {
@@ -138,4 +171,40 @@ describe("resolveSandboxContext", () => {
138171restore();
139172}
140173}, 15_000);
174+175+it("requests skill sync for read-only sandbox workspaces", async () => {
176+syncSkillsToWorkspaceMock.mockClear();
177+const bundledDir = await createSandboxFixtureDir("bundled");
178+const workspaceDir = await createSandboxFixtureDir("workspace");
179+180+const cfg: OpenClawConfig = {
181+agents: {
182+defaults: {
183+sandbox: {
184+mode: "all",
185+scope: "session",
186+workspaceAccess: "ro",
187+workspaceRoot: path.join(bundledDir, "sandboxes"),
188+},
189+},
190+},
191+};
192+193+const result = await ensureSandboxWorkspaceForSession({
194+config: cfg,
195+sessionKey: "agent:main:main",
196+ workspaceDir,
197+});
198+199+expect(result).not.toBeNull();
200+expect(syncSkillsToWorkspaceMock).toHaveBeenCalledWith(
201+expect.objectContaining({
202+sourceWorkspaceDir: workspaceDir,
203+targetWorkspaceDir: result?.workspaceDir,
204+config: cfg,
205+agentId: "main",
206+eligibility: { remote: { note: "test-remote" } },
207+}),
208+);
209+}, 15_000);
141210});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。