minivibe 0.2.0 → 0.2.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/README.md +27 -37
- package/agent/agent.js +42 -34
- package/package.json +1 -1
- package/vibe.js +118 -62
package/README.md
CHANGED
|
@@ -16,21 +16,19 @@ CLI wrapper for Claude Code with mobile remote control via MiniVibe iOS app.
|
|
|
16
16
|
## Quick Start
|
|
17
17
|
|
|
18
18
|
```bash
|
|
19
|
-
# Install
|
|
19
|
+
# Install
|
|
20
20
|
npm install -g minivibe
|
|
21
21
|
|
|
22
|
-
#
|
|
23
|
-
vibe --login
|
|
24
|
-
vibe --login --headless # Server/EC2 (device code)
|
|
25
|
-
|
|
26
|
-
# Option 1: Direct bridge connection
|
|
27
|
-
vibe --bridge wss://ws.minivibeapp.com
|
|
22
|
+
# Login (one-time)
|
|
23
|
+
vibe --login
|
|
28
24
|
|
|
29
|
-
#
|
|
30
|
-
vibe
|
|
31
|
-
vibe
|
|
25
|
+
# Start coding with remote control!
|
|
26
|
+
vibe
|
|
27
|
+
vibe "Fix the bug in main.js"
|
|
32
28
|
```
|
|
33
29
|
|
|
30
|
+
> **Note:** For local-only use without remote control, just run `claude` directly.
|
|
31
|
+
|
|
34
32
|
## Installation
|
|
35
33
|
|
|
36
34
|
### From npm (Recommended)
|
|
@@ -80,22 +78,24 @@ Get token from MiniVibe iOS app: Settings > Copy Token for CLI.
|
|
|
80
78
|
|
|
81
79
|
## Usage Modes
|
|
82
80
|
|
|
83
|
-
### Direct
|
|
81
|
+
### Direct Mode (Default)
|
|
84
82
|
|
|
85
|
-
|
|
83
|
+
Just run `vibe` after logging in:
|
|
86
84
|
|
|
87
85
|
```bash
|
|
88
|
-
vibe
|
|
89
|
-
vibe
|
|
86
|
+
vibe # Start session
|
|
87
|
+
vibe "Fix the bug" # With initial prompt
|
|
88
|
+
vibe --e2e # With end-to-end encryption
|
|
90
89
|
```
|
|
91
90
|
|
|
92
91
|
### Agent Mode (Recommended for Servers)
|
|
93
92
|
|
|
94
|
-
Use a local agent to manage sessions:
|
|
93
|
+
Use a local agent to manage multiple sessions:
|
|
95
94
|
|
|
96
95
|
```bash
|
|
97
96
|
# Terminal 1: Start the agent (runs continuously)
|
|
98
|
-
vibe-agent --
|
|
97
|
+
vibe-agent --login # First time only
|
|
98
|
+
vibe-agent # Start daemon
|
|
99
99
|
|
|
100
100
|
# Terminal 2+: Create sessions via agent
|
|
101
101
|
vibe --agent
|
|
@@ -109,34 +109,25 @@ vibe --agent --name "Backend Work"
|
|
|
109
109
|
- Sessions survive network hiccups
|
|
110
110
|
- Cleaner process management
|
|
111
111
|
|
|
112
|
-
### Local Mode (No Bridge)
|
|
113
|
-
|
|
114
|
-
Run without remote control:
|
|
115
|
-
|
|
116
|
-
```bash
|
|
117
|
-
vibe # Interactive
|
|
118
|
-
vibe "Explain this code" # With prompt
|
|
119
|
-
```
|
|
120
|
-
|
|
121
112
|
## Options
|
|
122
113
|
|
|
123
114
|
### vibe
|
|
124
115
|
|
|
125
116
|
| Option | Description |
|
|
126
117
|
|--------|-------------|
|
|
127
|
-
| `--
|
|
118
|
+
| `--login` | Sign in with Google |
|
|
119
|
+
| `--headless` | Use device code flow for headless environments |
|
|
128
120
|
| `--agent [url]` | Connect via local vibe-agent (default: auto-discover) |
|
|
129
121
|
| `--name <name>` | Name this session (shown in mobile app) |
|
|
130
122
|
| `--resume <id>` | Resume a previous session (auto-detects directory) |
|
|
131
123
|
| `--attach <id>` | Attach to running session via local agent |
|
|
132
124
|
| `--remote <id>` | Remote control session via bridge (no local Claude needed) |
|
|
133
125
|
| `--list` | List running sessions on local agent |
|
|
134
|
-
| `--
|
|
135
|
-
| `--
|
|
126
|
+
| `--e2e` | Enable end-to-end encryption (auto key exchange with iOS) |
|
|
127
|
+
| `--dangerously-skip-permissions` | Auto-approve all tool executions |
|
|
128
|
+
| `--bridge <url>` | Override bridge URL (default: wss://ws.minivibeapp.com) |
|
|
136
129
|
| `--token <token>` | Set Firebase auth token manually |
|
|
137
130
|
| `--logout` | Remove stored auth token |
|
|
138
|
-
| `--dangerously-skip-permissions` | Auto-approve all tool executions |
|
|
139
|
-
| `--e2e` | Enable end-to-end encryption (auto key exchange with iOS) |
|
|
140
131
|
| `--node-pty` | Use Node.js PTY wrapper (required for Windows) |
|
|
141
132
|
| `--help, -h` | Show help message |
|
|
142
133
|
|
|
@@ -144,11 +135,11 @@ vibe "Explain this code" # With prompt
|
|
|
144
135
|
|
|
145
136
|
| Option | Description |
|
|
146
137
|
|--------|-------------|
|
|
147
|
-
| `--
|
|
148
|
-
| `--login` | Start device code login flow |
|
|
149
|
-
| `--token <token>` | Use specific Firebase token |
|
|
138
|
+
| `--login` | Sign in via device code flow |
|
|
150
139
|
| `--name <name>` | Set host display name |
|
|
151
140
|
| `--status` | Show current status and exit |
|
|
141
|
+
| `--bridge <url>` | Override bridge URL (default: wss://ws.minivibeapp.com) |
|
|
142
|
+
| `--token <token>` | Use specific Firebase token |
|
|
152
143
|
| `--help, -h` | Show help message |
|
|
153
144
|
|
|
154
145
|
## Skip Permissions Mode
|
|
@@ -156,7 +147,7 @@ vibe "Explain this code" # With prompt
|
|
|
156
147
|
For automated/headless environments where you trust the execution context:
|
|
157
148
|
|
|
158
149
|
```bash
|
|
159
|
-
vibe --dangerously-skip-permissions
|
|
150
|
+
vibe --dangerously-skip-permissions
|
|
160
151
|
vibe --dangerously-skip-permissions --agent
|
|
161
152
|
```
|
|
162
153
|
|
|
@@ -168,7 +159,7 @@ Enable E2E encryption to ensure the bridge server cannot read your message conte
|
|
|
168
159
|
|
|
169
160
|
```bash
|
|
170
161
|
# Start with E2E encryption enabled
|
|
171
|
-
vibe --e2e
|
|
162
|
+
vibe --e2e
|
|
172
163
|
```
|
|
173
164
|
|
|
174
165
|
Key exchange happens automatically when both CLI and iOS connect to the bridge:
|
|
@@ -207,7 +198,7 @@ Key exchange happens automatically when both CLI and iOS connect to the bridge:
|
|
|
207
198
|
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
|
|
208
199
|
```
|
|
209
200
|
|
|
210
|
-
**Direct mode:** `vibe
|
|
201
|
+
**Direct mode:** `vibe` connects directly to bridge server
|
|
211
202
|
|
|
212
203
|
**Agent mode:** `vibe --agent` connects to local `vibe-agent`, which manages bridge connection
|
|
213
204
|
|
|
@@ -238,7 +229,6 @@ May also need Visual Studio Build Tools and Python for native compilation.
|
|
|
238
229
|
| Path | Description |
|
|
239
230
|
|------|-------------|
|
|
240
231
|
| `~/.vibe/auth.json` | Stored authentication (token + refresh token) |
|
|
241
|
-
| `~/.vibe/token` | Legacy token file |
|
|
242
232
|
| `~/.vibe/e2e-keys.json` | E2E encryption keypair and peer info |
|
|
243
233
|
| `~/.vibe-agent/port` | Agent port file for auto-discovery |
|
|
244
234
|
|
package/agent/agent.js
CHANGED
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
* - Stop running sessions
|
|
10
10
|
*
|
|
11
11
|
* Usage:
|
|
12
|
-
* vibe-agent --
|
|
13
|
-
* vibe-agent
|
|
12
|
+
* vibe-agent --login Sign in (one-time)
|
|
13
|
+
* vibe-agent Start agent daemon
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
const { spawn, execSync } = require('child_process');
|
|
@@ -35,6 +35,22 @@ const HEARTBEAT_INTERVAL_MS = 30000;
|
|
|
35
35
|
const LOCAL_SERVER_PORT = 9999;
|
|
36
36
|
const PORT_FILE = path.join(os.homedir(), '.vibe-agent', 'port');
|
|
37
37
|
const MAX_SESSION_HISTORY_AGE_DAYS = 30;
|
|
38
|
+
const DEFAULT_BRIDGE_URL = 'wss://ws.minivibeapp.com';
|
|
39
|
+
|
|
40
|
+
// Show welcome message for first-time users (no auth)
|
|
41
|
+
function showWelcomeMessage() {
|
|
42
|
+
console.log(`
|
|
43
|
+
Welcome to vibe-agent!
|
|
44
|
+
|
|
45
|
+
vibe-agent lets you manage Claude Code sessions from your iPhone.
|
|
46
|
+
|
|
47
|
+
To get started:
|
|
48
|
+
1. Download MiniVibe from the App Store
|
|
49
|
+
2. Run: vibe-agent --login
|
|
50
|
+
|
|
51
|
+
For help: vibe-agent --help
|
|
52
|
+
`);
|
|
53
|
+
}
|
|
38
54
|
|
|
39
55
|
// Colors for terminal output
|
|
40
56
|
const colors = {
|
|
@@ -225,9 +241,10 @@ const localClients = new Map();
|
|
|
225
241
|
// ====================
|
|
226
242
|
|
|
227
243
|
function connect() {
|
|
244
|
+
// Bridge URL should always be set (defaults to DEFAULT_BRIDGE_URL)
|
|
228
245
|
if (!bridgeUrl) {
|
|
229
|
-
log('No bridge URL configured', colors.red);
|
|
230
|
-
|
|
246
|
+
log('No bridge URL configured (this should not happen)', colors.red);
|
|
247
|
+
process.exit(1);
|
|
231
248
|
}
|
|
232
249
|
|
|
233
250
|
log(`Connecting to ${bridgeUrl}...`, colors.cyan);
|
|
@@ -244,11 +261,13 @@ function connect() {
|
|
|
244
261
|
log('Connected to bridge', colors.green);
|
|
245
262
|
clearTimeout(reconnectTimer);
|
|
246
263
|
|
|
247
|
-
// Authenticate
|
|
264
|
+
// Authenticate (auth is required, so this should always be true)
|
|
248
265
|
if (authToken) {
|
|
249
266
|
send({ type: 'authenticate', token: authToken });
|
|
250
267
|
} else {
|
|
251
|
-
|
|
268
|
+
// Failsafe - should not reach here due to startup check
|
|
269
|
+
showWelcomeMessage();
|
|
270
|
+
process.exit(1);
|
|
252
271
|
}
|
|
253
272
|
});
|
|
254
273
|
|
|
@@ -1319,27 +1338,24 @@ function printHelp() {
|
|
|
1319
1338
|
${colors.cyan}${colors.bold}vibe-agent${colors.reset} - Persistent daemon for remote Claude Code sessions
|
|
1320
1339
|
|
|
1321
1340
|
${colors.bold}Usage:${colors.reset}
|
|
1322
|
-
vibe-agent
|
|
1323
|
-
vibe-agent --login
|
|
1324
|
-
vibe-agent --status
|
|
1341
|
+
vibe-agent Start agent daemon
|
|
1342
|
+
vibe-agent --login Sign in with Google (one-time)
|
|
1343
|
+
vibe-agent --status Show agent status
|
|
1325
1344
|
|
|
1326
1345
|
${colors.bold}Options:${colors.reset}
|
|
1327
|
-
--
|
|
1328
|
-
--login Start device code login flow
|
|
1329
|
-
--token <token> Use specific Firebase token
|
|
1346
|
+
--login Sign in via device code flow
|
|
1330
1347
|
--name <name> Set host display name
|
|
1331
1348
|
--status Show current status and exit
|
|
1332
1349
|
--help, -h Show this help
|
|
1333
1350
|
|
|
1334
|
-
${colors.bold}
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
# Start agent daemon
|
|
1339
|
-
vibe-agent --bridge wss://ws.minivibeapp.com
|
|
1351
|
+
${colors.bold}Advanced:${colors.reset}
|
|
1352
|
+
--bridge <url> Override bridge URL (default: wss://ws.minivibeapp.com)
|
|
1353
|
+
--token <token> Use specific Firebase token
|
|
1340
1354
|
|
|
1341
|
-
|
|
1342
|
-
vibe-agent --
|
|
1355
|
+
${colors.bold}Examples:${colors.reset}
|
|
1356
|
+
vibe-agent --login Sign in (one-time setup)
|
|
1357
|
+
vibe-agent Start agent
|
|
1358
|
+
vibe-agent --name "EC2" Start with custom name
|
|
1343
1359
|
`);
|
|
1344
1360
|
}
|
|
1345
1361
|
|
|
@@ -1397,7 +1413,7 @@ async function main() {
|
|
|
1397
1413
|
// Load saved config
|
|
1398
1414
|
const config = loadConfig();
|
|
1399
1415
|
|
|
1400
|
-
bridgeUrl = options.bridge || config.bridgeUrl;
|
|
1416
|
+
bridgeUrl = options.bridge || config.bridgeUrl || DEFAULT_BRIDGE_URL;
|
|
1401
1417
|
hostName = options.name || config.hostName || os.hostname();
|
|
1402
1418
|
agentId = config.agentId || null; // Load persisted agentId
|
|
1403
1419
|
|
|
@@ -1410,7 +1426,7 @@ async function main() {
|
|
|
1410
1426
|
}
|
|
1411
1427
|
|
|
1412
1428
|
// Save config for next time
|
|
1413
|
-
if (
|
|
1429
|
+
if (options.bridge) {
|
|
1414
1430
|
config.bridgeUrl = bridgeUrl;
|
|
1415
1431
|
}
|
|
1416
1432
|
if (options.name) {
|
|
@@ -1420,7 +1436,7 @@ async function main() {
|
|
|
1420
1436
|
|
|
1421
1437
|
// Status check
|
|
1422
1438
|
if (options.status) {
|
|
1423
|
-
console.log(`Bridge URL: ${bridgeUrl
|
|
1439
|
+
console.log(`Bridge URL: ${bridgeUrl}`);
|
|
1424
1440
|
console.log(`Host Name: ${hostName}`);
|
|
1425
1441
|
console.log(`Auth Token: ${authToken ? 'Configured' : 'Not configured'}`);
|
|
1426
1442
|
console.log(`Agent ID: ${agentId || 'Will be assigned on first connect'}`);
|
|
@@ -1429,23 +1445,15 @@ async function main() {
|
|
|
1429
1445
|
|
|
1430
1446
|
// Login flow
|
|
1431
1447
|
if (options.login) {
|
|
1432
|
-
if (!bridgeUrl) {
|
|
1433
|
-
log('--bridge URL required for login', colors.red);
|
|
1434
|
-
process.exit(1);
|
|
1435
|
-
}
|
|
1436
1448
|
const httpUrl = bridgeUrl.replace('wss://', 'https://').replace('ws://', 'http://');
|
|
1437
1449
|
await startHeadlessLogin(httpUrl);
|
|
1438
1450
|
return;
|
|
1439
1451
|
}
|
|
1440
1452
|
|
|
1441
|
-
//
|
|
1442
|
-
if (!bridgeUrl) {
|
|
1443
|
-
log('No bridge URL. Run: vibe-agent --bridge wss://ws.minivibeapp.com', colors.red);
|
|
1444
|
-
process.exit(1);
|
|
1445
|
-
}
|
|
1446
|
-
|
|
1453
|
+
// Require auth (block instead of warn)
|
|
1447
1454
|
if (!authToken) {
|
|
1448
|
-
|
|
1455
|
+
showWelcomeMessage();
|
|
1456
|
+
process.exit(1);
|
|
1449
1457
|
}
|
|
1450
1458
|
|
|
1451
1459
|
// Banner
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "minivibe",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "CLI wrapper for Claude Code with mobile remote control via MiniVibe iOS app",
|
|
5
5
|
"author": "MiniVibe <hello@minivibeapp.com>",
|
|
6
6
|
"homepage": "https://github.com/minivibeapp/minivibe",
|
package/vibe.js
CHANGED
|
@@ -19,6 +19,49 @@ const os = require('os');
|
|
|
19
19
|
const crypto = require('crypto');
|
|
20
20
|
const e2e = require('./e2e');
|
|
21
21
|
|
|
22
|
+
// Check if Claude Code is installed
|
|
23
|
+
function checkClaudeInstalled() {
|
|
24
|
+
try {
|
|
25
|
+
execSync('claude --version', { stdio: 'ignore' });
|
|
26
|
+
return true;
|
|
27
|
+
} catch {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Show welcome message for first-time users (no auth)
|
|
33
|
+
function showWelcomeMessage() {
|
|
34
|
+
console.log(`
|
|
35
|
+
Welcome to MiniVibe!
|
|
36
|
+
|
|
37
|
+
MiniVibe lets you control Claude Code from your iPhone.
|
|
38
|
+
|
|
39
|
+
To get started:
|
|
40
|
+
1. Download MiniVibe from the App Store
|
|
41
|
+
2. Run: vibe --login
|
|
42
|
+
|
|
43
|
+
For help: vibe --help
|
|
44
|
+
`);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Show error when Claude Code is not installed
|
|
48
|
+
function showClaudeNotFoundMessage() {
|
|
49
|
+
console.log(`
|
|
50
|
+
Claude Code not found
|
|
51
|
+
|
|
52
|
+
MiniVibe requires Claude Code CLI to be installed.
|
|
53
|
+
|
|
54
|
+
Install Claude Code:
|
|
55
|
+
https://claude.ai/download
|
|
56
|
+
|
|
57
|
+
After installing, run:
|
|
58
|
+
vibe --login
|
|
59
|
+
`);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Default bridge URL
|
|
63
|
+
const DEFAULT_BRIDGE_URL = 'wss://ws.minivibeapp.com';
|
|
64
|
+
|
|
22
65
|
// Find claude executable
|
|
23
66
|
function findClaudePath() {
|
|
24
67
|
try {
|
|
@@ -303,54 +346,41 @@ let e2eEnabled = false; // --e2e mode: enable end-to-end encryption
|
|
|
303
346
|
for (let i = 0; i < args.length; i++) {
|
|
304
347
|
if (args[i] === '--help' || args[i] === '-h') {
|
|
305
348
|
console.log(`
|
|
306
|
-
vibe
|
|
349
|
+
vibe - Claude Code with mobile remote control
|
|
307
350
|
|
|
308
351
|
Usage:
|
|
309
|
-
vibe
|
|
310
|
-
vibe
|
|
311
|
-
vibe --
|
|
312
|
-
vibe --
|
|
313
|
-
vibe --attach <id> Attach to session via local agent (full terminal)
|
|
314
|
-
vibe --remote <id> --bridge <url> Remote control session (no local Claude needed)
|
|
315
|
-
vibe --list List running sessions on local agent
|
|
316
|
-
vibe --login Sign in via minivibeapp.com (opens browser)
|
|
317
|
-
vibe --login --headless Sign in on headless server (no browser)
|
|
318
|
-
vibe Start interactive session
|
|
352
|
+
vibe Start session (connects to bridge)
|
|
353
|
+
vibe "prompt" Start with initial prompt
|
|
354
|
+
vibe --login Sign in with Google
|
|
355
|
+
vibe --agent Connect via local vibe-agent
|
|
319
356
|
|
|
320
357
|
Options:
|
|
321
|
-
--
|
|
322
|
-
--
|
|
358
|
+
--login Sign in via minivibeapp.com (opens browser)
|
|
359
|
+
--headless Use device code flow for servers (no browser)
|
|
360
|
+
--agent [url] Connect via local vibe-agent (default: auto-discover)
|
|
323
361
|
--name <name> Name this session (shown in mobile app)
|
|
324
|
-
--resume <id> Resume a previous session
|
|
325
|
-
--
|
|
326
|
-
|
|
362
|
+
--resume <id> Resume a previous session
|
|
363
|
+
--e2e Enable end-to-end encryption
|
|
364
|
+
|
|
365
|
+
Advanced:
|
|
366
|
+
--bridge <url> Override bridge URL (default: wss://ws.minivibeapp.com)
|
|
367
|
+
--attach <id> Attach to session via local agent (full terminal)
|
|
368
|
+
--remote <id> Remote control session via bridge (no local Claude needed)
|
|
327
369
|
--list List running sessions on local agent
|
|
328
|
-
--login Sign in via minivibeapp.com (opens browser)
|
|
329
|
-
--headless Don't open browser (for servers without display)
|
|
330
370
|
--token <token> Set Firebase auth token manually
|
|
331
371
|
--logout Remove stored auth token
|
|
332
|
-
--node-pty Use Node.js PTY wrapper (required for Windows
|
|
333
|
-
--dangerously-skip-permissions
|
|
334
|
-
--e2e Enable end-to-end encryption (auto key exchange with iOS)
|
|
372
|
+
--node-pty Use Node.js PTY wrapper (required for Windows)
|
|
373
|
+
--dangerously-skip-permissions Auto-approve all tool executions
|
|
335
374
|
--help, -h Show this help message
|
|
336
375
|
|
|
337
|
-
Attach vs Remote:
|
|
338
|
-
--attach <id> LOCAL: Full terminal passthrough via local vibe-agent
|
|
339
|
-
--remote <id> --bridge <url> REMOTE: Chat-style control via bridge server
|
|
340
|
-
- No local agent or Claude Code needed
|
|
341
|
-
- Control sessions running on any host
|
|
342
|
-
|
|
343
|
-
Authentication:
|
|
344
|
-
Use --login to sign in via minivibeapp.com (opens browser automatically).
|
|
345
|
-
Use --login --headless on servers without a display (EC2, etc.)
|
|
346
|
-
|
|
347
376
|
Examples:
|
|
348
|
-
vibe --login
|
|
349
|
-
vibe
|
|
350
|
-
vibe
|
|
351
|
-
vibe --
|
|
352
|
-
vibe --
|
|
353
|
-
|
|
377
|
+
vibe --login Sign in (one-time setup)
|
|
378
|
+
vibe Start session
|
|
379
|
+
vibe "Fix the bug" Start with prompt
|
|
380
|
+
vibe --e2e Enable encryption
|
|
381
|
+
vibe --agent Use local agent
|
|
382
|
+
|
|
383
|
+
For local-only use without remote control, run 'claude' directly.
|
|
354
384
|
`);
|
|
355
385
|
process.exit(0);
|
|
356
386
|
} else if (args[i] === '--headless') {
|
|
@@ -442,6 +472,39 @@ if (!authToken) {
|
|
|
442
472
|
authToken = getStoredToken();
|
|
443
473
|
}
|
|
444
474
|
|
|
475
|
+
// ====================
|
|
476
|
+
// Startup Checks
|
|
477
|
+
// ====================
|
|
478
|
+
|
|
479
|
+
// Skip checks if in login mode (already handled above)
|
|
480
|
+
if (!loginMode) {
|
|
481
|
+
const isAgentMode = !!agentUrl || listSessions;
|
|
482
|
+
|
|
483
|
+
// 1. --remote mode doesn't need local Claude (controls remote session)
|
|
484
|
+
// 2. --list mode doesn't need local Claude (just queries agent)
|
|
485
|
+
// 3. All other modes need Claude installed
|
|
486
|
+
if (!remoteAttachMode && !listSessions && !checkClaudeInstalled()) {
|
|
487
|
+
showClaudeNotFoundMessage();
|
|
488
|
+
process.exit(1);
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
// 3. Check auth (unless agent mode - agent handles its own auth)
|
|
492
|
+
if (!isAgentMode && !authToken) {
|
|
493
|
+
showWelcomeMessage();
|
|
494
|
+
process.exit(1);
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
// 4. Default to bridge URL when authenticated (and not in agent mode)
|
|
498
|
+
if (!isAgentMode && !bridgeUrl && authToken) {
|
|
499
|
+
bridgeUrl = DEFAULT_BRIDGE_URL;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
// 5. --remote without --bridge: use default bridge
|
|
503
|
+
if (remoteAttachMode && !bridgeUrl) {
|
|
504
|
+
bridgeUrl = DEFAULT_BRIDGE_URL;
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
|
|
445
508
|
// Initialize E2E encryption if enabled
|
|
446
509
|
// Track if E2E is pending (enabled but not yet established)
|
|
447
510
|
let e2ePending = false;
|
|
@@ -458,20 +521,7 @@ if (e2eEnabled) {
|
|
|
458
521
|
}
|
|
459
522
|
}
|
|
460
523
|
|
|
461
|
-
//
|
|
462
|
-
if (remoteAttachMode && !bridgeUrl) {
|
|
463
|
-
console.error('Error: --remote requires --bridge <url>');
|
|
464
|
-
console.error('Example: vibe --remote abc123 --bridge wss://ws.minivibeapp.com');
|
|
465
|
-
process.exit(1);
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
// Validate E2E requires bridge (for key exchange)
|
|
469
|
-
if (e2ePending && !bridgeUrl && !agentUrl) {
|
|
470
|
-
console.error('Error: --e2e with no saved peer requires --bridge <url>');
|
|
471
|
-
console.error('E2E encryption needs a bridge to exchange keys with iOS app.');
|
|
472
|
-
console.error('Example: vibe --e2e --bridge wss://ws.minivibeapp.com');
|
|
473
|
-
process.exit(1);
|
|
474
|
-
}
|
|
524
|
+
// Note: E2E key exchange now works automatically since bridge is defaulted when authenticated
|
|
475
525
|
|
|
476
526
|
// Session state
|
|
477
527
|
const sessionId = resumeSessionId || uuidv4();
|
|
@@ -693,13 +743,10 @@ function connectToBridge() {
|
|
|
693
743
|
|
|
694
744
|
const isAgentMode = !!agentUrl;
|
|
695
745
|
|
|
696
|
-
//
|
|
746
|
+
// Auth should already be checked in startup, but double-check here
|
|
697
747
|
if (!isAgentMode && !authToken) {
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
log(' Get your token from the MiniVibe mobile app.', colors.dim);
|
|
701
|
-
log('', '');
|
|
702
|
-
log(' Continuing without authentication (bridge may reject connection)', colors.dim);
|
|
748
|
+
showWelcomeMessage();
|
|
749
|
+
process.exit(1);
|
|
703
750
|
}
|
|
704
751
|
|
|
705
752
|
if (isAgentMode) {
|
|
@@ -765,6 +812,17 @@ function connectToBridge() {
|
|
|
765
812
|
});
|
|
766
813
|
|
|
767
814
|
bridgeSocket.on('error', (err) => {
|
|
815
|
+
if (isAgentMode && err.code === 'ECONNREFUSED') {
|
|
816
|
+
// Agent not running - show helpful message
|
|
817
|
+
console.log(`
|
|
818
|
+
Cannot connect to vibe-agent at ${targetUrl}
|
|
819
|
+
|
|
820
|
+
Make sure vibe-agent is running:
|
|
821
|
+
vibe-agent --login # First time
|
|
822
|
+
vibe-agent # Start daemon
|
|
823
|
+
`);
|
|
824
|
+
process.exit(1);
|
|
825
|
+
}
|
|
768
826
|
logStatus(`Bridge connection error: ${err.message}`);
|
|
769
827
|
});
|
|
770
828
|
}
|
|
@@ -2122,18 +2180,16 @@ function setupShutdown() {
|
|
|
2122
2180
|
// ====================
|
|
2123
2181
|
|
|
2124
2182
|
function remoteAttachMain() {
|
|
2125
|
-
// Validate before displaying banner
|
|
2183
|
+
// Validate before displaying banner (redundant with startup checks, but good failsafe)
|
|
2126
2184
|
if (!authToken) {
|
|
2127
|
-
|
|
2128
|
-
log('❌ Remote attach requires authentication', colors.red);
|
|
2129
|
-
log(' Run: vibe --login --bridge ' + bridgeUrl, colors.dim);
|
|
2185
|
+
showWelcomeMessage();
|
|
2130
2186
|
process.exit(1);
|
|
2131
2187
|
}
|
|
2132
2188
|
|
|
2133
2189
|
if (!resumeSessionId) {
|
|
2134
2190
|
console.log('');
|
|
2135
2191
|
log('❌ Remote mode requires a session ID', colors.red);
|
|
2136
|
-
log(' Run: vibe --remote <session-id>
|
|
2192
|
+
log(' Run: vibe --remote <session-id>', colors.dim);
|
|
2137
2193
|
process.exit(1);
|
|
2138
2194
|
}
|
|
2139
2195
|
|