clawdex-mobile 5.1.3-internal.8 → 5.2.0

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.
Files changed (48) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +6 -55
  3. package/bin/clawdex.js +2 -2
  4. package/docs/setup-and-operations.md +13 -99
  5. package/docs/troubleshooting.md +2 -70
  6. package/package.json +17 -6
  7. package/scripts/setup-secure-dev.sh +5 -79
  8. package/scripts/setup-wizard.sh +37 -87
  9. package/scripts/start-bridge-secure.js +13 -242
  10. package/services/cursor-app-server/README.md +39 -0
  11. package/services/cursor-app-server/dist/appServer.d.ts +52 -0
  12. package/services/cursor-app-server/dist/appServer.js +780 -0
  13. package/services/cursor-app-server/dist/appServer.js.map +1 -0
  14. package/services/cursor-app-server/dist/cursorWorkspace.d.ts +7 -0
  15. package/services/cursor-app-server/dist/cursorWorkspace.js +126 -0
  16. package/services/cursor-app-server/dist/cursorWorkspace.js.map +1 -0
  17. package/services/cursor-app-server/dist/index.d.ts +4 -0
  18. package/services/cursor-app-server/dist/index.js +4 -0
  19. package/services/cursor-app-server/dist/index.js.map +1 -0
  20. package/services/cursor-app-server/dist/input.d.ts +27 -0
  21. package/services/cursor-app-server/dist/input.js +143 -0
  22. package/services/cursor-app-server/dist/input.js.map +1 -0
  23. package/services/cursor-app-server/dist/jsonRpc.d.ts +15 -0
  24. package/services/cursor-app-server/dist/jsonRpc.js +93 -0
  25. package/services/cursor-app-server/dist/jsonRpc.js.map +1 -0
  26. package/services/cursor-app-server/dist/projection.d.ts +8 -0
  27. package/services/cursor-app-server/dist/projection.js +507 -0
  28. package/services/cursor-app-server/dist/projection.js.map +1 -0
  29. package/services/cursor-app-server/dist/sdkDriver.d.ts +50 -0
  30. package/services/cursor-app-server/dist/sdkDriver.js +166 -0
  31. package/services/cursor-app-server/dist/sdkDriver.js.map +1 -0
  32. package/services/cursor-app-server/dist/stdio.d.ts +2 -0
  33. package/services/cursor-app-server/dist/stdio.js +7 -0
  34. package/services/cursor-app-server/dist/stdio.js.map +1 -0
  35. package/services/cursor-app-server/dist/types.d.ts +218 -0
  36. package/services/cursor-app-server/dist/types.js +2 -0
  37. package/services/cursor-app-server/dist/types.js.map +1 -0
  38. package/services/cursor-app-server/package.json +43 -0
  39. package/services/rust-bridge/Cargo.lock +1 -1
  40. package/services/rust-bridge/Cargo.toml +1 -1
  41. package/services/rust-bridge/src/main.rs +1007 -390
  42. package/vendor/bridge-binaries/darwin-arm64/codex-rust-bridge +0 -0
  43. package/vendor/bridge-binaries/darwin-x64/codex-rust-bridge +0 -0
  44. package/vendor/bridge-binaries/linux-arm64/codex-rust-bridge +0 -0
  45. package/vendor/bridge-binaries/linux-armv7l/codex-rust-bridge +0 -0
  46. package/vendor/bridge-binaries/linux-x64/codex-rust-bridge +0 -0
  47. package/vendor/bridge-binaries/win32-x64/codex-rust-bridge.exe +0 -0
  48. package/scripts/codespaces-bootstrap.js +0 -297
package/CHANGELOG.md CHANGED
@@ -2,6 +2,21 @@
2
2
 
3
3
  All notable changes to this project are documented in this file.
4
4
 
5
+ ## 5.2.0 - 2026-05-18
6
+
7
+ ### Added
8
+ - Cursor support alongside Codex and OpenCode.
9
+ - Bundled `cursor-app-server` in the published `clawdex-mobile` package.
10
+ - Bridge-driven mobile UI payload support for richer runtime details.
11
+
12
+ ### Improved
13
+ - `clawdex init` now gives clearer Cursor API key setup guidance.
14
+ - Published-package setup now avoids source-checkout workspace assumptions.
15
+ - Bridge onboarding waits longer for first-start readiness.
16
+
17
+ ### Fixed
18
+ - Cursor setup now fails visibly when the API key or app-server path is missing instead of falling through silently.
19
+
5
20
  ## 5.1.2 - 2026-04-07
6
21
 
7
22
  ### Added
package/README.md CHANGED
@@ -4,9 +4,9 @@
4
4
  <img src="https://raw.githubusercontent.com/Mohit-Patil/clawdex-mobile/main/screenshots/social/clawdex-social-poster-1200x675.png" alt="Clawdex social banner" width="100%" />
5
5
  </p>
6
6
 
7
- Run Codex or OpenCode from your phone. `clawdex-mobile` ships the bridge CLI plus bundled Rust bridge binaries for supported hosts, and the mobile app pairs to that bridge over Tailscale, local LAN, or GitHub Codespaces forwarded HTTPS URLs.
7
+ Run Codex or OpenCode from your phone. `clawdex-mobile` ships the bridge CLI plus bundled Rust bridge binaries for supported hosts, and the mobile app pairs to that bridge over Tailscale or local LAN.
8
8
 
9
- This project is for trusted/private networking by default. GitHub Codespaces is supported as an internet-reachable exception: keep bridge auth enabled, use only repos you trust, and remember forwarded public ports reset to private when a codespace restarts.
9
+ This project is for trusted/private networking by default. Keep the bridge on a private network, leave bridge auth enabled, and do not expose it directly to the public internet.
10
10
 
11
11
  ## What You Get
12
12
 
@@ -25,11 +25,11 @@ Before you start:
25
25
  - `git`
26
26
  - `codex` in `PATH` for the default Codex flow
27
27
  - `opencode` in `PATH` if you want the OpenCode flow
28
- - `cursor-app-server` in `PATH` if you want the Cursor SDK flow
28
+ - Cursor app-server is bundled with `clawdex-mobile` for the Cursor SDK flow
29
29
 
30
30
  Install the mobile app:
31
31
 
32
- - Android APK: <https://github.com/Mohit-Patil/clawdex-mobile/releases/latest>
32
+ - Android APK: <https://www.getclawdex.com/android-beta/>
33
33
  - iOS: <https://apple.co/4rNAHRF>
34
34
 
35
35
  Install the CLI and start the bridge:
@@ -53,72 +53,23 @@ clawdex init
53
53
  clawdex stop
54
54
  ```
55
55
 
56
- ## GitHub Codespaces
57
-
58
- You can run the bridge inside a GitHub Codespace instead of keeping a laptop or server online.
59
-
60
- From a repo checkout inside Codespaces:
61
-
62
- ```bash
63
- npm run setup:wizard
64
- ```
65
-
66
- Pick `GitHub Codespaces` as the network mode. The setup flow writes forwarded HTTPS bridge URLs into `.env.secure`, and bridge startup will try to mark both bridge ports public automatically.
67
-
68
- Notes:
69
-
70
- - The mobile app should pair to the printed `https://<codespace>-8787.app.github.dev` URL, not `127.0.0.1`.
71
- - Browser preview uses a second forwarded port (`8788` by default), so both ports need public visibility.
72
- - GitHub resets public forwarded ports back to private when a codespace restarts. Restarting the bridge reruns the visibility step.
73
- - If automatic visibility setup fails, run `gh codespace ports visibility 8787:public 8788:public`.
74
- - If the mobile app is built with `EXPO_PUBLIC_GITHUB_APP_CLIENT_ID` and `EXPO_PUBLIC_GITHUB_APP_AUTH_BASE_URL`, users can now tap `Use GitHub Codespaces` in onboarding/settings, complete one in-app GitHub sign-in, pick a Codespace, and connect without manually copying the bridge token.
75
- - The tiny auth backend for that flow lives in `services/github-app-auth-worker`. Point the GitHub App callback URL at `https://<your-domain>/github/callback` and configure the worker with the GitHub App client ID/secret.
76
- - The app can also create a new repo-backed Codespace directly. It prefers `<signed-in-user>/<EXPO_PUBLIC_GITHUB_CODESPACES_REPO_NAME>` first. If that repo does not exist, it automatically forks `EXPO_PUBLIC_GITHUB_CODESPACES_SOURCE_OWNER/<EXPO_PUBLIC_GITHUB_CODESPACES_REPO_NAME>` into the signed-in user account, then creates the Codespace there.
77
-
78
- This repo now also includes a Codespaces bootstrap flow. On Codespace start/resume, `.devcontainer/devcontainer.json` runs:
79
-
80
- ```bash
81
- npm run codespaces:bootstrap
82
- ```
83
-
84
- During initial Codespace creation, the devcontainer also runs:
85
-
86
- ```bash
87
- npm run codespaces:bootstrap -- --prepare-only
88
- ```
89
-
90
- That pre-installs the selected engines and prebuilds the Rust bridge binary so the later startup path is faster. The normal bootstrap command rewrites `.env.secure` for Codespaces with `codex` as the default enabled engine and starts the bridge in the background. You can rerun either command manually any time.
91
-
92
- To enable more engines in Codespaces, set `CLAWDEX_CODESPACES_ENGINES` before bootstrap:
93
-
94
- ```bash
95
- CLAWDEX_CODESPACES_ENGINES=codex,opencode,cursor npm run codespaces:bootstrap
96
- ```
97
-
98
- When `opencode` or `cursor` are selected, bootstrap installs their CLI/server package if the command is missing. Cursor still needs `CURSOR_API_KEY` in the environment or `.env.secure`.
99
-
100
- The published npm package now includes that bootstrap script too, so a minimal Codespaces template repo can install `clawdex-mobile@latest` in `postCreateCommand` and call the packaged bootstrap without vendoring bridge source into the template itself.
101
-
102
- In Codespaces mode, the bootstrap also enables bridge-side GitHub bearer auth for the current `CODESPACE_NAME`, so the mobile app can authenticate with the same GitHub App user token it used to discover and start the Codespace.
103
-
104
56
  ## Extra Harness Setup
105
57
 
106
58
  OpenCode and Cursor can run beside Codex from the same bridge.
107
59
 
108
60
  ```bash
109
61
  npm install -g opencode-ai
110
- npm install -g @clawdex/cursor-app-server
111
62
  npm install -g clawdex-mobile@latest
112
63
  clawdex init --engines codex,opencode,cursor
113
64
  ```
114
65
 
115
- That writes `BRIDGE_ENABLED_ENGINES=codex,opencode,cursor` to `.env.secure`, so the mobile app can control the selected harnesses from one bridge. When Cursor is selected, `clawdex init` asks for the Cursor API key and saves it in `.env.secure`.
66
+ That writes `BRIDGE_ENABLED_ENGINES=codex,opencode,cursor` to `.env.secure`, so the mobile app can control the selected harnesses from one bridge. When Cursor is selected, `clawdex init` uses the bundled `cursor-app-server`, asks for a Cursor account API key from Cursor Dashboard > Integrations > User API Keys, and saves it in `.env.secure`. Cursor documents this under CLI authentication: https://docs.cursor.com/en/cli/reference/authentication
116
67
 
117
68
  Notes:
118
69
 
119
70
  - `clawdex init` without flags now lets you multi-select harnesses in the wizard with Space, then Enter to continue.
120
71
  - Use `clawdex init --engine codex`, `clawdex init --engine opencode`, or `clawdex init --engine cursor` if you want a single-harness setup.
121
- - For non-interactive host automation, set `CURSOR_API_KEY` before running setup. `CURSOR_MODEL` is optional; the app model picker sends the model for normal chats.
72
+ - For non-interactive host automation, set `CURSOR_API_KEY` before running setup. This should be a Cursor account API key for the Cursor agent/SDK, not an OpenAI, Anthropic, or other provider key configured inside the Cursor editor. `CURSOR_MODEL` is optional; the app model picker sends the model for normal chats.
122
73
 
123
74
  ## Monorepo Development
124
75
 
package/bin/clawdex.js CHANGED
@@ -10,11 +10,11 @@ function printUsage() {
10
10
  console.log(`Usage: clawdex <command> [options]
11
11
 
12
12
  Commands:
13
- init [--no-start] [--engine codex|opencode]
13
+ init [--no-start] [--engine codex|opencode|cursor] [--engines codex,opencode,cursor]
14
14
  Run interactive bridge onboarding and secure setup.
15
15
  By default, this also starts the secure bridge in the background.
16
16
  Use --no-start to configure only.
17
- Use --engine to set the preferred backend written to .env.secure.
17
+ Use --engine or --engines to choose the backend harnesses written to .env.secure.
18
18
 
19
19
  stop
20
20
  Stop bridge services for this project.
@@ -2,6 +2,8 @@
2
2
 
3
3
  This guide is the detailed companion to the top-level `README.md`.
4
4
 
5
+ For bridge-driven provider UI payloads such as Codex goals, see `docs/bridge-ui-surfaces.md`.
6
+
5
7
  ## Choosing Harnesses
6
8
 
7
9
  The setup wizard now lets you choose which harnesses the phone should control.
@@ -18,7 +20,7 @@ From a source checkout, the equivalent command is:
18
20
  npm run setup:wizard -- --engines codex,opencode,cursor
19
21
  ```
20
22
 
21
- That writes `BRIDGE_ENABLED_ENGINES=codex,opencode,cursor` into `.env.secure`, so the bridge starts the selected backends and the mobile app can control them from one UI. When Cursor is selected, `clawdex init` asks for the Cursor API key and saves it in `.env.secure`.
23
+ That writes `BRIDGE_ENABLED_ENGINES=codex,opencode,cursor` into `.env.secure`, so the bridge starts the selected backends and the mobile app can control them from one UI. When Cursor is selected, `clawdex init` uses the bundled `cursor-app-server`, asks for a Cursor account API key from Cursor Dashboard > Integrations > User API Keys, and saves it in `.env.secure`. Cursor documents this under CLI authentication: https://docs.cursor.com/en/cli/reference/authentication
22
24
 
23
25
  If you want only one harness, use `--engine codex`, `--engine opencode`, or `--engine cursor`.
24
26
 
@@ -39,87 +41,6 @@ Published npm releases bundle prebuilt bridge binaries for `darwin-arm64`, `darw
39
41
 
40
42
  Published CLI installs are bridge-only. They do not include the Expo workspace or mobile app source files.
41
43
 
42
- ## GitHub Codespaces Setup
43
-
44
- Codespaces can replace a user-managed always-on machine for development and lightweight remote use.
45
-
46
- From a repo checkout inside an active codespace:
47
-
48
- ```bash
49
- npm run setup:wizard
50
- ```
51
-
52
- Choose `GitHub Codespaces` for the bridge network mode.
53
-
54
- What that does:
55
-
56
- - binds the bridge locally inside the codespace
57
- - writes `BRIDGE_CONNECT_URL` and `BRIDGE_PREVIEW_CONNECT_URL` using the codespace forwarded HTTPS domain
58
- - enables bridge-side GitHub bearer auth for the current codespace
59
- - starts the bridge normally
60
- - attempts to mark the bridge port and browser-preview port public on each startup
61
-
62
- Important constraints:
63
-
64
- - Pair the mobile app to the printed `https://<codespace>-8787.app.github.dev` URL, not `127.0.0.1`
65
- - Browser preview uses the preview port (`8788` by default), so that forwarded port must also be public
66
- - GitHub resets public forwarded ports back to private whenever the codespace restarts
67
- - Keep bridge auth enabled and use Codespaces only for repos you trust, because public forwarded ports are internet-reachable
68
- - If the mobile app build sets `EXPO_PUBLIC_GITHUB_APP_CLIENT_ID` and `EXPO_PUBLIC_GITHUB_APP_AUTH_BASE_URL`, onboarding/settings can now open one GitHub sign-in, start the Codespace, and connect directly with the same GitHub App user token instead of copying `BRIDGE_AUTH_TOKEN`
69
- - Users do not need to grant the GitHub App repository installation access to the `clawdex-codespace` template for the normal Codespaces flow
70
- - The same in-app GitHub flow can create a new Codespace. It prefers `<signed-in-user>/<EXPO_PUBLIC_GITHUB_CODESPACES_REPO_NAME>`. If that repo does not exist yet, Clawdex automatically forks `EXPO_PUBLIC_GITHUB_CODESPACES_SOURCE_OWNER/<EXPO_PUBLIC_GITHUB_CODESPACES_REPO_NAME>` into the signed-in user account and creates the Codespace from that fork
71
- - Older saved GitHub Codespaces sessions may need one fresh sign-in from the app so the stored GitHub App token and refresh token are updated
72
-
73
- For the one-flow GitHub App setup:
74
-
75
- - deploy the tiny auth service under `services/github-app-auth-worker`
76
- - set the GitHub App `Callback URL` to `https://<your-domain>/github/callback`
77
- - set the mobile env `EXPO_PUBLIC_GITHUB_APP_AUTH_BASE_URL=https://<your-domain>`
78
-
79
- Manual recovery if port visibility does not update automatically:
80
-
81
- ```bash
82
- gh codespace ports visibility 8787:public 8788:public
83
- ```
84
-
85
- ### Codespaces Bootstrap
86
-
87
- The repo devcontainer now includes:
88
-
89
- - `postCreateCommand`: `npm install --include=dev && npm run codespaces:bootstrap -- --prepare-only`
90
- - `postStartCommand`: `npm run codespaces:bootstrap`
91
-
92
- `npm run codespaces:bootstrap` does the following:
93
-
94
- - installs the Codex CLI via `npm install -g @openai/codex` if it is missing
95
- - in `--prepare-only` mode, prebuilds the Rust bridge binary without starting it
96
- - rewrites `.env.secure` for `BRIDGE_NETWORK_MODE=codespaces`, `BRIDGE_GITHUB_CODESPACES_AUTH=true`, and the selected engine list
97
- - writes `CODEX_HOME=$HOME/.codex` in Codespaces so Codex-managed ChatGPT auth survives bridge restarts and Codespace wakes
98
- - starts the bridge in the background unless you set `CLAWDEX_CODESPACES_SKIP_START=true` or pass `--no-start`
99
-
100
- Clawdex-created Codespaces request a 45-minute idle timeout. The bridge emits a lightweight active-turn keepalive while a Codex, OpenCode, or Cursor turn is running, so active work has activity even if a long step is otherwise quiet. When no turn is running, the keepalive stops and GitHub can pause the Codespace normally to save cost.
101
-
102
- That means the first Codespace create now front-loads the expensive bridge compile during `postCreateCommand`, so the later `postStartCommand` can usually start the bridge much faster.
103
-
104
- The same bootstrap script is included in the published `clawdex-mobile` npm package. That lets the `clawdex-codespace` template stay minimal: it can install `clawdex-mobile@latest` globally in the devcontainer and invoke the packaged bootstrap against the current workspace instead of copying `scripts/*` and `services/rust-bridge/*` into the template repo.
105
-
106
- Manual examples:
107
-
108
- ```bash
109
- npm run codespaces:bootstrap -- --prepare-only
110
- npm run codespaces:bootstrap
111
- npm run codespaces:bootstrap -- --no-start
112
- CLAWDEX_CODESPACES_ENGINES=codex,opencode,cursor npm run codespaces:bootstrap
113
- ```
114
-
115
- Minimal template equivalent:
116
-
117
- ```bash
118
- npm install -g clawdex-mobile@latest @openai/codex
119
- CLAWDEX_WORKSPACE_ROOT="$PWD" node "$(npm root -g)/clawdex-mobile/scripts/codespaces-bootstrap.js" --prepare-only
120
- CLAWDEX_WORKSPACE_ROOT="$PWD" node "$(npm root -g)/clawdex-mobile/scripts/codespaces-bootstrap.js"
121
- ```
122
-
123
44
  ## Manual Secure Setup (No Wizard)
124
45
 
125
46
  ### 1) Install dependencies
@@ -161,7 +82,7 @@ When multiple harnesses are selected, the bridge starts each backend and merges
161
82
 
162
83
  ### 4) Pair from the mobile app
163
84
 
164
- Open the installed mobile app on your phone, then scan the bridge QR. If needed, enter the bridge URL manually (for example `http://100.x.y.z:8787`, `http://192.168.x.y:8787`, or `https://<codespace>-8787.app.github.dev`). The chosen bridge URL is stored on-device and can be changed later in Settings.
85
+ Open the installed mobile app on your phone, then scan the bridge QR. If needed, enter the bridge URL manually (for example `http://100.x.y.z:8787` or `http://192.168.x.y:8787`). The chosen bridge URL is stored on-device and can be changed later in Settings.
165
86
 
166
87
  ### In-app Bridge Maintenance
167
88
 
@@ -268,7 +189,7 @@ npm run teardown -- --yes
268
189
 
269
190
  | Variable | Purpose |
270
191
  |---|---|
271
- | `BRIDGE_NETWORK_MODE` | bridge connectivity mode (`tailscale`, `local`, or `codespaces`) |
192
+ | `BRIDGE_NETWORK_MODE` | bridge connectivity mode (`tailscale` or `local`) |
272
193
  | `BRIDGE_HOST` | bind host for rust bridge |
273
194
  | `BRIDGE_PORT` | bridge port (default `8787`) |
274
195
  | `BRIDGE_PREVIEW_PORT` | browser preview port for proxied localhost web apps (default `BRIDGE_PORT + 1`) |
@@ -276,16 +197,12 @@ npm run teardown -- --yes
276
197
  | `BRIDGE_PREVIEW_CONNECT_URL` | externally reachable browser preview base URL |
277
198
  | `BRIDGE_AUTH_TOKEN` | required auth token |
278
199
  | `BRIDGE_ALLOW_QUERY_TOKEN_AUTH` | query-token auth fallback |
279
- | `BRIDGE_GITHUB_CODESPACES_AUTH` | accept GitHub bearer tokens for the current codespace |
280
- | `BRIDGE_GITHUB_CODESPACE_NAME` | codespace name used when validating GitHub bearer tokens |
281
- | `BRIDGE_GITHUB_API_URL` | GitHub REST API base URL for Codespaces auth checks |
282
- | `CODEX_HOME` | Codex auth/config home; set to `$HOME/.codex` in Codespaces so ChatGPT auth persists across bridge restarts |
283
200
  | `CODEX_CLI_BIN` | codex executable |
284
201
  | `BRIDGE_ACTIVE_ENGINE` | internal preferred routing backend used when multiple harnesses are enabled |
285
202
  | `BRIDGE_ENABLED_ENGINES` | selected harnesses to expose (`codex`, `opencode`, `cursor`, or a comma-separated mix) |
286
203
  | `OPENCODE_CLI_BIN` | opencode executable for dual-engine startup |
287
- | `CURSOR_APP_SERVER_BIN` | Cursor app-server executable, usually `cursor-app-server` |
288
- | `CURSOR_API_KEY` | Cursor API key used by the Cursor SDK harness; collected by `clawdex init` when Cursor is selected |
204
+ | `CURSOR_APP_SERVER_BIN` | Cursor app-server executable, usually the `cursor-app-server` binary bundled with `clawdex-mobile` |
205
+ | `CURSOR_API_KEY` | Cursor account API key used by the Cursor SDK harness; create it from Cursor Dashboard > Integrations > User API Keys, then provide it to `clawdex init` when Cursor is selected. See https://docs.cursor.com/en/cli/reference/authentication |
289
206
  | `CURSOR_MODEL` | optional Cursor model id for non-interactive host defaults; normal mobile chats send the selected model |
290
207
  | `BRIDGE_OPENCODE_HOST` | loopback host for spawned opencode server |
291
208
  | `BRIDGE_OPENCODE_PORT` | loopback port for spawned opencode server |
@@ -299,13 +216,6 @@ npm run teardown -- --yes
299
216
  | Variable | Purpose |
300
217
  |---|---|
301
218
  | `EXPO_PUBLIC_HOST_BRIDGE_TOKEN` | token used by local mobile dev builds |
302
- | `EXPO_PUBLIC_GITHUB_APP_CLIENT_ID` | GitHub App client ID for in-app Codespaces sign-in |
303
- | `EXPO_PUBLIC_GITHUB_APP_SLUG` | optional GitHub App slug, reserved for future manage-access flows |
304
- | `EXPO_PUBLIC_GITHUB_APP_AUTH_BASE_URL` | HTTPS origin for the GitHub App auth worker (`/api/github/exchange`, `/api/github/refresh`, `/github/callback`) |
305
- | `EXPO_PUBLIC_GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN` | forwarded port domain used to derive Codespaces bridge URLs (`app.github.dev` by default) |
306
- | `EXPO_PUBLIC_GITHUB_CODESPACES_REPO_NAME` | repository name to sort matching Codespaces first in the in-app picker |
307
- | `EXPO_PUBLIC_GITHUB_CODESPACES_SOURCE_OWNER` | template/source repository owner used for automatic forking when the signed-in user does not have a same-name repo |
308
- | `EXPO_PUBLIC_GITHUB_CODESPACES_REPO_REF` | optional git ref/branch used when creating a new Codespace |
309
219
  | `EXPO_PUBLIC_ALLOW_QUERY_TOKEN_AUTH` | query-token behavior for WebSocket auth fallback |
310
220
  | `EXPO_PUBLIC_ALLOW_INSECURE_REMOTE_BRIDGE` | suppress insecure-HTTP warning |
311
221
  | `EXPO_PUBLIC_PRIVACY_POLICY_URL` | in-app Privacy link |
@@ -326,8 +236,7 @@ If you enable the optional tip jar:
326
236
  ## Production Readiness Checklist
327
237
 
328
238
  - Keep bridge network-private only by default (Tailscale/private LAN/VPN + host firewall)
329
- - If using GitHub Codespaces, remember the bridge is internet-reachable whenever its forwarded ports are public
330
- - Require bridge auth of some kind (`BRIDGE_AUTH_TOKEN` or GitHub Codespaces auth)
239
+ - Require bridge auth with `BRIDGE_AUTH_TOKEN`
331
240
  - Keep `BRIDGE_ALLOW_QUERY_TOKEN_AUTH=true` only on private networks (required for Android WS auth fallback)
332
241
  - Do not set `BRIDGE_ALLOW_INSECURE_NO_AUTH=true` outside local debugging
333
242
  - Scope `BRIDGE_WORKDIR` to minimal required root
@@ -454,12 +363,17 @@ Automation verifies tag/version consistency and publishes to npm.
454
363
  - `bridge/approvals/list`
455
364
  - `bridge/approvals/resolve`
456
365
  - `bridge/userInput/resolve`
366
+ - `bridge/ui/present`
367
+ - `bridge/ui/update`
368
+ - `bridge/ui/dismiss`
369
+ - `bridge/ui/resolve`
457
370
 
458
371
  ### Notifications (examples)
459
372
 
460
373
  - `turn/*`, `item/*`
461
374
  - `bridge/approval.*`
462
375
  - `bridge/userInput.*`
376
+ - `bridge/ui.*`
463
377
  - `bridge/terminal/completed`
464
378
  - `bridge/git/updated`
465
379
  - `bridge/connection/state`
@@ -34,93 +34,26 @@ npm run stop:services
34
34
  ## Bridge auth errors (`401`, invalid token)
35
35
 
36
36
  - For the shipped mobile app, rescan the bridge QR or update the stored token in Settings.
37
- - For GitHub-auth Codespaces profiles, reopen `GitHub Codespaces` in the app and sign in with GitHub again if the GitHub App token or refresh token was revoked or expired.
38
37
  - For a local dev build, also ensure `BRIDGE_AUTH_TOKEN` in `.env.secure` matches `EXPO_PUBLIC_HOST_BRIDGE_TOKEN` in `apps/mobile/.env`.
39
38
  - Restart the bridge after token changes.
40
39
  - On secure-launcher installs, `Settings > Bridge Maintenance > Restart bridge safely` can do that from the phone.
41
40
  - If an in-app bridge update fails, inspect `.bridge-updater.log` and `.bridge-update-status.json` in the bridge install root.
42
41
 
43
- ## GitHub Codespaces bridge URL does not connect
44
-
45
- - Pair to the printed forwarded HTTPS URL such as `https://<codespace>-8787.app.github.dev`, not `127.0.0.1`.
46
- - Public forwarded ports reset back to private when the codespace restarts.
47
- - Restart the bridge or rerun `npm run codespaces:bootstrap` to rerun the automatic visibility step.
48
- - If needed, set both ports public manually:
49
-
50
- ```bash
51
- gh codespace ports visibility 8787:public 8788:public
52
- ```
53
-
54
- - If `gh` is unavailable in the codespace, use the Codespaces `Ports` panel and change both forwarded ports to `Public`.
55
- - Keep bridge auth enabled. Public forwarded ports without bridge auth are not a safe setup.
56
- - If GitHub direct sign-in is not showing in the app, confirm the build includes `EXPO_PUBLIC_GITHUB_APP_CLIENT_ID`, `EXPO_PUBLIC_GITHUB_APP_SLUG`, and `EXPO_PUBLIC_GITHUB_APP_AUTH_BASE_URL`.
57
- - If the GitHub browser sheet returns but sign-in still fails, confirm the GitHub App callback URL is `https://<your-domain>/github/callback` and that `Request user authorization (OAuth) during installation` is enabled.
58
- - If the app signs in but still cannot create a Codespace or clone/push inside it, reopen the GitHub App access step in the app and make sure the template repo and any target repos are selected for the installation.
59
- - If in-app Codespace creation forks or targets the wrong repo, check `EXPO_PUBLIC_GITHUB_CODESPACES_REPO_NAME`, `EXPO_PUBLIC_GITHUB_CODESPACES_SOURCE_OWNER`, and `EXPO_PUBLIC_GITHUB_CODESPACES_REPO_REF` in the mobile build env.
60
-
61
- ## GitHub Codespaces bootstrap did not start the bridge
62
-
63
- - Check the post-start command output in the Codespace terminal or rerun it manually:
64
-
65
- ```bash
66
- npm run codespaces:bootstrap -- --prepare-only
67
- npm run codespaces:bootstrap
68
- ```
69
-
70
- - On the minimal `clawdex-codespace` template, rerun the packaged bootstrap instead:
71
-
72
- ```bash
73
- CLAWDEX_WORKSPACE_ROOT="$PWD" node "$(npm root -g)/clawdex-mobile/scripts/codespaces-bootstrap.js" --prepare-only
74
- CLAWDEX_WORKSPACE_ROOT="$PWD" node "$(npm root -g)/clawdex-mobile/scripts/codespaces-bootstrap.js"
75
- ```
76
-
77
- - The Codespaces bootstrap only prepares the `codex` engine. It will try to install Codex automatically with `npm install -g @openai/codex`.
78
- - `--prepare-only` installs Codex if needed and prebuilds the Rust bridge binary without starting the bridge.
79
- - The bootstrap also enables `BRIDGE_GITHUB_CODESPACES_AUTH=true` so GitHub bearer tokens can connect directly to the bridge.
80
- - If that install fails, fix npm/global package permissions in the codespace and rerun the bootstrap.
81
- - Bridge startup logs and runtime state live in the Codespace repo root:
82
-
83
- ```bash
84
- tail -n 200 .bridge.log
85
- ls -la .bridge.pid .bridge.log .env.secure
86
- ```
87
-
88
- - To only rewrite `.env.secure` without starting the bridge:
89
-
90
- ```bash
91
- npm run codespaces:bootstrap -- --no-start
92
- ```
93
-
94
- ## Git push in a Codespace fails with `403` or permission denied
95
-
96
- - The app now bootstraps GitHub HTTPS git credentials inside the Codespace after GitHub sign-in.
97
- - If you signed in before this behavior shipped, reopen `GitHub Codespaces` in the app and sign in with GitHub once more so the saved token includes repository access.
98
- - The bootstrap also rewrites common `git@github.com:...` and `ssh://git@github.com/...` remotes to HTTPS so they can use the same credential.
99
- - After reconnecting, retry the clone/push from the app or from the Codespace shell.
100
-
101
42
  ## Voice transcription says no credentials were found
102
43
 
103
44
  - The bridge can transcribe with `OPENAI_API_KEY`, `BRIDGE_CHATGPT_ACCESS_TOKEN`, a legacy bridge token cache, or the Codex-managed ChatGPT token in `$CODEX_HOME/auth.json`.
104
- - In GitHub Codespaces, finish the Codex login step from the app first. Codex writes the login to `$HOME/.codex/auth.json`, and `.env.secure` sets `CODEX_HOME` to that persistent location.
105
- - Current app builds automatically restart the Codespace Codex app-server after the Codex login step so it reloads the Codex auth home. On older builds, restart the bridge once after logging in:
45
+ - If Codex login just completed, restart the bridge once so it reloads the Codex auth home:
106
46
 
107
47
  ```bash
108
48
  npm run secure:bridge
109
49
  ```
110
50
 
111
- - You can inspect whether Codex saved auth in the Codespace:
51
+ - You can inspect whether Codex saved auth:
112
52
 
113
53
  ```bash
114
54
  ls -la "${CODEX_HOME:-$HOME/.codex}/auth.json"
115
55
  ```
116
56
 
117
- ## Codespace wakes but Codex says account authentication is required
118
-
119
- - Codespaces should use Codex-managed auth, the same as a local bridge. The login is stored in `${CODEX_HOME:-$HOME/.codex}/auth.json`.
120
- - The app starts Codex's normal ChatGPT web login first. It captures the OAuth callback on the phone and forwards that callback to the Codex loopback server inside the Codespace, so device-code login is only a fallback.
121
- - Run `source .env.secure && ls -la "$CODEX_HOME/auth.json"` in the Codespace to confirm the auth file exists.
122
- - If the file is missing, reopen GitHub Codespaces setup in the app and complete the Codex login step once. After that, bridge restarts and Codespace wakes should not require reauthentication.
123
-
124
57
  ## Local browser preview does not open
125
58
 
126
59
  - The in-app browser only supports loopback targets from the bridge host: `localhost`, `127.0.0.1`, or `::1`.
@@ -131,7 +64,6 @@ ls -la "${CODEX_HOME:-$HOME/.codex}/auth.json"
131
64
  - By default the preview server binds to `BRIDGE_PORT + 1`.
132
65
  - Restart the bridge after changing `BRIDGE_PREVIEW_PORT`.
133
66
  - If the page shell loads but live reload does not, verify the target dev server is still serving its WebSocket/HMR endpoint locally.
134
- - In GitHub Codespaces, the preview port (`8788` by default) must also be public or the Browser screen will fail even if the main bridge port works.
135
67
 
136
68
  ## Tailscale issues
137
69
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "clawdex-mobile",
3
- "version": "5.1.3-internal.8",
4
- "description": "Private-network mobile bridge and CLI for Codex and OpenCode",
3
+ "version": "5.2.0",
4
+ "description": "Private-network mobile bridge and CLI for Codex, OpenCode, and Cursor",
5
5
  "keywords": [
6
6
  "codex",
7
7
  "opencode",
@@ -20,10 +20,13 @@
20
20
  "access": "public"
21
21
  },
22
22
  "dependencies": {
23
- "qrcode-terminal": "^0.12.0"
23
+ "@cursor/sdk": "1.0.11",
24
+ "qrcode-terminal": "^0.12.0",
25
+ "zod": "^3.25.0"
24
26
  },
25
27
  "bin": {
26
- "clawdex": "./bin/clawdex.js"
28
+ "clawdex": "bin/clawdex.js",
29
+ "cursor-app-server": "services/cursor-app-server/dist/stdio.js"
27
30
  },
28
31
  "files": [
29
32
  "CHANGELOG.md",
@@ -34,11 +37,13 @@
34
37
  "docs/troubleshooting.md",
35
38
  "scripts/bridge-binary.js",
36
39
  "scripts/bridge-self-update.js",
37
- "scripts/codespaces-bootstrap.js",
38
40
  "scripts/setup-secure-dev.sh",
39
41
  "scripts/setup-wizard.sh",
40
42
  "scripts/start-bridge-secure.js",
41
43
  "scripts/stop-services.sh",
44
+ "services/cursor-app-server/dist",
45
+ "services/cursor-app-server/README.md",
46
+ "services/cursor-app-server/package.json",
42
47
  "services/rust-bridge/Cargo.lock",
43
48
  "services/rust-bridge/Cargo.toml",
44
49
  "services/rust-bridge/src",
@@ -52,18 +57,24 @@
52
57
  "mobile": "./scripts/start-expo.sh mobile",
53
58
  "ios": "./scripts/start-expo.sh ios",
54
59
  "android": "./scripts/start-expo.sh android",
60
+ "desktop:mac": "swift run --package-path apps/macos ClawdexDesktop",
61
+ "desktop:mac:build": "swift build --package-path apps/macos",
62
+ "desktop:mac:bundle": "./scripts/build-macos-desktop-app.sh",
63
+ "desktop:mac:sign": "./scripts/sign-macos-desktop-app.sh",
64
+ "desktop:mac:notarize": "./scripts/notarize-macos-desktop-app.sh",
55
65
  "stack:lan": "./scripts/start-mobile-stack-lan.sh",
56
66
  "stack:tailscale": "./scripts/start-mobile-stack-tailscale.sh",
57
67
  "bridge": "BRIDGE_WORKDIR=$(pwd) npm run -w @codex/rust-bridge dev",
68
+ "bridge:ui:demo": "node ./scripts/send-bridge-ui-demo.js",
58
69
  "bridge:package:stage-current": "node ./scripts/bridge-binary.js stage-current",
59
70
  "setup:wizard": "./scripts/setup-wizard.sh",
60
71
  "stop:services": "./scripts/stop-services.sh",
61
72
  "secure:setup": "./scripts/setup-secure-dev.sh",
62
73
  "secure:bridge": "node ./scripts/start-bridge-secure.js",
63
74
  "secure:bridge:dev": "node ./scripts/start-bridge-secure.js --dev",
64
- "codespaces:bootstrap": "node ./scripts/codespaces-bootstrap.js",
65
75
  "bridge:ts": "BRIDGE_WORKDIR=$(pwd) npm run -w @codex/mac-bridge dev",
66
76
  "version:sync": "node scripts/sync-versions.js",
77
+ "prepack": "npm run build -w @clawdex/cursor-app-server",
67
78
  "build": "npm run --workspaces build",
68
79
  "typecheck": "npm run --workspaces typecheck",
69
80
  "lint": "npm run --workspaces lint",
@@ -112,51 +112,6 @@ is_non_loopback_ipv4() {
112
112
  [[ "$ip" != 127.* ]]
113
113
  }
114
114
 
115
- normalize_base_url() {
116
- local value="$1"
117
- value="$(printf '%s' "$value" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
118
- if [[ -z "$value" ]]; then
119
- return 1
120
- fi
121
-
122
- case "$value" in
123
- http://*|https://*)
124
- ;;
125
- *)
126
- return 1
127
- ;;
128
- esac
129
-
130
- printf '%s' "${value%/}"
131
- }
132
-
133
- resolve_codespaces_forwarded_url() {
134
- local port="$1"
135
- local override="$2"
136
- local normalized_override=""
137
- local codespace_name=""
138
- local forwarding_domain=""
139
-
140
- if [[ -n "$override" ]]; then
141
- normalized_override="$(normalize_base_url "$override" || true)"
142
- if [[ -z "$normalized_override" ]]; then
143
- echo "error: invalid Codespaces URL override '$override'." >&2
144
- return 1
145
- fi
146
- printf '%s' "$normalized_override"
147
- return 0
148
- fi
149
-
150
- codespace_name="$(printf '%s' "${CODESPACE_NAME:-}" | tr -d '[:space:]')"
151
- forwarding_domain="$(printf '%s' "${GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN:-}" | tr -d '[:space:]')"
152
- if [[ -z "$codespace_name" ]] || [[ -z "$forwarding_domain" ]]; then
153
- echo "error: GitHub Codespaces env vars are missing. Run this inside an active codespace or set BRIDGE_CONNECT_URL_OVERRIDE." >&2
154
- return 1
155
- fi
156
-
157
- printf 'https://%s-%s.%s' "$codespace_name" "$port" "$forwarding_domain"
158
- }
159
-
160
115
  resolve_tailscale_ipv4() {
161
116
  local ip
162
117
  ip="$(tailscale ip -4 2>/dev/null | head -n1 | tr -d '[:space:]' || true)"
@@ -272,10 +227,10 @@ HOST_SOURCE=""
272
227
  BRIDGE_NETWORK_MODE="${BRIDGE_NETWORK_MODE:-tailscale}"
273
228
 
274
229
  case "$BRIDGE_NETWORK_MODE" in
275
- tailscale|local|codespaces)
230
+ tailscale|local)
276
231
  ;;
277
232
  *)
278
- echo "error: BRIDGE_NETWORK_MODE must be 'tailscale', 'local', or 'codespaces'." >&2
233
+ echo "error: BRIDGE_NETWORK_MODE must be 'tailscale' or 'local'." >&2
279
234
  exit 1
280
235
  ;;
281
236
  esac
@@ -345,9 +300,6 @@ else
345
300
  ensure_tailscale_cli
346
301
  BRIDGE_HOST="$(resolve_tailscale_ipv4)"
347
302
  HOST_SOURCE="tailscale"
348
- elif [[ "$BRIDGE_NETWORK_MODE" == "codespaces" ]]; then
349
- BRIDGE_HOST="127.0.0.1"
350
- HOST_SOURCE="codespaces"
351
303
  else
352
304
  BRIDGE_HOST="$(resolve_local_ipv4)"
353
305
  HOST_SOURCE="local"
@@ -361,17 +313,8 @@ if [[ "$BRIDGE_PREVIEW_PORT" == "$BRIDGE_PORT" ]]; then
361
313
  exit 1
362
314
  fi
363
315
 
364
- if [[ "$BRIDGE_NETWORK_MODE" == "codespaces" ]]; then
365
- BRIDGE_CONNECT_URL="$(
366
- resolve_codespaces_forwarded_url "$BRIDGE_PORT" "${BRIDGE_CONNECT_URL_OVERRIDE:-}"
367
- )"
368
- BRIDGE_PREVIEW_CONNECT_URL="$(
369
- resolve_codespaces_forwarded_url "$BRIDGE_PREVIEW_PORT" "${BRIDGE_PREVIEW_CONNECT_URL_OVERRIDE:-}"
370
- )"
371
- else
372
- BRIDGE_CONNECT_URL="http://$BRIDGE_HOST:$BRIDGE_PORT"
373
- BRIDGE_PREVIEW_CONNECT_URL="http://$BRIDGE_HOST:$BRIDGE_PREVIEW_PORT"
374
- fi
316
+ BRIDGE_CONNECT_URL="http://$BRIDGE_HOST:$BRIDGE_PORT"
317
+ BRIDGE_PREVIEW_CONNECT_URL="http://$BRIDGE_HOST:$BRIDGE_PREVIEW_PORT"
375
318
 
376
319
  EXISTING_TOKEN=""
377
320
  if [[ -f "$SECURE_ENV_FILE" ]]; then
@@ -383,17 +326,6 @@ if [[ -z "$BRIDGE_TOKEN" ]]; then
383
326
  BRIDGE_TOKEN="$(openssl rand -hex 24)"
384
327
  fi
385
328
 
386
- GITHUB_CODESPACES_AUTH_ENABLED="false"
387
- GITHUB_CODESPACES_NAME=""
388
- CODEX_HOME_ENV_BLOCK=""
389
- if [[ "$BRIDGE_NETWORK_MODE" == "codespaces" ]]; then
390
- GITHUB_CODESPACES_AUTH_ENABLED="true"
391
- GITHUB_CODESPACES_NAME="$(printf '%s' "${CODESPACE_NAME:-}" | tr -d '[:space:]')"
392
- CODEX_AUTH_HOME="${CODEX_HOME:-$HOME/.codex}"
393
- mkdir -p "$CODEX_AUTH_HOME"
394
- CODEX_HOME_ENV_BLOCK="CODEX_HOME=$CODEX_AUTH_HOME"
395
- fi
396
-
397
329
  cat > "$SECURE_ENV_FILE" <<EOT
398
330
  BRIDGE_NETWORK_MODE=$BRIDGE_NETWORK_MODE
399
331
  BRIDGE_HOST=$BRIDGE_HOST
@@ -403,12 +335,8 @@ BRIDGE_CONNECT_URL=$BRIDGE_CONNECT_URL
403
335
  BRIDGE_PREVIEW_CONNECT_URL=$BRIDGE_PREVIEW_CONNECT_URL
404
336
  BRIDGE_AUTH_TOKEN=$BRIDGE_TOKEN
405
337
  BRIDGE_ALLOW_QUERY_TOKEN_AUTH=true
406
- BRIDGE_GITHUB_CODESPACES_AUTH=$GITHUB_CODESPACES_AUTH_ENABLED
407
- BRIDGE_GITHUB_CODESPACE_NAME=$GITHUB_CODESPACES_NAME
408
- BRIDGE_GITHUB_API_URL=https://api.github.com
409
338
  BRIDGE_ACTIVE_ENGINE=$BRIDGE_ACTIVE_ENGINE
410
339
  BRIDGE_ENABLED_ENGINES=$BRIDGE_ENABLED_ENGINES
411
- $CODEX_HOME_ENV_BLOCK
412
340
  CODEX_CLI_BIN=codex
413
341
  OPENCODE_CLI_BIN=$OPENCODE_CLI_BIN
414
342
  CURSOR_APP_SERVER_BIN=$CURSOR_APP_SERVER_BIN
@@ -425,6 +353,7 @@ if has_local_mobile_workspace; then
425
353
  upsert_env_key "$MOBILE_ENV_FILE" "EXPO_PUBLIC_MAC_BRIDGE_TOKEN" "$BRIDGE_TOKEN"
426
354
  upsert_env_key "$MOBILE_ENV_FILE" "EXPO_PUBLIC_ALLOW_QUERY_TOKEN_AUTH" "true"
427
355
  upsert_env_key "$MOBILE_ENV_FILE" "EXPO_PUBLIC_ALLOW_INSECURE_REMOTE_BRIDGE" "true"
356
+ chmod 600 "$MOBILE_ENV_FILE"
428
357
  fi
429
358
 
430
359
  echo "Secure dev setup complete."
@@ -433,9 +362,6 @@ echo "Bridge network mode: $BRIDGE_NETWORK_MODE"
433
362
  echo "Bridge host: $BRIDGE_HOST ($HOST_SOURCE)"
434
363
  echo "Bridge port: $BRIDGE_PORT"
435
364
  echo "Bridge connect URL: $BRIDGE_CONNECT_URL"
436
- if [[ "$GITHUB_CODESPACES_AUTH_ENABLED" == "true" ]]; then
437
- echo "GitHub Codespaces auth: enabled"
438
- fi
439
365
  echo "Harnesses: $BRIDGE_ENABLED_ENGINES"
440
366
  echo "Token source: $SECURE_ENV_FILE"
441
367
  if has_local_mobile_workspace; then