kiro-mobile-bridge 1.0.10 → 1.0.12
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 +12 -15
- package/package.json +1 -1
- package/src/server.js +2 -9
- package/src/utils/network.js +32 -6
package/README.md
CHANGED
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
# Kiro Mobile Bridge
|
|
2
2
|
|
|
3
|
-
A mobile
|
|
3
|
+
A lightweight mobile interface that lets you monitor and control Kiro IDE agent sessions from your phone over LAN, with a live preview of chat, tasks, and code via Chrome DevTools Protocol.
|
|
4
|
+
|
|
5
|
+
<img width="1829" height="1065" alt="Untitled design (2)" src="https://github.com/user-attachments/assets/6f55e527-7e66-46b6-b0fe-c2a5a527dec4" />
|
|
4
6
|
|
|
5
|
-
<img width="1829" height="1065" alt="Untitled design (1)" src="https://github.com/user-attachments/assets/0590c332-80e1-4874-b27d-e7babe6202c8" />
|
|
6
7
|
|
|
7
8
|
## Features
|
|
8
9
|
|
|
9
10
|
- 📱 Mobile-optimized web interface with tab navigation
|
|
10
|
-
- 💬 **Chat
|
|
11
|
-
- 📝 **Code
|
|
12
|
-
- 📋 **Tasks
|
|
11
|
+
- 💬 **Chat** - View and send messages to Kiro's agent
|
|
12
|
+
- 📝 **Code** - Browse file explorer and view files with syntax highlighting
|
|
13
|
+
- 📋 **Tasks** - View and navigate Kiro spec task files
|
|
13
14
|
- 🔄 Real-time updates via WebSocket with adaptive polling
|
|
14
|
-
- 🔍 Auto-discovers Kiro instances on ports 9000-9003, 9222, 9229
|
|
15
|
-
- 🎨 Preserves original Kiro styling
|
|
16
15
|
|
|
17
16
|
## Prerequisites
|
|
18
17
|
|
|
@@ -24,21 +23,20 @@ A mobile web interface for monitoring Kiro IDE agent sessions from your phone ov
|
|
|
24
23
|
### 1. Enable CDP in Kiro
|
|
25
24
|
|
|
26
25
|
Start Kiro with the remote debugging port enabled:
|
|
27
|
-
|
|
26
|
+
|
|
27
|
+
**Run Kiro with debugging port:**
|
|
28
28
|
```bash
|
|
29
29
|
# Windows (from default install location)
|
|
30
30
|
"%LOCALAPPDATA%\Programs\Kiro\Kiro.exe" --remote-debugging-port=9000
|
|
31
|
-
|
|
32
31
|
# macOS
|
|
33
32
|
/Applications/Kiro.app/Contents/MacOS/Kiro --remote-debugging-port=9000
|
|
34
|
-
|
|
35
33
|
# Linux (installed)
|
|
36
34
|
/opt/Kiro/kiro --remote-debugging-port=9000
|
|
37
35
|
```
|
|
38
36
|
|
|
39
37
|
### 2. Run with npx (Recommended)
|
|
40
38
|
|
|
41
|
-
|
|
39
|
+
Start Server
|
|
42
40
|
|
|
43
41
|
```bash
|
|
44
42
|
npx kiro-mobile-bridge
|
|
@@ -56,11 +54,10 @@ npm start
|
|
|
56
54
|
You'll see output like:
|
|
57
55
|
|
|
58
56
|
```
|
|
59
|
-
|
|
57
|
+
Kiro Mobile Bridge
|
|
60
58
|
─────────────────────
|
|
61
59
|
Local: http://localhost:3000
|
|
62
|
-
Network: http://192.168.
|
|
63
|
-
|
|
60
|
+
Network: http://192.168.16.106:3000
|
|
64
61
|
Open the Network URL on your phone to monitor Kiro.
|
|
65
62
|
```
|
|
66
63
|
|
|
@@ -109,13 +106,13 @@ Open the Network URL on your phone to monitor Kiro.
|
|
|
109
106
|
|
|
110
107
|
## Security Notes
|
|
111
108
|
|
|
109
|
+
#### Only run this on trusted networks.
|
|
112
110
|
**This is designed for local network use only:**
|
|
113
111
|
|
|
114
112
|
- No authentication
|
|
115
113
|
- No HTTPS
|
|
116
114
|
- Exposes Kiro's chat interface to anyone on your network
|
|
117
115
|
|
|
118
|
-
Only run this on trusted networks.
|
|
119
116
|
|
|
120
117
|
## License
|
|
121
118
|
|
package/package.json
CHANGED
package/src/server.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
3
|
* Kiro Mobile Bridge Server
|
|
4
|
-
* @version 1.0.10
|
|
5
|
-
*
|
|
6
4
|
* A mobile web interface for monitoring Kiro IDE agent sessions from your phone over LAN.
|
|
7
5
|
* Captures snapshots of the chat interface via CDP and lets you send messages remotely.
|
|
8
6
|
*/
|
|
@@ -40,11 +38,6 @@ const __dirname = dirname(__filename);
|
|
|
40
38
|
// =============================================================================
|
|
41
39
|
|
|
42
40
|
const PORT = process.env.PORT || 3000;
|
|
43
|
-
|
|
44
|
-
// =============================================================================
|
|
45
|
-
// State Management
|
|
46
|
-
// =============================================================================
|
|
47
|
-
|
|
48
41
|
const cascades = new Map(); // cascadeId -> { id, cdp, metadata, snapshot, css, snapshotHash, editor, editorHash }
|
|
49
42
|
const mainWindowCDP = { connection: null, id: null };
|
|
50
43
|
|
|
@@ -362,11 +355,11 @@ wss.on('connection', (ws, req) => {
|
|
|
362
355
|
ws.on('error', (err) => console.error(`[WebSocket] Error from ${clientIP}:`, err.message));
|
|
363
356
|
});
|
|
364
357
|
|
|
365
|
-
httpServer.listen(PORT, () => {
|
|
358
|
+
httpServer.listen(PORT, '0.0.0.0', () => {
|
|
366
359
|
const localIP = getLocalIP();
|
|
367
360
|
console.log('');
|
|
368
361
|
console.log('Kiro Mobile Bridge');
|
|
369
|
-
console.log('
|
|
362
|
+
console.log('────────────────────');
|
|
370
363
|
console.log(`Local: http://localhost:${PORT}`);
|
|
371
364
|
console.log(`Network: http://${localIP}:${PORT}`);
|
|
372
365
|
console.log('');
|
package/src/utils/network.js
CHANGED
|
@@ -3,6 +3,16 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { networkInterfaces } from 'os';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Check if interface is IPv4
|
|
8
|
+
* Handles both string ('IPv4') and number (4) family values
|
|
9
|
+
* @param {object} iface - Network interface object
|
|
10
|
+
* @returns {boolean}
|
|
11
|
+
*/
|
|
12
|
+
function isIPv4(iface) {
|
|
13
|
+
return iface.family === 'IPv4' || iface.family === 4;
|
|
14
|
+
}
|
|
15
|
+
|
|
6
16
|
/**
|
|
7
17
|
* Get local IP address for LAN access
|
|
8
18
|
* Returns the first non-internal IPv4 address found.
|
|
@@ -15,25 +25,41 @@ import { networkInterfaces } from 'os';
|
|
|
15
25
|
export function getLocalIP() {
|
|
16
26
|
const interfaces = networkInterfaces();
|
|
17
27
|
|
|
18
|
-
// Prioritize common interface names
|
|
19
|
-
const priorityInterfaces = ['
|
|
28
|
+
// Prioritize common interface names (Linux, macOS, Windows)
|
|
29
|
+
const priorityInterfaces = ['Ethernet', 'Wi-Fi', 'eth0', 'en0', 'wlan0'];
|
|
20
30
|
|
|
21
31
|
// First, try priority interfaces
|
|
22
32
|
for (const name of priorityInterfaces) {
|
|
23
33
|
const ifaces = interfaces[name];
|
|
24
34
|
if (ifaces) {
|
|
25
35
|
for (const iface of ifaces) {
|
|
26
|
-
if (iface
|
|
36
|
+
if (isIPv4(iface) && !iface.internal) {
|
|
27
37
|
return iface.address;
|
|
28
38
|
}
|
|
29
39
|
}
|
|
30
40
|
}
|
|
31
41
|
}
|
|
32
42
|
|
|
33
|
-
// Fallback: return first non-internal IPv4
|
|
43
|
+
// Fallback: return first non-internal IPv4 (skip virtual/WSL interfaces)
|
|
44
|
+
for (const name of Object.keys(interfaces)) {
|
|
45
|
+
// Skip virtual interfaces (WSL, Docker, VPN, etc.)
|
|
46
|
+
if (name.toLowerCase().includes('vethernet') ||
|
|
47
|
+
name.toLowerCase().includes('docker') ||
|
|
48
|
+
name.toLowerCase().includes('vmware') ||
|
|
49
|
+
name.toLowerCase().includes('virtualbox')) {
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
for (const iface of interfaces[name]) {
|
|
53
|
+
if (isIPv4(iface) && !iface.internal) {
|
|
54
|
+
return iface.address;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Last resort: any non-internal IPv4
|
|
34
60
|
for (const name of Object.keys(interfaces)) {
|
|
35
61
|
for (const iface of interfaces[name]) {
|
|
36
|
-
if (iface
|
|
62
|
+
if (isIPv4(iface) && !iface.internal) {
|
|
37
63
|
return iface.address;
|
|
38
64
|
}
|
|
39
65
|
}
|
|
@@ -54,7 +80,7 @@ export function getAllLocalIPs() {
|
|
|
54
80
|
|
|
55
81
|
for (const name of Object.keys(interfaces)) {
|
|
56
82
|
for (const iface of interfaces[name]) {
|
|
57
|
-
if (iface
|
|
83
|
+
if (isIPv4(iface) && !iface.internal) {
|
|
58
84
|
results.push({ name, address: iface.address });
|
|
59
85
|
}
|
|
60
86
|
}
|