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 }); } + }, + ); +});