@minhspark/codex-mcp-bridge 1.26.0 → 1.26.2

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codex-mcp-bridge",
3
- "version": "1.26.0",
3
+ "version": "1.26.2",
4
4
  "description": "Connect ChatGPT to your own Codex Desktop projects and conversations.",
5
5
  "author": {
6
6
  "name": "Bui Dang Minh"
package/CHANGELOG.md CHANGED
@@ -4,6 +4,43 @@ Follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and [SemVer](ht
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [1.26.2] - 2026-11-01
8
+
9
+ ### Upgrade
10
+
11
+ Install or update the global package and all managed client and background-service settings with one command, including upgrades from 1.26.0 or 1.26.1:
12
+
13
+ ```sh
14
+ npm exec --yes --ignore-scripts --package=@minhspark/codex-mcp-bridge@latest -- codex-bridge-update
15
+ ```
16
+
17
+ Use `npm.cmd` in Windows PowerShell. npm downloads the latest updater without running setup in its cache; the updater installs that exact resolved version globally with managed setup enabled and verifies the global installation. No second installation command is required.
18
+
19
+ ### Added
20
+
21
+ - Automatic `codex-bridge-update` orchestration for package replacement, all managed client settings and background-service configuration. Before replacing a Windows installation held by an owned legacy relay, it moves only that service to newer code using private relay storage as its working directory, waits for work to drain and verifies replacement readiness. The temporary runtime points to the downloaded updater package. It reports a pending migration instead of killing processes or interrupting jobs.
22
+ - Preserve disabled services, provider authentication, custom project grants and permission denials throughout the update. Setup does not open apps or chats, and a deliberately disabled service is not reported as ready.
23
+
24
+ ### Fixed
25
+
26
+ - New background service and daemon launches use private relay storage as their working directory instead of the npm installation directory, preventing those processes from locking the package on Windows. The updater migrates owned legacy instances before package replacement. Worker jobs continue using their explicitly authorized project directories.
27
+
28
+ ## [1.26.1] - 2026-11-01
29
+
30
+ ### Upgrade
31
+
32
+ Update the package and reapply all managed client and background-service settings with the same command:
33
+
34
+ ```sh
35
+ npm install -g @minhspark/codex-mcp-bridge@latest --allow-scripts=@minhspark/codex-mcp-bridge --foreground-scripts
36
+ ```
37
+
38
+ Use `npm.cmd` in Windows PowerShell. Setup does not open apps or chats.
39
+
40
+ ### Fixed
41
+
42
+ - Read-only background-service checks validate the installed runtime environment. A normal terminal no longer reports a healthy service as unconfigured merely because npm added temporary entries to `PATH` during installation. Package, startup ownership and running-runtime identity checks remain in place.
43
+
7
44
  ## [1.26.0] - 2026-11-01
8
45
 
9
46
  ### Upgrade
package/README.md CHANGED
@@ -23,23 +23,27 @@ https://github.com/user-attachments/assets/98b23989-826f-4d7d-9dcb-ad7dd2739095
23
23
 
24
24
  ## Installation
25
25
 
26
- One global npm command installs the package, configures the local Claude, Codex and Antigravity bridges, and installs the independent worker relay. Native handoffs require the selected Desktop apps; background work requires the selected provider CLIs and their own authentication. Setup preserves existing project restrictions and custom settings; it does not sign in, grant workspace trust, change permission modes, or restart running apps.
26
+ One npm command installs or updates the global package, applies all managed Claude, Codex and Antigravity settings, and configures the independent worker relay. Native handoffs require the selected Desktop apps; background work requires the selected provider CLIs and their own authentication. Setup preserves existing project restrictions and custom settings; it does not sign in, grant workspace trust, change permission modes, or restart running apps.
27
27
 
28
28
  ### Package — npm
29
29
 
30
30
  **macOS / Linux / WSL**
31
31
 
32
32
  ```bash
33
- npm install -g @minhspark/codex-mcp-bridge@latest --allow-scripts=@minhspark/codex-mcp-bridge --foreground-scripts
33
+ npm exec --yes --ignore-scripts --package=@minhspark/codex-mcp-bridge@latest -- codex-bridge-update
34
34
  ```
35
35
 
36
36
  **Windows PowerShell**
37
37
 
38
38
  ```powershell
39
- npm.cmd install -g @minhspark/codex-mcp-bridge@latest --allow-scripts=@minhspark/codex-mcp-bridge --foreground-scripts
39
+ npm.cmd exec --yes --ignore-scripts --package=@minhspark/codex-mcp-bridge@latest -- codex-bridge-update
40
40
  ```
41
41
 
42
- Requires **Node.js 22.13+**. Use `.cmd` for this package's commands in Windows PowerShell. **Every release uses this same single install/update command.** It updates the package, applies the managed bridge settings across Claude, Codex and Antigravity, configures the independent background worker relay, and verifies saved registrations and service activation separately. Comprehensive setup migrates historical automatic Codex navigation to `CODEX_BRIDGE_OPEN_IN_APP=0`, enables Claude's native background preference and updates Antigravity's existing Windows background preference where supported. Accounts, project grants, unrelated custom registrations and existing permission denials remain unchanged. Setup adds only the four worker-relay communication grants required by headless Antigravity; it does not enable broad permission bypasses. If a native Codex CLI is missing, setup installs a pinned official `@openai/codex` package in the current user's `~/.config/GptClaudeBridge/tools` (or the corresponding `XDG_CONFIG_HOME` path); no separate CLI install command is needed.
42
+ Requires **Node.js 22.13+**. Use `.cmd` for this package's commands in Windows PowerShell. **Use this same single command for a fresh install and every update**, including upgrades from 1.26.0 or 1.26.1. npm fetches the latest updater into its cache without running setup there. The updater installs that exact resolved version globally, runs the managed setup hook, and verifies the global version, saved settings and service activation separately. A second installation command is not required.
43
+
44
+ For an enabled legacy Windows relay from 1.26.0 or 1.26.1, the updater moves only this package's owned service to newer code using private relay storage as its working directory before replacing the global package. The temporary service runtime points to the downloaded updater package; changing the working directory releases the old package lock. It waits for active work to drain and the replacement transport to become ready without killing processes or opening apps or chats. If migration is still pending after its bounded wait, it reports `UPDATE_RELAY_PENDING`; keep the existing jobs and receipts and rerun the same command after they finish. Intentionally disabled services stay disabled and are not reported as ready.
45
+
46
+ Managed setup migrates historical automatic Codex navigation to `CODEX_BRIDGE_OPEN_IN_APP=0`, enables Claude's native background preference and updates Antigravity's existing Windows background preference where supported. Accounts, project grants, unrelated custom registrations and existing permission denials remain unchanged. Setup adds only the four worker-relay communication grants required by headless Antigravity; it does not enable broad permission bypasses. If a native Codex CLI is missing, setup installs a pinned official `@openai/codex` package in the current user's `~/.config/GptClaudeBridge/tools` (or the corresponding `XDG_CONFIG_HOME` path); no separate CLI install command is needed.
43
47
 
44
48
  ### Independent background workers
45
49
 
@@ -61,7 +65,7 @@ Keep the same request UUID for retries and read its durable receipt. Queued work
61
65
 
62
66
  Worker delegation is bounded. `WORKER_DELEGATION_CAPACITY` means the destination has no free execution slot and that delegation was not sent or queued behind waiting workers. Inspect or finish existing delegated work before retrying the same unsent request. Queue and delegation limits are reported explicitly.
63
67
 
64
- `--allow-scripts=@minhspark/codex-mcp-bridge` authorizes only this package's setup hook. npm versions that block install scripts by default need this flag; a plain install works only when the hook is allowed. `--foreground-scripts` displays configuration progress and failures that npm otherwise hides. If npm prints `1 package had install scripts blocked`, rerun the recommended command or run `codex-bridge-setup` explicitly.
68
+ The recommended command's `--ignore-scripts` applies only to downloading the updater into npm's cache. The updater explicitly enables this package's setup hook for the global installation and displays its progress. This avoids client MCP registrations pointing into a temporary npm cache directory. A direct global npm install remains an advanced alternative, but it skips the updater's migration of an old service that can lock the package on Windows.
65
69
 
66
70
  | Client | Installed entry | Purpose |
67
71
  | --- | --- | --- |
@@ -75,11 +79,11 @@ Worker delegation is bounded. `WORKER_DELEGATION_CAPACITY` means the destination
75
79
 
76
80
  For native Claude-to-Codex handoffs, use an existing native Claude **Code** session and the same local project saved in Codex Desktop. The shared `codex-bridge-desktop` connector has its own legacy route; it does not establish a native Code sender identity. Setup applies saved configuration without opening or restarting apps. Saved configuration is not proof of a live connection; available supervisors reload compatible workers when idle. Complete [verification](#verify-the-installation) with the tools already available in the actual clients. If a native host is unloaded, report the diagnostic instead of opening chats to load a relay.
77
81
 
78
- Automatic setup runs only for a **global npm install**. Local `npm install` and `npm ci` do not change app settings. Set `CODEX_BRIDGE_SKIP_SETUP=1`, or pass `--ignore-scripts`, to install the package without configuring apps. The optional [workflow skill](#workflow-skill--npx-skills), VS Code preview, and hosted ChatGPT pairing retain their separate setup steps.
82
+ Automatic setup runs during the updater's **global npm installation**. Local `npm install` and `npm ci` do not change app settings. For a deliberate package-only installation, use a direct global npm install with `CODEX_BRIDGE_SKIP_SETUP=1` or `--ignore-scripts`; that opt-out is separate from the cache-only `--ignore-scripts` in the recommended updater command. The optional [workflow skill](#workflow-skill--npx-skills), VS Code preview, and hosted ChatGPT pairing retain their separate setup steps.
79
83
 
80
84
  ### Setup recovery and checks
81
85
 
82
- If an app configuration step fails, setup and the global install return a nonzero exit with the failing component. Correct its reported issue and rerun the update command above, or rerun configuration on an existing installation:
86
+ If service migration, installation or managed setup fails, the updater returns a nonzero exit and reports the failed step. Inspect that component and the installed version, correct the reported cause, and rerun the same update command above. npm can roll back package files while settings already written remain changed. For configuration-only repair of an already installed package, the following is an optional alternative:
83
87
 
84
88
  ```bash
85
89
  codex-bridge-setup
@@ -545,12 +549,12 @@ Node.js 22.13+ is required. If a command is missing, open a new terminal and che
545
549
  If the package or registrations are missing, use the complete installation command:
546
550
 
547
551
  ```powershell
548
- npm.cmd install -g @minhspark/codex-mcp-bridge@latest --allow-scripts=@minhspark/codex-mcp-bridge --foreground-scripts
552
+ npm.cmd exec --yes --ignore-scripts --package=@minhspark/codex-mcp-bridge@latest -- codex-bridge-update
549
553
  ```
550
554
 
551
- On npm 12, `1 package had install scripts blocked` means the setup hook did not run. The scoped `--allow-scripts` flag authorizes this package's hook; it does not enable every package's scripts globally. `--foreground-scripts` displays lifecycle progress. A local `npm install`/`npm ci`, `--ignore-scripts`, or `CODEX_BRIDGE_SKIP_SETUP=1` intentionally skips automatic setup.
555
+ This runs the latest updater outside the global package directory, handles an owned legacy service that can lock that directory, and installs the exact resolved package with its setup hook enabled. `--ignore-scripts` suppresses setup only for the temporary cached updater. If a previous direct install printed `1 package had install scripts blocked`, use this same updater command to install and apply the managed settings together. Intentional setup opt-outs and disabled-service choices are not silently removed.
552
556
 
553
- For an already-installed package, preview and apply setup explicitly:
557
+ For an already-installed package, these optional commands preview or repair configuration without updating package files:
554
558
 
555
559
  ```powershell
556
560
  codex-bridge-setup.cmd --dry-run
@@ -558,7 +562,7 @@ codex-bridge-setup.cmd
558
562
  codex-bridge-setup.cmd --check
559
563
  ```
560
564
 
561
- `--dry-run` does not write settings or download tools. Setup resolves an existing Codex CLI or installs its managed official copy; `--no-download` requires one to be available already. A failed postinstall configuration step retains the npm package so it can be repaired. Explicit setup and `--check` return a nonzero exit code for incomplete configuration. Read the named component's error; running the same command cannot resolve a deliberate opt-out or an unrelated conflicting registration.
565
+ `--dry-run` does not write settings or download tools. Setup resolves an existing Codex CLI or installs its managed official copy; `--no-download` requires one to be available already. Failed setup or update returns a nonzero exit; inspect the reported component and installed version, correct the cause, then rerun the same updater command. Package rollback does not guarantee that settings or command shims return to their previous state. Explicit setup and `--check` also return a nonzero exit code for incomplete configuration. Running the same command cannot resolve a deliberate opt-out or an unrelated conflicting registration.
562
566
 
563
567
  ### Missing module, stale source path, or a different running version
564
568
 
@@ -12,26 +12,28 @@ connector. Install Node.js 22.13+ under the macOS account that will use the
12
12
  bridges. Native handoffs require signed-in apps and the same local project saved
13
13
  in Codex Desktop and Claude's Code tab. Independent background workers use
14
14
  separately authenticated provider CLIs and do not require open Desktop apps.
15
- Run:
15
+ Use the same command for a fresh installation and every update:
16
16
 
17
17
  ```bash
18
- npm install -g @minhspark/codex-mcp-bridge@latest --allow-scripts=@minhspark/codex-mcp-bridge --foreground-scripts
18
+ npm exec --yes --ignore-scripts --package=@minhspark/codex-mcp-bridge@latest -- codex-bridge-update
19
19
  ```
20
20
 
21
- The script allowance applies only to this package's setup hook. npm versions
22
- that block install scripts by default need it; a plain install is sufficient
23
- only when the hook is allowed. `--foreground-scripts` displays setup progress.
24
- If npm reports `1 package had install scripts blocked`, rerun the command above
25
- or run `codex-bridge-setup` explicitly.
21
+ npm downloads the latest updater into its cache. `--ignore-scripts` suppresses
22
+ setup only in that temporary location. The updater installs its exact resolved
23
+ version globally, enables this package's managed setup hook, displays progress
24
+ and verifies the global version and configuration. No second installation or
25
+ setup command is required. Existing disabled choices, authentication and custom
26
+ project grants are preserved; the updater does not open apps or chats or kill
27
+ processes. A pending service migration is reported instead of interrupting work.
26
28
 
27
29
  Setup registers the local bridges, adds native pipe forwarding, and bootstraps
28
30
  the relay executor. It reuses an available Codex CLI or installs a pinned
29
31
  official package under `~/.config/GptClaudeBridge/tools` (or
30
32
  `XDG_CONFIG_HOME/GptClaudeBridge/tools`). No separate Codex CLI install command
31
33
  is required. Run the install under the account that uses the apps, without `sudo`.
32
- The package remains installed if an app configuration step fails, preserving
33
- the setup command for repair. A successful npm exit does not verify that every
34
- component is configured.
34
+ If setup or update exits nonzero, inspect the reported component and installed
35
+ version, correct the cause, and rerun the same updater command. npm can roll back
36
+ package files without restoring settings already written or command shims.
35
37
 
36
38
  The command also installs an independent per-user LaunchAgent for separate
37
39
  Claude, Codex and Antigravity CLI workers and updates its managed settings on
@@ -89,6 +91,7 @@ codex-bridge-setup --dry-run
89
91
  codex-bridge-setup
90
92
  ```
91
93
 
94
+ These are optional configuration-only checks and repairs after installation.
92
95
  `--check` inspects registrations; `--dry-run` previews components and paths
93
96
  without downloads or writes; the plain command applies setup again. Add
94
97
  `--json` for structured output or `--no-download` to require an existing Codex
@@ -96,10 +99,12 @@ CLI. `codex-mcp-bridge setup` runs the same setup. An incomplete result identifi
96
99
  the component to correct before rerunning. Explicit setup and `--check` return
97
100
  a nonzero exit status while configuration is incomplete.
98
101
 
99
- Local `npm install` and `npm ci` do not change app settings. Set
100
- `CODEX_BRIDGE_SKIP_SETUP=1` or use `--ignore-scripts` to skip setup during a
101
- global install. For Homebrew, run `codex-bridge-setup` after installing the
102
- formula. A pinned source checkout can use `node scripts/setup.mjs`.
102
+ Local `npm install` and `npm ci` do not change app settings. For a deliberate
103
+ package-only installation, a direct global npm install can use
104
+ `CODEX_BRIDGE_SKIP_SETUP=1` or `--ignore-scripts`; this differs from the cache-only
105
+ script suppression in the recommended updater command. For Homebrew, run
106
+ `codex-bridge-setup` after installing the formula. A pinned source checkout can
107
+ use `node scripts/setup.mjs`.
103
108
 
104
109
  The [manual macOS commands](../README.md#macos-terminal) and
105
110
  [Claude Code registration commands](../README.md#register-claude-code) remain
@@ -3,25 +3,38 @@
3
3
  Install Node.js 22.13+. Native handoffs use signed-in Desktop apps and the same
4
4
  local project saved in Codex Desktop and Claude Desktop's **Code tab**.
5
5
  Independent background work uses separately authenticated provider CLIs and
6
- does not require the Desktop apps to be open. Run one PowerShell command:
6
+ does not require the Desktop apps to be open. Use this one PowerShell command
7
+ for a fresh installation or an update, including from 1.26.0 or 1.26.1:
7
8
 
8
9
  ```powershell
9
- npm.cmd install -g @minhspark/codex-mcp-bridge@latest --allow-scripts=@minhspark/codex-mcp-bridge --foreground-scripts
10
+ npm.cmd exec --yes --ignore-scripts --package=@minhspark/codex-mcp-bridge@latest -- codex-bridge-update
10
11
  ```
11
12
 
12
- The `--allow-scripts` value permits only this package's setup hook. npm versions
13
- that block install scripts by default need it; a plain install runs setup only
14
- when scripts are allowed. `--foreground-scripts` displays setup progress. If
15
- npm reports `1 package had install scripts blocked`, run the recommended command
16
- again or run `codex-bridge-setup.cmd` explicitly.
13
+ npm downloads the latest updater into its cache. `--ignore-scripts` prevents
14
+ setup from running in that temporary location; the updater then installs its
15
+ exact resolved version globally with this package's managed setup hook enabled.
16
+ It displays progress and verifies the global version and saved settings.
17
+ No second installation or setup command is required.
18
+
19
+ An older Windows background service can keep the global npm package directory
20
+ locked as its working directory. Before replacing the package, the updater
21
+ moves only this package's owned legacy service to newer code using private relay
22
+ storage as its working directory when needed. The temporary runtime points to
23
+ the downloaded updater package. It waits for active work to drain and the
24
+ replacement transport to become ready, without killing processes or opening
25
+ apps or chats. If that migration
26
+ remains pending, `UPDATE_RELAY_PENDING` leaves jobs and receipts intact; rerun
27
+ the same command after the active work finishes. Deliberately disabled services
28
+ remain disabled and are not reported as ready.
17
29
 
18
30
  The global installation configures the bridges and verifies their saved
19
31
  registrations. It reuses an available native Codex CLI, or installs a pinned
20
32
  official package in the current user's `.config\GptClaudeBridge\tools`
21
33
  directory. It also configures native pipe forwarding and bootstraps the relay
22
- executor. A failed component is reported as incomplete rather than ready. The
23
- package stays installed when an app configuration step fails, so the setup
24
- command remains available for repair. npm success alone does not verify setup.
34
+ executor. A failed component is reported as incomplete rather than ready. If
35
+ setup or update exits nonzero, inspect the reported component and installed
36
+ version, correct the cause, and rerun the same updater command. npm can roll back
37
+ package files without restoring settings already written or command shims.
25
38
 
26
39
  The same command installs the independent worker relay as a hidden per-user
27
40
  scheduled task and applies its managed settings on every update. It registers
@@ -78,6 +91,7 @@ codex-bridge-setup.cmd --dry-run
78
91
  codex-bridge-setup.cmd
79
92
  ```
80
93
 
94
+ These are optional configuration-only checks and repairs after installation.
81
95
  The first command inspects configuration; the second previews components and
82
96
  paths without writes or downloads; the third applies setup again. Add `--json`
83
97
  for structured output or `--no-download` to require an existing Codex CLI.
@@ -87,8 +101,12 @@ incomplete.
87
101
  has no bridge tools, inspect and reconnect `codex-bridge` using `/mcp` before
88
102
  attempting delivery.
89
103
 
90
- Local `npm install` and `npm ci` do not configure apps. To opt out during a
91
- global install, set `CODEX_BRIDGE_SKIP_SETUP=1` or use `--ignore-scripts`.
104
+ Local `npm install` and `npm ci` do not configure apps. For a deliberate
105
+ package-only installation, a direct global npm install can use
106
+ `CODEX_BRIDGE_SKIP_SETUP=1` or `--ignore-scripts`. This differs from the
107
+ recommended updater command, which suppresses setup only in its temporary cache
108
+ and enables it for the final global installation. A direct install skips the
109
+ updater's migration of legacy Windows services that can lock the package.
92
110
  The optional card extension, hosted ChatGPT pairing, and VS Code preview have
93
111
  separate installation steps.
94
112
 
@@ -1,18 +1,20 @@
1
1
  # Project onboarding and shared authorization
2
2
 
3
- The recommended global installation registers the bridges and configures the
4
- independent worker relay automatically:
3
+ One command installs or updates the global package, registers the bridges and
4
+ configures the independent worker relay automatically:
5
5
 
6
6
  ```sh
7
- npm install -g @minhspark/codex-mcp-bridge@latest --allow-scripts=@minhspark/codex-mcp-bridge --foreground-scripts
7
+ npm exec --yes --ignore-scripts --package=@minhspark/codex-mcp-bridge@latest -- codex-bridge-update
8
8
  ```
9
9
 
10
- In Windows PowerShell use `npm.cmd`. The script allowance authorizes only this
11
- package's setup hook; npm versions that block install scripts by default need
12
- it. A plain install runs setup only when the hook is allowed.
13
- `--foreground-scripts` displays progress. If npm prints
14
- `1 package had install scripts blocked`, rerun the recommended command or run
15
- `codex-bridge-setup` explicitly. The setup creates
10
+ In Windows PowerShell use `npm.cmd`. npm fetches the latest updater into its
11
+ cache with setup disabled there. The updater moves an owned legacy service to
12
+ newer code using private relay storage as its working directory when needed,
13
+ temporarily using the downloaded updater package. It waits for active work to
14
+ drain, then installs its exact resolved version globally with the setup hook
15
+ enabled. It verifies the global installation and managed settings. No second
16
+ installation command is required. It does not open apps or chats or kill
17
+ processes. The setup creates
16
18
  `codex-bridge` for Claude Code and the separate `codex-bridge-desktop` shared
17
19
  Claude connector, configures Codex and Antigravity, and initializes the native
18
20
  relay on Windows/macOS. It also installs the per-user background service and
@@ -32,11 +34,15 @@ display results. Use a terminal or another responsive client, subject to the
32
34
  `codex-bridge-setup --check` inspects all saved registrations. Use
33
35
  `codex-bridge-setup --dry-run` to preview or rerun `codex-bridge-setup` to apply
34
36
  setup after correcting an incomplete component. Add `.cmd` on Windows and
35
- `--json` for structured output. Local package installs do not run setup;
36
- `CODEX_BRIDGE_SKIP_SETUP=1` and npm `--ignore-scripts` opt out of global setup.
37
- If app configuration is incomplete, npm retains the package for repair; its
38
- success exit alone does not verify setup. Explicit setup and `--check` return
39
- a nonzero status until the saved configuration passes verification.
37
+ `--json` for structured output. Local package installs do not run setup.
38
+ For a deliberate package-only direct global installation,
39
+ `CODEX_BRIDGE_SKIP_SETUP=1` or npm `--ignore-scripts` opts out of setup; this is
40
+ separate from the cache-only script suppression in the recommended updater.
41
+ Failed setup or update returns a nonzero exit. Inspect the reported component
42
+ and installed version, correct the cause, then rerun the same updater command.
43
+ npm can roll back package files without restoring settings or command shims.
44
+ Explicit setup and `--check` also return a nonzero status until the saved
45
+ configuration passes verification.
40
46
 
41
47
  ## Shared project policy
42
48
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@minhspark/codex-mcp-bridge",
3
- "version": "1.26.0",
3
+ "version": "1.26.2",
4
4
  "description": "Connect Claude, Codex, and Antigravity through MCP, with native Desktop handoffs and bridge-owned Antigravity CLI sessions.",
5
5
  "keywords": [
6
6
  "mcp",
@@ -30,6 +30,7 @@
30
30
  "codex-mcp-bridge-install": "scripts/install-claude-desktop.mjs",
31
31
  "codex-bridge-code-install": "scripts/install-claude-code.mjs",
32
32
  "codex-bridge-setup": "scripts/setup.mjs",
33
+ "codex-bridge-update": "scripts/update.mjs",
33
34
  "worker-relay": "scripts/worker-relay.mjs",
34
35
  "bridge-projects": "scripts/bridge-projects.mjs",
35
36
  "claude-mcp-bridge-install": "scripts/install-codex-mcp.mjs",
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.26.0",
4
+ "version": "1.26.2",
5
5
  "description": "Connect ChatGPT to your own Codex Desktop projects and conversations.",
6
6
  "author": {
7
7
  "name": "Bui Dang Minh",
@@ -8,4 +8,5 @@ relayService = WScript.Arguments(1)
8
8
  If InStr(relayNode, Chr(34)) > 0 Or InStr(relayNode, "%") > 0 Then WScript.Quit 2
9
9
  If InStr(relayService, Chr(34)) > 0 Or InStr(relayService, "%") > 0 Then WScript.Quit 2
10
10
  relayEnvironment("AGENT_RELAY_DIRECTORY") = WScript.Arguments(2)
11
+ relayShell.CurrentDirectory = WScript.Arguments(2)
11
12
  WScript.Quit relayShell.Run(Chr(34) & relayNode & Chr(34) & " " & Chr(34) & relayService & Chr(34), 0, True)
@@ -12,6 +12,7 @@ import { isMainModule, stableNodeBin } from "../src/install-paths.mjs";
12
12
  import { readRegularConfigFile } from "../src/project-policy.mjs";
13
13
 
14
14
  const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
15
+ const RUNTIME_ENVIRONMENT_KEYS = ["HOME", "PATH", "CODEX_HOME", "CLAUDE_CONFIG_DIR", "XDG_CONFIG_HOME"];
15
16
  const TASK_SCRIPT = String.raw`$ErrorActionPreference = 'Stop'
16
17
  $relayRequest = [Console]::In.ReadToEnd() | ConvertFrom-Json
17
18
  try {
@@ -178,7 +179,7 @@ function taskXml({ command, args, user, enabled }) {
178
179
 
179
180
  function savedEnvironment(env, config) {
180
181
  const result = { AGENT_RELAY_DIRECTORY: config.paths.root, AGENT_RELAY_SERVICE_OWNER: RELAY_SERVICE_OWNER };
181
- for (const name of ["HOME", "PATH", "CODEX_HOME", "CLAUDE_CONFIG_DIR", "XDG_CONFIG_HOME"]) {
182
+ for (const name of RUNTIME_ENVIRONMENT_KEYS) {
182
183
  if (typeof env[name] === "string" && env[name] && !/[\u0000-\u001f\u007f]/.test(env[name])) result[name] = env[name];
183
184
  }
184
185
  return result;
@@ -359,25 +360,33 @@ export async function installBackgroundRelay({ env = process.env, platform = pro
359
360
  return { status: result?.status ?? result?.exitCode ?? 0, stdout: String(result?.stdout ?? "") };
360
361
  };
361
362
  const runtimeFile = path.join(config.paths.root, "service-runtime.json");
362
- const desiredRuntime = { schemaVersion: 1, owner: RELAY_SERVICE_OWNER, packageRoot: root, nodeExecutable: node, packageVersion,
363
- environment: Object.fromEntries(Object.entries(savedEnvironment(env, config)).filter(([name]) => !name.startsWith("AGENT_RELAY_"))) };
364
- const expectedRuntimeId = relayServiceRuntimeId(desiredRuntime);
365
363
  const readRuntime = () => {
366
364
  const raw = readRegularConfigFile(runtimeFile, { missing: true, maxBytes: 64 * 1024 });
367
365
  if (raw === null) return null;
368
366
  let value;
369
367
  try { value = JSON.parse(raw); } catch { throw installFailure("SERVICE_RUNTIME_INVALID"); }
370
368
  if (value?.schemaVersion !== 1 || value.owner !== RELAY_SERVICE_OWNER) throw installFailure("SERVICE_CONFIGURATION_CONFLICT");
369
+ if (value.environment !== undefined && (!value.environment || typeof value.environment !== "object" || Array.isArray(value.environment)
370
+ || Object.entries(value.environment).some(([name, entry]) => !RUNTIME_ENVIRONMENT_KEYS.includes(name)
371
+ || typeof entry !== "string" || !entry || /[\u0000-\u001f\u007f]/.test(entry)))) throw installFailure("SERVICE_RUNTIME_INVALID");
371
372
  return value;
372
373
  };
373
374
  const previousRuntime = readRuntime();
375
+ const installedEnv = check && previousRuntime ? {
376
+ ...Object.fromEntries(Object.entries(env).filter(([name]) => !RUNTIME_ENVIRONMENT_KEYS.includes(name))),
377
+ ...previousRuntime.environment,
378
+ } : env;
379
+ const desiredRuntime = { schemaVersion: 1, owner: RELAY_SERVICE_OWNER, packageRoot: root, nodeExecutable: node, packageVersion,
380
+ environment: check && previousRuntime ? previousRuntime.environment ?? {}
381
+ : Object.fromEntries(Object.entries(savedEnvironment(env, config)).filter(([name]) => !name.startsWith("AGENT_RELAY_"))) };
382
+ const expectedRuntimeId = relayServiceRuntimeId(desiredRuntime);
374
383
  const runtimeChanged = JSON.stringify(previousRuntime) !== JSON.stringify(desiredRuntime);
375
384
  const prepareRuntime = async () => {
376
385
  if (JSON.stringify(readRuntime()) !== JSON.stringify(previousRuntime)) throw installFailure("SERVICE_CONFIGURATION_CHANGED");
377
386
  if (runtimeChanged) writeRelayJson(runtimeFile, desiredRuntime);
378
387
  if (JSON.stringify(readRuntime()) !== JSON.stringify(desiredRuntime)) throw installFailure("SERVICE_READBACK_FAILED");
379
388
  };
380
- const context = { env, config, root, node, service, label, invoke, mutate: !dryRun && !check, uid, nativeRun: run === execute, prepareRuntime };
389
+ const context = { env: installedEnv, config, root, node, service, label, invoke, mutate: !dryRun && !check, uid, nativeRun: run === execute, prepareRuntime };
381
390
  const installed = await ({ win32: installWindows, darwin: installMac, linux: installLinux })[platform](context);
382
391
  installed.configured = installed.configured && JSON.stringify(readRuntime()) === JSON.stringify(desiredRuntime);
383
392
  const result = { ...base, ...installed, dryRun, deliveryEnabled: installed.enabled, liveVerified: false,
@@ -25,7 +25,7 @@ import { removeRelayFile } from "../src/native-relay-files.mjs";
25
25
 
26
26
  exitForVersionRequest(import.meta.url);
27
27
 
28
- const VERSION = "1.26.0";
28
+ const VERSION = "1.26.2";
29
29
  const root = stableInstallPath(path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."));
30
30
  const entry = path.join(root, "src", "mcp-supervisor.mjs");
31
31
  const entryArgs = ["native-relay-companion.mjs"];
@@ -0,0 +1,210 @@
1
+ #!/usr/bin/env node
2
+ import fs from "node:fs";
3
+ import os from "node:os";
4
+ import path from "node:path";
5
+ import { execFile } from "node:child_process";
6
+ import { fileURLToPath } from "node:url";
7
+ import { installBackgroundRelay } from "./install-background-relay.mjs";
8
+ import { readRelayConfiguration } from "../src/background-relay-config.mjs";
9
+ import { readRelayServiceRuntime, RELAY_SERVICE_OWNER } from "../src/background-relay-service.mjs";
10
+ import { assertPrivateRelayFile } from "../src/background-relay-storage.mjs";
11
+ import { isMainModule } from "../src/install-paths.mjs";
12
+ import { readRegularConfigFile } from "../src/project-policy.mjs";
13
+ import { exitForVersionRequest } from "../src/cli-version.mjs";
14
+ import { bridgeDiagnostic, withBridgeDiagnostic } from "../src/recipient-preflight.mjs";
15
+
16
+ const PACKAGE = "@minhspark/codex-mcp-bridge";
17
+ const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
18
+ const MANAGED_ENV = new Set(["HOME", "PATH", "CODEX_HOME", "CLAUDE_CONFIG_DIR", "XDG_CONFIG_HOME"]);
19
+ const RETRY = "Run the same codex-bridge-update command again after inspecting this report. Existing work and receipts were preserved.";
20
+ const pause = ms => new Promise(resolve => setTimeout(resolve, ms));
21
+
22
+ function failure(code, message, phase, cause) {
23
+ return Object.assign(new Error(message), { code, phase, deliveryState: "not_applicable", ...(cause ? { cause } : {}) });
24
+ }
25
+
26
+ function packageVersion(root, missing = false) {
27
+ const raw = readRegularConfigFile(path.join(root, "package.json"), { missing, maxBytes: 128 * 1024 });
28
+ if (raw === null) return null;
29
+ let value;
30
+ try { value = JSON.parse(raw); } catch {}
31
+ if (value?.name !== PACKAGE || typeof value.version !== "string" || value.version.length > 96 || !/^\d+\.\d+\.\d+(?:[-+][A-Za-z0-9.+-]+)?$/.test(value.version)) {
32
+ throw failure("UPDATE_PACKAGE_INVALID", "The bridge package identity or version could not be verified.", "preflight");
33
+ }
34
+ return value.version;
35
+ }
36
+
37
+ function newerVersion(left, right) {
38
+ const split = value => { const [core, ...suffix] = value.split("+")[0].split("-"); return { core: core.split(".").map(BigInt), suffix: suffix.join("-") }; };
39
+ const a = split(left);
40
+ const b = split(right);
41
+ for (let index = 0; index < 3; index++) if (a.core[index] !== b.core[index]) return a.core[index] > b.core[index];
42
+ if (!a.suffix || !b.suffix) return !a.suffix && Boolean(b.suffix);
43
+ const parts = [a.suffix.split("."), b.suffix.split(".")];
44
+ for (let index = 0; index < Math.max(...parts.map(part => part.length)); index++) {
45
+ const [x, y] = parts.map(part => part[index]);
46
+ if (x === y) continue;
47
+ if (x === undefined || y === undefined) return y === undefined;
48
+ const numeric = [x, y].map(value => /^\d+$/.test(value));
49
+ return numeric.every(Boolean) ? BigInt(x) > BigInt(y) : numeric[0] !== numeric[1] ? numeric[1] : x > y;
50
+ }
51
+ return false;
52
+ }
53
+
54
+ export function resolveUpdateNpm(env = process.env) {
55
+ for (const candidate of [env.npm_execpath, path.join(path.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js")]) {
56
+ try {
57
+ if (typeof candidate !== "string" || !path.isAbsolute(candidate)) continue;
58
+ const resolved = fs.realpathSync.native(candidate);
59
+ if (!/^(?:npm-cli|npm)\.js$/.test(path.basename(resolved)) || !fs.statSync(resolved).isFile()) continue;
60
+ const metadata = JSON.parse(readRegularConfigFile(path.resolve(path.dirname(resolved), "..", "package.json"), { maxBytes: 128 * 1024 }));
61
+ if (metadata.name === "npm") return resolved;
62
+ } catch {}
63
+ }
64
+ throw failure("UPDATE_NPM_NOT_FOUND", "A supported npm CLI could not be located. Run this updater through npm exec.", "preflight");
65
+ }
66
+
67
+ function execute(command, args, options) {
68
+ return new Promise(resolve => {
69
+ execFile(command, args, options, (error, stdout, stderr) => resolve({ status: error ? 1 : 0, error, stdout, stderr }));
70
+ });
71
+ }
72
+
73
+ function inside(directory, root) {
74
+ const relative = path.relative(root, directory);
75
+ return relative === "" || relative !== ".." && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative);
76
+ }
77
+
78
+ function neutralDirectory(roots, env) {
79
+ for (const candidate of [os.tmpdir(), env.USERPROFILE, env.HOME, os.homedir()]) {
80
+ try {
81
+ if (typeof candidate !== "string" || !path.isAbsolute(candidate)) continue;
82
+ const directory = fs.realpathSync.native(candidate);
83
+ if (fs.statSync(directory).isDirectory() && roots.every(root => !inside(directory, root))) return directory;
84
+ } catch {}
85
+ }
86
+ throw failure("UPDATE_DIRECTORY_UNAVAILABLE", "No working directory outside the package installation is available.", "preflight");
87
+ }
88
+
89
+ function childFailure(result, phase) {
90
+ const match = /npm\s+(?:ERR!|error)\s+code\s+([A-Z][A-Z0-9_]{0,79})\b/.exec(String(result?.stderr ?? ""));
91
+ const code = match?.[1] ?? (/^[A-Z][A-Z0-9_]{0,79}$/.test(result?.error?.code ?? "") ? result.error.code : null);
92
+ const cause = code ? Object.assign(new Error("The child command reported a failure."), { code }) : undefined;
93
+ return failure(code === "EBUSY" ? "UPDATE_PACKAGE_BUSY" : phase === "verification" ? "UPDATE_SETUP_INCOMPLETE" : "UPDATE_NPM_FAILED",
94
+ code === "EBUSY" ? `The installed package is still held open by another process. No process was stopped. ${RETRY}`
95
+ : `The ${phase === "verification" ? "installed setup verification" : "npm command"} did not complete. ${RETRY}`, phase, cause);
96
+ }
97
+
98
+ function serviceQuiescent(config) {
99
+ for (const name of ["service.lock", "service-status.json"]) {
100
+ const file = path.join(config.paths.root, name);
101
+ if (!assertPrivateRelayFile(file, { missing: true })) continue;
102
+ let state;
103
+ try { state = JSON.parse(readRegularConfigFile(file, { maxBytes: 64 * 1024 })); } catch { return false; }
104
+ if (state?.schemaVersion !== 1 || state.owner !== RELAY_SERVICE_OWNER || !Number.isSafeInteger(state.pid) || state.pid < 1) return false;
105
+ if (state.status === "running" && (!Number.isSafeInteger(state.daemonPid) || state.daemonPid < 1)) return false;
106
+ for (const pid of [state.pid, state.daemonPid].filter(Number.isSafeInteger)) {
107
+ try { process.kill(pid, 0); return false; }
108
+ catch (error) { if (error.code !== "ESRCH") return false; }
109
+ }
110
+ }
111
+ return true;
112
+ }
113
+
114
+ export async function runUpdate({ args = [], env = process.env, platform = process.platform, root = ROOT, run = execute,
115
+ installService = installBackgroundRelay, readConfig = readRelayConfiguration, readRuntime = readRelayServiceRuntime,
116
+ quiescent = serviceQuiescent, now = Date.now, sleep = pause, waitMs = 120000, onProgress = () => {} } = {}) {
117
+ if (args.some(arg => !["--help", "--json"].includes(arg))) throw failure("UPDATE_ARGUMENT_INVALID", "Usage: codex-bridge-update [--json] [--help]", "preflight");
118
+ if (args.includes("--help")) return { help: "Usage: codex-bridge-update [--json]\nSafely update the global bridge and all managed settings. Legacy Windows relays migrate when existing work finishes; pending migrations can be retried with the same command." };
119
+ if (env.CODEX_BRIDGE_SKIP_SETUP === "1") throw failure("UPDATE_SETUP_DISABLED", "CODEX_BRIDGE_SKIP_SETUP=1 disables managed setup. Remove that explicit opt-out before requesting this complete update.", "preflight");
120
+ if (!Number.isSafeInteger(waitMs) || waitMs < 1 || waitMs > 600000) throw failure("UPDATE_ARGUMENT_INVALID", "The update readiness deadline is invalid.", "preflight");
121
+ root = fs.realpathSync.native(root);
122
+ const version = packageVersion(root);
123
+ const npm = resolveUpdateNpm(env);
124
+ let cwd = neutralDirectory([root], env);
125
+ let childEnv = Object.fromEntries(Object.entries(env).filter(([name]) => !/^AGENT_RELAY_(?!DIRECTORY$)/i.test(name)));
126
+ const command = async (arguments_, phase, timeout = 600000) => {
127
+ let result;
128
+ try {
129
+ result = await run(process.execPath, arguments_, { env: childEnv, cwd, encoding: "utf8", windowsHide: true,
130
+ shell: false, timeout, maxBuffer: 8 * 1024 * 1024, stdio: ["ignore", "pipe", "pipe"] });
131
+ } catch (error) { throw childFailure({ error, stderr: error.stderr }, phase); }
132
+ if (result?.error || (result?.status ?? result?.exitCode ?? 0) !== 0) throw childFailure(result, phase);
133
+ return String(result?.stdout ?? "");
134
+ };
135
+ const modules = (await command([npm, "root", "--global"], "preflight", 30000)).trim();
136
+ if (!path.isAbsolute(modules) || /[\u0000-\u001f\u007f]/.test(modules)) throw failure("UPDATE_GLOBAL_ROOT_INVALID", "npm returned an invalid global installation directory.", "preflight");
137
+ const prefix = (await command([npm, "prefix", "--global"], "preflight", 30000)).trim();
138
+ if (!path.isAbsolute(prefix) || /[\u0000-\u001f\u007f]/.test(prefix)
139
+ || path.relative(modules, path.join(prefix, ...(platform === "win32" ? [] : ["lib"]), "node_modules")) !== "") {
140
+ throw failure("UPDATE_GLOBAL_ROOT_INVALID", "npm returned inconsistent global prefix and installation directories.", "preflight");
141
+ }
142
+ const globalRoot = path.join(modules, "@minhspark", "codex-mcp-bridge");
143
+ cwd = neutralDirectory([root, globalRoot], env);
144
+ const previousVersion = packageVersion(globalRoot, true);
145
+ if (previousVersion && newerVersion(previousVersion, version)) throw failure("UPDATE_DOWNGRADE_REFUSED", "The global bridge is newer than this updater. Run the update command with the latest published package.", "preflight");
146
+ const config = readConfig({ env: childEnv, platform, missing: true });
147
+ let runtime;
148
+ if (config) {
149
+ runtime = readRuntime(config.paths.root, { root: globalRoot, nodeExecutable: process.execPath });
150
+ if (runtime.packageVersion && newerVersion(runtime.packageVersion, version)) throw failure("UPDATE_DOWNGRADE_REFUSED", "The owned relay runtime is newer than this updater. Run the update command with the latest published package.", "preflight");
151
+ if (runtime.environment !== undefined) childEnv = { ...Object.fromEntries(Object.entries(childEnv).filter(([name]) => !MANAGED_ENV.has(name.toUpperCase()))), ...runtime.environment };
152
+ childEnv.AGENT_RELAY_DIRECTORY = config.paths.root;
153
+ }
154
+ const awaitService = async (target, mutate, phase, expectedVersion = version) => {
155
+ const deadline = now() + waitMs;
156
+ let check = !mutate;
157
+ for (;;) {
158
+ const service = await installService({ env: childEnv, platform, root: target, check, pollAttempts: 1 });
159
+ check = true;
160
+ if (service.configured !== true) throw failure("UPDATE_SERVICE_UNVERIFIED", `The owned relay service could not be verified. ${RETRY}`, phase,
161
+ service.code ? Object.assign(new Error("The service installer reported a failure."), { code: service.code }) : undefined);
162
+ if (service.enabled === false) {
163
+ if (phase === "migration" && !quiescent(config)) throw Object.assign(failure("UPDATE_RELAY_PENDING", `The disabled relay still has an owned process whose release could not be verified. ${RETRY}`, phase), { pending: true });
164
+ return { enabled: false, ready: false, liveVerified: false };
165
+ }
166
+ if (service.enabled === true && service.liveVerified === true && service.ready === true && service.version === expectedVersion
167
+ && Number.isSafeInteger(service.pid) && service.pid > 0) return { enabled: true, ready: true, liveVerified: true, version: expectedVersion, pid: service.pid };
168
+ if (now() >= deadline) throw Object.assign(failure("UPDATE_RELAY_PENDING", `The relay is still completing its owned runtime transition. ${RETRY}`, phase), { pending: true });
169
+ await sleep(Math.min(1000, Math.max(1, deadline - now())));
170
+ }
171
+ };
172
+ let migrated = false;
173
+ const legacy = value => ["1.26.0", "1.26.1"].includes(value);
174
+ if (platform === "win32" && config && (legacy(previousVersion) || legacy(runtime.packageVersion))) {
175
+ if (config.enabled === false) {
176
+ if (!quiescent(config)) throw Object.assign(failure("UPDATE_RELAY_PENDING", `The disabled relay still has an owned process whose release could not be verified. ${RETRY}`, "migration"), { pending: true });
177
+ } else {
178
+ onProgress("Waiting for the legacy relay to finish existing work and activate the update runtime.");
179
+ const staged = runtime.packageVersion && !legacy(runtime.packageVersion) && !newerVersion("1.26.2", runtime.packageVersion);
180
+ const service = await awaitService(staged ? runtime.packageRoot : root, !staged, "migration", staged ? runtime.packageVersion : version);
181
+ migrated = !staged && service.enabled;
182
+ }
183
+ }
184
+ onProgress(`Installing bridge ${version} and applying managed settings.`);
185
+ await command([npm, "install", "--global", "--prefix", prefix, `${PACKAGE}@${version}`, "--ignore-scripts=false", `--allow-scripts=${PACKAGE}`, "--foreground-scripts"], "installation");
186
+ if (packageVersion(globalRoot) !== version) throw failure("UPDATE_VERSION_MISMATCH", "The global package version does not match the updater version. Rerun the same update command.", "verification");
187
+ onProgress("Verifying the global bridge settings and owned relay runtime.");
188
+ let setup;
189
+ try { setup = JSON.parse(await command([path.join(globalRoot, "scripts", "setup.mjs"), "--check", "--json"], "verification")); }
190
+ catch (error) { if (error?.code) throw error; throw failure("UPDATE_SETUP_INCOMPLETE", `Global setup did not return a verifiable result. ${RETRY}`, "verification"); }
191
+ if (setup?.configured !== true) throw failure("UPDATE_SETUP_INCOMPLETE", `The global bridge settings are incomplete. ${RETRY}`, "verification");
192
+ const service = await awaitService(globalRoot, false, "verification");
193
+ return { updated: true, configured: true, version, previousVersion, migrated, service, opensApps: false, opensChats: false };
194
+ }
195
+
196
+ if (isMainModule(process.argv[1], import.meta.url)) {
197
+ exitForVersionRequest(import.meta.url);
198
+ const args = process.argv.slice(2);
199
+ try {
200
+ process.chdir(neutralDirectory([ROOT], process.env));
201
+ const result = await runUpdate({ args, onProgress: message => process.stderr.write(`${message}\n`) });
202
+ process.stdout.write(result.help ? `${result.help}\n` : args.includes("--json") ? `${JSON.stringify(result, null, 2)}\n`
203
+ : `Bridge ${result.version} updated; managed settings verified. Background relay ${result.service.ready ? "ready" : "remains intentionally disabled"}.\n`);
204
+ } catch (error) {
205
+ const options = { component: "bridge-update", operation: "update", deliveryState: "not_applicable" };
206
+ if (args.includes("--json")) process.stdout.write(JSON.stringify({ updated: false, pending: error.pending === true, diagnostic: bridgeDiagnostic(error, options) }, null, 2) + "\n");
207
+ else process.stderr.write(withBridgeDiagnostic({ isError: true, content: [] }, error, options).content.map(item => item.text ?? "").join("\n") + "\n");
208
+ process.exitCode = 1;
209
+ }
210
+ }
@@ -233,7 +233,7 @@ export async function runBackgroundRelayService({ env = process.env, platform =
233
233
  signal?.addEventListener("abort", stop, { once: true });
234
234
  try {
235
235
  child = spawn(runtime.nodeExecutable, [path.join(root, "src", "background-relay-daemon.mjs")], {
236
- cwd: root, env: childEnv, windowsHide: true, shell: false, stdio: ["ignore", "ignore", "pipe"],
236
+ cwd: config.paths.root, env: childEnv, windowsHide: true, shell: false, stdio: ["ignore", "ignore", "pipe"],
237
237
  });
238
238
  child.stderr?.on("error", () => {});
239
239
  child.stderr?.on("data", captureDiagnostic);
@@ -291,6 +291,7 @@ if (!new URL(import.meta.url).search && isMainModule(process.argv[1], import.met
291
291
  process.on("SIGINT", stop);
292
292
  process.on("SIGTERM", stop);
293
293
  try {
294
+ process.chdir(readRelayConfiguration().paths.root);
294
295
  let run = runBackgroundRelayService;
295
296
  while (true) {
296
297
  const result = await run({ signal: controller.signal });
@@ -31,7 +31,7 @@ import { BACKGROUND_WORKER_GUIDANCE, registerBackgroundTools } from "./backgroun
31
31
 
32
32
  exitForVersionRequest(import.meta.url);
33
33
 
34
- const VERSION = "1.26.0";
34
+ const VERSION = "1.26.2";
35
35
  void import("./telemetry.mjs").then(({ startUsageReporting }) => startUsageReporting({ version: VERSION })).catch(() => {});
36
36
  const FORWARD_MIN_INTERVAL_MS = 5000;
37
37
  const FORWARD_MAX_PER_SESSION = 50;
package/src/index.mjs CHANGED
@@ -44,7 +44,7 @@ import { BACKGROUND_WORKER_GUIDANCE, registerBackgroundTools } from "./backgroun
44
44
 
45
45
  exitForVersionRequest(import.meta.url);
46
46
 
47
- const VERSION = "1.26.0";
47
+ const VERSION = "1.26.2";
48
48
  void import("./telemetry.mjs").then(({ startUsageReporting }) => startUsageReporting({ version: VERSION })).catch(() => {});
49
49
  const log = (msg) => process.stderr.write(`[codex-mcp-bridge] ${msg}\n`);
50
50
 
@@ -43,7 +43,7 @@ import { remoteCodexSocketPath, remoteNativeAdapter, remoteRequestResponse } fro
43
43
 
44
44
  exitForVersionRequest(import.meta.url);
45
45
 
46
- const VERSION = "1.26.0";
46
+ const VERSION = "1.26.2";
47
47
  const log = (msg) => process.stderr.write(`[native-relay] ${msg}\n`);
48
48
 
49
49
  function errorResponse(code, message, sent, details) {