From 368ebe76e75f6d7a4a43af85c11fb1d244f11a7f Mon Sep 17 00:00:00 2001 From: Dotta Date: Mon, 7 Sep 2026 13:47:12 -0500 Subject: [PATCH] fix(adapters): leave sandbox work folders to the remote runner Co-Authored-By: Paperclip --- .../claude-local/src/server/execute.ts | 4 ++- .../opencode-local/src/server/execute.ts | 4 ++- .../adapters/pi-local/src/server/execute.ts | 4 ++- ...legacy-sandbox-work-folder-startup.test.ts | 36 +++++++++++++++++++ 4 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 server/src/__tests__/legacy-sandbox-work-folder-startup.test.ts diff --git a/packages/adapters/claude-local/src/server/execute.ts b/packages/adapters/claude-local/src/server/execute.ts index 0f24419c9f..1d25cc9313 100644 --- a/packages/adapters/claude-local/src/server/execute.ts +++ b/packages/adapters/claude-local/src/server/execute.ts @@ -212,7 +212,9 @@ async function buildClaudeRuntimeConfig(input: ClaudeExecutionInput): Promise = { ...buildPaperclipEnv(agent) }; diff --git a/packages/adapters/opencode-local/src/server/execute.ts b/packages/adapters/opencode-local/src/server/execute.ts index dba49d84c8..c56b7f01c0 100644 --- a/packages/adapters/opencode-local/src/server/execute.ts +++ b/packages/adapters/opencode-local/src/server/execute.ts @@ -252,7 +252,9 @@ export async function execute(ctx: AdapterExecutionContext): Promise { + it.each([["claude_local", claude], ["opencode_local", opencode], ["pi_local", pi]] as const)( + "%s leaves sandbox paths to the remote runner", + async (adapterType, execute) => { + const root = await mkdtemp(join(tmpdir(), "remote-work-folder-")); + const hostSentinel = join(root, "host-file"); + await writeFile(hostSentinel, "host-owned"); + // This sandbox path cannot be mkdir'd on the app host. Reaching the + // remote command probe proves startup did not claim the path locally. + const cwd = join(hostSentinel, "repos", "project"); + const probe = vi.fn(async () => { throw new Error("remote-probe-reached"); }); + try { + await expect(execute({ + runId: "remote-work-folder-run", + agent: { id: "agent", companyId: "company", name: "test", adapterType, adapterConfig: {} }, + config: { engine: "cli", cwd, command: "qualified-provider", env: {} }, + context: { paperclipWorkspace: { cwd } }, + runtime: { sessionId: null, sessionParams: null, sessionDisplayId: null, taskKey: null }, + executionTarget: { kind: "remote", transport: "sandbox", providerKey: "daytona", + remoteCwd: cwd, workFolderHome: root, runner: { execute: probe } }, + onLog: async () => {}, + })).rejects.toThrow("remote-probe-reached"); + expect(probe).toHaveBeenCalled(); + expect(await readFile(hostSentinel, "utf8")).toBe("host-owned"); + } finally { await rm(root, { recursive: true, force: true }); } + }, + ); +});