diff --git a/packages/agent/src/adapters/codex-app-server/spawn.test.ts b/packages/agent/src/adapters/codex-app-server/spawn.test.ts index 9e9f23f7f2..6794bef2dd 100644 --- a/packages/agent/src/adapters/codex-app-server/spawn.test.ts +++ b/packages/agent/src/adapters/codex-app-server/spawn.test.ts @@ -126,6 +126,30 @@ describe("buildAppServerArgs", () => { expect(args).toContain('model_verbosity="low"'); }); + it("pins the cloud BASH_ENV into tool shells for secondary checkouts", () => { + const args = buildAppServerArgs( + { binaryPath: "/bundle/codex" }, + { IS_SANDBOX: "1", BASH_ENV: "/tmp/agentsh-bash-env.sh" }, + ); + + expect(args).toContain( + 'shell_environment_policy.set.BASH_ENV="/tmp/agentsh-bash-env.sh"', + ); + }); + + it("does not override BASH_ENV outside a managed sandbox", () => { + const args = buildAppServerArgs( + { binaryPath: "/bundle/codex" }, + { BASH_ENV: "/Users/example/.bash-env" }, + ); + + expect( + args.some((arg) => + arg.startsWith("shell_environment_policy.set.BASH_ENV="), + ), + ).toBe(false); + }); + it("does not set instructions at spawn (developer_instructions are per-thread)", () => { const args = buildAppServerArgs({ binaryPath: "/bundle/codex", diff --git a/packages/agent/src/adapters/codex-app-server/spawn.ts b/packages/agent/src/adapters/codex-app-server/spawn.ts index 6d25686200..81deb7a4aa 100644 --- a/packages/agent/src/adapters/codex-app-server/spawn.ts +++ b/packages/agent/src/adapters/codex-app-server/spawn.ts @@ -91,6 +91,7 @@ function tomlInlineTable(entries: Record): string { export function buildAppServerArgs( options: CodexAppServerProcessOptions, + environment: NodeJS.ProcessEnv = process.env, ): string[] { const args: string[] = ["app-server"]; @@ -130,6 +131,16 @@ export function buildAppServerArgs( // still override it via configOverrides, which the trailing loop appends last. args.push("-c", `approvals_reviewer="user"`); + // Codex snapshots shell state only for the thread's initial cwd. Cloud tasks + // can work in additional checkouts, so pin the backend-controlled BASH_ENV + // path into every tool shell instead of relying on snapshot restoration. + if (environment.IS_SANDBOX && environment.BASH_ENV) { + args.push( + "-c", + `shell_environment_policy.set.BASH_ENV=${tomlBasicString(environment.BASH_ENV)}`, + ); + } + // Disable the user's ambient ~/.codex MCP servers so the adapter only exposes // MCP servers PostHog injects per-thread; otherwise codex fails connecting to them. for (const name of new CodexSettingsManager( @@ -199,7 +210,7 @@ export function spawnCodexAppServerProcess( } env.PATH = `${dirname(options.binaryPath)}${delimiter}${env.PATH ?? ""}`; - const args = buildAppServerArgs(options); + const args = buildAppServerArgs(options, env); logger.info("Spawning codex app-server process", { command: options.binaryPath,