@leo000001/codex-mcp 0.2.1 → 2.0.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.
package/CHANGELOG.md CHANGED
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
12
12
  - `approvalPolicy`, `sandbox`, and `effort` are now **required** parameters in the `codex` tool — callers must explicitly set based on their own permission level and task complexity
13
13
  - `effort` parameter promoted from `advanced.effort` to top-level parameter in the `codex` tool
14
14
  - `codex_reply` parameter `sandboxPolicy` renamed to `sandbox`
15
+ - `codex_check` parameter `execpolicyAmendment` renamed to `execpolicy_amendment` to match app-server protocol field naming
15
16
 
16
17
  ### Changed
17
18
 
@@ -23,6 +24,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
23
24
  - Approval and user-input timeout timers now call `.unref()` to avoid blocking process exit
24
25
  - Documentation aligned with implementation details for event eviction and e2e guidance
25
26
  - Tool input defaults are now defined in schema (`cursor`, `maxEvents`, `includeSensitive`, `advanced.approvalTimeoutMs`) and client-facing text avoids duplicated default descriptions
27
+ - `codex_session` adds `clean_background_terminals` action to call `thread/background_terminals/clean`
28
+ - Approval action payloads now expose `approvalId` and `networkApprovalContext` when provided by app-server
26
29
 
27
30
  ## [0.1.0] - 2026-02-15
28
31
 
package/README.md CHANGED
@@ -180,12 +180,12 @@ Send a follow-up message to an existing session.
180
180
 
181
181
  ### `codex_session` — Manage sessions
182
182
 
183
- List, inspect, cancel, interrupt, or fork sessions.
183
+ List, inspect, cancel, interrupt, fork sessions, or clean background terminals.
184
184
 
185
185
  | Parameter | Type | Required | Description |
186
186
  | ------------------ | ------- | ----------------------------- | ---------------------------------------------------------------------- |
187
- | `action` | string | Yes | `"list"`, `"get"`, `"cancel"`, `"interrupt"`, or `"fork"` |
188
- | `sessionId` | string | For get/cancel/interrupt/fork | Target session ID |
187
+ | `action` | string | Yes | `"list"`, `"get"`, `"cancel"`, `"interrupt"`, `"fork"`, or `"clean_background_terminals"` |
188
+ | `sessionId` | string | For get/cancel/interrupt/fork/clean_background_terminals | Target session ID |
189
189
  | `includeSensitive` | boolean | No | Include `cwd`/`profile`/`config`/`threadId` in `get`. Default: `false` |
190
190
 
191
191
  **Returns:**
@@ -193,6 +193,7 @@ List, inspect, cancel, interrupt, or fork sessions.
193
193
  - `action="get"` → `PublicSessionInfo` (or `SensitiveSessionInfo` when `includeSensitive=true`)
194
194
  - `action="cancel"|"interrupt"` → `{ success: true, message }`
195
195
  - `action="fork"` → `{ sessionId, threadId, status: "idle", pollInterval }`
196
+ - `action="clean_background_terminals"` → `{ success: true, message }`
196
197
 
197
198
  ```json
198
199
  { "action": "list" }
@@ -200,6 +201,7 @@ List, inspect, cancel, interrupt, or fork sessions.
200
201
  { "action": "cancel", "sessionId": "sess_abc123" }
201
202
  { "action": "interrupt", "sessionId": "sess_abc123" }
202
203
  { "action": "fork", "sessionId": "sess_abc123" }
204
+ { "action": "clean_background_terminals", "sessionId": "sess_abc123" }
203
205
  ```
204
206
 
205
207
  ### `codex_check` — Poll events & respond
@@ -216,7 +218,7 @@ Query a running session for events, respond to approval requests, or answer user
216
218
  | `pollOptions` | object | No | Optional controls: `includeEvents` (default `true`), `includeActions` (default `true`), `includeResult` (default `true`), `maxBytes` (default unlimited) |
217
219
  | `requestId` | string | For respond_permission/user_input | Request ID from `actions[]` |
218
220
  | `decision` | string | For respond_permission | For command approvals: `"accept"`, `"acceptForSession"`, `"acceptWithExecpolicyAmendment"`, `"decline"`, `"cancel"`; for file changes: `"accept"`, `"acceptForSession"`, `"decline"`, `"cancel"` |
219
- | `execpolicyAmendment` | string[] | For acceptWithExecpolicyAmendment | Exec policy amendment list (required when `decision="acceptWithExecpolicyAmendment"`) |
221
+ | `execpolicy_amendment` | string[] | For acceptWithExecpolicyAmendment | Exec policy amendment list (required when `decision="acceptWithExecpolicyAmendment"`) |
220
222
  | `denyMessage` | string | No | Internal note on deny (not sent to app-server) |
221
223
  | `answers` | object | For respond_user_input | For `respond_user_input`: `questionId -> { answers: string[] }` |
222
224
 
@@ -264,7 +266,7 @@ Approvals/results/errors are pinned to reduce eviction risk.
264
266
  When the agent requests approval or user input, `poll` includes an `actions[]` list. Respond with:
265
267
 
266
268
  - `respond_permission`: `decision` is one of `accept`, `acceptForSession`, `decline`, `cancel`.
267
- - For command approvals, `acceptWithExecpolicyAmendment` is supported and requires `execpolicyAmendment`.
269
+ - For command approvals, `acceptWithExecpolicyAmendment` is supported and requires `execpolicy_amendment`.
268
270
  - `respond_user_input`: send `answers` keyed by `questionId`.
269
271
 
270
272
  Pending approvals auto-decline after `advanced.approvalTimeoutMs`.
package/dist/index.js CHANGED
@@ -34,6 +34,7 @@ var Methods = {
34
34
  THREAD_START: "thread/start",
35
35
  THREAD_RESUME: "thread/resume",
36
36
  THREAD_FORK: "thread/fork",
37
+ THREAD_BACKGROUND_TERMINALS_CLEAN: "thread/backgroundTerminals/clean",
37
38
  TURN_START: "turn/start",
38
39
  TURN_INTERRUPT: "turn/interrupt",
39
40
  TURN_STEER: "turn/steer",
@@ -48,19 +49,31 @@ var Methods = {
48
49
  // Server → Client notifications
49
50
  ERROR: "error",
50
51
  THREAD_STARTED: "thread/started",
52
+ THREAD_ARCHIVED: "thread/archived",
53
+ THREAD_UNARCHIVED: "thread/unarchived",
54
+ THREAD_NAME_UPDATED: "thread/name/updated",
55
+ THREAD_TOKEN_USAGE_UPDATED: "thread/tokenUsage/updated",
51
56
  TURN_STARTED: "turn/started",
52
57
  TURN_COMPLETED: "turn/completed",
53
58
  TURN_DIFF_UPDATED: "turn/diff/updated",
54
59
  TURN_PLAN_UPDATED: "turn/plan/updated",
55
60
  ITEM_STARTED: "item/started",
56
61
  ITEM_COMPLETED: "item/completed",
62
+ RAW_RESPONSE_ITEM_COMPLETED: "rawResponseItem/completed",
57
63
  AGENT_MESSAGE_DELTA: "item/agentMessage/delta",
58
64
  COMMAND_OUTPUT_DELTA: "item/commandExecution/outputDelta",
65
+ COMMAND_TERMINAL_INTERACTION: "item/commandExecution/terminalInteraction",
59
66
  FILE_CHANGE_OUTPUT_DELTA: "item/fileChange/outputDelta",
60
67
  REASONING_TEXT_DELTA: "item/reasoning/textDelta",
61
68
  REASONING_SUMMARY_DELTA: "item/reasoning/summaryTextDelta",
69
+ REASONING_SUMMARY_PART_ADDED: "item/reasoning/summaryPartAdded",
62
70
  PLAN_DELTA: "item/plan/delta",
63
71
  MCP_TOOL_PROGRESS: "item/mcpToolCall/progress",
72
+ MODEL_REROUTED: "model/rerouted",
73
+ FUZZY_FILE_SEARCH_SESSION_UPDATED: "fuzzyFileSearch/sessionUpdated",
74
+ FUZZY_FILE_SEARCH_SESSION_COMPLETED: "fuzzyFileSearch/sessionCompleted",
75
+ WINDOWS_WORLD_WRITABLE_WARNING: "windows/worldWritableWarning",
76
+ ACCOUNT_LOGIN_COMPLETED: "account/login/completed",
64
77
  SESSION_CONFIGURED: "sessionConfigured"
65
78
  };
66
79
 
@@ -164,7 +177,14 @@ var SANDBOX_MODES = ["read-only", "workspace-write", "danger-full-access"];
164
177
  var PERSONALITIES = ["none", "friendly", "pragmatic"];
165
178
  var EFFORT_LEVELS = ["none", "minimal", "low", "medium", "high", "xhigh"];
166
179
  var SUMMARY_MODES = ["auto", "concise", "detailed", "none"];
167
- var SESSION_ACTIONS = ["list", "get", "cancel", "interrupt", "fork"];
180
+ var SESSION_ACTIONS = [
181
+ "list",
182
+ "get",
183
+ "cancel",
184
+ "interrupt",
185
+ "fork",
186
+ "clean_background_terminals"
187
+ ];
168
188
  var CHECK_ACTIONS = ["poll", "respond_permission", "respond_user_input"];
169
189
  var RESPONSE_MODES = ["minimal", "delta_compact", "full"];
170
190
  var COMMAND_DECISIONS = [
@@ -213,7 +233,7 @@ var DEFAULT_TERMINAL_CLEANUP_MS = 5 * 60 * 1e3;
213
233
  var CLEANUP_INTERVAL_MS = 6e4;
214
234
 
215
235
  // src/app-server/client.ts
216
- var CLIENT_VERSION = true ? "0.2.1" : "0.0.0-dev";
236
+ var CLIENT_VERSION = true ? "2.0.0" : "0.0.0-dev";
217
237
  var DEFAULT_REQUEST_TIMEOUT = 3e4;
218
238
  var STARTUP_REQUEST_TIMEOUT = 9e4;
219
239
  var MAX_WRITE_QUEUE_BYTES = 5 * 1024 * 1024;
@@ -330,6 +350,9 @@ var AppServerClient = class extends EventEmitter {
330
350
  async threadResume(params) {
331
351
  return this.request(Methods.THREAD_RESUME, params);
332
352
  }
353
+ async threadBackgroundTerminalsClean(params) {
354
+ return this.request(Methods.THREAD_BACKGROUND_TERMINALS_CLEAN, params);
355
+ }
333
356
  async turnStart(params, timeout = STARTUP_REQUEST_TIMEOUT) {
334
357
  return this.request(Methods.TURN_START, params, timeout);
335
358
  }
@@ -959,6 +982,32 @@ var SessionManager = class {
959
982
  turnId: session.activeTurnId
960
983
  });
961
984
  }
985
+ async cleanBackgroundTerminals(sessionId) {
986
+ const session = this.getSessionOrThrow(sessionId);
987
+ const client = this.getClientOrThrow(sessionId);
988
+ if (session.status === "cancelled") {
989
+ throw new Error(
990
+ `Error [${"CANCELLED" /* CANCELLED */}]: Session '${sessionId}' has been cancelled and cannot be cleaned`
991
+ );
992
+ }
993
+ if (!session.threadId) {
994
+ throw new Error(
995
+ `Error [${"INTERNAL" /* INTERNAL */}]: Session '${sessionId}' has no threadId, cannot clean background terminals`
996
+ );
997
+ }
998
+ await client.threadBackgroundTerminalsClean({ threadId: session.threadId });
999
+ session.lastActiveAt = (/* @__PURE__ */ new Date()).toISOString();
1000
+ pushEvent(
1001
+ session.eventBuffer,
1002
+ "progress",
1003
+ {
1004
+ method: Methods.THREAD_BACKGROUND_TERMINALS_CLEAN,
1005
+ threadId: session.threadId,
1006
+ status: "requested"
1007
+ },
1008
+ true
1009
+ );
1010
+ }
962
1011
  async forkSession(sessionId) {
963
1012
  const session = this.getSessionOrThrow(sessionId);
964
1013
  const originalClient = this.getClientOrThrow(sessionId);
@@ -1064,6 +1113,8 @@ var SessionManager = class {
1064
1113
  params: req.params,
1065
1114
  itemId: req.itemId,
1066
1115
  reason: req.reason,
1116
+ approvalId: req.approvalId,
1117
+ networkApprovalContext: req.networkApprovalContext,
1067
1118
  createdAt: req.createdAt
1068
1119
  });
1069
1120
  }
@@ -1167,9 +1218,9 @@ var SessionManager = class {
1167
1218
  `Error [${"INVALID_ARGUMENT" /* INVALID_ARGUMENT */}]: Invalid command decision '${decision}'`
1168
1219
  );
1169
1220
  }
1170
- if (decision === "acceptWithExecpolicyAmendment" && (!extra?.execpolicyAmendment || extra.execpolicyAmendment.length === 0)) {
1221
+ if (decision === "acceptWithExecpolicyAmendment" && (!extra?.execpolicy_amendment || extra.execpolicy_amendment.length === 0)) {
1171
1222
  throw new Error(
1172
- `Error [${"INVALID_ARGUMENT" /* INVALID_ARGUMENT */}]: execpolicyAmendment required for acceptWithExecpolicyAmendment`
1223
+ `Error [${"INVALID_ARGUMENT" /* INVALID_ARGUMENT */}]: execpolicy_amendment required for acceptWithExecpolicyAmendment`
1173
1224
  );
1174
1225
  }
1175
1226
  } else if (req.kind === "fileChange") {
@@ -1185,7 +1236,7 @@ var SessionManager = class {
1185
1236
  }
1186
1237
  let response;
1187
1238
  if (req.kind === "command") {
1188
- response = buildCommandApprovalResponse(decision, extra?.execpolicyAmendment);
1239
+ response = buildCommandApprovalResponse(decision, extra?.execpolicy_amendment);
1189
1240
  } else if (req.kind === "fileChange") {
1190
1241
  response = { decision };
1191
1242
  }
@@ -1204,6 +1255,8 @@ var SessionManager = class {
1204
1255
  {
1205
1256
  requestId,
1206
1257
  kind: req.kind,
1258
+ approvalId: req.approvalId,
1259
+ networkApprovalContext: req.networkApprovalContext,
1207
1260
  decision,
1208
1261
  denyMessage: extra?.denyMessage
1209
1262
  },
@@ -1237,6 +1290,8 @@ var SessionManager = class {
1237
1290
  {
1238
1291
  requestId,
1239
1292
  kind: "user_input",
1293
+ approvalId: req.approvalId,
1294
+ networkApprovalContext: req.networkApprovalContext,
1240
1295
  answers
1241
1296
  },
1242
1297
  true
@@ -1289,10 +1344,39 @@ var SessionManager = class {
1289
1344
  session.lastActiveAt = (/* @__PURE__ */ new Date()).toISOString();
1290
1345
  const p = params;
1291
1346
  switch (method) {
1347
+ case Methods.THREAD_STARTED: {
1348
+ const thread = isRecord(p.thread) ? p.thread : void 0;
1349
+ pushEvent(session.eventBuffer, "progress", {
1350
+ method,
1351
+ ...p,
1352
+ threadId: normalizeOptionalString(p.threadId) ?? normalizeOptionalString(thread?.id),
1353
+ status: normalizeOptionalString(thread?.status)
1354
+ });
1355
+ break;
1356
+ }
1357
+ case Methods.THREAD_ARCHIVED:
1358
+ case Methods.THREAD_UNARCHIVED:
1359
+ case Methods.THREAD_NAME_UPDATED:
1360
+ case Methods.THREAD_TOKEN_USAGE_UPDATED:
1361
+ case Methods.FUZZY_FILE_SEARCH_SESSION_UPDATED:
1362
+ case Methods.FUZZY_FILE_SEARCH_SESSION_COMPLETED:
1363
+ case Methods.WINDOWS_WORLD_WRITABLE_WARNING:
1364
+ case Methods.ACCOUNT_LOGIN_COMPLETED:
1365
+ pushEvent(session.eventBuffer, "progress", { method, ...p });
1366
+ break;
1292
1367
  case Methods.TURN_STARTED:
1293
1368
  if (session.status === "cancelled") break;
1294
- session.activeTurnId = p.turn?.id ?? (typeof p.turnId === "string" ? p.turnId : void 0);
1295
- pushEvent(session.eventBuffer, "progress", { method, ...p });
1369
+ {
1370
+ const turnObj = p.turn;
1371
+ const status = normalizeOptionalString(turnObj?.status);
1372
+ session.activeTurnId = normalizeOptionalString(turnObj?.id) ?? (typeof p.turnId === "string" ? p.turnId : void 0);
1373
+ pushEvent(session.eventBuffer, "progress", {
1374
+ method,
1375
+ ...p,
1376
+ turnId: session.activeTurnId,
1377
+ status
1378
+ });
1379
+ }
1296
1380
  break;
1297
1381
  case Methods.TURN_COMPLETED: {
1298
1382
  if (session.status === "cancelled") break;
@@ -1309,7 +1393,17 @@ var SessionManager = class {
1309
1393
  turnError: turnObj?.error,
1310
1394
  completedAt: (/* @__PURE__ */ new Date()).toISOString()
1311
1395
  };
1312
- pushEvent(session.eventBuffer, "result", { method, ...p }, true);
1396
+ pushEvent(
1397
+ session.eventBuffer,
1398
+ "result",
1399
+ {
1400
+ method,
1401
+ ...p,
1402
+ turnId: completedTurnId,
1403
+ status: normalizeOptionalString(turnObj?.status)
1404
+ },
1405
+ true
1406
+ );
1313
1407
  break;
1314
1408
  }
1315
1409
  case Methods.ERROR: {
@@ -1343,12 +1437,20 @@ var SessionManager = class {
1343
1437
  case Methods.AGENT_MESSAGE_DELTA:
1344
1438
  pushEvent(session.eventBuffer, "output", { method, delta: p.delta, itemId: p.itemId });
1345
1439
  break;
1440
+ case Methods.ITEM_STARTED:
1346
1441
  case Methods.ITEM_COMPLETED:
1442
+ case Methods.RAW_RESPONSE_ITEM_COMPLETED:
1347
1443
  {
1348
1444
  const item = p.item;
1349
1445
  const itemType = item && typeof item.type === "string" ? item.type : void 0;
1446
+ const status = normalizeOptionalString(item?.status);
1350
1447
  const eventType = itemType === "agentMessage" || itemType === "userMessage" ? "output" : "progress";
1351
- pushEvent(session.eventBuffer, eventType, { method, item: p.item });
1448
+ pushEvent(session.eventBuffer, eventType, {
1449
+ method,
1450
+ ...p,
1451
+ item: p.item,
1452
+ status
1453
+ });
1352
1454
  }
1353
1455
  break;
1354
1456
  case Methods.COMMAND_OUTPUT_DELTA: {
@@ -1361,14 +1463,16 @@ var SessionManager = class {
1361
1463
  }
1362
1464
  break;
1363
1465
  }
1466
+ case Methods.COMMAND_TERMINAL_INTERACTION:
1364
1467
  case Methods.FILE_CHANGE_OUTPUT_DELTA:
1365
1468
  case Methods.REASONING_TEXT_DELTA:
1366
1469
  case Methods.REASONING_SUMMARY_DELTA:
1470
+ case Methods.REASONING_SUMMARY_PART_ADDED:
1367
1471
  case Methods.PLAN_DELTA:
1368
1472
  case Methods.MCP_TOOL_PROGRESS:
1369
- case Methods.ITEM_STARTED:
1370
1473
  case Methods.TURN_DIFF_UPDATED:
1371
1474
  case Methods.TURN_PLAN_UPDATED:
1475
+ case Methods.MODEL_REROUTED:
1372
1476
  pushEvent(session.eventBuffer, "progress", { method, ...p });
1373
1477
  break;
1374
1478
  default:
@@ -1385,15 +1489,22 @@ var SessionManager = class {
1385
1489
  switch (method) {
1386
1490
  case Methods.COMMAND_APPROVAL: {
1387
1491
  const requestId = `req_${randomUUID().slice(0, 8)}`;
1388
- const reason = normalizeOptionalString(p.reason);
1492
+ const approvalParams = params;
1493
+ const reason = normalizeOptionalString(approvalParams.reason);
1494
+ const approvalId = normalizeOptionalString(
1495
+ approvalParams.approvalId ?? approvalParams.approval_id
1496
+ );
1497
+ const networkApprovalContext = approvalParams.networkApprovalContext ?? approvalParams.network_approval_context;
1389
1498
  const pending = {
1390
1499
  requestId,
1391
1500
  kind: "command",
1392
1501
  params,
1393
- itemId: p.itemId,
1394
- threadId: p.threadId,
1395
- turnId: p.turnId,
1502
+ itemId: normalizeOptionalString(approvalParams.itemId) ?? "",
1503
+ threadId: normalizeOptionalString(approvalParams.threadId) ?? "",
1504
+ turnId: normalizeOptionalString(approvalParams.turnId) ?? "",
1396
1505
  reason,
1506
+ approvalId,
1507
+ networkApprovalContext,
1397
1508
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
1398
1509
  resolved: false,
1399
1510
  respond: (result) => client.respondToServer(id, result)
@@ -1415,6 +1526,7 @@ var SessionManager = class {
1415
1526
  {
1416
1527
  requestId,
1417
1528
  kind: "command",
1529
+ approvalId,
1418
1530
  decision: "decline",
1419
1531
  timeout: true
1420
1532
  },
@@ -1434,9 +1546,12 @@ var SessionManager = class {
1434
1546
  {
1435
1547
  requestId,
1436
1548
  kind: "command",
1437
- command: p.command,
1438
- cwd: p.cwd,
1439
- reason
1549
+ itemId: approvalParams.itemId,
1550
+ approvalId,
1551
+ command: approvalParams.command,
1552
+ cwd: approvalParams.cwd,
1553
+ reason,
1554
+ networkApprovalContext
1440
1555
  },
1441
1556
  true
1442
1557
  );
@@ -1983,17 +2098,17 @@ function toSensitiveInfo(session) {
1983
2098
  config: session.config
1984
2099
  };
1985
2100
  }
1986
- function buildCommandApprovalResponse(decision, execpolicyAmendment) {
2101
+ function buildCommandApprovalResponse(decision, execpolicy_amendment) {
1987
2102
  if (decision === "acceptWithExecpolicyAmendment") {
1988
- if (!execpolicyAmendment || execpolicyAmendment.length === 0) {
2103
+ if (!execpolicy_amendment || execpolicy_amendment.length === 0) {
1989
2104
  throw new Error(
1990
- `Error [${"INVALID_ARGUMENT" /* INVALID_ARGUMENT */}]: execpolicyAmendment required for acceptWithExecpolicyAmendment`
2105
+ `Error [${"INVALID_ARGUMENT" /* INVALID_ARGUMENT */}]: execpolicy_amendment required for acceptWithExecpolicyAmendment`
1991
2106
  );
1992
2107
  }
1993
2108
  return {
1994
2109
  decision: {
1995
2110
  acceptWithExecpolicyAmendment: {
1996
- execpolicy_amendment: execpolicyAmendment
2111
+ execpolicy_amendment
1997
2112
  }
1998
2113
  }
1999
2114
  };
@@ -2094,6 +2209,18 @@ async function executeCodexSession(args, sessionManager) {
2094
2209
  };
2095
2210
  }
2096
2211
  return await sessionManager.forkSession(args.sessionId);
2212
+ case "clean_background_terminals":
2213
+ if (!args.sessionId) {
2214
+ return {
2215
+ error: `Error [${"INVALID_ARGUMENT" /* INVALID_ARGUMENT */}]: sessionId required for 'clean_background_terminals'`,
2216
+ isError: true
2217
+ };
2218
+ }
2219
+ await sessionManager.cleanBackgroundTerminals(args.sessionId);
2220
+ return {
2221
+ success: true,
2222
+ message: `Background terminals cleaned for session ${args.sessionId}`
2223
+ };
2097
2224
  default:
2098
2225
  return {
2099
2226
  error: `Error [${"INVALID_ARGUMENT" /* INVALID_ARGUMENT */}]: Unknown action '${args.action}'`,
@@ -2123,7 +2250,7 @@ function executeCodexCheck(args, sessionManager) {
2123
2250
  }
2124
2251
  try {
2125
2252
  sessionManager.resolveApproval(args.sessionId, args.requestId, args.decision, {
2126
- execpolicyAmendment: args.execpolicyAmendment,
2253
+ execpolicy_amendment: args.execpolicy_amendment,
2127
2254
  denyMessage: args.denyMessage
2128
2255
  });
2129
2256
  } catch (err) {
@@ -2732,7 +2859,7 @@ function registerResources(server, deps) {
2732
2859
  }
2733
2860
 
2734
2861
  // src/server.ts
2735
- var SERVER_VERSION = true ? "0.2.1" : "0.0.0-dev";
2862
+ var SERVER_VERSION = true ? "2.0.0" : "0.0.0-dev";
2736
2863
  function formatErrorMessage(err) {
2737
2864
  const message = err instanceof Error ? err.message : String(err);
2738
2865
  const m = /^Error \[([A-Z_]+)\]:\s*(.*)$/.exec(message);
@@ -2883,16 +3010,17 @@ function createServer(serverCwd) {
2883
3010
  "codex_session",
2884
3011
  {
2885
3012
  title: "Manage Sessions",
2886
- description: `Session actions: list, get, cancel, interrupt, fork.
3013
+ description: `Session actions: list, get, cancel, interrupt, fork, clean_background_terminals.
2887
3014
 
2888
3015
  - list: sessions in memory.
2889
3016
  - get: details. includeSensitive defaults to false; true adds threadId/cwd/profile/config.
2890
3017
  - cancel: terminal.
2891
3018
  - interrupt: stop current turn.
2892
- - fork: clone current thread into a new session; source remains unchanged.`,
3019
+ - fork: clone current thread into a new session; source remains unchanged.
3020
+ - clean_background_terminals: ask app-server to clean stale background terminals for this thread.`,
2893
3021
  inputSchema: {
2894
3022
  action: z.enum(SESSION_ACTIONS),
2895
- sessionId: z.string().optional().describe("Required for get/cancel/interrupt/fork"),
3023
+ sessionId: z.string().optional().describe("Required for get/cancel/interrupt/fork/clean_background_terminals"),
2896
3024
  includeSensitive: z.boolean().default(false).optional().describe("Include cwd/config/threadId/profile in get (default: false)")
2897
3025
  },
2898
3026
  outputSchema: {
@@ -2982,9 +3110,9 @@ cursor omitted => use session last cursor. cursorResetTo => reset and continue.`
2982
3110
  // respond_permission
2983
3111
  requestId: z.string().optional().describe("Request ID from actions[]"),
2984
3112
  decision: z.enum(ALL_DECISIONS).optional().describe(
2985
- "Approval decision for respond_permission. acceptWithExecpolicyAmendment requires execpolicyAmendment."
3113
+ "Approval decision for respond_permission. acceptWithExecpolicyAmendment requires execpolicy_amendment."
2986
3114
  ),
2987
- execpolicyAmendment: z.array(z.string()).optional().describe("For acceptWithExecpolicyAmendment only"),
3115
+ execpolicy_amendment: z.array(z.string()).optional().describe("For acceptWithExecpolicyAmendment only"),
2988
3116
  denyMessage: z.string().optional().describe("Deny reason (not sent to agent)"),
2989
3117
  // respond_user_input
2990
3118
  answers: z.record(