@hmduc16031996/claude-mb-bridge 2.2.2 → 2.3.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.
- package/README.md +31 -54
- package/dist/index.js +9 -5
- package/dist/server.js +33 -8
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,76 +1,53 @@
|
|
|
1
|
-
# Claude
|
|
1
|
+
# Claude Mobile Bridge 🤖📱
|
|
2
2
|
|
|
3
|
-
A lightweight bridge between the **Claude Code CLI** and your **mobile app**
|
|
4
|
-
|
|
5
|
-

|
|
3
|
+
A lightweight bridge between the **Claude Code CLI** and your **mobile app** via a secure Cloudflare Tunnel. This tool allows you to interact with your local development environment directly from your mobile device using the Claude Code CLI.
|
|
6
4
|
|
|
7
5
|
## ✨ Features
|
|
8
6
|
|
|
9
|
-
- **
|
|
10
|
-
- **
|
|
11
|
-
- **
|
|
12
|
-
- **
|
|
13
|
-
- **Background Service**: Easily install as a login item on macOS to keep the bridge running.
|
|
14
|
-
- **Model Selection**: Supports switching between Claude 3.5 Sonnet, 3 Opus, and 3.5 Haiku.
|
|
15
|
-
- **Command Cancellation**: Stop running Claude processes directly from your mobile app.
|
|
7
|
+
- **Secure Tunneling**: Uses Cloudflare Tunnel (`cloudflared`) to expose your local terminal securely.
|
|
8
|
+
- **Terminal Integration**: Full terminal emulation using `node-pty` and `xterm.js`.
|
|
9
|
+
- **Session Management**: Pairing via tokens and a central coordination server.
|
|
10
|
+
- **Cross-Platform**: Works on macOS, Linux, and Windows.
|
|
16
11
|
|
|
17
12
|
## 📋 Prerequisites
|
|
18
13
|
|
|
19
14
|
1. **Node.js**: Version 18.0.0 or higher.
|
|
20
|
-
2. **Claude Code CLI**:
|
|
21
|
-
|
|
22
|
-
-
|
|
23
|
-
|
|
15
|
+
2. **Claude Code CLI**: Installed and authenticated (`npm install -g @anthropic-ai/claude-code`).
|
|
16
|
+
3. **Cloudflared**: The Cloudflare Tunnel CLI must be installed and in your PATH.
|
|
17
|
+
- `brew install cloudflared` (macOS)
|
|
18
|
+
- [Download for other platforms](https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/installation/)
|
|
24
19
|
|
|
25
|
-
## 🚀 Installation
|
|
20
|
+
## 🚀 Installation & Usage
|
|
26
21
|
|
|
27
|
-
Install the package globally
|
|
22
|
+
Install the package globally:
|
|
28
23
|
|
|
29
24
|
```bash
|
|
30
|
-
|
|
31
|
-
npx claude-mb-bridge
|
|
32
|
-
|
|
33
|
-
# Or install globally
|
|
34
|
-
npm install -g claude-mb-bridge
|
|
25
|
+
npm install -g @hmduc16031996/claude-mb-bridge
|
|
35
26
|
```
|
|
36
27
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
1. **Start the Bridge**: Run `claude-mb-bridge` in your project's root directory.
|
|
40
|
-
2. **Get Pair Code**: The bridge will start a local pairing server (default port: `38473`).
|
|
41
|
-
3. **Connect Mobile App**: Open your mobile app, enter the 6-digit code displayed in your terminal.
|
|
42
|
-
4. **Authorized**: Once paired, the bridge will remember your device and automatically reconnect in the future.
|
|
43
|
-
|
|
44
|
-
## 💻 CLI Options
|
|
45
|
-
|
|
46
|
-
| Option | Description |
|
|
47
|
-
| :--- | :--- |
|
|
48
|
-
| `-p, --path <dir>` | Project directory for Claude to work in (defaults to current directory) |
|
|
49
|
-
| `--port <number>` | Port for the pairing server (default: `38473`) |
|
|
50
|
-
| `--install` | Install as a background service (starts on login) |
|
|
51
|
-
| `--uninstall` | Remove the background service |
|
|
52
|
-
| `--version` | Show version number |
|
|
53
|
-
|
|
54
|
-
## ⚙️ Configuration
|
|
55
|
-
|
|
56
|
-
The bridge stores its configuration in `~/.claude-mobile/config.json`.
|
|
57
|
-
|
|
58
|
-
You can override the default Supabase credentials using environment variables:
|
|
28
|
+
Or run it directly using `npx`:
|
|
59
29
|
|
|
60
30
|
```bash
|
|
61
|
-
|
|
62
|
-
SUPABASE_ANON_KEY="your-anon-key"
|
|
31
|
+
npx @hmduc16031996/claude-mb-bridge --token YOUR_PAIRING_TOKEN
|
|
63
32
|
```
|
|
64
33
|
|
|
65
|
-
|
|
34
|
+
### Options
|
|
35
|
+
|
|
36
|
+
| Option | Description | Default |
|
|
37
|
+
| :--- | :--- | :--- |
|
|
38
|
+
| `--token` | **Required**. Pairing token from your mobile app. | |
|
|
39
|
+
| `--server` | URL of the central coordination server. | `http://127.0.0.1:3000` |
|
|
40
|
+
| `--path` | Working directory for the terminal session. | `process.cwd()` |
|
|
41
|
+
| `--port` | Local port for the terminal server. | `38473` |
|
|
42
|
+
|
|
43
|
+
## 🏗️ How it Works
|
|
66
44
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
5. **Mobile App** displays the reply to the user.
|
|
45
|
+
1. **Start the Bridge**: Run the CLI with your pairing token.
|
|
46
|
+
2. **Local Server**: The bridge starts a local HTTP/WebSocket server that hosts a terminal interface.
|
|
47
|
+
3. **Cloudflare Tunnel**: It automatically creates a temporary `.trycloudflare.com` tunnel pointing to your local server.
|
|
48
|
+
4. **Connect**: The bridge reports the tunnel URL to the central server, which then allows your mobile app to connect to the terminal via the secure URL.
|
|
49
|
+
5. **Interactive Session**: Use Claude Code directly in your mobile app as if you were in your local terminal.
|
|
73
50
|
|
|
74
51
|
## 📄 License
|
|
75
52
|
|
|
76
|
-
MIT © [
|
|
53
|
+
MIT © [hmduc16031996](https://github.com/hmduc16031996)
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
1
|
import { Command } from 'commander';
|
|
3
2
|
import { CloudflareTunnel } from './tunnel.js';
|
|
4
3
|
import { startTerminalServer } from './server.js';
|
|
@@ -6,9 +5,9 @@ const program = new Command();
|
|
|
6
5
|
program
|
|
7
6
|
.name('claude-mobile-bridge')
|
|
8
7
|
.description('Bridge Claude Code CLI to mobile via WebView')
|
|
9
|
-
.version('2.
|
|
8
|
+
.version('2.3.2')
|
|
10
9
|
.option('--token <token>', 'Pairing token from mobile app')
|
|
11
|
-
.option('--server <url>', 'Backend server URL', 'http://127.0.0.1:
|
|
10
|
+
.option('--server <url>', 'Backend server URL', 'http://127.0.0.1:3777')
|
|
12
11
|
.option('--path <path>', 'Working directory', process.cwd())
|
|
13
12
|
.option('--port <port>', 'Local port for terminal server', '38473')
|
|
14
13
|
.action(async (options) => {
|
|
@@ -31,16 +30,21 @@ program
|
|
|
31
30
|
}
|
|
32
31
|
};
|
|
33
32
|
// 1. Start local terminal server
|
|
33
|
+
console.log('📦 Starting terminal server...');
|
|
34
34
|
const localPort = parseInt(port, 10);
|
|
35
35
|
const { server: terminalServer, actualPort } = await startTerminalServer(localPort, path, cleanup);
|
|
36
|
+
console.log(`✅ Terminal server started on port ${actualPort}`);
|
|
36
37
|
// 2. Start Cloudflare Tunnel
|
|
38
|
+
console.log('🌐 Establishing secure tunnel...');
|
|
37
39
|
const tunnel = new CloudflareTunnel();
|
|
38
40
|
const tunnelResult = await tunnel.start(actualPort);
|
|
39
41
|
if (!tunnelResult.url) {
|
|
40
42
|
console.error('❌ Failed to start Cloudflare Tunnel.');
|
|
41
43
|
process.exit(1);
|
|
42
44
|
}
|
|
45
|
+
console.log('✅ Secure tunnel established');
|
|
43
46
|
// 3. Validate token and report public URL to central server
|
|
47
|
+
console.log('🔑 Validating session token...');
|
|
44
48
|
try {
|
|
45
49
|
const res = await fetch(`${server}/api/sessions/${token}/validate`, {
|
|
46
50
|
method: 'POST',
|
|
@@ -54,11 +58,11 @@ program
|
|
|
54
58
|
if (!res.ok) {
|
|
55
59
|
throw new Error('Invalid token or session expired');
|
|
56
60
|
}
|
|
57
|
-
console.log('✅ Session connected');
|
|
61
|
+
console.log('✅ Session connected and authorized');
|
|
58
62
|
}
|
|
59
63
|
catch (err) {
|
|
60
64
|
console.error(`❌ Validation failed: ${err.message}`);
|
|
61
|
-
console.error(' Ensure the central server is
|
|
65
|
+
console.error(' Ensure the central server is available');
|
|
62
66
|
cleanup();
|
|
63
67
|
}
|
|
64
68
|
// Handle graceful shutdown signals
|
package/dist/server.js
CHANGED
|
@@ -19,14 +19,39 @@ export function startTerminalServer(port, workingDir, onDisconnect) {
|
|
|
19
19
|
wss.on('connection', (ws, req) => {
|
|
20
20
|
console.log(`📡 New connection attempt from ${req.socket.remoteAddress}`);
|
|
21
21
|
console.log('✅ Connection authorized');
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
22
|
+
// Use absolute paths for shells to avoid posix_spawnp failure
|
|
23
|
+
let shell = '/bin/bash';
|
|
24
|
+
if (process.platform === 'win32') {
|
|
25
|
+
shell = 'powershell.exe';
|
|
26
|
+
}
|
|
27
|
+
else if (process.platform === 'darwin') {
|
|
28
|
+
// Prefer zsh on macOS as it's the modern default, fallback to bash
|
|
29
|
+
shell = require('fs').existsSync('/bin/zsh') ? '/bin/zsh' : '/bin/bash';
|
|
30
|
+
}
|
|
31
|
+
console.log(`🚀 Spawning shell: ${shell} in ${workingDir}`);
|
|
32
|
+
let term;
|
|
33
|
+
try {
|
|
34
|
+
// Ensure working directory exists
|
|
35
|
+
if (!require('fs').existsSync(workingDir)) {
|
|
36
|
+
console.error(`❌ Working directory does not exist: ${workingDir}`);
|
|
37
|
+
ws.send('\r\n\x1b[31mError: Working directory does not exist\x1b[0m\r\n');
|
|
38
|
+
ws.close();
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
term = pty.spawn(shell, [], {
|
|
42
|
+
name: 'xterm-256color',
|
|
43
|
+
cols: 80,
|
|
44
|
+
rows: 24,
|
|
45
|
+
cwd: workingDir,
|
|
46
|
+
env: process.env
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
console.error(`❌ Failed to spawn terminal: ${err.message}`);
|
|
51
|
+
ws.send(`\r\n\x1b[31mError: Failed to spawn terminal (${err.message})\x1b[0m\r\n`);
|
|
52
|
+
ws.close();
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
30
55
|
term.write('claude\r');
|
|
31
56
|
term.onData((data) => {
|
|
32
57
|
ws.send(data);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hmduc16031996/claude-mb-bridge",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.2",
|
|
4
4
|
"description": "Bridge between Claude Code CLI and your mobile app via WebView",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"claude-mb-bridge": "dist/index.js"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
|
-
"build": "tsc
|
|
11
|
+
"build": "tsc",
|
|
12
12
|
"start": "node dist/index.js",
|
|
13
13
|
"dev": "tsx src/index.ts",
|
|
14
14
|
"postinstall": "node scripts/postinstall.cjs"
|