clawdex-mobile 5.1.3-internal.11 → 5.1.3-internal.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -3
- package/bin/clawdex.js +2 -2
- package/docs/setup-and-operations.md +2 -2
- package/package.json +11 -4
- package/scripts/setup-wizard.sh +11 -21
- package/scripts/start-bridge-secure.js +6 -53
- package/services/cursor-app-server/README.md +39 -0
- package/services/cursor-app-server/dist/appServer.d.ts +52 -0
- package/services/cursor-app-server/dist/appServer.js +780 -0
- package/services/cursor-app-server/dist/appServer.js.map +1 -0
- package/services/cursor-app-server/dist/cursorWorkspace.d.ts +7 -0
- package/services/cursor-app-server/dist/cursorWorkspace.js +126 -0
- package/services/cursor-app-server/dist/cursorWorkspace.js.map +1 -0
- package/services/cursor-app-server/dist/index.d.ts +4 -0
- package/services/cursor-app-server/dist/index.js +4 -0
- package/services/cursor-app-server/dist/index.js.map +1 -0
- package/services/cursor-app-server/dist/input.d.ts +27 -0
- package/services/cursor-app-server/dist/input.js +143 -0
- package/services/cursor-app-server/dist/input.js.map +1 -0
- package/services/cursor-app-server/dist/jsonRpc.d.ts +15 -0
- package/services/cursor-app-server/dist/jsonRpc.js +93 -0
- package/services/cursor-app-server/dist/jsonRpc.js.map +1 -0
- package/services/cursor-app-server/dist/projection.d.ts +8 -0
- package/services/cursor-app-server/dist/projection.js +507 -0
- package/services/cursor-app-server/dist/projection.js.map +1 -0
- package/services/cursor-app-server/dist/sdkDriver.d.ts +50 -0
- package/services/cursor-app-server/dist/sdkDriver.js +166 -0
- package/services/cursor-app-server/dist/sdkDriver.js.map +1 -0
- package/services/cursor-app-server/dist/stdio.d.ts +2 -0
- package/services/cursor-app-server/dist/stdio.js +7 -0
- package/services/cursor-app-server/dist/stdio.js.map +1 -0
- package/services/cursor-app-server/dist/types.d.ts +218 -0
- package/services/cursor-app-server/dist/types.js +2 -0
- package/services/cursor-app-server/dist/types.js.map +1 -0
- package/services/cursor-app-server/package.json +43 -0
- package/services/rust-bridge/Cargo.lock +1 -1
- package/services/rust-bridge/Cargo.toml +1 -1
- package/vendor/bridge-binaries/darwin-arm64/codex-rust-bridge +0 -0
- package/vendor/bridge-binaries/darwin-x64/codex-rust-bridge +0 -0
- package/vendor/bridge-binaries/linux-arm64/codex-rust-bridge +0 -0
- package/vendor/bridge-binaries/linux-armv7l/codex-rust-bridge +0 -0
- package/vendor/bridge-binaries/linux-x64/codex-rust-bridge +0 -0
- package/vendor/bridge-binaries/win32-x64/codex-rust-bridge.exe +0 -0
package/README.md
CHANGED
|
@@ -25,7 +25,7 @@ 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
|
-
-
|
|
28
|
+
- Cursor app-server is bundled with `clawdex-mobile` for the Cursor SDK flow
|
|
29
29
|
|
|
30
30
|
Install the mobile app:
|
|
31
31
|
|
|
@@ -59,12 +59,11 @@ OpenCode and Cursor can run beside Codex from the same bridge.
|
|
|
59
59
|
|
|
60
60
|
```bash
|
|
61
61
|
npm install -g opencode-ai
|
|
62
|
-
npm install -g @clawdex/cursor-app-server
|
|
63
62
|
npm install -g clawdex-mobile@latest
|
|
64
63
|
clawdex init --engines codex,opencode,cursor
|
|
65
64
|
```
|
|
66
65
|
|
|
67
|
-
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 the Cursor API key, and saves it in `.env.secure`.
|
|
68
67
|
|
|
69
68
|
Notes:
|
|
70
69
|
|
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
|
|
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.
|
|
@@ -18,7 +18,7 @@ From a source checkout, the equivalent command is:
|
|
|
18
18
|
npm run setup:wizard -- --engines codex,opencode,cursor
|
|
19
19
|
```
|
|
20
20
|
|
|
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`.
|
|
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` uses the bundled `cursor-app-server`, asks for the Cursor API key, and saves it in `.env.secure`.
|
|
22
22
|
|
|
23
23
|
If you want only one harness, use `--engine codex`, `--engine opencode`, or `--engine cursor`.
|
|
24
24
|
|
|
@@ -199,7 +199,7 @@ npm run teardown -- --yes
|
|
|
199
199
|
| `BRIDGE_ACTIVE_ENGINE` | internal preferred routing backend used when multiple harnesses are enabled |
|
|
200
200
|
| `BRIDGE_ENABLED_ENGINES` | selected harnesses to expose (`codex`, `opencode`, `cursor`, or a comma-separated mix) |
|
|
201
201
|
| `OPENCODE_CLI_BIN` | opencode executable for dual-engine startup |
|
|
202
|
-
| `CURSOR_APP_SERVER_BIN` | Cursor app-server executable, usually `cursor-app-server` |
|
|
202
|
+
| `CURSOR_APP_SERVER_BIN` | Cursor app-server executable, usually the `cursor-app-server` binary bundled with `clawdex-mobile` |
|
|
203
203
|
| `CURSOR_API_KEY` | Cursor API key used by the Cursor SDK harness; collected by `clawdex init` when Cursor is selected |
|
|
204
204
|
| `CURSOR_MODEL` | optional Cursor model id for non-interactive host defaults; normal mobile chats send the selected model |
|
|
205
205
|
| `BRIDGE_OPENCODE_HOST` | loopback host for spawned opencode server |
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clawdex-mobile",
|
|
3
|
-
"version": "5.1.3-internal.
|
|
4
|
-
"description": "Private-network mobile bridge and CLI for Codex and
|
|
3
|
+
"version": "5.1.3-internal.13",
|
|
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
|
-
"
|
|
23
|
+
"@cursor/sdk": "1.0.11",
|
|
24
|
+
"qrcode-terminal": "^0.12.0",
|
|
25
|
+
"zod": "^3.25.0"
|
|
24
26
|
},
|
|
25
27
|
"bin": {
|
|
26
|
-
"clawdex": "
|
|
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",
|
|
@@ -38,6 +41,9 @@
|
|
|
38
41
|
"scripts/setup-wizard.sh",
|
|
39
42
|
"scripts/start-bridge-secure.js",
|
|
40
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",
|
|
41
47
|
"services/rust-bridge/Cargo.lock",
|
|
42
48
|
"services/rust-bridge/Cargo.toml",
|
|
43
49
|
"services/rust-bridge/src",
|
|
@@ -67,6 +73,7 @@
|
|
|
67
73
|
"secure:bridge:dev": "node ./scripts/start-bridge-secure.js --dev",
|
|
68
74
|
"bridge:ts": "BRIDGE_WORKDIR=$(pwd) npm run -w @codex/mac-bridge dev",
|
|
69
75
|
"version:sync": "node scripts/sync-versions.js",
|
|
76
|
+
"prepack": "npm run build -w @clawdex/cursor-app-server",
|
|
70
77
|
"build": "npm run --workspaces build",
|
|
71
78
|
"typecheck": "npm run --workspaces typecheck",
|
|
72
79
|
"lint": "npm run --workspaces lint",
|
package/scripts/setup-wizard.sh
CHANGED
|
@@ -1296,29 +1296,20 @@ ensure_cursor_app_server() {
|
|
|
1296
1296
|
local existing_api_key=""
|
|
1297
1297
|
local existing_model=""
|
|
1298
1298
|
local provided_api_key="${CURSOR_API_KEY:-}"
|
|
1299
|
+
local resolved_cursor_app_server_bin=""
|
|
1299
1300
|
|
|
1300
|
-
if [[ -
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1301
|
+
if [[ -n "${CURSOR_APP_SERVER_BIN:-}" ]]; then
|
|
1302
|
+
resolved_cursor_app_server_bin="$CURSOR_APP_SERVER_BIN"
|
|
1303
|
+
elif command -v cursor-app-server >/dev/null 2>&1; then
|
|
1304
|
+
resolved_cursor_app_server_bin="$(command -v cursor-app-server)"
|
|
1304
1305
|
fi
|
|
1305
1306
|
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
if npm install -g @clawdex/cursor-app-server; then
|
|
1310
|
-
hash -r
|
|
1311
|
-
else
|
|
1312
|
-
warn "Automatic install failed."
|
|
1313
|
-
fi
|
|
1314
|
-
fi
|
|
1315
|
-
|
|
1316
|
-
if ! command -v cursor-app-server >/dev/null 2>&1 && ! confirm_prompt "Retry Cursor app-server check?" "Y"; then
|
|
1317
|
-
abort_wizard "Install @clawdex/cursor-app-server and rerun: clawdex init --engine cursor"
|
|
1318
|
-
fi
|
|
1319
|
-
done
|
|
1307
|
+
if [[ -z "$resolved_cursor_app_server_bin" ]]; then
|
|
1308
|
+
abort_wizard "cursor-app-server was not found. Upgrade clawdex-mobile so npm links the bundled command, then rerun: clawdex init --engine cursor"
|
|
1309
|
+
fi
|
|
1320
1310
|
|
|
1321
|
-
|
|
1311
|
+
CURSOR_APP_SERVER_BIN="$resolved_cursor_app_server_bin"
|
|
1312
|
+
ok "Found cursor-app-server: $CURSOR_APP_SERVER_BIN"
|
|
1322
1313
|
|
|
1323
1314
|
existing_api_key="$(extract_env_value "$SECURE_ENV_FILE" "CURSOR_API_KEY")"
|
|
1324
1315
|
existing_model="$(extract_env_value "$SECURE_ENV_FILE" "CURSOR_MODEL")"
|
|
@@ -1743,8 +1734,7 @@ ensure_core_tools
|
|
|
1743
1734
|
if has_packaged_bridge_binary; then
|
|
1744
1735
|
ok "Found packaged Rust bridge binary for this host."
|
|
1745
1736
|
else
|
|
1746
|
-
|
|
1747
|
-
ensure_local_rust_build_toolchain
|
|
1737
|
+
abort_wizard "No packaged bridge binary found for this host. Reinstall clawdex-mobile so npm installs the bundled bridge binary, then rerun setup."
|
|
1748
1738
|
fi
|
|
1749
1739
|
|
|
1750
1740
|
section "Config handling"
|
|
@@ -377,48 +377,6 @@ function commandExists(command) {
|
|
|
377
377
|
return result.status === 0;
|
|
378
378
|
}
|
|
379
379
|
|
|
380
|
-
function walkFiles(directory) {
|
|
381
|
-
const entries = fs.readdirSync(directory, { withFileTypes: true });
|
|
382
|
-
const files = [];
|
|
383
|
-
|
|
384
|
-
for (const entry of entries) {
|
|
385
|
-
const entryPath = path.join(directory, entry.name);
|
|
386
|
-
if (entry.isDirectory()) {
|
|
387
|
-
files.push(...walkFiles(entryPath));
|
|
388
|
-
continue;
|
|
389
|
-
}
|
|
390
|
-
if (entry.isFile()) {
|
|
391
|
-
files.push(entryPath);
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
return files;
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
function isBuiltBinaryFresh(packageDir, binaryPath) {
|
|
399
|
-
if (!fs.existsSync(binaryPath)) {
|
|
400
|
-
return false;
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
const binaryMtime = fs.statSync(binaryPath).mtimeMs;
|
|
404
|
-
const watchPaths = [
|
|
405
|
-
path.join(packageDir, "services", "rust-bridge", "Cargo.toml"),
|
|
406
|
-
path.join(packageDir, "services", "rust-bridge", "Cargo.lock"),
|
|
407
|
-
];
|
|
408
|
-
const sourceDir = path.join(packageDir, "services", "rust-bridge", "src");
|
|
409
|
-
|
|
410
|
-
if (fs.existsSync(sourceDir)) {
|
|
411
|
-
watchPaths.push(...walkFiles(sourceDir));
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
return watchPaths.every((watchPath) => {
|
|
415
|
-
if (!fs.existsSync(watchPath)) {
|
|
416
|
-
return true;
|
|
417
|
-
}
|
|
418
|
-
return fs.statSync(watchPath).mtimeMs <= binaryMtime;
|
|
419
|
-
});
|
|
420
|
-
}
|
|
421
|
-
|
|
422
380
|
function printMissingCompilerHint() {
|
|
423
381
|
if (process.platform === "win32") {
|
|
424
382
|
console.error("Install Visual Studio Build Tools (Desktop development with C++) and Rust, then retry.");
|
|
@@ -615,20 +573,15 @@ function resolveLaunch(workspaceDir, packageDir, env, { devMode, forceSourceBuil
|
|
|
615
573
|
}
|
|
616
574
|
|
|
617
575
|
const builtBinary = builtBinaryPath(packageDir, os.platform(), buildProfile);
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
cwd: workspaceDir,
|
|
624
|
-
env,
|
|
625
|
-
healthTimeoutMs: defaultHealthTimeoutMs,
|
|
626
|
-
};
|
|
576
|
+
|
|
577
|
+
if (!forceSourceBuild) {
|
|
578
|
+
console.error("error: no packaged bridge binary was found for this host.");
|
|
579
|
+
console.error("Reinstall a published clawdex-mobile package with bundled bridge binaries.");
|
|
580
|
+
process.exit(1);
|
|
627
581
|
}
|
|
628
582
|
|
|
629
583
|
if (!commandExists("cargo")) {
|
|
630
|
-
console.error("error:
|
|
631
|
-
console.error("Reinstall a published clawdex-mobile package with bundled bridge binaries, or install Rust and retry.");
|
|
584
|
+
console.error("error: CLAWDEX_BRIDGE_FORCE_SOURCE_BUILD=true was set, but cargo is not installed.");
|
|
632
585
|
process.exit(1);
|
|
633
586
|
}
|
|
634
587
|
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# @clawdex/cursor-app-server
|
|
2
|
+
|
|
3
|
+
App-server shaped JSON-RPC adapter for Cursor agents.
|
|
4
|
+
|
|
5
|
+
This package is intentionally strict. It does not fall back to Codex, OpenCode,
|
|
6
|
+
mock agents, empty model lists, or implicit workspace directories. Missing
|
|
7
|
+
Cursor runtime configuration is surfaced as an error.
|
|
8
|
+
|
|
9
|
+
## Contract
|
|
10
|
+
|
|
11
|
+
Supported JSON-RPC methods:
|
|
12
|
+
|
|
13
|
+
- `thread/list`
|
|
14
|
+
- `thread/loaded/list`
|
|
15
|
+
- `thread/read`
|
|
16
|
+
- `thread/start`
|
|
17
|
+
- `turn/start`
|
|
18
|
+
- `turn/interrupt`
|
|
19
|
+
- `model/list`
|
|
20
|
+
|
|
21
|
+
Emitted notifications:
|
|
22
|
+
|
|
23
|
+
- `thread/started`
|
|
24
|
+
- `thread/status/changed`
|
|
25
|
+
- `turn/started`
|
|
26
|
+
- `item/agentMessage/delta`
|
|
27
|
+
- `item/reasoning/textDelta`
|
|
28
|
+
- `item/started`
|
|
29
|
+
- `turn/completed`
|
|
30
|
+
|
|
31
|
+
## Run
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
CURSOR_WORKDIR="$PWD" CURSOR_MODEL="cursor-small" CURSOR_API_KEY="..." cursor-app-server
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
`CURSOR_WORKDIR` is required for local agents. `CURSOR_MODEL` is required unless
|
|
38
|
+
a request provides an explicit model. `CURSOR_API_KEY` is required for Cursor SDK
|
|
39
|
+
operations and model listing.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { AppServerNotification, CursorAppServerOptions, CursorStreamMessage } from './types.js';
|
|
2
|
+
type NotificationListener = (notification: AppServerNotification) => void;
|
|
3
|
+
export declare class CursorAppServer {
|
|
4
|
+
private readonly runtime;
|
|
5
|
+
private readonly driver;
|
|
6
|
+
private readonly configuredCwd;
|
|
7
|
+
private readonly apiKey;
|
|
8
|
+
private readonly defaultModel;
|
|
9
|
+
private readonly cursorProjectsDir;
|
|
10
|
+
private readonly events;
|
|
11
|
+
private readonly liveThreads;
|
|
12
|
+
private readonly knownThreadCwds;
|
|
13
|
+
private readonly knownThreadStoreCwds;
|
|
14
|
+
constructor(options: CursorAppServerOptions);
|
|
15
|
+
onNotification(listener: NotificationListener): () => void;
|
|
16
|
+
request(method: string, params?: unknown): Promise<Record<string, unknown>>;
|
|
17
|
+
private listThreads;
|
|
18
|
+
private readThread;
|
|
19
|
+
private listLoadedThreads;
|
|
20
|
+
private startThread;
|
|
21
|
+
private startTurn;
|
|
22
|
+
private interruptTurn;
|
|
23
|
+
private listModels;
|
|
24
|
+
private initialize;
|
|
25
|
+
private getOrResumeLiveThread;
|
|
26
|
+
private consumeRun;
|
|
27
|
+
private applyStreamMessage;
|
|
28
|
+
private applyRunResult;
|
|
29
|
+
private findOrCreateTextItem;
|
|
30
|
+
private upsertToolCallItem;
|
|
31
|
+
private findAssistantItem;
|
|
32
|
+
private requireCwd;
|
|
33
|
+
private resolveKnownThreadWorkspace;
|
|
34
|
+
private rememberAgentCwd;
|
|
35
|
+
private listKnownWorkspaceCwds;
|
|
36
|
+
private resolveAgentEffectiveCwd;
|
|
37
|
+
private readPersistedThread;
|
|
38
|
+
private resumePersistedThread;
|
|
39
|
+
private candidateStoreCwds;
|
|
40
|
+
private requireModel;
|
|
41
|
+
private requireTurnModel;
|
|
42
|
+
private configuredModelOrUndefined;
|
|
43
|
+
private latestPersistedRunModel;
|
|
44
|
+
private requireApiKey;
|
|
45
|
+
private buildUserMessage;
|
|
46
|
+
private buildUserThreadContent;
|
|
47
|
+
private toModelSelection;
|
|
48
|
+
private emit;
|
|
49
|
+
}
|
|
50
|
+
export declare function createCursorAppServerFromEnv(env?: NodeJS.ProcessEnv): CursorAppServer;
|
|
51
|
+
export declare function cursorStreamMessageText(message: CursorStreamMessage): string;
|
|
52
|
+
export {};
|