@minhspark/codex-mcp-bridge 1.22.2 → 1.22.3
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/.codex-plugin/plugin.json +1 -1
- package/CHANGELOG.md +16 -0
- package/package.json +1 -1
- package/plugin.json +1 -1
- package/scripts/install-native-relay.mjs +1 -1
- package/src/claude-bridge.mjs +1 -1
- package/src/claude-desktop-context.mjs +15 -2
- package/src/claude-sender-context.mjs +19 -1
- package/src/index.mjs +1 -1
- package/src/native-relay-companion.mjs +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,22 @@ Follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and [SemVer](ht
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [1.22.3] - 2026-10-15
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- Retry the complete Claude Desktop identity snapshot up to three times when task metadata changes during inspection. An unrelated active chat updating its metadata no longer causes an immediate sender rejection; persistent changes, conflicting identities, archived tasks, and invalid metadata still fail closed.
|
|
12
|
+
- Include bounded metadata diagnostic codes in sender-verification failures instead of discarding the underlying failure category behind a generic account message. Diagnostics exclude task contents and untrusted error text.
|
|
13
|
+
|
|
14
|
+
### Verification
|
|
15
|
+
|
|
16
|
+
- Regression tests reproduce a one-time unrelated metadata update, persistent updates, archive changes, duplicate identities, and diagnostic sanitization.
|
|
17
|
+
- A live Windows check from the originally affected Claude Code session completed two reads, one diagnostic send to its existing Codex task, and reply observation through the returned delivery receipt. The exact diagnostic reply was verified in the destination task.
|
|
18
|
+
|
|
19
|
+
### Upgrade notes
|
|
20
|
+
|
|
21
|
+
- Existing supervisors load the updated source when safe. Shared Desktop MCP entries still cannot identify a Code task's process ancestry; use the per-Code bridge registration. The repair does not resend earlier work or weaken account, process, or project checks.
|
|
22
|
+
|
|
7
23
|
## [1.22.2] - 2026-10-13
|
|
8
24
|
|
|
9
25
|
### Fixed
|
package/package.json
CHANGED
package/plugin.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
|
|
3
3
|
"name": "codex-mcp-bridge",
|
|
4
|
-
"version": "1.22.
|
|
4
|
+
"version": "1.22.3",
|
|
5
5
|
"description": "Connect ChatGPT to your own Codex Desktop projects and conversations.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Bui Dang Minh",
|
|
@@ -23,7 +23,7 @@ import { enableCodexFullAccess, fullAccessEnabled } from "../src/codex-full-acce
|
|
|
23
23
|
|
|
24
24
|
exitForVersionRequest(import.meta.url);
|
|
25
25
|
|
|
26
|
-
const VERSION = "1.22.
|
|
26
|
+
const VERSION = "1.22.3";
|
|
27
27
|
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
28
28
|
const entry = path.join(root, "src", "mcp-supervisor.mjs");
|
|
29
29
|
const entryArgs = ["native-relay-companion.mjs"];
|
package/src/claude-bridge.mjs
CHANGED
|
@@ -29,7 +29,7 @@ import { registerProjectOnboardingTools } from "./project-onboarding-tools.mjs";
|
|
|
29
29
|
|
|
30
30
|
exitForVersionRequest(import.meta.url);
|
|
31
31
|
|
|
32
|
-
const VERSION = "1.22.
|
|
32
|
+
const VERSION = "1.22.3";
|
|
33
33
|
void import("./telemetry.mjs").then(({ startUsageReporting }) => startUsageReporting({ version: VERSION })).catch(() => {});
|
|
34
34
|
const FORWARD_MIN_INTERVAL_MS = 5000;
|
|
35
35
|
const FORWARD_MAX_PER_SESSION = 50;
|
|
@@ -132,7 +132,14 @@ export function readClaudeDesktopContext(session, { platform = process.platform,
|
|
|
132
132
|
try {
|
|
133
133
|
const directory = root ?? (account ? path.join(account.root, "claude-code-sessions") : sessionsRoot(platform, env));
|
|
134
134
|
if (!fs.existsSync(directory)) return result("missing", "Claude Desktop task metadata is not available on this host.");
|
|
135
|
-
|
|
135
|
+
for (let attempt = 0; attempt < 3; attempt += 1) {
|
|
136
|
+
try {
|
|
137
|
+
records = readClaudeDesktopTasks({ platform, env, root, account });
|
|
138
|
+
break;
|
|
139
|
+
} catch (error) {
|
|
140
|
+
if (error.message !== "metadata changed" || attempt === 2) throw error;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
136
143
|
} catch (error) {
|
|
137
144
|
const detail = {
|
|
138
145
|
"file limit": " A task metadata file exceeds the 4 MiB per-file limit.",
|
|
@@ -140,7 +147,13 @@ export function readClaudeDesktopContext(session, { platform = process.platform,
|
|
|
140
147
|
"scan limit": " The task directory exceeds the 8192-entry scan limit.",
|
|
141
148
|
"metadata changed": " Task metadata changed during inspection; retry discovery.",
|
|
142
149
|
}[error.message] ?? "";
|
|
143
|
-
|
|
150
|
+
const code = {
|
|
151
|
+
"file limit": "FILE_LIMIT",
|
|
152
|
+
"identity limit": "IDENTITY_LIMIT",
|
|
153
|
+
"scan limit": "SCAN_LIMIT",
|
|
154
|
+
"metadata changed": "METADATA_CHANGED",
|
|
155
|
+
}[error.message] ?? "UNREADABLE_METADATA";
|
|
156
|
+
return { ...result("mismatch", `Claude Desktop task metadata could not be read completely and consistently; no task identity is confirmed.${detail}`), diagnostic: { stage: "task_metadata", code } };
|
|
144
157
|
}
|
|
145
158
|
|
|
146
159
|
const primary = records.filter((record) => record.cliSessionId === session.sessionId);
|
|
@@ -265,6 +265,17 @@ function senderFailureCode(error) {
|
|
|
265
265
|
return "UNAVAILABLE";
|
|
266
266
|
}
|
|
267
267
|
|
|
268
|
+
const METADATA_FAILURE_CODES = new Set(["METADATA_CHANGED", "FILE_LIMIT", "IDENTITY_LIMIT", "SCAN_LIMIT", "UNREADABLE_METADATA", "MISSING", "MISMATCH", "AMBIGUOUS", "UNAVAILABLE"]);
|
|
269
|
+
const INSPECTION_FAILURE_CODES = new Set(["INSPECTOR_START_TIMEOUT", "INSPECTION_TIMEOUT", "OUTPUT_LIMIT", "ENOENT", "EACCES", "EPERM", "NATIVE_EXIT", "INVALID_JSON", "UNAVAILABLE"]);
|
|
270
|
+
|
|
271
|
+
function safeSenderDiagnostic(diagnostic) {
|
|
272
|
+
if (!diagnostic || typeof diagnostic !== "object") return null;
|
|
273
|
+
const { stage, code } = diagnostic;
|
|
274
|
+
if (stage === "task_metadata" && (METADATA_FAILURE_CODES.has(code) || INSPECTION_FAILURE_CODES.has(code))) return { stage, code };
|
|
275
|
+
if (["session_registry", "process_inspection", "ancestry_validation"].includes(stage) && INSPECTION_FAILURE_CODES.has(code)) return { stage, code };
|
|
276
|
+
return null;
|
|
277
|
+
}
|
|
278
|
+
|
|
268
279
|
export async function readClaudeSenderContext({ account, parentPid = process.ppid, readAncestry = readProcessAncestry, listSessions = listClaudeSessions, readContext = readClaudeDesktopContext } = {}) {
|
|
269
280
|
if (account?.status !== "verified" || !account.fingerprint) return senderResult("unavailable", "The calling Claude account is not verified.");
|
|
270
281
|
let stage = "session_registry";
|
|
@@ -291,7 +302,12 @@ export async function readClaudeSenderContext({ account, parentPid = process.ppi
|
|
|
291
302
|
if (session.processStart && session.processStart !== process.processStart) return senderResult("unavailable", "The calling Claude session's registered process identity changed.");
|
|
292
303
|
stage = "task_metadata";
|
|
293
304
|
const context = readContext(session, { account });
|
|
294
|
-
if (context.status !== "matched")
|
|
305
|
+
if (context.status !== "matched") {
|
|
306
|
+
const code = context.diagnostic?.stage === "task_metadata" && METADATA_FAILURE_CODES.has(context.diagnostic.code)
|
|
307
|
+
? context.diagnostic.code
|
|
308
|
+
: ["missing", "mismatch", "ambiguous"].includes(context.status) ? context.status.toUpperCase() : "UNAVAILABLE";
|
|
309
|
+
return senderResult("unavailable", `The calling Claude Code session is not confirmed in the currently signed-in account. (${stage}:${code})`, { diagnostic: { stage, code } });
|
|
310
|
+
}
|
|
295
311
|
return senderResult("verified", "The calling MCP process belongs to a live Claude Desktop Code session in the selected account.", {
|
|
296
312
|
pid: session.pid, sessionId: session.sessionId, taskId: context.taskId, cwd: context.cwd,
|
|
297
313
|
processStart: process.processStart, accountFingerprint: account.fingerprint,
|
|
@@ -307,6 +323,8 @@ export function requireClaudeSenderContext(sender) {
|
|
|
307
323
|
if (sender?.status !== "verified") {
|
|
308
324
|
const error = new Error(sender?.reason ?? "The calling Claude Desktop Code session is unverified.");
|
|
309
325
|
error.code = "CLAUDE_SENDER_CONTEXT_UNVERIFIED";
|
|
326
|
+
const diagnostic = safeSenderDiagnostic(sender?.diagnostic);
|
|
327
|
+
if (diagnostic) error.diagnostic = diagnostic;
|
|
310
328
|
throw error;
|
|
311
329
|
}
|
|
312
330
|
return sender;
|
package/src/index.mjs
CHANGED
|
@@ -40,7 +40,7 @@ import { PROJECT_SETUP_TOOLS, registerProjectOnboardingTools } from "./project-o
|
|
|
40
40
|
|
|
41
41
|
exitForVersionRequest(import.meta.url);
|
|
42
42
|
|
|
43
|
-
const VERSION = "1.22.
|
|
43
|
+
const VERSION = "1.22.3";
|
|
44
44
|
void import("./telemetry.mjs").then(({ startUsageReporting }) => startUsageReporting({ version: VERSION })).catch(() => {});
|
|
45
45
|
const log = (msg) => process.stderr.write(`[codex-mcp-bridge] ${msg}\n`);
|
|
46
46
|
|
|
@@ -38,7 +38,7 @@ import { NativeCreationReceipts, creationIdValid } from "./native-creation-recei
|
|
|
38
38
|
|
|
39
39
|
exitForVersionRequest(import.meta.url);
|
|
40
40
|
|
|
41
|
-
const VERSION = "1.22.
|
|
41
|
+
const VERSION = "1.22.3";
|
|
42
42
|
const log = (msg) => process.stderr.write(`[native-relay] ${msg}\n`);
|
|
43
43
|
|
|
44
44
|
function errorResponse(code, message, sent, details) {
|