@@ -4,6 +4,7 @@ import * as acp from "@agentclientprotocol/sdk";
44import { type McpServer , RequestError } from "@agentclientprotocol/sdk" ;
55import type { ApprovalHandler , CodexAppServerClient } from "./CodexAppServerClient" ;
66import open from "open" ;
7+ import type { Disposable } from "vscode-jsonrpc" ;
78import type {
89 ClientInfo ,
910 ReasoningEffort ,
@@ -40,6 +41,8 @@ export class CodexAcpClient {
4041 private readonly config : JsonObject ;
4142 private readonly modelProvider : string | null ;
4243 private gatewayConfig : GatewayConfig | null ;
44+ private pendingLoginCompleted : Promise < AccountLoginCompletedNotification > | null = null ;
45+ private pendingAccountUpdated : Promise < AccountUpdatedNotification > | null = null ;
4346
4447
4548 constructor ( codexClient : CodexAppServerClient , codexConfig ?: JsonObject , modelProvider ?: string ) {
@@ -393,17 +396,44 @@ export class CodexAcpClient {
393396 }
394397
395398 private async awaitNextLoginCompleted ( ) : Promise < AccountLoginCompletedNotification > {
396- return await new Promise ( ( resolve ) => {
397- this . codexClient . connection . onNotification ( "account/login/completed" , ( event : AccountLoginCompletedNotification ) => {
398- resolve ( event ) ;
399- } ) ;
400- } ) ;
399+ if ( this . pendingLoginCompleted !== null ) {
400+ return await this . pendingLoginCompleted ;
401+ }
402+ this . pendingLoginCompleted = this . awaitSingleNotification (
403+ "account/login/completed" ,
404+ ( event : AccountLoginCompletedNotification ) => event ,
405+ ) ;
406+ try {
407+ return await this . pendingLoginCompleted ;
408+ } finally {
409+ this . pendingLoginCompleted = null ;
410+ }
401411 }
402412
403413 private async awaitNextAccountUpdated ( ) : Promise < AccountUpdatedNotification > {
414+ if ( this . pendingAccountUpdated !== null ) {
415+ return await this . pendingAccountUpdated ;
416+ }
417+ this . pendingAccountUpdated = this . awaitSingleNotification (
418+ "account/updated" ,
419+ ( event : AccountUpdatedNotification ) => event ,
420+ ) ;
421+ try {
422+ return await this . pendingAccountUpdated ;
423+ } finally {
424+ this . pendingAccountUpdated = null ;
425+ }
426+ }
427+
428+ private async awaitSingleNotification < T > (
429+ method : "account/login/completed" | "account/updated" ,
430+ mapEvent : ( event : T ) => T ,
431+ ) : Promise < T > {
404432 return await new Promise ( ( resolve ) => {
405- this . codexClient . connection . onNotification ( "account/updated" , ( event : AccountUpdatedNotification ) => {
406- resolve ( event ) ;
433+ let disposable : Disposable | undefined ;
434+ disposable = this . codexClient . connection . onNotification ( method , ( event : T ) => {
435+ disposable ?. dispose ( ) ;
436+ resolve ( mapEvent ( event ) ) ;
407437 } ) ;
408438 } ) ;
409439 }
0 commit comments