@leo000001/codex-mcp 2.1.3 → 2.1.4

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/dist/index.js CHANGED
@@ -392,7 +392,7 @@ var DEFAULT_TERMINAL_CLEANUP_MS = 5 * 60 * 1e3;
392
392
  var CLEANUP_INTERVAL_MS = 6e4;
393
393
 
394
394
  // src/app-server/client.ts
395
- var CLIENT_VERSION = true ? "2.1.3" : "0.0.0-dev";
395
+ var CLIENT_VERSION = true ? "2.1.4" : "0.0.0-dev";
396
396
  var DEFAULT_REQUEST_TIMEOUT = 3e4;
397
397
  var STARTUP_REQUEST_TIMEOUT = 9e4;
398
398
  var MAX_WRITE_QUEUE_BYTES = 5 * 1024 * 1024;
@@ -814,7 +814,7 @@ function resolveAndValidateCwd(inputCwd, baseCwd) {
814
814
  function redactPaths(message) {
815
815
  const uncPath = /(^|[\s'"(])\\\\[^\s\\/:]+\\[^\s:]+(?:\\[^\s:]+)*/g;
816
816
  const windowsPath = /\b[A-Za-z]:\\[^\s:]+/g;
817
- const posixPath = /(^|[\s'"(])\/[^\s:'")]+/g;
817
+ const posixPath = /(^|[\s'"(])\/[^\s:'")]*\/[^\s:'")]+/g;
818
818
  return message.replace(uncPath, (_m, prefix) => `${prefix}<path>`).replace(windowsPath, "<path>").replace(posixPath, (_m, prefix) => `${prefix}<path>`);
819
819
  }
820
820
 
@@ -1464,10 +1464,10 @@ var SessionManager = class {
1464
1464
  `Error [${"INTERNAL" /* INTERNAL */}]: Failed to build approval response for request '${requestId}'`
1465
1465
  );
1466
1466
  }
1467
- sendPendingRequestResponseOrThrow(req, response, sessionId, requestId);
1468
1467
  req.resolved = true;
1469
1468
  req.decision = decision;
1470
1469
  if (req.timeoutHandle) clearTimeout(req.timeoutHandle);
1470
+ sendPendingRequestResponseOrThrow(req, response, sessionId, requestId);
1471
1471
  pushEvent(
1472
1472
  session.eventBuffer,
1473
1473
  "approval_result",
@@ -1494,14 +1494,14 @@ var SessionManager = class {
1494
1494
  `Error [${"REQUEST_NOT_FOUND" /* REQUEST_NOT_FOUND */}]: User input request '${requestId}' not found`
1495
1495
  );
1496
1496
  }
1497
+ req.resolved = true;
1498
+ if (req.timeoutHandle) clearTimeout(req.timeoutHandle);
1497
1499
  sendPendingRequestResponseOrThrow(
1498
1500
  req,
1499
1501
  { answers },
1500
1502
  sessionId,
1501
1503
  requestId
1502
1504
  );
1503
- req.resolved = true;
1504
- if (req.timeoutHandle) clearTimeout(req.timeoutHandle);
1505
1505
  pushEvent(
1506
1506
  session.eventBuffer,
1507
1507
  "approval_result",
@@ -2018,6 +2018,14 @@ function clearSessionPendingRequests(session) {
2018
2018
  session.pendingRequests.clear();
2019
2019
  for (const [, req] of entries) {
2020
2020
  if (req.timeoutHandle) clearTimeout(req.timeoutHandle);
2021
+ if (!req.resolved && req.respond) {
2022
+ try {
2023
+ if (req.kind === "command") req.respond({ decision: "cancel" });
2024
+ else if (req.kind === "fileChange") req.respond({ decision: "cancel" });
2025
+ else if (req.kind === "user_input") req.respond({ answers: {} });
2026
+ } catch {
2027
+ }
2028
+ }
2021
2029
  req.resolved = true;
2022
2030
  }
2023
2031
  }
@@ -2299,15 +2307,27 @@ function tryCoalesceProgressDelta(buf, type, data, pinned) {
2299
2307
  return true;
2300
2308
  }
2301
2309
  function evictEvents(buf) {
2302
- while (buf.events.length > buf.maxSize) {
2303
- const idx = buf.events.findIndex((e) => !e.pinned);
2304
- if (idx === -1) break;
2305
- buf.events.splice(idx, 1);
2306
- }
2307
- while (buf.events.length > buf.maxSize) {
2308
- const idx = buf.events.findIndex((e) => e.type === "approval_result");
2309
- if (idx === -1) break;
2310
- buf.events.splice(idx, 1);
2310
+ if (buf.events.length > buf.maxSize) {
2311
+ const overflow2 = buf.events.length - buf.maxSize;
2312
+ const unpinnedIdx = [];
2313
+ const approvalResultIdx2 = [];
2314
+ for (let i = 0; i < buf.events.length; i++) {
2315
+ const event = buf.events[i];
2316
+ if (!event.pinned) unpinnedIdx.push(i);
2317
+ else if (event.type === "approval_result") approvalResultIdx2.push(i);
2318
+ }
2319
+ const drop2 = /* @__PURE__ */ new Set();
2320
+ for (const idx of unpinnedIdx) {
2321
+ if (drop2.size >= overflow2) break;
2322
+ drop2.add(idx);
2323
+ }
2324
+ for (const idx of approvalResultIdx2) {
2325
+ if (drop2.size >= overflow2) break;
2326
+ drop2.add(idx);
2327
+ }
2328
+ if (drop2.size > 0) {
2329
+ buf.events = buf.events.filter((_, idx) => !drop2.has(idx));
2330
+ }
2311
2331
  }
2312
2332
  if (buf.events.length <= buf.hardMaxSize) return;
2313
2333
  const overflow = buf.events.length - buf.hardMaxSize;
@@ -2833,7 +2853,8 @@ function asTextResource(uri, text, mimeType) {
2833
2853
  }
2834
2854
  function detectCodexCliVersion(timeoutMs = 1500) {
2835
2855
  try {
2836
- const run = spawnSync("codex", ["--version"], {
2856
+ const executable = getDefaultCodexExecutable();
2857
+ const run = spawnSync(executable.command, ["--version"], {
2837
2858
  encoding: "utf8",
2838
2859
  timeout: timeoutMs,
2839
2860
  windowsHide: true
@@ -3240,7 +3261,7 @@ function registerResources(server, deps) {
3240
3261
  }
3241
3262
 
3242
3263
  // src/server.ts
3243
- var SERVER_VERSION = true ? "2.1.3" : "0.0.0-dev";
3264
+ var SERVER_VERSION = true ? "2.1.4" : "0.0.0-dev";
3244
3265
  function formatErrorMessage(err) {
3245
3266
  const message = err instanceof Error ? err.message : String(err);
3246
3267
  const m = /^Error \[([A-Z_]+)\]:\s*(.*)$/.exec(message);
@@ -3768,6 +3789,15 @@ function probeAppServer(codexCommand, codexIsPath, env) {
3768
3789
  proc.kill("SIGTERM");
3769
3790
  } catch {
3770
3791
  }
3792
+ const forceKill = setTimeout(() => {
3793
+ try {
3794
+ if (!proc.killed && proc.exitCode === null) {
3795
+ proc.kill("SIGKILL");
3796
+ }
3797
+ } catch {
3798
+ }
3799
+ }, 2e3);
3800
+ if (forceKill.unref) forceKill.unref();
3771
3801
  settle(false);
3772
3802
  }, DETECTION_TIMEOUT_MS);
3773
3803
  if (timer.unref) timer.unref();
@@ -3776,7 +3806,7 @@ function probeAppServer(codexCommand, codexIsPath, env) {
3776
3806
 
3777
3807
  // src/app-server/exec-client.ts
3778
3808
  import { spawn as spawn3 } from "child_process";
3779
- import { writeFileSync, mkdtempSync } from "fs";
3809
+ import { writeFileSync, mkdtempSync, rmSync } from "fs";
3780
3810
  import { EventEmitter as EventEmitter2 } from "events";
3781
3811
  import { randomUUID as randomUUID2 } from "crypto";
3782
3812
  import { tmpdir } from "os";
@@ -3873,6 +3903,7 @@ var ExecClient = class extends EventEmitter2 {
3873
3903
  threadStartParams = null;
3874
3904
  lastAgentMessageText = "";
3875
3905
  turnCompleted = false;
3906
+ schemaTmpDirs = [];
3876
3907
  // Handlers
3877
3908
  notificationHandler = null;
3878
3909
  serverRequestHandler = null;
@@ -3959,6 +3990,7 @@ var ExecClient = class extends EventEmitter2 {
3959
3990
  });
3960
3991
  proc.on("exit", (code, signal) => {
3961
3992
  if (this.turnId && !this._destroyed && !this.turnCompleted) {
3993
+ this.turnCompleted = true;
3962
3994
  if (code !== 0 && code !== null) {
3963
3995
  this.emitNotification(Methods.ERROR, {
3964
3996
  threadId: this.threadId,
@@ -3967,6 +3999,17 @@ var ExecClient = class extends EventEmitter2 {
3967
3999
  willRetry: false
3968
4000
  });
3969
4001
  }
4002
+ const turnId2 = this.turnId ?? "";
4003
+ this.emitNotification(Methods.TURN_COMPLETED, {
4004
+ threadId: this.threadId,
4005
+ turn: {
4006
+ id: turnId2,
4007
+ status: code === 0 ? "completed" : "failed",
4008
+ output: this.lastAgentMessageText || void 0,
4009
+ ...code !== 0 && code !== null ? { error: { message: `exec process exited with code ${code}` } } : signal ? { error: { message: `exec process killed by signal ${signal}` } } : {}
4010
+ }
4011
+ });
4012
+ this.turnId = null;
3970
4013
  }
3971
4014
  if (!this._destroyed) {
3972
4015
  this.emit("exit", code, signal);
@@ -4030,6 +4073,13 @@ var ExecClient = class extends EventEmitter2 {
4030
4073
  }
4031
4074
  this.process = null;
4032
4075
  this.removeAllListeners();
4076
+ for (const dir of this.schemaTmpDirs) {
4077
+ try {
4078
+ rmSync(dir, { recursive: true, force: true });
4079
+ } catch {
4080
+ }
4081
+ }
4082
+ this.schemaTmpDirs = [];
4033
4083
  }
4034
4084
  // ── Private helpers ─────────────────────────────────────────────
4035
4085
  /**
@@ -4057,6 +4107,7 @@ var ExecClient = class extends EventEmitter2 {
4057
4107
  if (params.outputSchema && Object.keys(params.outputSchema).length > 0) {
4058
4108
  try {
4059
4109
  const tmpDir = mkdtempSync(join(tmpdir(), "codex-mcp-schema-"));
4110
+ this.schemaTmpDirs.push(tmpDir);
4060
4111
  const schemaPath = join(tmpDir, "output-schema.json");
4061
4112
  writeFileSync(schemaPath, JSON.stringify(params.outputSchema));
4062
4113
  args.push("--output-schema", schemaPath);
@@ -4143,7 +4194,7 @@ var ExecClient = class extends EventEmitter2 {
4143
4194
  const type = event.type;
4144
4195
  switch (type) {
4145
4196
  case "thread.started": {
4146
- const cliThreadId = event.thread_id;
4197
+ const cliThreadId = event.thread_id ?? event.threadId;
4147
4198
  if (cliThreadId) {
4148
4199
  this.threadId = cliThreadId;
4149
4200
  this.realThreadId = cliThreadId;