@@ -1082,6 +1082,13 @@ export async function runCodexAppServerAttempt(
10821082 ? resolvedWorkspace
10831083 : sandbox . workspaceDir
10841084 : resolvedWorkspace ;
1085+ const requestedCwd = params . cwd ? resolveUserPath ( params . cwd ) : undefined ;
1086+ if ( sandbox ?. enabled && requestedCwd && requestedCwd !== resolvedWorkspace ) {
1087+ throw new Error (
1088+ "cwd override is not supported for sandboxed Codex app-server runs; omit cwd or use the agent workspace as cwd" ,
1089+ ) ;
1090+ }
1091+ const effectiveCwd = sandbox ?. enabled ? effectiveWorkspace : ( requestedCwd ?? effectiveWorkspace ) ;
10851092 await ensureCodexWorkspaceDirOnce ( effectiveWorkspace ) ;
10861093 preDynamicStartupStages . mark ( "effective-workspace" ) ;
10871094 const appServer = resolveCodexAppServerForOpenClawToolPolicy ( {
@@ -1238,6 +1245,7 @@ export async function runCodexAppServerAttempt(
12381245 params,
12391246 resolvedWorkspace,
12401247 effectiveWorkspace,
1248+ effectiveCwd,
12411249 sandboxSessionKey,
12421250 sandbox,
12431251 nativeToolSurfaceEnabled,
@@ -1253,6 +1261,7 @@ export async function runCodexAppServerAttempt(
12531261 params,
12541262 resolvedWorkspace,
12551263 effectiveWorkspace,
1264+ effectiveCwd,
12561265 sandboxSessionKey,
12571266 sandbox,
12581267 nativeToolSurfaceEnabled,
@@ -1314,6 +1323,7 @@ export async function runCodexAppServerAttempt(
13141323 buildHarnessContextEngineRuntimeContext ( {
13151324 attempt : buildActiveRunAttemptParams ( ) ,
13161325 workspaceDir : effectiveWorkspace ,
1326+ cwd : effectiveCwd ,
13171327 agentDir,
13181328 activeAgentId : sessionAgentId ,
13191329 contextEnginePluginId : activeContextEnginePluginId ,
@@ -1488,7 +1498,7 @@ export async function runCodexAppServerAttempt(
14881498 } ) ;
14891499 const trajectoryRecorder = createCodexTrajectoryRecorder ( {
14901500 attempt : params ,
1491- cwd : effectiveWorkspace ,
1501+ cwd : effectiveCwd ,
14921502 developerInstructions : buildRenderedCodexDeveloperInstructions ( ) ,
14931503 prompt : codexTurnPromptText ,
14941504 tools : toolBridge . availableSpecs ,
@@ -1507,7 +1517,7 @@ export async function runCodexAppServerAttempt(
15071517 }
15081518 } ;
15091519 let codexEnvironmentSelection : CodexTurnEnvironmentParams [ ] | undefined ;
1510- let codexExecutionCwd = effectiveWorkspace ;
1520+ let codexExecutionCwd = effectiveCwd ;
15111521 let codexSandboxPolicy : CodexSandboxPolicy | undefined ;
15121522 let restartContextEngineCodexThread :
15131523 | ( ( ) => Promise < CodexAppServerThreadLifecycleBinding > )
@@ -1679,7 +1689,7 @@ export async function runCodexAppServerAttempt(
16791689 nativeToolSurfaceEnabled ,
16801690 ) ;
16811691 const startupExecutionCwd = resolveCodexAppServerExecutionCwd ( {
1682- effectiveWorkspace ,
1692+ effectiveCwd ,
16831693 environment : startupSandboxEnvironment ,
16841694 nativeToolSurfaceEnabled,
16851695 } ) ;
@@ -1832,7 +1842,7 @@ export async function runCodexAppServerAttempt(
18321842 } ) ;
18331843 recordCodexTrajectoryContext ( trajectoryRecorder , {
18341844 attempt : params ,
1835- cwd : effectiveWorkspace ,
1845+ cwd : effectiveCwd ,
18361846 developerInstructions : promptBuild . developerInstructions ,
18371847 prompt : codexTurnPromptText ,
18381848 tools : toolBridge . availableSpecs ,
@@ -3281,6 +3291,7 @@ export async function runCodexAppServerAttempt(
32813291 agentId : sessionAgentId ,
32823292 notifyUserMessagePersisted,
32833293 sessionKey : sandboxSessionKey ,
3294+ cwd : effectiveCwd ,
32843295 threadId : thread . threadId ,
32853296 turnId : activeTurnId ,
32863297 } ) ;
@@ -3397,6 +3408,7 @@ export async function runCodexAppServerAttempt(
33973408 notifyUserMessagePersisted,
33983409 result,
33993410 sessionKey : contextSessionKey ,
3411+ cwd : effectiveCwd ,
34003412 threadId : thread . threadId ,
34013413 turnId : activeTurnId ,
34023414 } ) ;
@@ -3437,6 +3449,7 @@ export async function runCodexAppServerAttempt(
34373449 runtimeContext : buildHarnessContextEngineRuntimeContextFromUsage ( {
34383450 attempt : buildActiveRunAttemptParams ( ) ,
34393451 workspaceDir : effectiveWorkspace ,
3452+ cwd : effectiveCwd ,
34403453 agentDir,
34413454 activeAgentId : sessionAgentId ,
34423455 contextEnginePluginId : activeContextEnginePluginId ,
@@ -4170,6 +4183,7 @@ type DynamicToolBuildParams = {
41704183 params : EmbeddedRunAttemptParams ;
41714184 resolvedWorkspace : string ;
41724185 effectiveWorkspace : string ;
4186+ effectiveCwd ?: string ;
41734187 sandboxSessionKey : string ;
41744188 sandbox : Awaited < ReturnType < typeof resolveSandboxContext > > ;
41754189 nativeToolSurfaceEnabled ?: boolean ;
@@ -4318,6 +4332,7 @@ async function buildDynamicTools(input: DynamicToolBuildParams) {
43184332 sessionId : params . sessionId ,
43194333 runId : params . runId ,
43204334 agentDir,
4335+ cwd : input . effectiveCwd ?? input . effectiveWorkspace ,
43214336 workspaceDir : input . effectiveWorkspace ,
43224337 spawnWorkspaceDir : resolveAttemptSpawnWorkspaceDir ( {
43234338 sandbox : input . sandbox ,
@@ -4572,13 +4587,13 @@ function resolveCodexSandboxEnvironmentSelection(
45724587}
45734588
45744589function resolveCodexAppServerExecutionCwd ( params : {
4575- effectiveWorkspace : string ;
4590+ effectiveCwd : string ;
45764591 environment ?: CodexSandboxExecEnvironment ;
45774592 nativeToolSurfaceEnabled : boolean ;
45784593} ) : string {
45794594 return params . environment && params . nativeToolSurfaceEnabled
45804595 ? params . environment . cwd
4581- : params . effectiveWorkspace ;
4596+ : params . effectiveCwd ;
45824597}
45834598
45844599function resolveCodexExternalSandboxPolicyForOpenClawSandbox (
@@ -6153,6 +6168,7 @@ async function mirrorTranscriptBestEffort(params: {
61536168 notifyUserMessagePersisted : ( message : Extract < AgentMessage , { role : "user" } > ) => void ;
61546169 result : EmbeddedRunAttemptResult ;
61556170 sessionKey ?: string ;
6171+ cwd : string ;
61566172 threadId : string ;
61576173 turnId : string ;
61586174} ) : Promise < void > {
@@ -6166,6 +6182,8 @@ async function mirrorTranscriptBestEffort(params: {
61666182 sessionFile : params . params . sessionFile ,
61676183 agentId : params . agentId ,
61686184 sessionKey : params . sessionKey ,
6185+ sessionId : params . params . sessionId ,
6186+ cwd : params . cwd ,
61696187 messages,
61706188 // Scope is thread-stable. Each entry in `messagesSnapshot` is tagged
61716189 // with a per-turn `attachCodexMirrorIdentity` value carrying its own
@@ -6234,6 +6252,7 @@ async function mirrorPromptAtTurnStartBestEffort(params: {
62346252 agentId ?: string ;
62356253 notifyUserMessagePersisted : ( message : Extract < AgentMessage , { role : "user" } > ) => void ;
62366254 sessionKey ?: string ;
6255+ cwd : string ;
62376256 threadId : string ;
62386257 turnId : string ;
62396258} ) : Promise < void > {
@@ -6250,6 +6269,8 @@ async function mirrorPromptAtTurnStartBestEffort(params: {
62506269 sessionFile : params . params . sessionFile ,
62516270 agentId : params . agentId ,
62526271 sessionKey : params . sessionKey ,
6272+ sessionId : params . params . sessionId ,
6273+ cwd : params . cwd ,
62536274 messages : [ userPromptMessage ] ,
62546275 idempotencyScope : `codex-app-server:${ params . threadId } ` ,
62556276 config : params . params . config ,
0 commit comments