@@ -36,8 +36,11 @@ import {
3636import packageJson from "../../../package.json" with { type : "json" } ;
3737import { POSTHOG_NOTIFICATIONS } from "../../acp-extensions" ;
3838import {
39- CODE_EXECUTION_MODES ,
4039 type CodeExecutionMode ,
40+ type CodexNativeMode ,
41+ isCodeExecutionMode ,
42+ isCodexNativeMode ,
43+ type PermissionMode ,
4144} from "../../execution-mode" ;
4245import type { ProcessSpawnedCallback } from "../../types" ;
4346import { Logger } from "../../utils/logger" ;
@@ -83,20 +86,41 @@ type CodexSession = BaseSession & {
8386 settingsManager : CodexSettingsManager ;
8487} ;
8588
86- function toCodeExecutionMode ( mode ?: string ) : CodeExecutionMode {
87- if ( mode && ( CODE_EXECUTION_MODES as readonly string [ ] ) . includes ( mode ) ) {
88- return mode as CodeExecutionMode ;
89+ function toCodexPermissionMode ( mode ?: string ) : PermissionMode {
90+ if ( mode && ( isCodexNativeMode ( mode ) || isCodeExecutionMode ( mode ) ) ) {
91+ return mode ;
8992 }
90- return "default " ;
93+ return "auto " ;
9194}
9295
93- const CODEX_NATIVE_MODE : Record < CodeExecutionMode , string > = {
94- default : "default " ,
95- acceptEdits : "default " ,
96- plan : "plan " ,
97- bypassPermissions : "default " ,
96+ const CODEX_NATIVE_MODE : Record < CodeExecutionMode , CodexNativeMode > = {
97+ default : "auto " ,
98+ acceptEdits : "auto " ,
99+ plan : "read-only " ,
100+ bypassPermissions : "full-access " ,
98101} ;
99102
103+ function toCodexNativeMode ( mode ?: string ) : CodexNativeMode {
104+ if ( mode && isCodexNativeMode ( mode ) ) {
105+ return mode ;
106+ }
107+ if ( mode && isCodeExecutionMode ( mode ) ) {
108+ return CODEX_NATIVE_MODE [ mode ] ;
109+ }
110+ return "auto" ;
111+ }
112+
113+ function getCurrentPermissionMode (
114+ currentModeId ?: string ,
115+ fallbackMode ?: string ,
116+ ) : PermissionMode {
117+ if ( currentModeId && isCodexNativeMode ( currentModeId ) ) {
118+ return currentModeId ;
119+ }
120+
121+ return toCodexPermissionMode ( fallbackMode ) ;
122+ }
123+
100124export class CodexAcpAgent extends BaseAcpAgent {
101125 readonly adapterName = "codex" ;
102126 declare session : CodexSession ;
@@ -179,20 +203,27 @@ export class CodexAcpAgent extends BaseAcpAgent {
179203
180204 async newSession ( params : NewSessionRequest ) : Promise < NewSessionResponse > {
181205 const meta = params . _meta as NewSessionMeta | undefined ;
206+ const requestedPermissionMode = toCodexPermissionMode ( meta ?. permissionMode ) ;
182207
183208 const response = await this . codexConnection . newSession ( params ) ;
184209
185210 // Initialize session state
186211 this . sessionState = createSessionState ( response . sessionId , params . cwd , {
187212 taskRunId : meta ?. taskRunId ,
188213 taskId : meta ?. taskId ?? meta ?. persistence ?. taskId ,
189- modeId : response . modes ?. currentModeId ?? "default " ,
214+ modeId : response . modes ?. currentModeId ?? "auto " ,
190215 modelId : response . models ?. currentModelId ,
191- permissionMode : toCodeExecutionMode ( meta ?. permissionMode ) ,
216+ permissionMode : requestedPermissionMode ,
192217 } ) ;
193218 this . sessionId = response . sessionId ;
194219 this . sessionState . configOptions = response . configOptions ?? [ ] ;
195220
221+ await this . applyInitialPermissionMode (
222+ response . sessionId ,
223+ meta ?. permissionMode ,
224+ response . modes ?. currentModeId ,
225+ ) ;
226+
196227 // Emit _posthog/sdk_session so the app can track the session
197228 if ( meta ?. taskRunId ) {
198229 await this . client . extNotification ( POSTHOG_NOTIFICATIONS . SDK_SESSION , {
@@ -213,9 +244,14 @@ export class CodexAcpAgent extends BaseAcpAgent {
213244 async loadSession ( params : LoadSessionRequest ) : Promise < LoadSessionResponse > {
214245 const response = await this . codexConnection . loadSession ( params ) ;
215246 const meta = params . _meta as NewSessionMeta | undefined ;
247+ const currentPermissionMode = getCurrentPermissionMode (
248+ response . modes ?. currentModeId ,
249+ meta ?. permissionMode ,
250+ ) ;
216251
217252 this . sessionState = createSessionState ( params . sessionId , params . cwd , {
218- permissionMode : toCodeExecutionMode ( meta ?. permissionMode ) ,
253+ modeId : response . modes ?. currentModeId ?? "auto" ,
254+ permissionMode : currentPermissionMode ,
219255 } ) ;
220256 this . sessionId = params . sessionId ;
221257 this . sessionState . configOptions = response . configOptions ?? [ ] ;
@@ -234,10 +270,15 @@ export class CodexAcpAgent extends BaseAcpAgent {
234270 } ) ;
235271
236272 const meta = params . _meta as NewSessionMeta | undefined ;
273+ const currentPermissionMode = getCurrentPermissionMode (
274+ loadResponse . modes ?. currentModeId ,
275+ meta ?. permissionMode ,
276+ ) ;
237277 this . sessionState = createSessionState ( params . sessionId , params . cwd , {
238278 taskRunId : meta ?. taskRunId ,
239279 taskId : meta ?. taskId ?? meta ?. persistence ?. taskId ,
240- permissionMode : toCodeExecutionMode ( meta ?. permissionMode ) ,
280+ modeId : loadResponse . modes ?. currentModeId ?? "auto" ,
281+ permissionMode : currentPermissionMode ,
241282 } ) ;
242283 this . sessionId = params . sessionId ;
243284 this . sessionState . configOptions = loadResponse . configOptions ?? [ ] ;
@@ -268,17 +309,49 @@ export class CodexAcpAgent extends BaseAcpAgent {
268309 } ) ;
269310
270311 const meta = params . _meta as NewSessionMeta | undefined ;
312+ const requestedPermissionMode = toCodexPermissionMode ( meta ?. permissionMode ) ;
271313 this . sessionState = createSessionState ( newResponse . sessionId , params . cwd , {
272314 taskRunId : meta ?. taskRunId ,
273315 taskId : meta ?. taskId ?? meta ?. persistence ?. taskId ,
274- permissionMode : toCodeExecutionMode ( meta ?. permissionMode ) ,
316+ modeId : newResponse . modes ?. currentModeId ?? "auto" ,
317+ permissionMode : requestedPermissionMode ,
275318 } ) ;
276319 this . sessionId = newResponse . sessionId ;
277320 this . sessionState . configOptions = newResponse . configOptions ?? [ ] ;
278321
322+ await this . applyInitialPermissionMode (
323+ newResponse . sessionId ,
324+ meta ?. permissionMode ,
325+ newResponse . modes ?. currentModeId ,
326+ ) ;
327+
279328 return newResponse ;
280329 }
281330
331+ private async applyInitialPermissionMode (
332+ sessionId : string ,
333+ permissionMode ?: string ,
334+ currentModeId ?: string ,
335+ ) : Promise < void > {
336+ if ( ! permissionMode ) {
337+ return ;
338+ }
339+
340+ const nativeMode = toCodexNativeMode ( permissionMode ) ;
341+ if ( nativeMode === currentModeId ) {
342+ this . sessionState . modeId = nativeMode ;
343+ this . sessionState . permissionMode = toCodexPermissionMode ( permissionMode ) ;
344+ return ;
345+ }
346+
347+ await this . codexConnection . setSessionMode ( {
348+ sessionId,
349+ modeId : nativeMode ,
350+ } ) ;
351+ this . sessionState . modeId = nativeMode ;
352+ this . sessionState . permissionMode = toCodexPermissionMode ( permissionMode ) ;
353+ }
354+
282355 async listSessions (
283356 params : ListSessionsRequest ,
284357 ) : Promise < ListSessionsResponse > {
@@ -347,8 +420,8 @@ export class CodexAcpAgent extends BaseAcpAgent {
347420 async setSessionMode (
348421 params : SetSessionModeRequest ,
349422 ) : Promise < SetSessionModeResponse > {
350- const requestedMode = toCodeExecutionMode ( params . modeId ) ;
351- const nativeMode = CODEX_NATIVE_MODE [ requestedMode ] ;
423+ const requestedMode = toCodexPermissionMode ( params . modeId ) ;
424+ const nativeMode = toCodexNativeMode ( params . modeId ) ;
352425
353426 const response = await this . codexConnection . setSessionMode ( {
354427 ...params ,
0 commit comments