claude2codex 0.3.6 → 0.3.7

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/README.md CHANGED
@@ -231,7 +231,8 @@ Codex then enters its goal-continuation loop: after each turn, it checks "did I
231
231
  | `CODEX_MODEL` | Codex default | Model override |
232
232
  | `CODEX_APPROVAL_POLICY` | `never` | Approval policy (autonomous by default) |
233
233
  | `CODEX_PERMISSIONS` | Unset | Permissions profile passed to Codex |
234
- | `CODEX_JOB_TIMEOUT_MS` | `1800000` | Maximum job duration (30 min) |
234
+ | `CODEX_JOB_TIMEOUT_MS` | `7200000` | Overall maximum job duration (2 hours) |
235
+ | `C2C_IDLE_TIMEOUT_MS` | `1200000` | Timeout after no Codex notifications during a running attempt (20 min); `0` disables. Queued/dependency wait time excluded |
235
236
  | `CODEX_QUIET_MS` | `30000` | Quiet period before treating an active goal as finished |
236
237
  | `GOAL_OBJECTIVE_MAX` | `2000` | Maximum rendered goal-objective length; `codex_implement` rejects over-limit contracts at submit time |
237
238
  | `C2C_STATE_DIR` | `~/.claude2codex/jobs` | Persistent job registry (atomic per-job JSON files) |
package/README.zh-CN.md CHANGED
@@ -252,7 +252,8 @@ Python 3.12,Poetry。从项目根目录运行。
252
252
  | `CODEX_MODEL` | Codex 默认 | 模型覆盖 |
253
253
  | `CODEX_APPROVAL_POLICY` | `never` | 审批策略(默认自主执行) |
254
254
  | `CODEX_PERMISSIONS` | 未设置 | 权限配置透传 |
255
- | `CODEX_JOB_TIMEOUT_MS` | `1800000` | 单任务最大时长(30 分钟) |
255
+ | `CODEX_JOB_TIMEOUT_MS` | `7200000` | 单任务总时长硬上限(2 小时) |
256
+ | `C2C_IDLE_TIMEOUT_MS` | `1200000` | 运行中的尝试连续无 Codex 通知时超时(20 分钟),`0` 禁用;排队和等待依赖的时间不计入 |
256
257
  | `CODEX_QUIET_MS` | `30000` | 判定活跃目标已完成前的静默等待时间 |
257
258
  | `GOAL_OBJECTIVE_MAX` | `2000` | 渲染后 goal-objective 的最大长度;超限的合同会被 `codex_implement` 在提交时拒绝 |
258
259
  | `C2C_STATE_DIR` | `~/.claude2codex/jobs` | 持久化任务注册表(每任务一个原子写入的 JSON 文件) |
package/dist/server.js CHANGED
@@ -262,7 +262,7 @@ var CodexAppServer = class {
262
262
  */
263
263
  async initialize() {
264
264
  const result = await this.request("initialize", {
265
- clientInfo: { name: "claude2codex", title: "Claude\u2194Codex Contract Bridge", version: "0.3.6" },
265
+ clientInfo: { name: "claude2codex", title: "Claude\u2194Codex Contract Bridge", version: "0.3.7" },
266
266
  capabilities: { experimentalApi: true }
267
267
  });
268
268
  this.notify("initialized", {});
@@ -641,6 +641,7 @@ async function runAttempt(job, opts, timeoutMs) {
641
641
  let lastCodexError;
642
642
  let quietTimer;
643
643
  let stallTimer;
644
+ let idleTimer;
644
645
  let settle;
645
646
  const doneSignal = new Promise((res) => settle = res);
646
647
  const progress = (event, message) => opts.onProgress?.({ jobId: job.id, event, message });
@@ -675,6 +676,14 @@ async function runAttempt(job, opts, timeoutMs) {
675
676
  settle();
676
677
  }, cfg.quietMs);
677
678
  }
679
+ function armIdleTimer() {
680
+ clearTimeout(idleTimer);
681
+ if (cfg.idleTimeoutMs === 0) return;
682
+ idleTimer = setTimeout(() => {
683
+ finalize("timeout", `no Codex notification for ${cfg.idleTimeoutMs}ms (C2C_IDLE_TIMEOUT_MS)`);
684
+ settle();
685
+ }, cfg.idleTimeoutMs);
686
+ }
678
687
  function clearStallTimer() {
679
688
  clearTimeout(stallTimer);
680
689
  stallTimer = void 0;
@@ -708,11 +717,13 @@ async function runAttempt(job, opts, timeoutMs) {
708
717
  writeLog("info", "job_resumed", { job_id: job.id, stalled_for_ms: stalledForMs });
709
718
  progress("resumed", `job resumed after ${stalledForMs}ms`);
710
719
  }
720
+ armIdleTimer();
711
721
  job.lastActivityAt = now.toISOString();
712
722
  store.save(job);
713
723
  if (activeTurn) armStallTimer();
714
724
  }
715
725
  function finalize(state, error) {
726
+ clearTimeout(idleTimer);
716
727
  clearStallTimer();
717
728
  if (state === "done" && job.turns === 0) {
718
729
  state = "error";
@@ -721,6 +732,7 @@ async function runAttempt(job, opts, timeoutMs) {
721
732
  finish(job, state, client, error);
722
733
  }
723
734
  function handleNotification(method, params) {
735
+ if (job.state !== "starting" && job.state !== "running") return;
724
736
  writeLog("debug", "codex_notification", {
725
737
  job_id: job.id,
726
738
  attempt: job.attempts ?? 1,
@@ -838,10 +850,11 @@ async function runAttempt(job, opts, timeoutMs) {
838
850
  if (!activeTurn) armQuietTimer();
839
851
  }
840
852
  const overallTimer = setTimeout(() => {
841
- finalize("timeout", `job exceeded ${cfg.jobTimeoutMs}ms`);
853
+ finalize("timeout", `job exceeded ${cfg.jobTimeoutMs}ms (CODEX_JOB_TIMEOUT_MS)`);
842
854
  settle();
843
855
  }, timeoutMs);
844
856
  try {
857
+ armIdleTimer();
845
858
  await client.initialize();
846
859
  const threadParams = {
847
860
  cwd: cfg.cwd,
@@ -890,6 +903,7 @@ async function runAttempt(job, opts, timeoutMs) {
890
903
  const failure = processError ?? (error instanceof Error ? error : new Error(String(error)));
891
904
  return { error: failure, processFailure: client.exited };
892
905
  } finally {
906
+ clearTimeout(idleTimer);
893
907
  clearTimeout(overallTimer);
894
908
  clearTimeout(quietTimer);
895
909
  clearStallTimer();
@@ -929,7 +943,8 @@ function config(cwd) {
929
943
  model: process.env.CODEX_MODEL || void 0,
930
944
  approvalPolicy: process.env.CODEX_APPROVAL_POLICY ?? "never",
931
945
  permissions: process.env.CODEX_PERMISSIONS || void 0,
932
- jobTimeoutMs: envInt("CODEX_JOB_TIMEOUT_MS", 18e5),
946
+ jobTimeoutMs: envInt("CODEX_JOB_TIMEOUT_MS", 72e5),
947
+ idleTimeoutMs: Math.max(0, envInt("C2C_IDLE_TIMEOUT_MS", 12e5)),
933
948
  quietMs: envInt("CODEX_QUIET_MS", 3e4),
934
949
  stallWarnMs: Math.max(0, envInt("C2C_STALL_WARN_MS", 12e4)),
935
950
  retries: Math.max(0, envInt("C2C_RETRIES", 1)),
@@ -972,7 +987,7 @@ var SERVER_INSTRUCTIONS = `When the user asks to delegate work to Codex (or to u
972
987
  If a Codex job itself fails (error, 0 tokens, no handoff), report it and wait; don't implement the task yourself unless the user explicitly asks.
973
988
  Full formats: the c2c-workflow prompt.`;
974
989
  var server = new McpServer(
975
- { name: "c2c-codex", version: "0.3.6" },
990
+ { name: "c2c-codex", version: "0.3.7" },
976
991
  { instructions: SERVER_INSTRUCTIONS }
977
992
  );
978
993
  var reasoningEffort = z.enum(["low", "medium", "high", "xhigh", "max", "ultra"]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude2codex",
3
- "version": "0.3.6",
3
+ "version": "0.3.7",
4
4
  "type": "module",
5
5
  "description": "MCP server bridging Claude (architect/reviewer) and Codex (implementer) via Goal/Delta Contracts and Codex's thread-goal loop.",
6
6
  "bin": {