@minhspark/codex-mcp-bridge 1.21.2 → 1.21.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/.codex-plugin/plugin.json +1 -1
- package/CHANGELOG.md +22 -0
- package/README.md +10 -6
- package/glama.json +6 -0
- package/package.json +2 -1
- package/plugin.json +1 -1
- package/scripts/install-native-relay.mjs +1 -1
- package/scripts/publish-repo-analytics.mjs +2 -19
- package/src/claude-bridge.mjs +1 -1
- package/src/index.mjs +1 -1
- package/src/native-relay-companion.mjs +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,28 @@ Follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and [SemVer](ht
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [1.21.4] - 2026-10-11
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Add the Glama ownership manifest to the repository and published package so the directory can identify the maintainer.
|
|
12
|
+
- Document Glama metadata synchronization, hosted usage limitations, and Docker infrastructure failures.
|
|
13
|
+
|
|
14
|
+
### Upgrade notes
|
|
15
|
+
|
|
16
|
+
- MCP behavior is unchanged. Glama must synchronize the repository to detect the manifest; its Docker service must be available before a new hosted release can be built.
|
|
17
|
+
|
|
18
|
+
## [1.21.3] - 2026-10-10
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- Replace the large README download chart with compact monthly npm downloads and dependent repository badges. The badges link to npmcharts and GitHub dependents.
|
|
23
|
+
- Stop publishing the unused download chart to the analytics branch; the dashboard and archived daily download history remain available.
|
|
24
|
+
|
|
25
|
+
### Upgrade notes
|
|
26
|
+
|
|
27
|
+
- MCP behavior is unchanged. The next repository analytics refresh removes the old chart asset from the analytics branch.
|
|
28
|
+
|
|
7
29
|
## [1.21.2] - 2026-10-10
|
|
8
30
|
|
|
9
31
|
### Added
|
package/README.md
CHANGED
|
@@ -8,6 +8,8 @@ Local Desktop handoff guides: [daily workflow and directory verification](docs/d
|
|
|
8
8
|
|
|
9
9
|
[](https://www.npmjs.com/package/@minhspark/codex-mcp-bridge)
|
|
10
10
|
[](https://www.npmjs.com/package/@minhspark/codex-mcp-bridge)
|
|
11
|
+
[](https://www.npmcharts.com/compare/%40minhspark%2Fcodex-mcp-bridge?minimal=true)
|
|
12
|
+
[](https://github.com/buidangminh23/codex-mcp-bridge/network/dependents)
|
|
11
13
|
[](https://skills.sh/buidangminh23/codex-mcp-bridge/codex-bridge)
|
|
12
14
|
[](https://buidangminh23.github.io/codex-mcp-bridge/)
|
|
13
15
|
[](LICENSE)
|
|
@@ -16,12 +18,6 @@ Send prompts and replies between **Claude and Codex**, keeping each conversation
|
|
|
16
18
|
|
|
17
19
|
https://github.com/user-attachments/assets/98b23989-826f-4d7d-9dcb-ad7dd2739095
|
|
18
20
|
|
|
19
|
-
## Package activity
|
|
20
|
-
|
|
21
|
-
[](https://www.npmcharts.com/compare/%40minhspark%2Fcodex-mcp-bridge?minimal=true)
|
|
22
|
-
|
|
23
|
-
[Explore the interactive npmcharts trend](https://www.npmcharts.com/compare/%40minhspark%2Fcodex-mcp-bridge?minimal=true) · [View public GitHub dependents](https://github.com/buidangminh23/codex-mcp-bridge/network/dependents). The chart uses the repository's hourly npm analytics snapshots; npm downloads include updates and automation.
|
|
24
|
-
|
|
25
21
|
## Release notifications
|
|
26
22
|
|
|
27
23
|
To receive new release notifications, open [this repository](https://github.com/buidangminh23/codex-mcp-bridge), select **Watch → Custom → Releases**, then click **Apply**. Choose GitHub or email delivery in your [notification settings](https://github.com/settings/notifications).
|
|
@@ -454,6 +450,14 @@ WHERE day >= (CURRENT_TIMESTAMP AT TIME ZONE 'UTC')::date - 29;
|
|
|
454
450
|
|
|
455
451
|
## Development
|
|
456
452
|
|
|
453
|
+
### Glama directory
|
|
454
|
+
|
|
455
|
+
The repository includes [glama.json](glama.json) with the maintainer's GitHub username, using [Glama's server schema](https://glama.ai/mcp/schemas/server.json). After changing it, use the listing's **Sync Server** action or repeat the ownership claim to refresh Glama's copy. See [Glama's manifest documentation](https://glama.ai/blog/2025-07-08-what-is-glamajson).
|
|
456
|
+
|
|
457
|
+
Glama's recent usage signal measures calls observed by Glama, independently of npm downloads and the bridge's opt-in installation analytics. Use **Try in Browser** and the read-only `codex_bridge_status` tool to check a hosted release. A cloud container cannot access the Codex Desktop app or signed-in sessions on a user's machine; run the bridge locally for those workflows. Related servers are managed separately in Glama's listing.
|
|
458
|
+
|
|
459
|
+
If a Glama test reports `DockerBuildError` with HTTP `502 Bad Gateway` and an empty build log, the Docker service request failed without an application build log. Retry when that service recovers. If it persists, provide Glama support with the test ID, timestamp, and error details. Changing `npm ci` or the launcher cannot repair that upstream failure; investigate repository build steps only when their logs identify an application error.
|
|
460
|
+
|
|
457
461
|
### Shared project scope for Desktop Code conversations
|
|
458
462
|
|
|
459
463
|
See [Desktop handoff design and recovery](docs/desktop-handoff-design.md) for the failure cases, integration with current upstream, and validation limits.
|
package/glama.json
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@minhspark/codex-mcp-bridge",
|
|
3
|
-
"version": "1.21.
|
|
3
|
+
"version": "1.21.4",
|
|
4
4
|
"description": "Two-way MCP bridge between Claude and Codex: prompts into a live Codex thread, messages into a running Claude Code session.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mcp",
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
"mcp.json",
|
|
44
44
|
".codex-plugin",
|
|
45
45
|
".mcp.json",
|
|
46
|
+
"glama.json",
|
|
46
47
|
"README.md",
|
|
47
48
|
"LICENSE",
|
|
48
49
|
"CHANGELOG.md",
|
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.21.
|
|
4
|
+
"version": "1.21.4",
|
|
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.21.
|
|
26
|
+
const VERSION = "1.21.4";
|
|
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"];
|
|
@@ -128,23 +128,6 @@ export function renderGithubViewsBadge(data, { now = Date.now() } = {}) {
|
|
|
128
128
|
return `<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="24" viewBox="0 0 ${width} 24" role="img" aria-label="${escapeXml(accessible)}"><title>${escapeXml(`${accessible}. ${detail}`)}</title><rect width="${width}" height="24" rx="4" fill="#555"/><path d="M${labelWidth} 0H${width - 4}Q${width} 0 ${width} 4V20Q${width} 24 ${width - 4} 24H${labelWidth}Z" fill="${color}"/><g fill="#fff" font-family="DejaVu Sans Mono,monospace" font-size="12" text-anchor="middle"><text x="${labelWidth / 2}" y="16">${escapeXml(label)}</text><text x="${labelWidth + messageWidth / 2}" y="16">${escapeXml(message)}</text></g></svg>\n`;
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
-
export function renderNpmDownloadsChart(data, { now = Date.now() } = {}) {
|
|
132
|
-
const snapshot = [...data.snapshots].sort((a, b) => String(b.collectedAt).localeCompare(String(a.collectedAt))).find(row => row.npm);
|
|
133
|
-
const collectedAt = snapshot?.sourceCollectedAt?.npm;
|
|
134
|
-
const rows = Object.entries(data.daily.npm || {}).filter(([day, row]) => date(day) && number(row?.downloads) != null).sort(([left], [right]) => left.localeCompare(right)).slice(-30);
|
|
135
|
-
const values = rows.map(([, row]) => row.downloads);
|
|
136
|
-
const maximum = Math.max(1, ...values);
|
|
137
|
-
const total = values.reduce((sum, value) => sum + value, 0);
|
|
138
|
-
const status = !date(collectedAt) ? 'Source unavailable' : now - Date.parse(collectedAt) > staleAfter ? 'Source stale at generation' : 'Source collected';
|
|
139
|
-
const summary = rows.length ? `${format(total)} downloads across ${rows.length} reported ${rows.length === 1 ? 'day' : 'days'} · ${rows[0][0]} to ${rows.at(-1)[0]} UTC` : 'No download history available';
|
|
140
|
-
const points = rows.map(([day, row], index) => ({ day, value: row.downloads, x: 76 + index * 680 / Math.max(1, rows.length - 1), y: 226 - row.downloads * 132 / maximum }));
|
|
141
|
-
const path = points.map((point, index) => `${index ? 'L' : 'M'}${point.x.toFixed(1)} ${point.y.toFixed(1)}`).join(' ');
|
|
142
|
-
const grid = [94, 160, 226].map(y => `<path d="M76 ${y}H756" stroke="#d8dee4" stroke-width="1"/>`).join('');
|
|
143
|
-
const axis = points.length ? `${grid}<text x="66" y="98" text-anchor="end" font-size="12" fill="#57606a">${escapeXml(format(maximum))}</text><text x="66" y="230" text-anchor="end" font-size="12" fill="#57606a">0</text><text x="76" y="250" font-size="12" fill="#57606a">${escapeXml(rows[0][0])}</text><text x="756" y="250" text-anchor="end" font-size="12" fill="#57606a">${escapeXml(rows.at(-1)[0])}</text>` : '';
|
|
144
|
-
const line = points.length ? `<path d="${path}" fill="none" stroke="#2f81f7" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>${points.map(point => `<circle cx="${point.x.toFixed(1)}" cy="${point.y.toFixed(1)}" r="3" fill="#2f81f7"><title>${escapeXml(`${point.day}: ${format(point.value)} downloads`)}</title></circle>`).join('')}` : '<text x="416" y="167" text-anchor="middle" font-size="17" fill="#57606a">Download data unavailable</text>';
|
|
145
|
-
return `<svg xmlns="http://www.w3.org/2000/svg" width="820" height="300" viewBox="0 0 820 300" role="img" aria-label="npm download trend"><title>npm download trend</title><desc>${escapeXml(`${summary}. ${status}: ${displayTime(collectedAt)}.`)}</desc><rect width="820" height="300" rx="12" fill="#ffffff"/><rect x="0.5" y="0.5" width="819" height="299" rx="11.5" fill="none" stroke="#d8dee4"/><g font-family="Arial, sans-serif"><text x="32" y="38" font-size="21" font-weight="bold" fill="#24292f">npm download trend</text><text x="32" y="65" font-size="14" fill="#57606a">${escapeXml(summary)}</text>${axis}${line}<text x="32" y="280" font-size="12" fill="${status === 'Source collected' ? '#57606a' : '#9a6700'}">${escapeXml(`npm API · ${status} · ${displayTime(collectedAt)}`)}</text></g></svg>\n`;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
131
|
export function renderLiveDashboard(data) {
|
|
149
132
|
const latest = source => [...data.snapshots].sort((a, b) => String(b.collectedAt).localeCompare(String(a.collectedAt))).find(row => row[source]);
|
|
150
133
|
const npm = latest('npm');
|
|
@@ -233,9 +216,9 @@ export function publicFiles(history, usage) {
|
|
|
233
216
|
const usageDays = Object.fromEntries((data.usage?.daily || []).map(row => [row.day, row.installations]));
|
|
234
217
|
const days = [...new Set([...Object.keys(data.daily.views), ...Object.keys(data.daily.clones), ...Object.keys(data.daily.npm), ...Object.keys(usageDays)])].sort().reverse();
|
|
235
218
|
const table = ['| Date (UTC) | Views | Unique visitors | Clones | Unique cloners | npm downloads | Active installations |', '|---|---:|---:|---:|---:|---:|---:|', ...days.map(day => `| ${day} | ${[data.daily.views[day]?.count, data.daily.views[day]?.uniques, data.daily.clones[day]?.count, data.daily.clones[day]?.uniques, data.daily.npm[day]?.downloads, usageDays[day]].map(format).join(' | ')} |`)].join('\n');
|
|
236
|
-
const readme = `# Public repository analytics\n\n\n\n
|
|
219
|
+
const readme = `# Public repository analytics\n\n\n\n[Aggregate JSON history](data.json) · [Repository](https://github.com/${data.repo})\n\nAll dates and source windows use UTC. Source timestamps on the dashboard show when each metric was last available. Downloads and clones include automation and do not measure people. Unique visitors/cloners apply only to the source window; never sum daily unique counts across dates. Active installations cover consenting installations only, with distinct counts for each whole period. Operating system and version breakdowns cover 30 days; an installation may appear in multiple version groups after upgrading.\n\nThis branch contains only aggregate statistics. No installation identifiers, prompts, account details, credentials, private error messages, or local paths are published. Missing metrics mean unavailable, not zero.\n\n## Daily history\n\nEvery archived source day is listed below, newest first. Active installations count consenting installations that reported that UTC day.\n\n${table}\n`;
|
|
237
220
|
const pagesUrl = `https://${data.repo.split('/')[0]}.github.io/${data.repo.split('/')[1]}/`;
|
|
238
|
-
return { 'stats-github-views.svg': renderGithubViewsBadge(data), '
|
|
221
|
+
return { 'stats-github-views.svg': renderGithubViewsBadge(data), 'dashboard.svg': renderPublicDashboard(data), 'README.md': readme.replace('![Repository dashboard]', `[Live dashboard · refreshes every 30 seconds](${pagesUrl})\n\n![Repository dashboard]`), 'data.json': `${JSON.stringify(data, null, 2)}\n`, 'index.html': renderLiveDashboard(data) };
|
|
239
222
|
}
|
|
240
223
|
|
|
241
224
|
export function githubEnvironment(token, env = process.env) {
|
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.21.
|
|
32
|
+
const VERSION = "1.21.4";
|
|
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;
|
package/src/index.mjs
CHANGED
|
@@ -39,7 +39,7 @@ import { PROJECT_SETUP_TOOLS, registerProjectOnboardingTools } from "./project-o
|
|
|
39
39
|
|
|
40
40
|
exitForVersionRequest(import.meta.url);
|
|
41
41
|
|
|
42
|
-
const VERSION = "1.21.
|
|
42
|
+
const VERSION = "1.21.4";
|
|
43
43
|
void import("./telemetry.mjs").then(({ startUsageReporting }) => startUsageReporting({ version: VERSION })).catch(() => {});
|
|
44
44
|
const log = (msg) => process.stderr.write(`[codex-mcp-bridge] ${msg}\n`);
|
|
45
45
|
|
|
@@ -36,7 +36,7 @@ import { NativeCreationReceipts, creationIdValid } from "./native-creation-recei
|
|
|
36
36
|
|
|
37
37
|
exitForVersionRequest(import.meta.url);
|
|
38
38
|
|
|
39
|
-
const VERSION = "1.21.
|
|
39
|
+
const VERSION = "1.21.4";
|
|
40
40
|
const log = (msg) => process.stderr.write(`[native-relay] ${msg}\n`);
|
|
41
41
|
|
|
42
42
|
function errorResponse(code, message, sent) {
|