@ccpocket/bridge 1.80.1 → 1.80.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -112,6 +112,9 @@ export declare class CodexProcess extends EventEmitter<CodexProcessEvents> {
112
112
  private _agentRole;
113
113
  private stopped;
114
114
  private startModel;
115
+ private readiness;
116
+ private readinessError;
117
+ private readinessWaiters;
115
118
  private inputResolve;
116
119
  private pendingTurnId;
117
120
  private pendingTurnCompletion;
@@ -243,6 +246,7 @@ export declare class CodexProcess extends EventEmitter<CodexProcessEvents> {
243
246
  listAvailableModelMetadata(): Promise<CodexModelMetadata[]>;
244
247
  start(projectPath: string, options?: CodexStartOptions): void;
245
248
  initializeOnly(projectPath: string): Promise<void>;
249
+ waitUntilReady(): Promise<void>;
246
250
  stop(): void;
247
251
  private prepareLaunch;
248
252
  private launchAppServer;
@@ -355,6 +359,9 @@ export declare class CodexProcess extends EventEmitter<CodexProcessEvents> {
355
359
  private respondToServerRequestError;
356
360
  private writeEnvelope;
357
361
  private rejectAllPending;
362
+ private resetReadiness;
363
+ private resolveReadiness;
364
+ private rejectReadiness;
358
365
  private setStatus;
359
366
  private emitMessage;
360
367
  private extractToolUseId;
@@ -33,7 +33,7 @@ export function isCodexThreadWriterConflict(error) {
33
33
  }
34
34
  export function codexErrorMessage(error) {
35
35
  if (isCodexThreadWriterConflict(error)) {
36
- return "This Codex thread is already open in another client. Close it there and try again.";
36
+ return "This Codex thread is already open in Codex Desktop or the Codex App. Close it there, then try again.";
37
37
  }
38
38
  return error instanceof Error ? error.message : String(error);
39
39
  }
@@ -64,6 +64,9 @@ export class CodexProcess extends EventEmitter {
64
64
  _agentRole = null;
65
65
  stopped = false;
66
66
  startModel;
67
+ readiness = "pending";
68
+ readinessError;
69
+ readinessWaiters = new Set();
67
70
  inputResolve = null;
68
71
  pendingTurnId = null;
69
72
  pendingTurnCompletion = null;
@@ -407,6 +410,7 @@ export class CodexProcess extends EventEmitter {
407
410
  if (this.transport) {
408
411
  this.stop();
409
412
  }
413
+ this.resetReadiness();
410
414
  this.prepareLaunch(projectPath, options);
411
415
  this.launchAppServer(projectPath, options);
412
416
  void this.bootstrap(projectPath, options);
@@ -415,13 +419,32 @@ export class CodexProcess extends EventEmitter {
415
419
  if (this.transport) {
416
420
  this.stop();
417
421
  }
418
- this.prepareLaunch(projectPath);
419
- this.launchAppServer(projectPath);
420
- await this.initializeRpcConnection();
421
- this.setStatus("idle");
422
+ this.resetReadiness();
423
+ try {
424
+ this.prepareLaunch(projectPath);
425
+ this.launchAppServer(projectPath);
426
+ await this.initializeRpcConnection();
427
+ this.setStatus("idle");
428
+ this.resolveReadiness();
429
+ }
430
+ catch (error) {
431
+ this.rejectReadiness(error);
432
+ throw error;
433
+ }
434
+ }
435
+ waitUntilReady() {
436
+ if (this.readiness === "ready")
437
+ return Promise.resolve();
438
+ if (this.readiness === "failed") {
439
+ return Promise.reject(this.readinessError);
440
+ }
441
+ return new Promise((resolve, reject) => {
442
+ this.readinessWaiters.add({ resolve, reject });
443
+ });
422
444
  }
423
445
  stop() {
424
446
  this.stopped = true;
447
+ this.rejectReadiness(new Error("codex app-server stopped"));
425
448
  if (this.inputResolve) {
426
449
  this.inputResolve({ text: "" });
427
450
  this.inputResolve = null;
@@ -1108,6 +1131,7 @@ export class CodexProcess extends EventEmitter {
1108
1131
  ...(cliJoin ? { codexCliJoin: cliJoin } : {}),
1109
1132
  });
1110
1133
  this.setStatus("idle");
1134
+ this.resolveReadiness();
1111
1135
  // Fetch completion entities in background (non-blocking).
1112
1136
  this._projectPath = projectPath;
1113
1137
  setTimeout(() => {
@@ -1118,6 +1142,7 @@ export class CodexProcess extends EventEmitter {
1118
1142
  await this.runInputLoop(options);
1119
1143
  }
1120
1144
  catch (err) {
1145
+ this.rejectReadiness(err);
1121
1146
  if (!this.stopped) {
1122
1147
  const message = codexErrorMessage(err);
1123
1148
  console.error("[codex-process] bootstrap error:", err);
@@ -2544,6 +2569,26 @@ export class CodexProcess extends EventEmitter {
2544
2569
  this.pendingTurnCompletion = null;
2545
2570
  }
2546
2571
  }
2572
+ resetReadiness() {
2573
+ this.rejectReadiness(new Error("codex app-server restarted"));
2574
+ this.readiness = "pending";
2575
+ this.readinessError = undefined;
2576
+ }
2577
+ resolveReadiness() {
2578
+ if (this.readiness !== "pending")
2579
+ return;
2580
+ this.readiness = "ready";
2581
+ for (const waiter of this.readinessWaiters)
2582
+ waiter.resolve();
2583
+ this.readinessWaiters.clear();
2584
+ }
2585
+ rejectReadiness(error) {
2586
+ this.readiness = "failed";
2587
+ this.readinessError = error;
2588
+ for (const waiter of this.readinessWaiters)
2589
+ waiter.reject(error);
2590
+ this.readinessWaiters.clear();
2591
+ }
2547
2592
  setStatus(status) {
2548
2593
  if (this._status !== status) {
2549
2594
  this._status = status;