@hmduc16031996/claude-mb-bridge 2.4.0 → 2.4.1
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/dist/index.js +2 -2
- package/dist/server.d.ts +1 -1
- package/dist/server.js +58 -7
- package/package.json +1 -1
- package/public/app.js +2118 -290
- package/public/index.html +204 -5
- package/public/styles.css +5 -5
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ const program = new Command();
|
|
|
6
6
|
program
|
|
7
7
|
.name('claude-mobile-bridge')
|
|
8
8
|
.description('Bridge Claude Code CLI to mobile via WebView')
|
|
9
|
-
.version('2.4.
|
|
9
|
+
.version('2.4.1')
|
|
10
10
|
.option('--token <token>', 'Pairing token from mobile app')
|
|
11
11
|
.option('--server <url>', 'Backend server URL', 'http://127.0.0.1:3110')
|
|
12
12
|
.option('--path <path>', 'Working directory', process.cwd())
|
|
@@ -33,7 +33,7 @@ program
|
|
|
33
33
|
// 1. Start local terminal server
|
|
34
34
|
console.log('📦 Starting terminal server...');
|
|
35
35
|
const localPort = parseInt(port, 10);
|
|
36
|
-
const { server: terminalServer, actualPort } = await startTerminalServer(localPort, path, cleanup);
|
|
36
|
+
const { server: terminalServer, actualPort } = await startTerminalServer(localPort, path, token, cleanup);
|
|
37
37
|
console.log(`✅ Terminal server started on port ${actualPort}`);
|
|
38
38
|
// 2. Start Cloudflare Tunnel
|
|
39
39
|
console.log('🌐 Establishing secure tunnel...');
|
package/dist/server.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare function startTerminalServer(port: number, workingDir: string, onDisconnect?: () => void): Promise<{
|
|
1
|
+
export declare function startTerminalServer(port: number, workingDir: string, terminalToken: string, onDisconnect?: () => void): Promise<{
|
|
2
2
|
server: any;
|
|
3
3
|
actualPort: number;
|
|
4
4
|
}>;
|
package/dist/server.js
CHANGED
|
@@ -78,7 +78,7 @@ class SessionManager {
|
|
|
78
78
|
return Array.from(this.sessions.values()).map(s => s.getInfo());
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
|
-
export function startTerminalServer(port, workingDir, onDisconnect) {
|
|
81
|
+
export function startTerminalServer(port, workingDir, terminalToken, onDisconnect) {
|
|
82
82
|
const app = express();
|
|
83
83
|
const server = createServer(app);
|
|
84
84
|
const wss = new WebSocketServer({ server });
|
|
@@ -88,6 +88,10 @@ export function startTerminalServer(port, workingDir, onDisconnect) {
|
|
|
88
88
|
app.get('/health', (req, res) => {
|
|
89
89
|
res.json({ status: 'ok' });
|
|
90
90
|
});
|
|
91
|
+
// Ports endpoint - returns empty list (no port detection in bridge mode)
|
|
92
|
+
app.get('/api/ports', (req, res) => {
|
|
93
|
+
res.json([]);
|
|
94
|
+
});
|
|
91
95
|
// Directory listing for autocomplete
|
|
92
96
|
app.get('/api/dirs', (req, res) => {
|
|
93
97
|
try {
|
|
@@ -131,6 +135,7 @@ export function startTerminalServer(port, workingDir, onDisconnect) {
|
|
|
131
135
|
});
|
|
132
136
|
wss.on('connection', (ws, req) => {
|
|
133
137
|
console.log(`📡 New connection from ${req.socket.remoteAddress}`);
|
|
138
|
+
let authenticated = false;
|
|
134
139
|
let activeSessionId = null;
|
|
135
140
|
let outputHandler = null;
|
|
136
141
|
const sendControl = (message) => {
|
|
@@ -148,7 +153,7 @@ export function startTerminalServer(port, workingDir, onDisconnect) {
|
|
|
148
153
|
if (activeSessionId && outputHandler) {
|
|
149
154
|
const oldSession = sessionManager.getSession(activeSessionId);
|
|
150
155
|
if (oldSession) {
|
|
151
|
-
oldSession.term.
|
|
156
|
+
oldSession.term.removeListener('data', outputHandler);
|
|
152
157
|
}
|
|
153
158
|
}
|
|
154
159
|
activeSessionId = sessionId;
|
|
@@ -160,9 +165,6 @@ export function startTerminalServer(port, workingDir, onDisconnect) {
|
|
|
160
165
|
session.term.on('data', outputHandler);
|
|
161
166
|
sendControl({ type: 'session:attached', session: session.getInfo() });
|
|
162
167
|
};
|
|
163
|
-
// Auto-create initial session if none exist or just use workingDir
|
|
164
|
-
const initialSession = sessionManager.createSession(workingDir);
|
|
165
|
-
attachToSession(initialSession.id);
|
|
166
168
|
ws.on('message', (msg, isBinary) => {
|
|
167
169
|
if (isBinary) {
|
|
168
170
|
let message;
|
|
@@ -173,6 +175,26 @@ export function startTerminalServer(port, workingDir, onDisconnect) {
|
|
|
173
175
|
sendControl({ type: 'error', error: 'Invalid control message' });
|
|
174
176
|
return;
|
|
175
177
|
}
|
|
178
|
+
// Auth must happen first
|
|
179
|
+
if (message.type === 'auth') {
|
|
180
|
+
if (message.token === terminalToken) {
|
|
181
|
+
authenticated = true;
|
|
182
|
+
sendControl({ type: 'auth:success' });
|
|
183
|
+
// Auto-create initial session and attach
|
|
184
|
+
const initialSession = sessionManager.createSession(workingDir);
|
|
185
|
+
attachToSession(initialSession.id);
|
|
186
|
+
console.log('✅ Client authenticated');
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
sendControl({ type: 'auth:failed', error: 'Invalid token' });
|
|
190
|
+
ws.close();
|
|
191
|
+
}
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
if (!authenticated) {
|
|
195
|
+
sendControl({ type: 'auth:failed', error: 'Not authenticated' });
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
176
198
|
switch (message.type) {
|
|
177
199
|
case 'session:create': {
|
|
178
200
|
let cwd = message.cwd || workingDir;
|
|
@@ -198,6 +220,11 @@ export function startTerminalServer(port, workingDir, onDisconnect) {
|
|
|
198
220
|
sendControl({ type: 'session:list', sessions: sessionManager.listSessions() });
|
|
199
221
|
break;
|
|
200
222
|
}
|
|
223
|
+
case 'session:discover': {
|
|
224
|
+
// No external session discovery in bridge mode
|
|
225
|
+
sendControl({ type: 'session:discovered', sessions: [] });
|
|
226
|
+
break;
|
|
227
|
+
}
|
|
201
228
|
case 'resize': {
|
|
202
229
|
const session = activeSessionId ? sessionManager.getSession(activeSessionId) : null;
|
|
203
230
|
if (session && message.cols && message.rows) {
|
|
@@ -228,9 +255,33 @@ export function startTerminalServer(port, workingDir, onDisconnect) {
|
|
|
228
255
|
}
|
|
229
256
|
break;
|
|
230
257
|
}
|
|
258
|
+
// Schedule stubs - not supported in bridge mode
|
|
259
|
+
case 'schedule:list': {
|
|
260
|
+
sendControl({ type: 'schedule:list', schedules: [] });
|
|
261
|
+
break;
|
|
262
|
+
}
|
|
263
|
+
case 'schedule:create': {
|
|
264
|
+
sendControl({ type: 'schedule:create_error', error: 'Schedules are not supported in bridge mode' });
|
|
265
|
+
break;
|
|
266
|
+
}
|
|
267
|
+
case 'schedule:update':
|
|
268
|
+
case 'schedule:delete':
|
|
269
|
+
case 'schedule:trigger':
|
|
270
|
+
case 'schedule:runs':
|
|
271
|
+
case 'schedule:log': {
|
|
272
|
+
// No-op stubs
|
|
273
|
+
break;
|
|
274
|
+
}
|
|
275
|
+
// Preferences - store in memory only (no persistence needed)
|
|
276
|
+
case 'preferences:set': {
|
|
277
|
+
// No-op: preferences are managed client-side via localStorage
|
|
278
|
+
break;
|
|
279
|
+
}
|
|
231
280
|
}
|
|
232
281
|
}
|
|
233
282
|
else {
|
|
283
|
+
if (!authenticated)
|
|
284
|
+
return;
|
|
234
285
|
// Raw text -> forward to active pty
|
|
235
286
|
const session = activeSessionId ? sessionManager.getSession(activeSessionId) : null;
|
|
236
287
|
if (session) {
|
|
@@ -242,7 +293,7 @@ export function startTerminalServer(port, workingDir, onDisconnect) {
|
|
|
242
293
|
if (activeSessionId && outputHandler) {
|
|
243
294
|
const session = sessionManager.getSession(activeSessionId);
|
|
244
295
|
if (session) {
|
|
245
|
-
session.term.
|
|
296
|
+
session.term.removeListener('data', outputHandler);
|
|
246
297
|
}
|
|
247
298
|
}
|
|
248
299
|
if (onDisconnect)
|
|
@@ -253,7 +304,7 @@ export function startTerminalServer(port, workingDir, onDisconnect) {
|
|
|
253
304
|
server.on('error', (err) => {
|
|
254
305
|
if (err.code === 'EADDRINUSE' && port !== 0) {
|
|
255
306
|
console.warn(`⚠️ Port ${port} is busy, trying a random port...`);
|
|
256
|
-
resolve(startTerminalServer(0, workingDir, onDisconnect));
|
|
307
|
+
resolve(startTerminalServer(0, workingDir, terminalToken, onDisconnect));
|
|
257
308
|
}
|
|
258
309
|
else {
|
|
259
310
|
reject(err);
|