@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 +3 -0
- package/README.md +7 -5
- package/dist/index.js +156 -28
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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
|
|
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 `"
|
|
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
|
-
| `
|
|
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 `
|
|
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 = [
|
|
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.
|
|
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?.
|
|
1221
|
+
if (decision === "acceptWithExecpolicyAmendment" && (!extra?.execpolicy_amendment || extra.execpolicy_amendment.length === 0)) {
|
|
1171
1222
|
throw new Error(
|
|
1172
|
-
`Error [${"INVALID_ARGUMENT" /* INVALID_ARGUMENT */}]:
|
|
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?.
|
|
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
|
-
|
|
1295
|
-
|
|
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(
|
|
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, {
|
|
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
|
|
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:
|
|
1394
|
-
threadId:
|
|
1395
|
-
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
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
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,
|
|
2101
|
+
function buildCommandApprovalResponse(decision, execpolicy_amendment) {
|
|
1987
2102
|
if (decision === "acceptWithExecpolicyAmendment") {
|
|
1988
|
-
if (!
|
|
2103
|
+
if (!execpolicy_amendment || execpolicy_amendment.length === 0) {
|
|
1989
2104
|
throw new Error(
|
|
1990
|
-
`Error [${"INVALID_ARGUMENT" /* INVALID_ARGUMENT */}]:
|
|
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
|
|
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
|
-
|
|
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.
|
|
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
|
|
3113
|
+
"Approval decision for respond_permission. acceptWithExecpolicyAmendment requires execpolicy_amendment."
|
|
2986
3114
|
),
|
|
2987
|
-
|
|
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(
|