refactor(agent): dedupe harness and command workflows

This commit is contained in:
Peter Steinberger
2026-02-16 14:52:09 +00:00
parent 04892ee230
commit f717a13039
204 changed files with 7366 additions and 11540 deletions

View File

@@ -88,19 +88,28 @@ function createSandbox(params: {
};
}
async function withUnsafeMountedSandboxHarness(
run: (ctx: { sandboxRoot: string; agentRoot: string; sandbox: SandboxContext }) => Promise<void>,
) {
const stateDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-sbx-mounts-"));
const sandboxRoot = path.join(stateDir, "sandbox");
const agentRoot = path.join(stateDir, "agent");
await fs.mkdir(sandboxRoot, { recursive: true });
await fs.mkdir(agentRoot, { recursive: true });
const bridge = createUnsafeMountedBridge({ root: sandboxRoot, agentHostRoot: agentRoot });
const sandbox = createSandbox({ sandboxRoot, agentRoot, fsBridge: bridge });
try {
await run({ sandboxRoot, agentRoot, sandbox });
} finally {
await fs.rm(stateDir, { recursive: true, force: true });
}
}
describe("tools.fs.workspaceOnly", () => {
it("defaults to allowing sandbox mounts outside the workspace root", async () => {
const stateDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-sbx-mounts-"));
const sandboxRoot = path.join(stateDir, "sandbox");
const agentRoot = path.join(stateDir, "agent");
await fs.mkdir(sandboxRoot, { recursive: true });
await fs.mkdir(agentRoot, { recursive: true });
try {
await withUnsafeMountedSandboxHarness(async ({ sandboxRoot, agentRoot, sandbox }) => {
await fs.writeFile(path.join(agentRoot, "secret.txt"), "shh", "utf8");
const bridge = createUnsafeMountedBridge({ root: sandboxRoot, agentHostRoot: agentRoot });
const sandbox = createSandbox({ sandboxRoot, agentRoot, fsBridge: bridge });
const tools = createOpenClawCodingTools({ sandbox, workspaceDir: sandboxRoot });
const readTool = tools.find((tool) => tool.name === "read");
const writeTool = tools.find((tool) => tool.name === "write");
@@ -112,23 +121,13 @@ describe("tools.fs.workspaceOnly", () => {
await writeTool?.execute("t2", { path: "/agent/owned.txt", content: "x" });
expect(await fs.readFile(path.join(agentRoot, "owned.txt"), "utf8")).toBe("x");
} finally {
await fs.rm(stateDir, { recursive: true, force: true });
}
});
});
it("rejects sandbox mounts outside the workspace root when enabled", async () => {
const stateDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-sbx-mounts-"));
const sandboxRoot = path.join(stateDir, "sandbox");
const agentRoot = path.join(stateDir, "agent");
await fs.mkdir(sandboxRoot, { recursive: true });
await fs.mkdir(agentRoot, { recursive: true });
try {
await withUnsafeMountedSandboxHarness(async ({ sandboxRoot, agentRoot, sandbox }) => {
await fs.writeFile(path.join(agentRoot, "secret.txt"), "shh", "utf8");
const bridge = createUnsafeMountedBridge({ root: sandboxRoot, agentHostRoot: agentRoot });
const sandbox = createSandbox({ sandboxRoot, agentRoot, fsBridge: bridge });
const cfg = { tools: { fs: { workspaceOnly: true } } } as unknown as OpenClawConfig;
const tools = createOpenClawCodingTools({ sandbox, workspaceDir: sandboxRoot, config: cfg });
const readTool = tools.find((tool) => tool.name === "read");
@@ -153,8 +152,6 @@ describe("tools.fs.workspaceOnly", () => {
editTool?.execute("t3", { path: "/agent/secret.txt", oldText: "shh", newText: "nope" }),
).rejects.toThrow(/Path escapes sandbox root/i);
expect(await fs.readFile(path.join(agentRoot, "secret.txt"), "utf8")).toBe("shh");
} finally {
await fs.rm(stateDir, { recursive: true, force: true });
}
});
});
});