@agentclientprotocol/codex-acp 1.9.0 → 1.10.0

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 +7 -0
  2. package/dist/index.js +501 -44
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -13,6 +13,7 @@ Use [OpenAI Codex](https://github.com/openai/codex) from [Agent Client Protocol]
13
13
  - Text prompts, embedded context, images, resource links, and additional workspace directories.
14
14
  - 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
15
  - [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.
16
+ - [Background terminal tasks](docs/async-tasks.md) in AIR, with task status and targeted stop support after capability negotiation.
16
17
  - Session-scoped long-running goals through the provider-neutral [goal extension](docs/goal-extension.md).
17
18
  - A per-turn [agent file-change report](docs/agent-file-change-report.md) after capability negotiation.
18
19
  - Client-provided MCP servers over command-based stdio config and HTTP transport.
@@ -82,6 +83,12 @@ Subagent sessions follow the draft [ACP subagent RFD](https://github.com/agentcl
82
83
 
83
84
  See [docs/subagent-sessions.md](docs/subagent-sessions.md) for the negotiation, lifecycle events, `session/load` reconstruction, and legacy fallback details.
84
85
 
86
+ ### Background terminal tasks
87
+
88
+ Codex can keep a shell command running after a turn continues. AIR clients can show this work in the Async Tasks panel and stop one command.
89
+
90
+ See [docs/async-tasks.md](docs/async-tasks.md) for the capability, lifecycle events, and stop request.
91
+
85
92
  ## License
86
93
 
87
94
  By contributing, you agree that your contributions will be licensed under the Apache 2.0 License.
package/dist/index.js CHANGED
@@ -22131,32 +22131,7 @@ function attachLogs(proc) {
22131
22131
  });
22132
22132
  }
22133
22133
 
22134
- // src/AirExtension.ts
22135
- var JETBRAINS_META_KEY = "jetbrains";
22136
- var AIR_META_KEY = "air";
22137
- var AIR_EXTENSION_VERSION_KEY = "version";
22138
- var AIR_EXTENSION_CAPABILITIES_KEY = "capabilities";
22139
- var AIR_SESSION_FAILURE_KEY = "sessionFailure";
22140
- var AIR_AGENT_FILE_CHANGE_REPORT_KEY = "agentFileChangeReport";
22141
- var AIR_NATIVE_SUBAGENT_SESSIONS_KEY = "nativeSubagentSessions";
22142
- var AIR_AGENT_FILE_CHANGE_REPORT_REQUEST_KEY = "agentFileChangeReportRequest";
22143
- var AIR_EXTENSION_VERSION = 1;
22144
- function clientSupportsAirCapability(capabilities, capability) {
22145
- const jetbrains = capabilities?._meta?.[JETBRAINS_META_KEY];
22146
- const air = jetbrains?.[AIR_META_KEY];
22147
- const version2 = air?.[AIR_EXTENSION_VERSION_KEY];
22148
- const supported = air?.[AIR_EXTENSION_CAPABILITIES_KEY];
22149
- return typeof version2 === "number" && Number.isInteger(version2) && version2 >= AIR_EXTENSION_VERSION && Array.isArray(supported) && supported.includes(capability);
22150
- }
22151
-
22152
- // src/subagents/AcpSubagents.ts
22153
- function clientSupportsSubagents(capabilities) {
22154
- const subagents = capabilities?.subagents;
22155
- if (typeof subagents === "object" && subagents !== null && !Array.isArray(subagents)) {
22156
- return true;
22157
- }
22158
- return clientSupportsAirCapability(capabilities, AIR_NATIVE_SUBAGENT_SESSIONS_KEY);
22159
- }
22134
+ // src/AcpSessionExtensions.ts
22160
22135
  function asSdkSessionNotification(notification) {
22161
22136
  return notification;
22162
22137
  }
@@ -23676,6 +23651,26 @@ function sameThreadGoalSnapshot(left, right) {
23676
23651
  // src/CodexEventHandler.ts
23677
23652
  import { randomUUID } from "node:crypto";
23678
23653
 
23654
+ // src/AirExtension.ts
23655
+ var JETBRAINS_META_KEY = "jetbrains";
23656
+ var AIR_META_KEY = "air";
23657
+ var AIR_EXTENSION_VERSION_KEY = "version";
23658
+ var AIR_EXTENSION_CAPABILITIES_KEY = "capabilities";
23659
+ var AIR_SESSION_FAILURE_KEY = "sessionFailure";
23660
+ var AIR_AGENT_FILE_CHANGE_REPORT_KEY = "agentFileChangeReport";
23661
+ var AIR_NATIVE_SUBAGENT_SESSIONS_KEY = "nativeSubagentSessions";
23662
+ var AIR_ASYNC_TASKS_KEY = "asyncTasks";
23663
+ var AIR_ASYNC_TASKS_BACKGROUNDED_KEY = "backgrounded";
23664
+ var AIR_AGENT_FILE_CHANGE_REPORT_REQUEST_KEY = "agentFileChangeReportRequest";
23665
+ var AIR_EXTENSION_VERSION = 1;
23666
+ function clientSupportsAirCapability(capabilities, capability) {
23667
+ const jetbrains = capabilities?._meta?.[JETBRAINS_META_KEY];
23668
+ const air = jetbrains?.[AIR_META_KEY];
23669
+ const version2 = air?.[AIR_EXTENSION_VERSION_KEY];
23670
+ const supported = air?.[AIR_EXTENSION_CAPABILITIES_KEY];
23671
+ return typeof version2 === "number" && Number.isInteger(version2) && version2 >= AIR_EXTENSION_VERSION && Array.isArray(supported) && supported.includes(capability);
23672
+ }
23673
+
23679
23674
  // src/subagents/CodexAgentPath.ts
23680
23675
  function normalizeAgentPath(path9) {
23681
23676
  const normalized = path9.trim().replace(/\/+$/, "");
@@ -23731,14 +23726,14 @@ var CodexSubagentEventRouter = class _CodexSubagentEventRouter {
23731
23726
  }
23732
23727
  return childTurn;
23733
23728
  }
23734
- const notificationThreadId = notification.params.threadId;
23735
- if (typeof notificationThreadId === "string" && this.pendingSpawns.has(notificationThreadId)) {
23736
- const pending = this.pendingSpawns.get(notificationThreadId);
23729
+ const notificationThreadId2 = notification.params.threadId;
23730
+ if (typeof notificationThreadId2 === "string" && this.pendingSpawns.has(notificationThreadId2)) {
23731
+ const pending = this.pendingSpawns.get(notificationThreadId2);
23737
23732
  if (pending.buffered.length === _CodexSubagentEventRouter.MAX_PENDING_NOTIFICATIONS) {
23738
23733
  pending.buffered.shift();
23739
23734
  pending.droppedBufferedNotifications += 1;
23740
23735
  if (pending.droppedBufferedNotifications === 1) {
23741
- logger.log(`Pending subagent ${notificationThreadId} exceeded the notification buffer; dropping oldest updates`);
23736
+ logger.log(`Pending subagent ${notificationThreadId2} exceeded the notification buffer; dropping oldest updates`);
23742
23737
  }
23743
23738
  }
23744
23739
  pending.buffered.push(notification);
@@ -23823,6 +23818,25 @@ var CodexSubagentEventRouter = class _CodexSubagentEventRouter {
23823
23818
  const threadId = notification.params.threadId;
23824
23819
  return typeof threadId === "string" && this.children.has(threadId) ? this.children.get(threadId).sessionId : this.rootSessionId;
23825
23820
  }
23821
+ closingChildSessions(notification) {
23822
+ if (!this.supported) return [];
23823
+ if (notification.method === "turn/completed") {
23824
+ if (terminalStateFromTurn(notification.params.turn.status) === void 0) return [];
23825
+ return this.closingChildSession(notification.params.threadId);
23826
+ }
23827
+ if (notification.method !== "item/started" && notification.method !== "item/completed") return [];
23828
+ const item = notification.params.item;
23829
+ if (item.type === "subAgentActivity") {
23830
+ return item.kind === "interrupted" ? this.closingChildSession(item.agentThreadId) : [];
23831
+ }
23832
+ if (item.type !== "collabAgentToolCall") return [];
23833
+ const closing = /* @__PURE__ */ new Map();
23834
+ for (const [threadId, state] of Object.entries(item.agentsStates)) {
23835
+ if (!state || terminalStateOf(state.status) === void 0) continue;
23836
+ for (const child of this.closingChildSession(threadId)) closing.set(threadId, child);
23837
+ }
23838
+ return [...closing.values()];
23839
+ }
23826
23840
  takeBufferedNotifications() {
23827
23841
  return this.replayQueue.splice(0);
23828
23842
  }
@@ -23898,6 +23912,10 @@ var CodexSubagentEventRouter = class _CodexSubagentEventRouter {
23898
23912
  isKnownChild(threadId) {
23899
23913
  return threadId !== this.rootSessionId && (this.children.has(threadId) || this.pendingSpawns.has(threadId) || this.terminalPendingSpawns.has(threadId));
23900
23914
  }
23915
+ closingChildSession(threadId) {
23916
+ const child = this.children.get(threadId);
23917
+ return child && child.terminalState === void 0 ? [{ threadId, sessionId: child.sessionId }] : [];
23918
+ }
23901
23919
  async materialize(childSessionId, path9) {
23902
23920
  if (this.children.has(childSessionId)) return;
23903
23921
  const pending = this.pendingSpawns.get(childSessionId);
@@ -24306,17 +24324,29 @@ var CodexEventHandler = class _CodexEventHandler {
24306
24324
  }
24307
24325
  async handleNotification(notification) {
24308
24326
  await this.flushPendingErrors();
24327
+ const closingChildren = this.subagents.closingChildSessions(notification);
24328
+ for (const child of closingChildren) {
24329
+ await this.sessionState.asyncTasks.reconcile(child.threadId, child.sessionId);
24330
+ }
24309
24331
  const handledBySubagents = await this.subagents.handle(notification);
24310
24332
  for (const buffered of this.subagents.takeBufferedNotifications()) {
24311
24333
  await this.handleNotification(buffered);
24312
24334
  }
24313
- if (handledBySubagents) {
24314
- return;
24335
+ const ignoredBySubagents = !handledBySubagents && this.subagents.shouldIgnore(notification);
24336
+ let updateEvent;
24337
+ if (!handledBySubagents && !ignoredBySubagents && notification.method === "item/started" && notification.params.item.type === "commandExecution") {
24338
+ updateEvent = await this.createUpdateEvent(notification);
24315
24339
  }
24316
- if (this.subagents.shouldIgnore(notification)) {
24317
- return;
24340
+ if (!handledBySubagents) {
24341
+ await this.sessionState.asyncTasks.handleNotification(
24342
+ notification,
24343
+ this.subagents.notificationSessionId(notification),
24344
+ toolCallTitle(updateEvent)
24345
+ );
24318
24346
  }
24319
- const updateEvent = await this.createUpdateEvent(notification);
24347
+ if (handledBySubagents) return;
24348
+ if (ignoredBySubagents) return;
24349
+ if (updateEvent === void 0) updateEvent = await this.createUpdateEvent(notification);
24320
24350
  if (updateEvent) {
24321
24351
  await this.session.update(updateEvent, this.subagents.notificationSessionId(notification));
24322
24352
  }
@@ -25153,6 +25183,10 @@ ${event.stdin}
25153
25183
  return createGuardianApprovalReviewToolCall(params);
25154
25184
  }
25155
25185
  };
25186
+ function toolCallTitle(update) {
25187
+ if (update?.sessionUpdate !== "tool_call") return void 0;
25188
+ return update.title;
25189
+ }
25156
25190
 
25157
25191
  // src/permissions/option-ids.ts
25158
25192
  var ApprovalOptionId = {
@@ -27285,7 +27319,7 @@ var package_default = {
27285
27319
  publishConfig: {
27286
27320
  access: "public"
27287
27321
  },
27288
- version: "1.9.0",
27322
+ version: "1.10.0",
27289
27323
  description: "",
27290
27324
  main: "dist/index.js",
27291
27325
  bin: {
@@ -27348,7 +27382,7 @@ var package_default = {
27348
27382
  },
27349
27383
  dependencies: {
27350
27384
  "@agentclientprotocol/sdk": "^1.4.0",
27351
- "@openai/codex": "^0.153.2",
27385
+ "@openai/codex": "^0.153.3",
27352
27386
  diff: "^9.0.0",
27353
27387
  open: "^11.0.1",
27354
27388
  "vscode-jsonrpc": "^9.0.1",
@@ -29491,6 +29525,12 @@ var CodexAppServerClient = class {
29491
29525
  async threadCompactStart(params) {
29492
29526
  return await this.sendRequest({ method: "thread/compact/start", params });
29493
29527
  }
29528
+ async threadBackgroundTerminalsList(params) {
29529
+ return await this.sendRequest({ method: "thread/backgroundTerminals/list", params });
29530
+ }
29531
+ async threadBackgroundTerminalsTerminate(params) {
29532
+ return await this.sendRequest({ method: "thread/backgroundTerminals/terminate", params });
29533
+ }
29494
29534
  async threadGoalSet(params) {
29495
29535
  return await this.sendRequest({ method: "thread/goal/set", params });
29496
29536
  }
@@ -31462,6 +31502,9 @@ function numberValue(value) {
31462
31502
  return typeof value === "number" && Number.isFinite(value) ? value : null;
31463
31503
  }
31464
31504
 
31505
+ // src/async-tasks/AsyncTaskExtension.ts
31506
+ var ASYNC_TASK_STOP_METHOD = "_session/async_task/stop";
31507
+
31465
31508
  // src/AuthStatusMeta.ts
31466
31509
  var AUTH_STATUS_UPDATE_METHOD = "_auth/status_update";
31467
31510
  var AUTH_STATUS_META_KEY = "authStatus";
@@ -31599,7 +31642,7 @@ function sameAuthStatus(previous, next) {
31599
31642
  var LEGACY_SET_SESSION_MODEL_METHOD = "session/set_model";
31600
31643
  var SESSION_STEERING_METHOD = "_session/steering";
31601
31644
  function isExtMethodRequest(request) {
31602
- return request.method === "authentication/status" || request.method === "authentication/logout" || request.method === LEGACY_SET_SESSION_MODEL_METHOD || request.method === GOAL_CONTROL_METHOD || request.method === LEGACY_GOAL_CONTROL_METHOD || request.method === SESSION_STEERING_METHOD;
31645
+ return request.method === "authentication/status" || request.method === "authentication/logout" || request.method === LEGACY_SET_SESSION_MODEL_METHOD || request.method === GOAL_CONTROL_METHOD || request.method === LEGACY_GOAL_CONTROL_METHOD || request.method === SESSION_STEERING_METHOD || request.method === ASYNC_TASK_STOP_METHOD;
31603
31646
  }
31604
31647
 
31605
31648
  // src/FastModeConfig.ts
@@ -31666,6 +31709,15 @@ function clientSupportsPlanUpdates(clientCapabilities) {
31666
31709
  return clientCapabilities?.plan != null;
31667
31710
  }
31668
31711
 
31712
+ // src/subagents/AcpSubagents.ts
31713
+ function clientSupportsSubagents(capabilities) {
31714
+ const subagents = capabilities?.subagents;
31715
+ if (typeof subagents === "object" && subagents !== null && !Array.isArray(subagents)) {
31716
+ return true;
31717
+ }
31718
+ return clientSupportsAirCapability(capabilities, AIR_NATIVE_SUBAGENT_SESSIONS_KEY);
31719
+ }
31720
+
31669
31721
  // src/CodexAcpServer.ts
31670
31722
  import { randomUUID as randomUUID2 } from "node:crypto";
31671
31723
 
@@ -31754,6 +31806,332 @@ function extractTitle(turn) {
31754
31806
 
31755
31807
  // src/CodexAcpServer.ts
31756
31808
  import { once } from "node:events";
31809
+
31810
+ // src/async-tasks/CodexBackgroundTerminalTasks.ts
31811
+ var CodexBackgroundTerminalTasks = class {
31812
+ constructor(enabled, rootSessionId, appServer, session) {
31813
+ this.enabled = enabled;
31814
+ this.rootSessionId = rootSessionId;
31815
+ this.appServer = appServer;
31816
+ this.session = session;
31817
+ }
31818
+ enabled;
31819
+ rootSessionId;
31820
+ appServer;
31821
+ session;
31822
+ tasks = /* @__PURE__ */ new Map();
31823
+ syncs = /* @__PURE__ */ new Map();
31824
+ appServerGeneration = 0;
31825
+ appServerQueriesEnabled = true;
31826
+ disposed = false;
31827
+ async handleNotification(notification, sessionId, commandTitle2) {
31828
+ if (!this.isActive()) return;
31829
+ const threadId = notificationThreadId(notification);
31830
+ if (threadId === null) return;
31831
+ if (notification.method === "item/started" && notification.params.item.type === "commandExecution") {
31832
+ this.observeCommandStarted(notification.params.item, threadId, sessionId, commandTitle2);
31833
+ return;
31834
+ }
31835
+ if (notification.method === "item/completed" && notification.params.item.type === "commandExecution") {
31836
+ await this.observeCommandCompleted(notification.params.item, threadId);
31837
+ return;
31838
+ }
31839
+ if (notification.method === "turn/completed") {
31840
+ await this.reconcile(threadId, sessionId);
31841
+ return;
31842
+ }
31843
+ if (notification.method === "item/started") {
31844
+ this.refresh(threadId, sessionId);
31845
+ }
31846
+ }
31847
+ observeCommandStarted(item, threadId, sessionId, commandTitle2) {
31848
+ if (!this.isActive() || item.processId === null) return;
31849
+ this.remember(threadId, sessionId, {
31850
+ itemId: item.id,
31851
+ processId: item.processId,
31852
+ command: item.command
31853
+ }, commandTitle2);
31854
+ }
31855
+ async observeCommandCompleted(item, threadId) {
31856
+ if (!this.isActive()) return;
31857
+ const task = this.tasks.get(wireTaskId(this.rootSessionId, threadId, item.id));
31858
+ if (task) await this.finish(task, item.status === "completed" ? "completed" : "failed");
31859
+ }
31860
+ refresh(threadId = this.rootSessionId, sessionId = this.rootSessionId) {
31861
+ void this.reconcile(threadId, sessionId);
31862
+ }
31863
+ async reconcile(threadId = this.rootSessionId, sessionId = this.rootSessionId) {
31864
+ try {
31865
+ await this.sync(threadId, sessionId);
31866
+ } catch (error51) {
31867
+ if (this.isActive()) logger.error(`Failed to list background terminals for ${threadId}`, error51);
31868
+ }
31869
+ }
31870
+ setAppServer(appServer) {
31871
+ this.appServer = appServer;
31872
+ this.appServerGeneration += 1;
31873
+ this.appServerQueriesEnabled = true;
31874
+ }
31875
+ prepareForAppServerReplacement() {
31876
+ this.appServerGeneration += 1;
31877
+ this.appServerQueriesEnabled = false;
31878
+ }
31879
+ async recover(threadId, sessionId, itemIds) {
31880
+ if (!this.canQueryAppServer() || itemIds.size === 0) return;
31881
+ const snapshot = await this.listAll(threadId);
31882
+ if (snapshot === null) return;
31883
+ for (const terminal of snapshot.terminals) {
31884
+ if (!this.queryIsCurrent(snapshot.generation)) return;
31885
+ if (!itemIds.has(terminal.itemId)) continue;
31886
+ const task = this.remember(threadId, sessionId, terminal);
31887
+ if (task.publication === "unpublished" && task.state === "running") await this.announce(task);
31888
+ }
31889
+ }
31890
+ async finishAll(state) {
31891
+ if (!this.isActive()) return;
31892
+ const errors = [];
31893
+ for (const task of this.tasks.values()) {
31894
+ try {
31895
+ await this.finish(task, state);
31896
+ } catch (error51) {
31897
+ errors.push(error51);
31898
+ }
31899
+ }
31900
+ if (errors.length > 0) {
31901
+ throw new AggregateError(errors, `Failed to finish ${errors.length} background terminal task(s)`);
31902
+ }
31903
+ }
31904
+ async sync(threadId = this.rootSessionId, sessionId = this.rootSessionId) {
31905
+ if (!this.canQueryAppServer()) return;
31906
+ const current = this.syncs.get(threadId);
31907
+ if (current) {
31908
+ current.requested = true;
31909
+ current.sessionId = sessionId;
31910
+ return await current.promise;
31911
+ }
31912
+ const pending = {
31913
+ requested: false,
31914
+ sessionId,
31915
+ promise: Promise.resolve()
31916
+ };
31917
+ pending.promise = this.syncUntilCurrent(threadId, pending).finally(() => {
31918
+ if (this.syncs.get(threadId) === pending) this.syncs.delete(threadId);
31919
+ });
31920
+ this.syncs.set(threadId, pending);
31921
+ await pending.promise;
31922
+ }
31923
+ async stop(taskId) {
31924
+ if (!this.isActive()) return false;
31925
+ const task = this.tasks.get(taskId);
31926
+ if (!task || task.publication !== "published") return false;
31927
+ if (task.state === "stopped" && !task.terminalPublished) {
31928
+ await this.publishTerminalState(task);
31929
+ return true;
31930
+ }
31931
+ if (task.state !== "running") return false;
31932
+ task.state = "stopping";
31933
+ try {
31934
+ const response = await this.appServer.threadBackgroundTerminalsTerminate({
31935
+ threadId: task.threadId,
31936
+ processId: task.processId
31937
+ });
31938
+ if (!response.terminated) {
31939
+ if (task.state === "stopping") task.state = "running";
31940
+ return false;
31941
+ }
31942
+ await this.finish(task, "stopped");
31943
+ return true;
31944
+ } catch (error51) {
31945
+ if (task.state === "stopping") task.state = "running";
31946
+ throw error51;
31947
+ }
31948
+ }
31949
+ clear() {
31950
+ this.disposed = true;
31951
+ this.appServerGeneration += 1;
31952
+ this.appServerQueriesEnabled = false;
31953
+ this.tasks.clear();
31954
+ this.syncs.clear();
31955
+ }
31956
+ async syncThread(threadId, sessionId) {
31957
+ const snapshot = await this.listAll(threadId);
31958
+ if (snapshot === null || !this.queryIsCurrent(snapshot.generation)) return;
31959
+ const liveTaskIds = /* @__PURE__ */ new Set();
31960
+ for (const terminal of snapshot.terminals) {
31961
+ if (!this.queryIsCurrent(snapshot.generation)) return;
31962
+ liveTaskIds.add(terminal.itemId);
31963
+ const task = this.remember(threadId, sessionId, terminal);
31964
+ if (task.publication === "unpublished" && task.state === "running") await this.announce(task);
31965
+ }
31966
+ for (const task of this.tasks.values()) {
31967
+ if (!this.queryIsCurrent(snapshot.generation)) return;
31968
+ if (task.threadId === threadId && task.publication === "published" && (task.state === "running" || task.state === "stopping") && !liveTaskIds.has(task.itemId)) {
31969
+ await this.finish(task, "stopped");
31970
+ }
31971
+ }
31972
+ }
31973
+ async syncUntilCurrent(threadId, pending) {
31974
+ let hasFailure = false;
31975
+ let failure;
31976
+ do {
31977
+ pending.requested = false;
31978
+ try {
31979
+ await this.syncThread(threadId, pending.sessionId);
31980
+ hasFailure = false;
31981
+ } catch (error51) {
31982
+ hasFailure = true;
31983
+ failure = error51;
31984
+ }
31985
+ } while (pending.requested && this.canQueryAppServer());
31986
+ if (hasFailure) throw failure;
31987
+ }
31988
+ async announce(task) {
31989
+ if (task.publication === "published") return;
31990
+ if (task.announcement !== null) {
31991
+ await task.announcement;
31992
+ return;
31993
+ }
31994
+ task.publication = "publishing";
31995
+ const announcement = this.publishAnnouncement(task);
31996
+ task.announcement = announcement;
31997
+ try {
31998
+ await announcement;
31999
+ } finally {
32000
+ if (task.announcement === announcement) task.announcement = null;
32001
+ }
32002
+ if (isTerminalState(task.state)) await this.publishTerminalState(task);
32003
+ }
32004
+ async publishAnnouncement(task) {
32005
+ try {
32006
+ await this.publishSpawn(task);
32007
+ task.publication = "published";
32008
+ } catch (error51) {
32009
+ task.publication = "unpublished";
32010
+ throw error51;
32011
+ }
32012
+ }
32013
+ async publishSpawn(task) {
32014
+ await this.session.update({
32015
+ sessionUpdate: "tool_call_update",
32016
+ toolCallId: task.itemId,
32017
+ _meta: {
32018
+ [JETBRAINS_META_KEY]: {
32019
+ [AIR_META_KEY]: {
32020
+ [AIR_ASYNC_TASKS_KEY]: {
32021
+ [AIR_ASYNC_TASKS_BACKGROUNDED_KEY]: true
32022
+ }
32023
+ }
32024
+ }
32025
+ }
32026
+ }, task.sessionId);
32027
+ await this.session.update({
32028
+ sessionUpdate: "async_task_spawned",
32029
+ asyncTaskId: task.asyncTaskId,
32030
+ name: task.name,
32031
+ taskType: "shell",
32032
+ showInTranscript: false,
32033
+ canStop: true,
32034
+ toolCallId: task.itemId
32035
+ }, task.sessionId);
32036
+ }
32037
+ remember(threadId, sessionId, terminal, commandTitle2) {
32038
+ const asyncTaskId = wireTaskId(this.rootSessionId, threadId, terminal.itemId);
32039
+ const existing = this.tasks.get(asyncTaskId);
32040
+ if (existing) {
32041
+ existing.processId = terminal.processId;
32042
+ if (commandTitle2 !== void 0) existing.name = commandTitle2;
32043
+ return existing;
32044
+ }
32045
+ const task = {
32046
+ threadId,
32047
+ sessionId,
32048
+ asyncTaskId,
32049
+ processId: terminal.processId,
32050
+ itemId: terminal.itemId,
32051
+ name: commandTitle2 ?? terminal.command,
32052
+ publication: "unpublished",
32053
+ announcement: null,
32054
+ terminalUpdate: null,
32055
+ terminalPublished: false,
32056
+ state: "running"
32057
+ };
32058
+ this.tasks.set(asyncTaskId, task);
32059
+ return task;
32060
+ }
32061
+ async finish(task, state) {
32062
+ if (task.state === "running" || task.state === "stopping") {
32063
+ task.state = state;
32064
+ } else if (task.state !== state) {
32065
+ return;
32066
+ }
32067
+ if (task.announcement !== null) await task.announcement;
32068
+ if (task.publication === "published") await this.publishTerminalState(task);
32069
+ }
32070
+ async publishTerminalState(task) {
32071
+ if (!isTerminalState(task.state) || task.terminalPublished) return;
32072
+ if (task.terminalUpdate !== null) {
32073
+ await task.terminalUpdate;
32074
+ return;
32075
+ }
32076
+ const terminalUpdate = this.session.update({
32077
+ sessionUpdate: "async_task_state_update",
32078
+ asyncTaskId: task.asyncTaskId,
32079
+ state: task.state,
32080
+ toolCallId: task.itemId
32081
+ }, task.sessionId);
32082
+ task.terminalUpdate = terminalUpdate;
32083
+ try {
32084
+ await terminalUpdate;
32085
+ task.terminalPublished = true;
32086
+ } finally {
32087
+ if (task.terminalUpdate === terminalUpdate) task.terminalUpdate = null;
32088
+ }
32089
+ }
32090
+ async listAll(threadId) {
32091
+ const appServer = this.appServer;
32092
+ const generation = this.appServerGeneration;
32093
+ const terminals = [];
32094
+ const seenCursors = /* @__PURE__ */ new Set();
32095
+ let cursor = null;
32096
+ do {
32097
+ const response = await appServer.threadBackgroundTerminalsList({
32098
+ threadId,
32099
+ cursor
32100
+ });
32101
+ if (!this.queryIsCurrent(generation)) return null;
32102
+ terminals.push(...response.data);
32103
+ cursor = response.nextCursor;
32104
+ if (cursor !== null) {
32105
+ if (seenCursors.has(cursor)) {
32106
+ throw new Error("Codex returned a repeated background terminal cursor");
32107
+ }
32108
+ seenCursors.add(cursor);
32109
+ }
32110
+ } while (cursor !== null);
32111
+ return { generation, terminals };
32112
+ }
32113
+ isActive() {
32114
+ return this.enabled && !this.disposed;
32115
+ }
32116
+ canQueryAppServer() {
32117
+ return this.isActive() && this.appServerQueriesEnabled;
32118
+ }
32119
+ queryIsCurrent(generation) {
32120
+ return this.canQueryAppServer() && generation === this.appServerGeneration;
32121
+ }
32122
+ };
32123
+ function isTerminalState(state) {
32124
+ return state === "completed" || state === "failed" || state === "stopped";
32125
+ }
32126
+ function wireTaskId(rootSessionId, threadId, itemId) {
32127
+ return threadId === rootSessionId ? itemId : `${threadId}:${itemId}`;
32128
+ }
32129
+ function notificationThreadId(notification) {
32130
+ const threadId = notification.params.threadId;
32131
+ return typeof threadId === "string" ? threadId : null;
32132
+ }
32133
+
32134
+ // src/CodexAcpServer.ts
31757
32135
  var CODEX_PROCESS_EXITED_ERROR_CODE = 1001;
31758
32136
  function clientSupportsTypedSessionFailures(capabilities) {
31759
32137
  return clientSupportsAirCapability(capabilities, AIR_SESSION_FAILURE_KEY);
@@ -31791,6 +32169,7 @@ var CodexAcpServer = class _CodexAcpServer {
31791
32169
  goalControlGenerations;
31792
32170
  permissionLifecycleContexts;
31793
32171
  codexProcessState;
32172
+ codexProcessGeneration = 0;
31794
32173
  initializeRequest = null;
31795
32174
  providerUpdate = null;
31796
32175
  constructor(connection, codexAcpClient, defaultAuthRequest, getExitCode, getRecentStderr, codexProcessState) {
@@ -31818,6 +32197,7 @@ var CodexAcpServer = class _CodexAcpServer {
31818
32197
  this.booleanConfigOptionsSupported = false;
31819
32198
  this.currentAuthStatus = null;
31820
32199
  this.availableCommands = this.createAvailableCommands(codexAcpClient);
32200
+ this.observeCodexProcess();
31821
32201
  }
31822
32202
  createAvailableCommands(client) {
31823
32203
  return new CodexCommands(
@@ -31890,7 +32270,8 @@ var CodexAcpServer = class _CodexAcpServer {
31890
32270
  [AIR_EXTENSION_CAPABILITIES_KEY]: [
31891
32271
  AIR_SESSION_FAILURE_KEY,
31892
32272
  AIR_AGENT_FILE_CHANGE_REPORT_KEY,
31893
- AIR_NATIVE_SUBAGENT_SESSIONS_KEY
32273
+ AIR_NATIVE_SUBAGENT_SESSIONS_KEY,
32274
+ AIR_ASYNC_TASKS_KEY
31894
32275
  ]
31895
32276
  }
31896
32277
  }
@@ -31913,6 +32294,18 @@ var CodexAcpServer = class _CodexAcpServer {
31913
32294
  return await this.unstable_setSessionModel(this.parseLegacySetSessionModelParams(methodRequest.params));
31914
32295
  case SESSION_STEERING_METHOD:
31915
32296
  return await this.executeOrQueueSteeringRequest(this.parseSessionSteerParams(methodRequest.params));
32297
+ case ASYNC_TASK_STOP_METHOD: {
32298
+ if (this.providerUpdate !== null) {
32299
+ await this.providerUpdate;
32300
+ }
32301
+ const sessionState = this.sessions.get(methodRequest.params.sessionId);
32302
+ if (!sessionState) return { stopped: false };
32303
+ return {
32304
+ stopped: await this.runWithProcessCheck(
32305
+ () => sessionState.asyncTasks.stop(methodRequest.params.asyncTaskId)
32306
+ )
32307
+ };
32308
+ }
31916
32309
  case GOAL_CONTROL_METHOD:
31917
32310
  case LEGACY_GOAL_CONTROL_METHOD: {
31918
32311
  const sessionState = this.sessions.get(methodRequest.params.sessionId);
@@ -32154,7 +32547,8 @@ Check ${configPath} and project .codex directories, especially their config.toml
32154
32547
  sessionId,
32155
32548
  clientSupportsSubagents(this.clientCapabilities),
32156
32549
  new ACPSessionConnection(this.connection, sessionId)
32157
- )
32550
+ ),
32551
+ asyncTasks: this.createAsyncTasks(sessionId)
32158
32552
  };
32159
32553
  sessionState.titleGen = new TitleGenerator(
32160
32554
  this.codexAcpClient.appServerClient,
@@ -32162,7 +32556,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
32162
32556
  sessionState.cwd,
32163
32557
  () => sessionState.sessionTitleSource
32164
32558
  );
32165
- this.sessions.set(sessionId, sessionState);
32559
+ this.installSessionState(sessionState);
32166
32560
  resumeSubscribed = false;
32167
32561
  const canPublishSessionUpdates = operation !== "fork";
32168
32562
  if (canPublishSessionUpdates && requestedMcpServers.length > 0 && mcpServerStartupVersion !== null) {
@@ -32177,6 +32571,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
32177
32571
  }
32178
32572
  if (operation === "resume") {
32179
32573
  this.publishCurrentGoalAsync(sessionState, sessionGeneration);
32574
+ this.publishAsyncTasksAsync(sessionState, sessionGeneration);
32180
32575
  }
32181
32576
  const sessionModelState = this.createModelState(models, currentModelId);
32182
32577
  const sessionModeState = sessionState.agentMode.toSessionModeState();
@@ -32206,6 +32601,18 @@ Check ${configPath} and project .codex directories, especially their config.toml
32206
32601
  }
32207
32602
  return a === b;
32208
32603
  }
32604
+ createAsyncTasks(sessionId) {
32605
+ return new CodexBackgroundTerminalTasks(
32606
+ clientSupportsAirCapability(this.clientCapabilities, AIR_ASYNC_TASKS_KEY),
32607
+ sessionId,
32608
+ this.codexAcpClient.appServerClient,
32609
+ new ACPSessionConnection(this.connection, sessionId)
32610
+ );
32611
+ }
32612
+ installSessionState(sessionState) {
32613
+ this.sessions.get(sessionState.sessionId)?.asyncTasks.clear();
32614
+ this.sessions.set(sessionState.sessionId, sessionState);
32615
+ }
32209
32616
  getAuthProviderForAuthenticateRequest(request) {
32210
32617
  if (isCodexAuthRequest(request) && request.methodId === "gateway") {
32211
32618
  return "custom-gateway";
@@ -32224,6 +32631,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
32224
32631
  thread
32225
32632
  } = await this.getOrCreateSessionWithHistory(params);
32226
32633
  await this.streamThreadHistory(sessionId, thread);
32634
+ await this.getSessionState(sessionId).asyncTasks.reconcile();
32227
32635
  logger.log("Session loaded", {
32228
32636
  sessionId,
32229
32637
  modelId: modelState.currentModelId,
@@ -32297,6 +32705,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
32297
32705
  try {
32298
32706
  if (sessionState) {
32299
32707
  await this.interruptSessionTurn(sessionState, "Close", true);
32708
+ sessionState.asyncTasks.clear();
32300
32709
  } else {
32301
32710
  logger.log("Close request received for unknown local session", { sessionId: params.sessionId });
32302
32711
  }
@@ -32432,6 +32841,10 @@ Check ${configPath} and project .codex directories, especially their config.toml
32432
32841
  await Promise.all(activePrompts);
32433
32842
  }
32434
32843
  logger.log("Restarting Codex app-server for provider update", { sessionCount: this.sessions.size });
32844
+ for (const session of this.sessions.values()) {
32845
+ session.asyncTasks.prepareForAppServerReplacement();
32846
+ }
32847
+ await this.finishAllAsyncTasks("stopped", "before the provider restart");
32435
32848
  const replacement = await this.restartCodexClient();
32436
32849
  apply(replacement);
32437
32850
  if (this.initializeRequest === null) {
@@ -32442,6 +32855,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
32442
32855
  this.availableCommands = this.createAvailableCommands(replacement);
32443
32856
  const resumeErrors = [];
32444
32857
  for (const session of this.sessions.values()) {
32858
+ session.asyncTasks.setAppServer(replacement.appServerClient);
32445
32859
  try {
32446
32860
  await replacement.resumeSession({
32447
32861
  sessionId: session.sessionId,
@@ -32450,6 +32864,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
32450
32864
  mcpServers: session.mcpServers ?? []
32451
32865
  });
32452
32866
  session.authProvider = replacement.getModelProvider();
32867
+ session.asyncTasks.refresh();
32453
32868
  logger.log("Resumed session after provider restart", { sessionId: session.sessionId });
32454
32869
  } catch (error51) {
32455
32870
  resumeErrors.push(error51);
@@ -32479,12 +32894,22 @@ Check ${configPath} and project .codex directories, especially their config.toml
32479
32894
  state.stderr = (state.stderr + data.toString()).slice(-2 * 1024);
32480
32895
  });
32481
32896
  }
32897
+ observeCodexProcess() {
32898
+ const process12 = this.codexProcessState?.connection.process;
32899
+ if (!process12) return;
32900
+ const generation = ++this.codexProcessGeneration;
32901
+ process12.once("exit", () => {
32902
+ if (generation !== this.codexProcessGeneration) return;
32903
+ void this.finishAllAsyncTasks("failed", "after the Codex process exited");
32904
+ });
32905
+ }
32482
32906
  async restartCodexClient() {
32483
32907
  const state = this.codexProcessState;
32484
32908
  if (state === null) {
32485
32909
  throw new Error("Codex process state is unavailable");
32486
32910
  }
32487
32911
  const previous = state.connection;
32912
+ this.codexProcessGeneration += 1;
32488
32913
  const exited = previous.process.exitCode === null ? once(previous.process, "exit") : Promise.resolve();
32489
32914
  previous.process.stdin.end();
32490
32915
  const forceKill = setTimeout(() => {
@@ -32498,6 +32923,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
32498
32923
  state.stderr = "";
32499
32924
  state.connection = startCodexConnection(state.codexPath);
32500
32925
  this.captureStderr();
32926
+ this.observeCodexProcess();
32501
32927
  return new CodexAcpClient(
32502
32928
  new CodexAppServerClient(state.connection.connection),
32503
32929
  state.config,
@@ -33047,6 +33473,10 @@ Check ${configPath} and project .codex directories, especially their config.toml
33047
33473
  publishCurrentGoalAsync(sessionState, sessionGeneration) {
33048
33474
  void this.publishCurrentGoalBestEffort(sessionState, sessionGeneration, true);
33049
33475
  }
33476
+ publishAsyncTasksAsync(sessionState, sessionGeneration) {
33477
+ if (!this.sessionPublishIsCurrent(sessionState, sessionGeneration)) return;
33478
+ sessionState.asyncTasks.refresh();
33479
+ }
33050
33480
  async publishCurrentGoalBestEffort(sessionState, sessionGeneration, force) {
33051
33481
  try {
33052
33482
  await this.publishCurrentGoal(sessionState, sessionGeneration, force);
@@ -33170,7 +33600,8 @@ Check ${configPath} and project .codex directories, especially their config.toml
33170
33600
  sessionId,
33171
33601
  clientSupportsSubagents(this.clientCapabilities),
33172
33602
  new ACPSessionConnection(this.connection, sessionId)
33173
- )
33603
+ ),
33604
+ asyncTasks: this.createAsyncTasks(sessionId)
33174
33605
  };
33175
33606
  sessionState.titleGen = new TitleGenerator(
33176
33607
  this.codexAcpClient.appServerClient,
@@ -33178,7 +33609,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
33178
33609
  sessionState.cwd,
33179
33610
  () => sessionState.sessionTitleSource
33180
33611
  );
33181
- this.sessions.set(sessionId, sessionState);
33612
+ this.installSessionState(sessionState);
33182
33613
  subscribed = false;
33183
33614
  if (requestedMcpServers.length > 0 && mcpServerStartupVersion !== null) {
33184
33615
  this.pendingMcpStartupSessions.set(sessionId, {
@@ -33270,6 +33701,15 @@ Check ${configPath} and project .codex directories, especially their config.toml
33270
33701
  /* @__PURE__ */ new Set([...ancestry, item.agentThreadId]),
33271
33702
  threadCache
33272
33703
  );
33704
+ try {
33705
+ await sessionState.asyncTasks.recover(
33706
+ item.agentThreadId,
33707
+ childSessionId,
33708
+ commandItemIds(childTurn.items)
33709
+ );
33710
+ } catch (error51) {
33711
+ logger.error(`Failed to restore background terminals for ${item.agentThreadId}`, error51);
33712
+ }
33273
33713
  }
33274
33714
  }
33275
33715
  } else if (activityKind === "completed" || activityKind === "interrupted") {
@@ -34320,6 +34760,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
34320
34760
  throw new RequestError(requestErrorCode, `VC++ redistributable should be installed`);
34321
34761
  }
34322
34762
  if (exitCode !== null) {
34763
+ await this.finishAllAsyncTasks("failed", "after the Codex process exited");
34323
34764
  const stderr = this.getRecentStderr().trim();
34324
34765
  const detail = stderr ? `:
34325
34766
  ${stderr}` : "";
@@ -34328,6 +34769,15 @@ ${stderr}` : "";
34328
34769
  throw err;
34329
34770
  }
34330
34771
  }
34772
+ async finishAllAsyncTasks(state, reason) {
34773
+ for (const session of this.sessions.values()) {
34774
+ try {
34775
+ await session.asyncTasks.finishAll(state);
34776
+ } catch (error51) {
34777
+ logger.error(`Failed to finish background terminal tasks ${reason}`, error51);
34778
+ }
34779
+ }
34780
+ }
34331
34781
  async cancel(params) {
34332
34782
  const sessionState = this.sessions.get(params.sessionId);
34333
34783
  if (!sessionState) {
@@ -34377,6 +34827,9 @@ function mergeHistoryUpdates(responseItemFallbackUpdates, threadUpdates) {
34377
34827
  }
34378
34828
  return merged;
34379
34829
  }
34830
+ function commandItemIds(items) {
34831
+ return new Set(items.filter((item) => item.type === "commandExecution").map((item) => item.id));
34832
+ }
34380
34833
  function historyUpdateKey(update) {
34381
34834
  switch (update.sessionUpdate) {
34382
34835
  case "user_message_chunk":
@@ -34560,6 +35013,10 @@ var goalControlParamsParser = external_exports.discriminatedUnion("action", [
34560
35013
  action: external_exports.enum(["pause", "resume", "clear"])
34561
35014
  }).passthrough()
34562
35015
  ]);
35016
+ var asyncTaskStopParamsParser = external_exports.object({
35017
+ sessionId: external_exports.string().trim().min(1),
35018
+ asyncTaskId: external_exports.string().trim().min(1)
35019
+ }).passthrough();
34563
35020
  if (process.argv.includes("--version")) {
34564
35021
  console.log(`${package_default.name} ${package_default.version}`);
34565
35022
  process.exit(0);
@@ -34640,5 +35097,5 @@ function startAcpServer() {
34640
35097
  codexAcpServer = null;
34641
35098
  }
34642
35099
  });
34643
- }).onRequest(methods.agent.initialize, (ctx) => getAgent().initialize(ctx.params)).onRequest(methods.agent.session.new, (ctx) => getAgent().newSession(ctx.params)).onRequest(methods.agent.session.load, (ctx) => getAgent().loadSession(ctx.params)).onRequest(methods.agent.session.fork, (ctx) => getAgent().forkSession(ctx.params)).onRequest(methods.agent.session.list, (ctx) => getAgent().listSessions(ctx.params)).onRequest(methods.agent.session.delete, (ctx) => getAgent().deleteSession(ctx.params)).onRequest(methods.agent.session.resume, (ctx) => getAgent().resumeSession(ctx.params)).onRequest(methods.agent.session.close, (ctx) => getAgent().closeSession(ctx.params)).onRequest(methods.agent.session.setMode, (ctx) => getAgent().setSessionMode(ctx.params)).onRequest(methods.agent.session.setConfigOption, (ctx) => getAgent().setSessionConfigOption(ctx.params)).onRequest(methods.agent.authenticate, (ctx) => getAgent().authenticate(ctx.params, ctx.requestId)).onRequest(methods.agent.logout, (ctx) => getAgent().logout(ctx.params)).onRequest(methods.agent.providers.list, (ctx) => getAgent().listProviders(ctx.params)).onRequest(methods.agent.providers.set, (ctx) => getAgent().setProvider(ctx.params)).onRequest(methods.agent.providers.disable, (ctx) => getAgent().disableProvider(ctx.params)).onRequest(methods.agent.session.prompt, (ctx) => getAgent().prompt(ctx.params, ctx.signal)).onNotification(methods.agent.session.cancel, (ctx) => getAgent().cancel(ctx.params)).onRequest("authentication/status", emptyExtensionParamsParser, (ctx) => getAgent().extMethod("authentication/status", ctx.params)).onRequest("authentication/logout", emptyExtensionParamsParser, (ctx) => getAgent().extMethod("authentication/logout", ctx.params)).onRequest(LEGACY_SET_SESSION_MODEL_METHOD, legacySetSessionModelParamsParser, (ctx) => getAgent().extMethod(LEGACY_SET_SESSION_MODEL_METHOD, ctx.params)).onRequest(SESSION_STEERING_METHOD, sessionSteerParamsParser, (ctx) => getAgent().extMethod(SESSION_STEERING_METHOD, ctx.params)).onRequest(GOAL_CONTROL_METHOD, goalControlParamsParser, (ctx) => getAgent().extMethod(GOAL_CONTROL_METHOD, ctx.params)).connect(acpJsonStream);
35100
+ }).onRequest(methods.agent.initialize, (ctx) => getAgent().initialize(ctx.params)).onRequest(methods.agent.session.new, (ctx) => getAgent().newSession(ctx.params)).onRequest(methods.agent.session.load, (ctx) => getAgent().loadSession(ctx.params)).onRequest(methods.agent.session.fork, (ctx) => getAgent().forkSession(ctx.params)).onRequest(methods.agent.session.list, (ctx) => getAgent().listSessions(ctx.params)).onRequest(methods.agent.session.delete, (ctx) => getAgent().deleteSession(ctx.params)).onRequest(methods.agent.session.resume, (ctx) => getAgent().resumeSession(ctx.params)).onRequest(methods.agent.session.close, (ctx) => getAgent().closeSession(ctx.params)).onRequest(methods.agent.session.setMode, (ctx) => getAgent().setSessionMode(ctx.params)).onRequest(methods.agent.session.setConfigOption, (ctx) => getAgent().setSessionConfigOption(ctx.params)).onRequest(methods.agent.authenticate, (ctx) => getAgent().authenticate(ctx.params, ctx.requestId)).onRequest(methods.agent.logout, (ctx) => getAgent().logout(ctx.params)).onRequest(methods.agent.providers.list, (ctx) => getAgent().listProviders(ctx.params)).onRequest(methods.agent.providers.set, (ctx) => getAgent().setProvider(ctx.params)).onRequest(methods.agent.providers.disable, (ctx) => getAgent().disableProvider(ctx.params)).onRequest(methods.agent.session.prompt, (ctx) => getAgent().prompt(ctx.params, ctx.signal)).onNotification(methods.agent.session.cancel, (ctx) => getAgent().cancel(ctx.params)).onRequest("authentication/status", emptyExtensionParamsParser, (ctx) => getAgent().extMethod("authentication/status", ctx.params)).onRequest("authentication/logout", emptyExtensionParamsParser, (ctx) => getAgent().extMethod("authentication/logout", ctx.params)).onRequest(LEGACY_SET_SESSION_MODEL_METHOD, legacySetSessionModelParamsParser, (ctx) => getAgent().extMethod(LEGACY_SET_SESSION_MODEL_METHOD, ctx.params)).onRequest(SESSION_STEERING_METHOD, sessionSteerParamsParser, (ctx) => getAgent().extMethod(SESSION_STEERING_METHOD, ctx.params)).onRequest(ASYNC_TASK_STOP_METHOD, asyncTaskStopParamsParser, (ctx) => getAgent().extMethod(ASYNC_TASK_STOP_METHOD, ctx.params)).onRequest(GOAL_CONTROL_METHOD, goalControlParamsParser, (ctx) => getAgent().extMethod(GOAL_CONTROL_METHOD, ctx.params)).connect(acpJsonStream);
34644
35101
  }
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.9.0",
6
+ "version": "1.10.0",
7
7
  "description": "",
8
8
  "main": "dist/index.js",
9
9
  "bin": {
@@ -66,7 +66,7 @@
66
66
  },
67
67
  "dependencies": {
68
68
  "@agentclientprotocol/sdk": "^1.4.0",
69
- "@openai/codex": "^0.153.2",
69
+ "@openai/codex": "^0.153.3",
70
70
  "diff": "^9.0.0",
71
71
  "open": "^11.0.1",
72
72
  "vscode-jsonrpc": "^9.0.1",