@agentconnect.md/codex-acp 1.10.0-agentconnect.1 → 1.11.0-agentconnect.1

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.
Files changed (3) hide show
  1. package/README.md +11 -0
  2. package/dist/index.js +233 -108
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -10,6 +10,7 @@ Use [OpenAI Codex](https://github.com/openai/codex) from [Agent Client Protocol]
10
10
 
11
11
  - ChatGPT, API key, and client-provided custom gateway authentication.
12
12
  - Model, reasoning effort, fast mode, approval, and sandbox mode configuration.
13
+ - Concrete recommended model and reasoning-effort values through the opt-in [AIR recommended config values](docs/recommended-config-values-extension.md) capability.
13
14
  - Text prompts, embedded context, images, resource links, and additional workspace directories.
14
15
  - Shell command, file change, [permission request](docs/permission-extension.md), MCP tool call, terminal output, reasoning, plan, web search, image generation, image view, token usage, and review events.
15
16
  - [Native ACP subagent sessions](docs/subagent-sessions.md) (after capability negotiation) with separate child histories and root-routed permissions; a legacy tool-call fallback otherwise.
@@ -40,6 +41,16 @@ The npm package includes a compatible `@openai/codex` dependency. Set `CODEX_PAT
40
41
  CODEX_PATH=/path/to/codex npx -y @agentclientprotocol/codex-acp
41
42
  ```
42
43
 
44
+ To try changes that have landed on `main` but are not released yet, install from the
45
+ `preview` channel. Pushes to `main` trigger preview publishing without waiting
46
+ for CI or release-please; release commits are excluded, and newer pushes can
47
+ replace queued previews. See
48
+ [docs/RELEASES.md](docs/RELEASES.md#preview-releases).
49
+
50
+ ```bash
51
+ npx -y @agentclientprotocol/codex-acp@preview
52
+ ```
53
+
43
54
  ## Authentication
44
55
 
45
56
  The adapter advertises ACP auth methods during initialization. Clients can authenticate with:
package/dist/index.js CHANGED
@@ -23670,16 +23670,37 @@ var AIR_SESSION_FAILURE_KEY = "sessionFailure";
23670
23670
  var AIR_AGENT_FILE_CHANGE_REPORT_KEY = "agentFileChangeReport";
23671
23671
  var AIR_NATIVE_SUBAGENT_SESSIONS_KEY = "nativeSubagentSessions";
23672
23672
  var AIR_ASYNC_TASKS_KEY = "asyncTasks";
23673
+ var AIR_RECOMMENDED_CONFIG_VALUE_KEY = "recommendedValue";
23673
23674
  var AIR_ASYNC_TASKS_BACKGROUNDED_KEY = "backgrounded";
23674
23675
  var AIR_AGENT_FILE_CHANGE_REPORT_REQUEST_KEY = "agentFileChangeReportRequest";
23675
23676
  var AIR_EXTENSION_VERSION = 1;
23677
+ function withAirMeta(meta3, key, value) {
23678
+ const root = asRecord(meta3);
23679
+ const jetbrains = asRecord(root[JETBRAINS_META_KEY]);
23680
+ const air = asRecord(jetbrains[AIR_META_KEY]);
23681
+ return {
23682
+ ...root,
23683
+ [JETBRAINS_META_KEY]: {
23684
+ ...jetbrains,
23685
+ [AIR_META_KEY]: {
23686
+ ...air,
23687
+ [AIR_EXTENSION_VERSION_KEY]: AIR_EXTENSION_VERSION,
23688
+ [key]: value
23689
+ }
23690
+ }
23691
+ };
23692
+ }
23676
23693
  function clientSupportsAirCapability(capabilities, capability) {
23677
- const jetbrains = capabilities?._meta?.[JETBRAINS_META_KEY];
23678
- const air = jetbrains?.[AIR_META_KEY];
23679
- const version2 = air?.[AIR_EXTENSION_VERSION_KEY];
23680
- const supported = air?.[AIR_EXTENSION_CAPABILITIES_KEY];
23694
+ const meta3 = asRecord(capabilities?._meta);
23695
+ const jetbrains = asRecord(meta3[JETBRAINS_META_KEY]);
23696
+ const air = asRecord(jetbrains[AIR_META_KEY]);
23697
+ const version2 = air[AIR_EXTENSION_VERSION_KEY];
23698
+ const supported = air[AIR_EXTENSION_CAPABILITIES_KEY];
23681
23699
  return typeof version2 === "number" && Number.isInteger(version2) && version2 >= AIR_EXTENSION_VERSION && Array.isArray(supported) && supported.includes(capability);
23682
23700
  }
23701
+ function asRecord(value) {
23702
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
23703
+ }
23683
23704
 
23684
23705
  // src/subagents/CodexAgentPath.ts
23685
23706
  function normalizeAgentPath(path9) {
@@ -25641,14 +25662,16 @@ function unique(values) {
25641
25662
 
25642
25663
  // src/permissions/CodexApprovalHandler.ts
25643
25664
  var CodexApprovalHandler = class {
25644
- constructor(connection, permissionContext, cancellationSignal) {
25665
+ constructor(connection, permissionContext, cancellationSignal, denyRequests) {
25645
25666
  this.connection = connection;
25646
25667
  this.permissionContext = permissionContext;
25647
25668
  this.cancellationSignal = cancellationSignal;
25669
+ this.denyRequests = denyRequests;
25648
25670
  }
25649
25671
  connection;
25650
25672
  permissionContext;
25651
25673
  cancellationSignal;
25674
+ denyRequests;
25652
25675
  async handleCommandExecution(params) {
25653
25676
  const authoritativeParams = params;
25654
25677
  const decisions = commandDecisionOptions(authoritativeParams);
@@ -25707,6 +25730,7 @@ var CodexApprovalHandler = class {
25707
25730
  }
25708
25731
  }
25709
25732
  requestPermission(request) {
25733
+ if (this.denyRequests?.()) return Promise.resolve({ outcome: { outcome: "cancelled" } });
25710
25734
  return this.connection.request(
25711
25735
  methods.client.session.requestPermission,
25712
25736
  request,
@@ -25966,8 +25990,9 @@ function buildMcpPermissionRequest(sessionId, params, context, nextStandaloneToo
25966
25990
  toolCallId: nextStandaloneToolCallId(),
25967
25991
  kind: context.isToolApproval ? "execute" : "other",
25968
25992
  status: "pending",
25993
+ title: context.isToolApproval ? "MCP tool call approval" : "Question from MCP server",
25969
25994
  content: [messageContent],
25970
- rawInput: { serverName: params.serverName, schema: params.requestedSchema }
25995
+ rawInput: { serverName: params.serverName, description: params.message, schema: params.requestedSchema }
25971
25996
  },
25972
25997
  ...context.isToolApproval ? { _meta: { is_mcp_tool_approval: true } } : {},
25973
25998
  options
@@ -25985,8 +26010,9 @@ function buildMcpPermissionRequest(sessionId, params, context, nextStandaloneToo
25985
26010
  toolCallId: `elicitation-${params.elicitationId}`,
25986
26011
  kind: "fetch",
25987
26012
  status: "pending",
26013
+ title: "MCP server requests to open a URL",
25988
26014
  content: [messageContent],
25989
- rawInput: { serverName: params.serverName, url: params.url }
26015
+ rawInput: { serverName: params.serverName, description: params.message, url: params.url }
25990
26016
  },
25991
26017
  options
25992
26018
  },
@@ -26099,31 +26125,20 @@ function userInputResponseValue(content, fieldId) {
26099
26125
  return value;
26100
26126
  }
26101
26127
  var CodexElicitationHandler = class {
26102
- connection;
26103
- permissionContext;
26104
- clientCapabilities;
26105
- cancellationSignal;
26106
- // In Rust, the MCP elicitation handler receives ElicitationRequestEvent directly from the MCP
26107
- // protocol layer, where id is set to "mcp_tool_call_approval_<call_id>" — the call ID is extracted
26108
- // by stripping that prefix.
26109
- //
26110
- // In TypeScript, Codex speaks the app-server JSON-RPC protocol (v2), where
26111
- // McpServerElicitationRequestParams omits elicitationId for form mode, so the MCP-level ID never
26112
- // reaches the client.
26113
- //
26114
- // Workaround: before requesting approval, Codex emits an item/started notification with an
26115
- // mcpToolCall item carrying the call id and server name. The shared permission lifecycle stores
26116
- // (threadId, serverName) → callId so this request can correlate to the rendered tool call item.
26117
- //
26118
- // The app-server handler exposes URL elicitationId, while serverRequest/resolved only exposes
26119
- // threadId here, so accepted URL elicitations are completed at thread scope.
26120
- pendingUrlElicitations = /* @__PURE__ */ new Map();
26121
- constructor(connection, permissionContext, clientCapabilities = null, cancellationSignal) {
26128
+ constructor(connection, permissionContext, clientCapabilities = null, cancellationSignal, fullAccessHttpServers) {
26129
+ this.fullAccessHttpServers = fullAccessHttpServers;
26122
26130
  this.connection = connection;
26123
26131
  this.permissionContext = permissionContext;
26124
26132
  this.clientCapabilities = clientCapabilities;
26125
26133
  this.cancellationSignal = cancellationSignal;
26126
26134
  }
26135
+ fullAccessHttpServers;
26136
+ connection;
26137
+ permissionContext;
26138
+ clientCapabilities;
26139
+ cancellationSignal;
26140
+ // App-server omits form elicitation IDs, so item/started correlates MCP approvals to tool calls.
26141
+ pendingUrlElicitations = /* @__PURE__ */ new Map();
26127
26142
  async handleNotification(notification) {
26128
26143
  switch (notification.method) {
26129
26144
  case "serverRequest/resolved":
@@ -26136,6 +26151,12 @@ var CodexElicitationHandler = class {
26136
26151
  async handleElicitation(params) {
26137
26152
  try {
26138
26153
  const context = this.createMcpElicitationContext(params);
26154
+ const httpServers = this.fullAccessHttpServers?.(params);
26155
+ if (httpServers !== void 0) {
26156
+ const accepted = !this.cancellationSignal?.aborted && params.mode === "form" && context.isToolApproval && context.persistOptions.has("session") && httpServers.has(params.serverName);
26157
+ await this.publishAcceptedMcpToolApproval(params.threadId, context, accepted);
26158
+ return { action: accepted ? "accept" : "cancel", content: accepted ? {} : null, _meta: null };
26159
+ }
26139
26160
  if (this.shouldUseAcpElicitation(params)) {
26140
26161
  const response2 = await this.connection.request(
26141
26162
  methods.client.elicitation.create,
@@ -26168,11 +26189,29 @@ var CodexElicitationHandler = class {
26168
26189
  context.isToolApproval,
26169
26190
  context.persistOptions
26170
26191
  );
26171
- if (correlatedCallId !== void 0 && result.action === "accept") {
26172
- await this.connection.notify(methods.client.session.update, {
26173
- sessionId: params.threadId,
26174
- update: { sessionUpdate: "tool_call_update", toolCallId: correlatedCallId, status: "in_progress" }
26175
- });
26192
+ if (correlatedCallId !== void 0) {
26193
+ if (result.action === "accept") {
26194
+ await this.connection.notify(methods.client.session.update, {
26195
+ sessionId: params.threadId,
26196
+ update: { sessionUpdate: "tool_call_update", toolCallId: correlatedCallId, status: "in_progress" }
26197
+ });
26198
+ }
26199
+ } else {
26200
+ try {
26201
+ await this.connection.notify(methods.client.session.update, {
26202
+ sessionId: params.threadId,
26203
+ update: {
26204
+ sessionUpdate: "tool_call_update",
26205
+ toolCallId: request.toolCall.toolCallId,
26206
+ status: "completed",
26207
+ title: request.toolCall.title,
26208
+ content: request.toolCall.content,
26209
+ rawOutput: { action: result.action }
26210
+ }
26211
+ });
26212
+ } catch (error51) {
26213
+ logger.error("Failed to finalize standalone MCP elicitation tool call", error51);
26214
+ }
26176
26215
  }
26177
26216
  return result;
26178
26217
  } catch (error51) {
@@ -26181,6 +26220,9 @@ var CodexElicitationHandler = class {
26181
26220
  }
26182
26221
  }
26183
26222
  async handleUserInput(params) {
26223
+ if (this.fullAccessHttpServers?.(params) !== void 0 && params.itemId === `mcp-deps-${params.turnId}` && params.questions.some((question) => question.id === "skill_mcp_dependency_install")) {
26224
+ return { answers: {} };
26225
+ }
26184
26226
  if (!clientSupportsFormElicitation(this.clientCapabilities)) {
26185
26227
  return { answers: {} };
26186
26228
  }
@@ -27329,7 +27371,7 @@ var package_default = {
27329
27371
  publishConfig: {
27330
27372
  access: "public"
27331
27373
  },
27332
- version: "1.10.0-agentconnect.1",
27374
+ version: "1.11.0-agentconnect.1",
27333
27375
  description: "",
27334
27376
  main: "dist/index.js",
27335
27377
  bin: {
@@ -27391,7 +27433,7 @@ var package_default = {
27391
27433
  },
27392
27434
  dependencies: {
27393
27435
  "@agentclientprotocol/sdk": "^1.4.0",
27394
- "@openai/codex": "^0.153.3",
27436
+ "@openai/codex": "^0.153.4",
27395
27437
  diff: "^9.0.0",
27396
27438
  open: "^11.0.1",
27397
27439
  "vscode-jsonrpc": "^9.0.1",
@@ -27524,9 +27566,9 @@ Working directory: ${JSON.stringify(workspace.cwd)}
27524
27566
  Additional allowed directories: ${JSON.stringify(workspace.additionalDirectories)}`;
27525
27567
  }
27526
27568
  function parseAgentFileChangeReportRequest(meta3) {
27527
- const jetbrains = asRecord(meta3?.[JETBRAINS_META_KEY]);
27528
- const air = asRecord(jetbrains?.[AIR_META_KEY]);
27529
- const request = asRecord(air?.[AIR_AGENT_FILE_CHANGE_REPORT_REQUEST_KEY]);
27569
+ const jetbrains = asRecord2(meta3?.[JETBRAINS_META_KEY]);
27570
+ const air = asRecord2(jetbrains?.[AIR_META_KEY]);
27571
+ const request = asRecord2(air?.[AIR_AGENT_FILE_CHANGE_REPORT_REQUEST_KEY]);
27530
27572
  if (request === null || !hasOnlyKeys(request, ["version", "requestId"]) || request["version"] !== AGENT_FILE_CHANGE_REPORT_VERSION) {
27531
27573
  return null;
27532
27574
  }
@@ -27593,7 +27635,7 @@ function parseModelFileChangeReport(turn) {
27593
27635
  } catch {
27594
27636
  throw new AgentFileChangeReportError("invalidOutput", "The audit turn returned invalid JSON");
27595
27637
  }
27596
- const report = asRecord(value);
27638
+ const report = asRecord2(value);
27597
27639
  if (report === null || !hasOnlyKeys(report, ["paths", "complete", "uncertainty"])) {
27598
27640
  throw new AgentFileChangeReportError("invalidOutput", "The audit turn returned an invalid object");
27599
27641
  }
@@ -27770,7 +27812,7 @@ function isWindowsAbsolutePath2(value) {
27770
27812
  function isValidPathText(value) {
27771
27813
  return value.length > 0 && !/[\u0000-\u001F\u007F-\u009F]/.test(value);
27772
27814
  }
27773
- function asRecord(value) {
27815
+ function asRecord2(value) {
27774
27816
  return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
27775
27817
  }
27776
27818
  function hasOnlyKeys(value, allowed) {
@@ -27897,12 +27939,10 @@ import { createHash } from "node:crypto";
27897
27939
  async function forkSession(request, additionalDirectories, dependencies) {
27898
27940
  await dependencies.refreshSkills(request.cwd, additionalDirectories);
27899
27941
  const lastTurnId = await resolveForkTurnId(request, dependencies.codexClient);
27942
+ const prepared = await dependencies.createSessionConfig(request.cwd, additionalDirectories, request.mcpServers ?? []);
27900
27943
  const response = await dependencies.codexClient.threadFork({
27901
- config: await dependencies.createSessionConfig(
27902
- request.cwd,
27903
- additionalDirectories,
27904
- request.mcpServers ?? []
27905
- ),
27944
+ excludeTurns: true,
27945
+ config: prepared.config,
27906
27946
  cwd: request.cwd,
27907
27947
  ...lastTurnId !== void 0 && { lastTurnId },
27908
27948
  modelProvider: await dependencies.getResumeModelProvider(),
@@ -27917,16 +27957,14 @@ async function forkSession(request, additionalDirectories, dependencies) {
27917
27957
  collaborationMode: dependencies.getCollaborationMode(response.thread.id),
27918
27958
  modelProvider: response.modelProvider,
27919
27959
  currentServiceTier: response.serviceTier ?? null,
27920
- additionalDirectories
27960
+ additionalDirectories,
27961
+ fullAccessHttpMcpServers: prepared.fullAccessHttpMcpServers
27921
27962
  };
27922
27963
  }
27923
27964
  async function resolveForkTurnId(request, codexClient) {
27924
27965
  const forkPoint = readAirForkPoint(request._meta);
27925
27966
  if (!forkPoint) return void 0;
27926
- const history = await codexClient.threadRead({
27927
- threadId: request.sessionId,
27928
- includeTurns: true
27929
- });
27967
+ const history = await codexClient.threadReadWithHistory(request.sessionId);
27930
27968
  const candidateIds = airForkMessageIdCandidates(forkPoint.messageId);
27931
27969
  const itemTurnId = candidateIds.map((candidateId) => history.thread.turns.find((turn) => turn.items.some((item) => item.id === candidateId))?.id).find((turnId) => turnId !== void 0);
27932
27970
  if (itemTurnId) return itemTurnId;
@@ -28378,8 +28416,11 @@ var CodexAcpClient = class {
28378
28416
  const additionalDirectories = readAdditionalDirectories(request.cwd, request.additionalDirectories, request._meta);
28379
28417
  const initialAgentMode = AgentMode.getInitialAgentMode();
28380
28418
  await this.refreshSkills(request.cwd, additionalDirectories);
28419
+ const prepared = await this.createSessionConfig(request.cwd, additionalDirectories, request.mcpServers ?? []);
28420
+ await this.restrictResumedHttpMcpServers(request.sessionId, prepared);
28381
28421
  const response = await this.codexClient.threadResume({
28382
- config: await this.createSessionConfig(request.cwd, additionalDirectories, request.mcpServers ?? []),
28422
+ excludeTurns: true,
28423
+ config: prepared.config,
28383
28424
  cwd: request.cwd,
28384
28425
  modelProvider: await this.getResumeModelProvider(),
28385
28426
  threadId: request.sessionId,
@@ -28395,7 +28436,8 @@ var CodexAcpClient = class {
28395
28436
  collaborationMode: this.getCollaborationMode(response.thread.id),
28396
28437
  modelProvider: response.modelProvider,
28397
28438
  currentServiceTier: response.serviceTier ?? null,
28398
- additionalDirectories
28439
+ additionalDirectories,
28440
+ fullAccessHttpMcpServers: prepared.fullAccessHttpMcpServers
28399
28441
  };
28400
28442
  }
28401
28443
  async forkSession(request) {
@@ -28414,18 +28456,21 @@ var CodexAcpClient = class {
28414
28456
  const additionalDirectories = readAdditionalDirectories(request.cwd, request.additionalDirectories, request._meta);
28415
28457
  const initialAgentMode = AgentMode.getInitialAgentMode();
28416
28458
  await this.refreshSkills(request.cwd, additionalDirectories);
28459
+ const prepared = await this.createSessionConfig(request.cwd, additionalDirectories, request.mcpServers ?? []);
28460
+ await this.restrictResumedHttpMcpServers(request.sessionId, prepared);
28417
28461
  const response = await this.codexClient.threadResume({
28418
- config: await this.createSessionConfig(request.cwd, additionalDirectories, request.mcpServers ?? []),
28462
+ excludeTurns: true,
28463
+ config: prepared.config,
28419
28464
  cwd: request.cwd,
28420
28465
  modelProvider: await this.getResumeModelProvider(),
28421
28466
  threadId: request.sessionId,
28422
28467
  ...this.permissionProfileSelection(initialAgentMode, request.cwd, additionalDirectories)
28423
28468
  });
28424
28469
  onSubscribed?.();
28425
- const historyResponse = await this.codexClient.threadRead({
28426
- threadId: response.thread.id,
28427
- includeTurns: true
28428
- });
28470
+ const thread = response.thread.historyMode === "paginated" ? {
28471
+ ...response.thread,
28472
+ turns: response.turnsBackwardsCursor === null ? [] : await this.codexClient.threadReadHistory(response.thread.id, response.turnsBackwardsCursor)
28473
+ } : (await this.codexClient.threadReadWithHistory(response.thread.id)).thread;
28429
28474
  const codexModels = await this.fetchAvailableModels();
28430
28475
  const currentModelId = this.createModelId(codexModels, response.model, response.reasoningEffort).toString();
28431
28476
  return {
@@ -28435,22 +28480,21 @@ var CodexAcpClient = class {
28435
28480
  collaborationMode: this.getCollaborationMode(response.thread.id),
28436
28481
  modelProvider: response.modelProvider,
28437
28482
  currentServiceTier: response.serviceTier ?? null,
28438
- thread: historyResponse.thread,
28439
- additionalDirectories
28483
+ thread,
28484
+ additionalDirectories,
28485
+ fullAccessHttpMcpServers: prepared.fullAccessHttpMcpServers
28440
28486
  };
28441
28487
  }
28442
28488
  async readSessionThread(sessionId) {
28443
- return (await this.codexClient.threadRead({
28444
- threadId: sessionId,
28445
- includeTurns: true
28446
- })).thread;
28489
+ return (await this.codexClient.threadReadWithHistory(sessionId)).thread;
28447
28490
  }
28448
28491
  async newSession(request) {
28449
28492
  const additionalDirectories = readAdditionalDirectories(request.cwd, request.additionalDirectories, request._meta);
28450
28493
  const initialAgentMode = AgentMode.getInitialAgentMode();
28451
28494
  await this.refreshSkills(request.cwd, additionalDirectories);
28495
+ const prepared = await this.createSessionConfig(request.cwd, additionalDirectories, request.mcpServers);
28452
28496
  const response = await this.codexClient.threadStart({
28453
- config: await this.createSessionConfig(request.cwd, additionalDirectories, request.mcpServers),
28497
+ config: prepared.config,
28454
28498
  modelProvider: this.getModelProvider(),
28455
28499
  cwd: request.cwd,
28456
28500
  ...this.permissionProfileSelection(initialAgentMode, request.cwd, additionalDirectories)
@@ -28467,7 +28511,8 @@ var CodexAcpClient = class {
28467
28511
  collaborationMode: this.getCollaborationMode(response.thread.id),
28468
28512
  modelProvider: response.modelProvider,
28469
28513
  currentServiceTier: response.serviceTier ?? null,
28470
- additionalDirectories
28514
+ additionalDirectories,
28515
+ fullAccessHttpMcpServers: prepared.fullAccessHttpMcpServers
28471
28516
  };
28472
28517
  }
28473
28518
  async closeSession(sessionId) {
@@ -28482,11 +28527,23 @@ var CodexAcpClient = class {
28482
28527
  const config2 = this.permissionProfileConfig;
28483
28528
  if (!config2) return {};
28484
28529
  return {
28485
- approvalPolicy: agentMode.approvalPolicy,
28530
+ approvalPolicy: this.approvalPolicyForMode(agentMode),
28486
28531
  permissions: permissionProfileForMode(config2, agentMode.id),
28487
28532
  runtimeWorkspaceRoots: sessionRoots(cwd, additionalDirectories)
28488
28533
  };
28489
28534
  }
28535
+ isProtectedFullAccess(agentMode) {
28536
+ return this.permissionProfileConfig !== void 0 && agentMode.kind === "full_access";
28537
+ }
28538
+ approvalPolicyForMode(agentMode) {
28539
+ if (!this.isProtectedFullAccess(agentMode)) return agentMode.approvalPolicy;
28540
+ return { granular: { sandbox_approval: false, rules: false, skill_approval: false, request_permissions: false, mcp_elicitations: false } };
28541
+ }
28542
+ async restrictResumedHttpMcpServers(sessionId, prepared) {
28543
+ if (prepared.fullAccessHttpMcpServers.length === 0) return;
28544
+ const loaded = await this.codexClient.threadLoadedList({});
28545
+ if (loaded.data.includes(sessionId) || loaded.nextCursor !== null) prepared.fullAccessHttpMcpServers = [];
28546
+ }
28490
28547
  async deleteSession(sessionId) {
28491
28548
  await this.codexClient.threadArchive({ threadId: sessionId });
28492
28549
  }
@@ -28571,23 +28628,25 @@ var CodexAcpClient = class {
28571
28628
  };
28572
28629
  const configWithWorkspaceRoots = mergeSandboxWorkspaceWriteRoots(mergedConfig, additionalDirectories);
28573
28630
  if (mcpServers.length === 0) {
28574
- return configWithWorkspaceRoots;
28631
+ return { config: configWithWorkspaceRoots, fullAccessHttpMcpServers: [] };
28575
28632
  }
28576
28633
  const requestedServers = mcpServers.map((mcp) => ({
28577
28634
  name: sanitizeMcpServerName(mcp.name),
28578
28635
  server: mcp
28579
28636
  }));
28580
28637
  let serversToConfigure = requestedServers;
28638
+ const existingNames = shouldDeduplicateMcpConflicts() || this.permissionProfileConfig ? await this.getConfigMcpServerNames(projectPath) : /* @__PURE__ */ new Set();
28581
28639
  if (shouldDeduplicateMcpConflicts()) {
28582
- const existingNames = await this.getConfigMcpServerNames(projectPath);
28583
28640
  serversToConfigure = requestedServers.filter((mcp) => !existingNames.has(mcp.name));
28584
28641
  }
28585
28642
  if (serversToConfigure.length === 0) {
28586
- return configWithWorkspaceRoots;
28643
+ return { config: configWithWorkspaceRoots, fullAccessHttpMcpServers: [] };
28587
28644
  }
28645
+ const configuredServers = Object.fromEntries(serversToConfigure.map((mcp) => [mcp.name, this.createMcpSeverConfig(mcp.server)]));
28646
+ const inheritedServers = isJsonObject(this.config["mcp_servers"]) ? this.config["mcp_servers"] : {};
28588
28647
  return {
28589
- ...configWithWorkspaceRoots,
28590
- "mcp_servers": Object.fromEntries(serversToConfigure.map((mcp) => [mcp.name, this.createMcpSeverConfig(mcp.server)]))
28648
+ config: { ...configWithWorkspaceRoots, mcp_servers: configuredServers },
28649
+ fullAccessHttpMcpServers: this.permissionProfileConfig ? Object.entries(configuredServers).filter(([name, server]) => typeof server["url"] === "string" && !existingNames.has(name) && !Object.hasOwn(inheritedServers, name)).map(([name]) => name) : []
28591
28650
  };
28592
28651
  }
28593
28652
  async getConfigMcpServerNames(projectPath) {
@@ -28720,7 +28779,7 @@ var CodexAcpClient = class {
28720
28779
  return await this.codexClient.runTurn({
28721
28780
  threadId: request.sessionId,
28722
28781
  input,
28723
- approvalPolicy: agentMode.approvalPolicy,
28782
+ approvalPolicy: this.approvalPolicyForMode(agentMode),
28724
28783
  approvalsReviewer: agentMode.approvalsReviewer,
28725
28784
  ...sandboxSelection,
28726
28785
  summary: disableSummary ? "none" : "auto",
@@ -28740,6 +28799,7 @@ var CodexAcpClient = class {
28740
28799
  let lateStopReason = null;
28741
28800
  try {
28742
28801
  const forkPromise = this.codexClient.threadFork({
28802
+ excludeTurns: true,
28743
28803
  threadId: params.sessionId,
28744
28804
  lastTurnId: params.turnId,
28745
28805
  cwd: params.workspace.cwd,
@@ -28828,7 +28888,7 @@ var CodexAcpClient = class {
28828
28888
  if (!config2) return;
28829
28889
  await this.codexClient.threadSettingsUpdate({
28830
28890
  threadId: sessionId,
28831
- approvalPolicy: agentMode.approvalPolicy,
28891
+ approvalPolicy: this.approvalPolicyForMode(agentMode),
28832
28892
  permissions: permissionProfileForMode(config2, agentMode.id)
28833
28893
  });
28834
28894
  }
@@ -29586,6 +29646,41 @@ var CodexAppServerClient = class {
29586
29646
  async threadRead(params) {
29587
29647
  return await this.sendRequest({ method: "thread/read", params });
29588
29648
  }
29649
+ async threadTurnsList(params) {
29650
+ return await this.sendRequest({ method: "thread/turns/list", params });
29651
+ }
29652
+ async threadReadWithHistory(threadId) {
29653
+ const response = await this.threadRead({ threadId });
29654
+ if (response.thread.historyMode === "legacy") {
29655
+ return await this.threadRead({ threadId, includeTurns: true });
29656
+ }
29657
+ const turns = await this.threadReadHistory(threadId);
29658
+ return { ...response, thread: { ...response.thread, turns } };
29659
+ }
29660
+ async threadReadHistory(threadId, initialCursor = null) {
29661
+ const turns = [];
29662
+ const seenCursors = /* @__PURE__ */ new Set();
29663
+ if (initialCursor !== null) seenCursors.add(initialCursor);
29664
+ let cursor = initialCursor;
29665
+ do {
29666
+ const page = await this.threadTurnsList({
29667
+ threadId,
29668
+ cursor,
29669
+ limit: 50,
29670
+ sortDirection: "desc",
29671
+ itemsView: "full"
29672
+ });
29673
+ turns.push(...page.data);
29674
+ cursor = page.nextCursor;
29675
+ if (cursor !== null) {
29676
+ if (seenCursors.has(cursor)) {
29677
+ throw new Error("Codex returned a repeated thread history cursor");
29678
+ }
29679
+ seenCursors.add(cursor);
29680
+ }
29681
+ } while (cursor !== null);
29682
+ return turns.reverse();
29683
+ }
29589
29684
  async threadArchive(params) {
29590
29685
  return await this.sendRequest({ method: "thread/archive", params });
29591
29686
  }
@@ -30024,6 +30119,10 @@ function extractTurnRouting(notification) {
30024
30119
  // src/ModelConfigOption.ts
30025
30120
  var MODEL_CONFIG_ID = "model";
30026
30121
  var REASONING_EFFORT_CONFIG_ID = "reasoning_effort";
30122
+ function formatModelDisplayName(displayName) {
30123
+ if (!/^gpt-/i.test(displayName)) return displayName;
30124
+ return displayName.replace(/^gpt-/i, "").split(/[-/]+/).filter(Boolean).map(capitalize).join(" ");
30125
+ }
30027
30126
  function capitalize(value) {
30028
30127
  return value.charAt(0).toUpperCase() + value.slice(1);
30029
30128
  }
@@ -30031,19 +30130,20 @@ function findSupportedEffort(options, effort) {
30031
30130
  if (!effort) return void 0;
30032
30131
  return options.find((o) => o.reasoningEffort === effort)?.reasoningEffort;
30033
30132
  }
30034
- function createModelConfigOption(availableModels, currentBaseModelId) {
30133
+ function createModelConfigOption(availableModels, currentBaseModelId, recommendedModelId) {
30035
30134
  const options = availableModels.map((model) => ({
30036
30135
  value: model.id,
30037
- name: model.displayName,
30136
+ name: formatModelDisplayName(model.displayName),
30038
30137
  description: model.description
30039
30138
  }));
30040
30139
  if (!availableModels.some((model) => model.id === currentBaseModelId)) {
30041
30140
  options.unshift({
30042
30141
  value: currentBaseModelId,
30043
- name: currentBaseModelId,
30142
+ name: formatModelDisplayName(currentBaseModelId),
30044
30143
  description: null
30045
30144
  });
30046
30145
  }
30146
+ const recommendation = recommendedModelId && options.some((option) => option.value === recommendedModelId) ? recommendedModelId : void 0;
30047
30147
  return {
30048
30148
  id: MODEL_CONFIG_ID,
30049
30149
  name: "Model",
@@ -30051,10 +30151,12 @@ function createModelConfigOption(availableModels, currentBaseModelId) {
30051
30151
  category: "model",
30052
30152
  type: "select",
30053
30153
  currentValue: currentBaseModelId,
30054
- options
30154
+ options,
30155
+ ...recommendation ? { _meta: withAirMeta(void 0, AIR_RECOMMENDED_CONFIG_VALUE_KEY, recommendation) } : {}
30055
30156
  };
30056
30157
  }
30057
- function createReasoningEffortConfigOption(supportedReasoningEfforts, currentEffort) {
30158
+ function createReasoningEffortConfigOption(supportedReasoningEfforts, currentEffort, recommendedEffort) {
30159
+ const recommendation = findSupportedEffort(supportedReasoningEfforts, recommendedEffort);
30058
30160
  return {
30059
30161
  id: REASONING_EFFORT_CONFIG_ID,
30060
30162
  name: "Reasoning effort",
@@ -30066,7 +30168,8 @@ function createReasoningEffortConfigOption(supportedReasoningEfforts, currentEff
30066
30168
  value: option.reasoningEffort,
30067
30169
  name: capitalize(option.reasoningEffort),
30068
30170
  description: option.description
30069
- }))
30171
+ })),
30172
+ ...recommendation ? { _meta: withAirMeta(void 0, AIR_RECOMMENDED_CONFIG_VALUE_KEY, recommendation) } : {}
30070
30173
  };
30071
30174
  }
30072
30175
 
@@ -30766,14 +30869,14 @@ function parseJsonRecord(line) {
30766
30869
  }
30767
30870
  try {
30768
30871
  const value = JSON.parse(line);
30769
- return asRecord2(value);
30872
+ return asRecord3(value);
30770
30873
  } catch {
30771
30874
  return null;
30772
30875
  }
30773
30876
  }
30774
30877
  function extractResponseItem(record2) {
30775
30878
  if (record2["type"] === "response_item") {
30776
- return asRecord2(record2["payload"]);
30879
+ return asRecord3(record2["payload"]);
30777
30880
  }
30778
30881
  const itemType = record2["type"];
30779
30882
  if (typeof itemType === "string" && isLegacyResponseItemType(itemType)) {
@@ -30807,7 +30910,7 @@ function createEventMsgUpdates(record2) {
30807
30910
  if (record2["type"] !== "event_msg") {
30808
30911
  return null;
30809
30912
  }
30810
- const payload = asRecord2(record2["payload"]);
30913
+ const payload = asRecord3(record2["payload"]);
30811
30914
  if (!payload) {
30812
30915
  return [];
30813
30916
  }
@@ -30851,7 +30954,7 @@ function imageBlocks(images) {
30851
30954
  if (typeof image === "string") {
30852
30955
  return [{ type: "text", text: `[@image](${image})` }];
30853
30956
  }
30854
- const record2 = asRecord2(image);
30957
+ const record2 = asRecord3(image);
30855
30958
  const path9 = record2 ? stringValue(record2["path"]) ?? stringValue(record2["url"]) : null;
30856
30959
  return path9 ? [{ type: "text", text: `[@image](${path9})` }] : [];
30857
30960
  });
@@ -30861,7 +30964,7 @@ function contentBlocksFromResponseContent(content) {
30861
30964
  return [];
30862
30965
  }
30863
30966
  return content.flatMap((entry) => {
30864
- const record2 = asRecord2(entry);
30967
+ const record2 = asRecord3(entry);
30865
30968
  if (!record2) {
30866
30969
  return [];
30867
30970
  }
@@ -30894,7 +30997,7 @@ function textParts(value) {
30894
30997
  if (typeof entry === "string") {
30895
30998
  return entry.length > 0 ? [entry] : [];
30896
30999
  }
30897
- const record2 = asRecord2(entry);
31000
+ const record2 = asRecord3(entry);
30898
31001
  if (!record2) {
30899
31002
  return [];
30900
31003
  }
@@ -30986,7 +31089,7 @@ function parseFunctionArguments(value) {
30986
31089
  }
30987
31090
  function rawInputForFunctionCall(name, args) {
30988
31091
  if (name === "exec_command") {
30989
- const record2 = asRecord2(args);
31092
+ const record2 = asRecord3(args);
30990
31093
  if (record2) {
30991
31094
  return {
30992
31095
  command: stringValue(record2["cmd"]) ?? stringValue(record2["command"]),
@@ -31033,14 +31136,14 @@ function functionCallUsesTerminal(item) {
31033
31136
  return item["name"] === "exec_command";
31034
31137
  }
31035
31138
  function commandFromFunctionArguments(args) {
31036
- const record2 = asRecord2(args);
31139
+ const record2 = asRecord3(args);
31037
31140
  if (!record2) {
31038
31141
  return null;
31039
31142
  }
31040
31143
  return stringValue(record2["cmd"]) ?? stringValue(record2["command"]);
31041
31144
  }
31042
31145
  function cwdFromFunctionArguments(args) {
31043
- const record2 = asRecord2(args);
31146
+ const record2 = asRecord3(args);
31044
31147
  if (!record2) {
31045
31148
  return "";
31046
31149
  }
@@ -31512,7 +31615,7 @@ function outputText(output) {
31512
31615
  return "";
31513
31616
  }
31514
31617
  return output.flatMap((entry) => {
31515
- const record2 = asRecord2(entry);
31618
+ const record2 = asRecord3(entry);
31516
31619
  if (!record2) {
31517
31620
  return [];
31518
31621
  }
@@ -31528,7 +31631,7 @@ function outputText(output) {
31528
31631
  }).join("\n");
31529
31632
  }
31530
31633
  function parseExitCode(rawOutput, output) {
31531
- const record2 = asRecord2(rawOutput);
31634
+ const record2 = asRecord3(rawOutput);
31532
31635
  if (record2) {
31533
31636
  const exitCode2 = numberValue(record2["exit_code"]) ?? numberValue(record2["exitCode"]);
31534
31637
  if (exitCode2 !== null) {
@@ -31559,7 +31662,7 @@ function looksLikeCommandFailure(output) {
31559
31662
  }
31560
31663
  return /(^|\n)(Error|Failed|Command failed|Sandbox error|No such file or directory|Permission denied|Operation not permitted|ENOENT|EACCES)(:|\b)/i.test(trimmed);
31561
31664
  }
31562
- function asRecord2(value) {
31665
+ function asRecord3(value) {
31563
31666
  if (value === null || typeof value !== "object" || Array.isArray(value)) {
31564
31667
  return null;
31565
31668
  }
@@ -32209,12 +32312,7 @@ function clientSupportsTypedSessionFailures(capabilities) {
32209
32312
  function clientSupportsAgentFileChangeReports(capabilities) {
32210
32313
  return clientSupportsAirCapability(capabilities, AIR_AGENT_FILE_CHANGE_REPORT_KEY);
32211
32314
  }
32212
- var CodexAcpServer = class _CodexAcpServer {
32213
- static MODEL_NAME_TOKEN_OVERRIDES = {
32214
- gpt: "GPT",
32215
- mini: "Mini",
32216
- codex: "Codex"
32217
- };
32315
+ var CodexAcpServer = class {
32218
32316
  codexAcpClient;
32219
32317
  connection;
32220
32318
  defaultAuthRequest;
@@ -32341,7 +32439,8 @@ var CodexAcpServer = class _CodexAcpServer {
32341
32439
  AIR_SESSION_FAILURE_KEY,
32342
32440
  AIR_AGENT_FILE_CHANGE_REPORT_KEY,
32343
32441
  AIR_NATIVE_SUBAGENT_SESSIONS_KEY,
32344
- AIR_ASYNC_TASKS_KEY
32442
+ AIR_ASYNC_TASKS_KEY,
32443
+ AIR_RECOMMENDED_CONFIG_VALUE_KEY
32345
32444
  ]
32346
32445
  }
32347
32446
  }
@@ -32594,6 +32693,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
32594
32693
  supportedReasoningEfforts: currentModel?.supportedReasoningEfforts ?? [],
32595
32694
  supportedInputModalities: currentModel?.inputModalities ?? ["text", "image"],
32596
32695
  agentMode: AgentMode.getInitialAgentMode(),
32696
+ fullAccessHttpMcpServers: sessionMetadata.fullAccessHttpMcpServers ?? [],
32597
32697
  collaborationMode: sessionMetadata.collaborationMode,
32598
32698
  currentTurnId: null,
32599
32699
  lastTokenUsage: null,
@@ -32927,12 +33027,13 @@ Check ${configPath} and project .codex directories, especially their config.toml
32927
33027
  for (const session of this.sessions.values()) {
32928
33028
  session.asyncTasks.setAppServer(replacement.appServerClient);
32929
33029
  try {
32930
- await replacement.resumeSession({
33030
+ const metadata = await replacement.resumeSession({
32931
33031
  sessionId: session.sessionId,
32932
33032
  cwd: session.cwd,
32933
33033
  additionalDirectories: session.additionalDirectories,
32934
33034
  mcpServers: session.mcpServers ?? []
32935
33035
  });
33036
+ session.fullAccessHttpMcpServers = metadata.fullAccessHttpMcpServers ?? [];
32936
33037
  session.authProvider = replacement.getModelProvider();
32937
33038
  session.asyncTasks.refresh();
32938
33039
  logger.log("Resumed session after provider restart", { sessionId: session.sessionId });
@@ -33220,6 +33321,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
33220
33321
  if (!newMode) {
33221
33322
  throw RequestError.invalidParams();
33222
33323
  }
33324
+ sessionState.permissionModeRevision = (sessionState.permissionModeRevision ?? 0) + 1;
33223
33325
  await this.codexAcpClient.setAgentMode(
33224
33326
  sessionState.sessionId,
33225
33327
  newMode
@@ -33511,14 +33613,24 @@ Check ${configPath} and project .codex directories, especially their config.toml
33511
33613
  }
33512
33614
  createSessionConfigOptions(sessionState) {
33513
33615
  const currentModelId = ModelId.fromString(sessionState.currentModelId);
33616
+ const useRecommendedValue = clientSupportsAirCapability(
33617
+ this.clientCapabilities,
33618
+ AIR_RECOMMENDED_CONFIG_VALUE_KEY
33619
+ );
33620
+ const currentModel = this.findCurrentModel(sessionState.availableModels, sessionState.currentModelId);
33621
+ const recommendedModelId = useRecommendedValue ? sessionState.availableModels.find((model) => model.isDefault)?.id : void 0;
33514
33622
  const configOptions = [
33515
33623
  sessionState.agentMode.toConfigOption(),
33516
33624
  createCollaborationModeConfigOption(sessionState.collaborationMode),
33517
- createModelConfigOption(sessionState.availableModels, currentModelId.model)
33625
+ createModelConfigOption(sessionState.availableModels, currentModelId.model, recommendedModelId)
33518
33626
  ];
33519
33627
  if (sessionState.supportedReasoningEfforts.length > 0) {
33520
33628
  configOptions.push(
33521
- createReasoningEffortConfigOption(sessionState.supportedReasoningEfforts, currentModelId.effort)
33629
+ createReasoningEffortConfigOption(
33630
+ sessionState.supportedReasoningEfforts,
33631
+ currentModelId.effort,
33632
+ useRecommendedValue ? currentModel?.defaultReasoningEffort : void 0
33633
+ )
33522
33634
  );
33523
33635
  }
33524
33636
  if (sessionState.currentModelSupportsFast) {
@@ -33595,14 +33707,11 @@ Check ${configPath} and project .codex directories, especially their config.toml
33595
33707
  const modelId = ModelId.fromString(currentModelId);
33596
33708
  return models.find((m) => m.id === modelId.model);
33597
33709
  }
33598
- normalizeModelDisplayName(displayName) {
33599
- return displayName.split("-").map((token) => _CodexAcpServer.MODEL_NAME_TOKEN_OVERRIDES[token.toLowerCase()] ?? token).join("-");
33600
- }
33601
33710
  createModelState(availableModels, selectedModelId) {
33602
33711
  const allowedModels = availableModels.flatMap(
33603
33712
  (model) => model.supportedReasoningEfforts.map((effort) => ({
33604
33713
  modelId: ModelId.fromComponents(model, effort.reasoningEffort).toString(),
33605
- name: `${this.normalizeModelDisplayName(model.displayName)} (${effort.reasoningEffort})`,
33714
+ name: `${formatModelDisplayName(model.displayName)} (${effort.reasoningEffort})`,
33606
33715
  description: `${model.description} ${effort.description}`
33607
33716
  }))
33608
33717
  );
@@ -33656,6 +33765,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
33656
33765
  supportedReasoningEfforts: currentModel?.supportedReasoningEfforts ?? [],
33657
33766
  supportedInputModalities: currentModel?.inputModalities ?? ["text", "image"],
33658
33767
  agentMode: AgentMode.getInitialAgentMode(),
33768
+ fullAccessHttpMcpServers: sessionMetadata.fullAccessHttpMcpServers ?? [],
33659
33769
  collaborationMode: sessionMetadata.collaborationMode,
33660
33770
  currentTurnId: null,
33661
33771
  lastTokenUsage: null,
@@ -34400,16 +34510,27 @@ Check ${configPath} and project .codex directories, especially their config.toml
34400
34510
  eventHandler = promptEventHandler;
34401
34511
  const permissionLifecycle = this.permissionLifecycleContext(sessionState);
34402
34512
  const permissionContext = permissionLifecycle.beginPrompt();
34513
+ let promptAgentMode;
34514
+ let permissionModeRevision;
34515
+ const httpServers = new Set(sessionState.fullAccessHttpMcpServers);
34516
+ const noHttpServers = /* @__PURE__ */ new Set();
34517
+ let mcpApprovalTurnId = null;
34518
+ const isProtectedFullAccess = () => this.codexAcpClient.isProtectedFullAccess(promptAgentMode ?? sessionState.agentMode);
34403
34519
  const approvalHandler = new CodexApprovalHandler(
34404
34520
  this.connection,
34405
34521
  permissionContext,
34406
- activePrompt.signal
34522
+ activePrompt.signal,
34523
+ isProtectedFullAccess
34407
34524
  );
34408
34525
  const elicitationHandler = new CodexElicitationHandler(
34409
34526
  this.connection,
34410
34527
  permissionContext,
34411
34528
  this.clientCapabilities,
34412
- activePrompt.signal
34529
+ activePrompt.signal,
34530
+ (request) => {
34531
+ if (!isProtectedFullAccess()) return void 0;
34532
+ return mcpApprovalTurnId !== null && request.turnId === mcpApprovalTurnId && sessionState.agentMode.kind === "full_access" && sessionState.permissionModeRevision === permissionModeRevision ? httpServers : noHttpServers;
34533
+ }
34413
34534
  );
34414
34535
  const observeInteraction = async (event) => {
34415
34536
  permissionContext.handleNotification(event);
@@ -34534,6 +34655,8 @@ Check ${configPath} and project .codex directories, especially their config.toml
34534
34655
  throw RequestError.invalidRequest("The current model does not support image input");
34535
34656
  }
34536
34657
  const agentMode = sessionState.agentMode;
34658
+ promptAgentMode = agentMode;
34659
+ permissionModeRevision = sessionState.permissionModeRevision;
34537
34660
  const serviceTier = resolveFastServiceTier(
34538
34661
  sessionState.fastModeEnabled,
34539
34662
  sessionState.currentModelSupportsFast
@@ -34550,6 +34673,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
34550
34673
  sessionState.cwd,
34551
34674
  sessionState.additionalDirectories,
34552
34675
  (turnId) => {
34676
+ mcpApprovalTurnId = turnId;
34553
34677
  const turn = { threadId: params.sessionId, turnId };
34554
34678
  activePrompt.currentTurn = turn;
34555
34679
  if (this.promptShouldStop(params.sessionId, activePrompt)) {
@@ -34560,7 +34684,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
34560
34684
  pendingTurnStart?.resolve(turnId);
34561
34685
  onTurnStarted?.();
34562
34686
  },
34563
- () => this.promptShouldStop(params.sessionId, activePrompt)
34687
+ () => this.promptShouldStop(params.sessionId, activePrompt) || sessionState.permissionModeRevision !== permissionModeRevision
34564
34688
  )
34565
34689
  );
34566
34690
  void sendPromptPromise.catch((err) => {
@@ -34640,6 +34764,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
34640
34764
  sessionState.cwd,
34641
34765
  sessionState.additionalDirectories,
34642
34766
  (turnId) => {
34767
+ mcpApprovalTurnId = turnId;
34643
34768
  const turn = { threadId: params.sessionId, turnId };
34644
34769
  activePrompt.currentTurn = turn;
34645
34770
  if (this.promptShouldStop(params.sessionId, activePrompt)) {
@@ -34650,7 +34775,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
34650
34775
  recoverableSessionFailure = sessionState.sessionFailure;
34651
34776
  promptNotificationsActive = true;
34652
34777
  },
34653
- () => this.promptShouldStop(params.sessionId, activePrompt)
34778
+ () => this.promptShouldStop(params.sessionId, activePrompt) || sessionState.permissionModeRevision !== permissionModeRevision
34654
34779
  )
34655
34780
  );
34656
34781
  void implementationPromise.catch((err) => {
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.10.0-agentconnect.1",
6
+ "version": "1.11.0-agentconnect.1",
7
7
  "description": "",
8
8
  "main": "dist/index.js",
9
9
  "bin": {
@@ -65,7 +65,7 @@
65
65
  },
66
66
  "dependencies": {
67
67
  "@agentclientprotocol/sdk": "^1.4.0",
68
- "@openai/codex": "^0.153.3",
68
+ "@openai/codex": "^0.153.4",
69
69
  "diff": "^9.0.0",
70
70
  "open": "^11.0.1",
71
71
  "vscode-jsonrpc": "^9.0.1",