minivibe 0.2.2 → 0.2.6
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 +4 -4
- package/agent/agent.js +56 -15
- package/package.json +1 -1
- package/vibe.js +50 -13
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ CLI wrapper for Claude Code with mobile remote control via MiniVibe iOS app.
|
|
|
20
20
|
npm install -g minivibe
|
|
21
21
|
|
|
22
22
|
# Login (one-time)
|
|
23
|
-
vibe
|
|
23
|
+
vibe login
|
|
24
24
|
|
|
25
25
|
# Start coding with remote control!
|
|
26
26
|
vibe
|
|
@@ -55,7 +55,7 @@ npm link
|
|
|
55
55
|
### Browser Login (Desktop)
|
|
56
56
|
|
|
57
57
|
```bash
|
|
58
|
-
vibe
|
|
58
|
+
vibe login
|
|
59
59
|
```
|
|
60
60
|
|
|
61
61
|
Opens browser for Google sign-in. Token is saved to `~/.vibe/auth.json`.
|
|
@@ -63,7 +63,7 @@ Opens browser for Google sign-in. Token is saved to `~/.vibe/auth.json`.
|
|
|
63
63
|
### Headless Login (Servers/EC2)
|
|
64
64
|
|
|
65
65
|
```bash
|
|
66
|
-
vibe
|
|
66
|
+
vibe login --headless
|
|
67
67
|
```
|
|
68
68
|
|
|
69
69
|
Displays a device code. Visit the URL on any device to authenticate.
|
|
@@ -94,7 +94,7 @@ Use a local agent to manage multiple sessions:
|
|
|
94
94
|
|
|
95
95
|
```bash
|
|
96
96
|
# Terminal 1: Start the agent (runs continuously)
|
|
97
|
-
vibe-agent
|
|
97
|
+
vibe-agent login # First time only
|
|
98
98
|
vibe-agent # Start daemon
|
|
99
99
|
|
|
100
100
|
# Terminal 2+: Create sessions via agent
|
package/agent/agent.js
CHANGED
|
@@ -25,9 +25,13 @@ const os = require('os');
|
|
|
25
25
|
// Configuration
|
|
26
26
|
// ====================
|
|
27
27
|
|
|
28
|
+
// Shared auth directory (same as vibe CLI)
|
|
29
|
+
const SHARED_AUTH_DIR = path.join(os.homedir(), '.vibe');
|
|
30
|
+
const AUTH_FILE = path.join(SHARED_AUTH_DIR, 'auth.json');
|
|
31
|
+
|
|
32
|
+
// Agent-specific config directory
|
|
28
33
|
const CONFIG_DIR = path.join(os.homedir(), '.vibe-agent');
|
|
29
34
|
const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
|
|
30
|
-
const AUTH_FILE = path.join(CONFIG_DIR, 'auth.json');
|
|
31
35
|
const SESSION_HISTORY_FILE = path.join(CONFIG_DIR, 'session-history.json');
|
|
32
36
|
|
|
33
37
|
const RECONNECT_DELAY_MS = 5000;
|
|
@@ -36,6 +40,7 @@ const LOCAL_SERVER_PORT = 9999;
|
|
|
36
40
|
const PORT_FILE = path.join(os.homedir(), '.vibe-agent', 'port');
|
|
37
41
|
const MAX_SESSION_HISTORY_AGE_DAYS = 30;
|
|
38
42
|
const DEFAULT_BRIDGE_URL = 'wss://ws.minivibeapp.com';
|
|
43
|
+
const PAIRING_URL = 'https://minivibeapp.com/pair';
|
|
39
44
|
|
|
40
45
|
// Show welcome message for first-time users (no auth)
|
|
41
46
|
function showWelcomeMessage() {
|
|
@@ -46,9 +51,10 @@ vibe-agent lets you manage Claude Code sessions from your iPhone.
|
|
|
46
51
|
|
|
47
52
|
To get started:
|
|
48
53
|
1. Download MiniVibe from the App Store
|
|
49
|
-
2. Run: vibe-agent
|
|
54
|
+
2. Run: vibe-agent login
|
|
55
|
+
(or 'vibe login' - auth is shared between vibe and vibe-agent)
|
|
50
56
|
|
|
51
|
-
For help: vibe-agent
|
|
57
|
+
For help: vibe-agent help
|
|
52
58
|
`);
|
|
53
59
|
}
|
|
54
60
|
|
|
@@ -111,8 +117,8 @@ function loadAuth() {
|
|
|
111
117
|
|
|
112
118
|
function saveAuth(idToken, refreshToken = null) {
|
|
113
119
|
try {
|
|
114
|
-
if (!fs.existsSync(
|
|
115
|
-
fs.mkdirSync(
|
|
120
|
+
if (!fs.existsSync(SHARED_AUTH_DIR)) {
|
|
121
|
+
fs.mkdirSync(SHARED_AUTH_DIR, { recursive: true });
|
|
116
122
|
}
|
|
117
123
|
const data = { idToken, refreshToken, updatedAt: new Date().toISOString() };
|
|
118
124
|
fs.writeFileSync(AUTH_FILE, JSON.stringify(data, null, 2), 'utf8');
|
|
@@ -1282,7 +1288,7 @@ ${'='.repeat(40)}
|
|
|
1282
1288
|
|
|
1283
1289
|
const { deviceId, code, expiresIn } = await codeRes.json();
|
|
1284
1290
|
|
|
1285
|
-
console.log(` Visit: ${
|
|
1291
|
+
console.log(` Visit: ${PAIRING_URL}`);
|
|
1286
1292
|
console.log(` Code: ${colors.bold}${code}${colors.reset}`);
|
|
1287
1293
|
console.log('');
|
|
1288
1294
|
console.log(` Code expires in ${Math.floor(expiresIn / 60)} minutes.`);
|
|
@@ -1339,32 +1345,49 @@ ${colors.cyan}${colors.bold}vibe-agent${colors.reset} - Persistent daemon for re
|
|
|
1339
1345
|
|
|
1340
1346
|
${colors.bold}Usage:${colors.reset}
|
|
1341
1347
|
vibe-agent Start agent daemon
|
|
1342
|
-
vibe-agent
|
|
1343
|
-
vibe-agent
|
|
1348
|
+
vibe-agent login Sign in with Google (one-time)
|
|
1349
|
+
vibe-agent logout Sign out and clear credentials
|
|
1350
|
+
vibe-agent status Show agent status
|
|
1351
|
+
|
|
1352
|
+
${colors.bold}Commands:${colors.reset}
|
|
1353
|
+
login Sign in via device code flow
|
|
1354
|
+
logout Sign out and clear saved credentials
|
|
1355
|
+
status Show current status and exit
|
|
1356
|
+
help Show this help
|
|
1344
1357
|
|
|
1345
1358
|
${colors.bold}Options:${colors.reset}
|
|
1346
|
-
--login Sign in via device code flow
|
|
1347
1359
|
--name <name> Set host display name
|
|
1348
|
-
--status Show current status and exit
|
|
1349
|
-
--help, -h Show this help
|
|
1350
|
-
|
|
1351
|
-
${colors.bold}Advanced:${colors.reset}
|
|
1352
1360
|
--bridge <url> Override bridge URL (default: wss://ws.minivibeapp.com)
|
|
1353
1361
|
--token <token> Use specific Firebase token
|
|
1354
1362
|
|
|
1355
1363
|
${colors.bold}Examples:${colors.reset}
|
|
1356
|
-
vibe-agent
|
|
1364
|
+
vibe-agent login Sign in (one-time setup)
|
|
1357
1365
|
vibe-agent Start agent
|
|
1358
1366
|
vibe-agent --name "EC2" Start with custom name
|
|
1359
1367
|
`);
|
|
1360
1368
|
}
|
|
1361
1369
|
|
|
1362
1370
|
function parseArgs() {
|
|
1363
|
-
const
|
|
1371
|
+
const rawArgs = process.argv.slice(2);
|
|
1372
|
+
|
|
1373
|
+
// Support subcommand style (vibe-agent login) alongside flag style (vibe-agent --login)
|
|
1374
|
+
const subcommands = {
|
|
1375
|
+
'login': '--login',
|
|
1376
|
+
'logout': '--logout',
|
|
1377
|
+
'status': '--status',
|
|
1378
|
+
'help': '--help'
|
|
1379
|
+
};
|
|
1380
|
+
|
|
1381
|
+
// Transform first arg if it's a subcommand
|
|
1382
|
+
const args = rawArgs.length > 0 && subcommands[rawArgs[0]]
|
|
1383
|
+
? [subcommands[rawArgs[0]], ...rawArgs.slice(1)]
|
|
1384
|
+
: rawArgs;
|
|
1385
|
+
|
|
1364
1386
|
const options = {
|
|
1365
1387
|
bridge: null,
|
|
1366
1388
|
token: null,
|
|
1367
1389
|
login: false,
|
|
1390
|
+
logout: false,
|
|
1368
1391
|
name: null,
|
|
1369
1392
|
status: false,
|
|
1370
1393
|
help: false
|
|
@@ -1382,6 +1405,9 @@ function parseArgs() {
|
|
|
1382
1405
|
case '--login':
|
|
1383
1406
|
options.login = true;
|
|
1384
1407
|
break;
|
|
1408
|
+
case '--logout':
|
|
1409
|
+
options.logout = true;
|
|
1410
|
+
break;
|
|
1385
1411
|
case '--name':
|
|
1386
1412
|
options.name = args[++i];
|
|
1387
1413
|
break;
|
|
@@ -1443,6 +1469,21 @@ async function main() {
|
|
|
1443
1469
|
process.exit(0);
|
|
1444
1470
|
}
|
|
1445
1471
|
|
|
1472
|
+
// Logout flow
|
|
1473
|
+
if (options.logout) {
|
|
1474
|
+
try {
|
|
1475
|
+
if (fs.existsSync(AUTH_FILE)) {
|
|
1476
|
+
fs.unlinkSync(AUTH_FILE);
|
|
1477
|
+
log('Logged out successfully', colors.green);
|
|
1478
|
+
} else {
|
|
1479
|
+
log('Not logged in', colors.yellow);
|
|
1480
|
+
}
|
|
1481
|
+
} catch (err) {
|
|
1482
|
+
log(`Logout failed: ${err.message}`, colors.red);
|
|
1483
|
+
}
|
|
1484
|
+
process.exit(0);
|
|
1485
|
+
}
|
|
1486
|
+
|
|
1446
1487
|
// Login flow
|
|
1447
1488
|
if (options.login) {
|
|
1448
1489
|
const httpUrl = bridgeUrl.replace('wss://', 'https://').replace('ws://', 'http://');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "minivibe",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.6",
|
|
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
|
@@ -326,7 +326,21 @@ async function startHeadlessLogin() {
|
|
|
326
326
|
}
|
|
327
327
|
|
|
328
328
|
// Parse arguments
|
|
329
|
-
const
|
|
329
|
+
const rawArgs = process.argv.slice(2);
|
|
330
|
+
|
|
331
|
+
// Support subcommand style (vibe login) alongside flag style (vibe --login)
|
|
332
|
+
const subcommands = {
|
|
333
|
+
'login': '--login',
|
|
334
|
+
'logout': '--logout',
|
|
335
|
+
'status': '--status',
|
|
336
|
+
'help': '--help'
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
// Transform first arg if it's a subcommand
|
|
340
|
+
const args = rawArgs.length > 0 && subcommands[rawArgs[0]]
|
|
341
|
+
? [subcommands[rawArgs[0]], ...rawArgs.slice(1)]
|
|
342
|
+
: rawArgs;
|
|
343
|
+
|
|
330
344
|
let initialPrompt = null;
|
|
331
345
|
let resumeSessionId = null;
|
|
332
346
|
let bridgeUrl = null;
|
|
@@ -348,11 +362,15 @@ vibe - Claude Code with mobile remote control
|
|
|
348
362
|
Usage:
|
|
349
363
|
vibe Start session (connects to bridge)
|
|
350
364
|
vibe "prompt" Start with initial prompt
|
|
351
|
-
vibe
|
|
352
|
-
vibe
|
|
365
|
+
vibe login Sign in with Google
|
|
366
|
+
vibe logout Sign out
|
|
367
|
+
|
|
368
|
+
Commands:
|
|
369
|
+
login Sign in via minivibeapp.com (opens browser)
|
|
370
|
+
logout Sign out and remove stored auth
|
|
371
|
+
help Show this help message
|
|
353
372
|
|
|
354
373
|
Options:
|
|
355
|
-
--login Sign in via minivibeapp.com (opens browser)
|
|
356
374
|
--headless Use device code flow for servers (no browser)
|
|
357
375
|
--agent [url] Connect via local vibe-agent (default: auto-discover)
|
|
358
376
|
--name <name> Name this session (shown in mobile app)
|
|
@@ -365,13 +383,12 @@ Advanced:
|
|
|
365
383
|
--remote <id> Remote control session via bridge (no local Claude needed)
|
|
366
384
|
--list List running sessions on local agent
|
|
367
385
|
--token <token> Set Firebase auth token manually
|
|
368
|
-
--logout Remove stored auth token
|
|
369
386
|
--node-pty Use Node.js PTY wrapper (required for Windows)
|
|
370
387
|
--dangerously-skip-permissions Auto-approve all tool executions
|
|
371
388
|
--help, -h Show this help message
|
|
372
389
|
|
|
373
390
|
Examples:
|
|
374
|
-
vibe
|
|
391
|
+
vibe login Sign in (one-time setup)
|
|
375
392
|
vibe Start session
|
|
376
393
|
vibe "Fix the bug" Start with prompt
|
|
377
394
|
vibe --e2e Enable encryption
|
|
@@ -428,15 +445,35 @@ For local-only use without remote control, run 'claude' directly.
|
|
|
428
445
|
console.log('Token stored successfully');
|
|
429
446
|
i++;
|
|
430
447
|
} else if (args[i] === '--logout') {
|
|
431
|
-
|
|
432
|
-
|
|
448
|
+
let loggedOut = false;
|
|
449
|
+
let errors = [];
|
|
450
|
+
|
|
451
|
+
// Try to delete AUTH_FILE
|
|
452
|
+
if (fs.existsSync(AUTH_FILE)) {
|
|
453
|
+
try {
|
|
454
|
+
fs.unlinkSync(AUTH_FILE);
|
|
455
|
+
loggedOut = true;
|
|
456
|
+
} catch (err) {
|
|
457
|
+
errors.push(`auth.json: ${err.message}`);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
// Try to delete TOKEN_FILE regardless of first result
|
|
462
|
+
if (fs.existsSync(TOKEN_FILE)) {
|
|
463
|
+
try {
|
|
433
464
|
fs.unlinkSync(TOKEN_FILE);
|
|
434
|
-
|
|
435
|
-
}
|
|
436
|
-
|
|
465
|
+
loggedOut = true;
|
|
466
|
+
} catch (err) {
|
|
467
|
+
errors.push(`token: ${err.message}`);
|
|
437
468
|
}
|
|
438
|
-
}
|
|
439
|
-
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
if (errors.length > 0) {
|
|
472
|
+
console.error('Logout partially failed:', errors.join(', '));
|
|
473
|
+
} else if (loggedOut) {
|
|
474
|
+
console.log('Logged out successfully');
|
|
475
|
+
} else {
|
|
476
|
+
console.log('Not logged in');
|
|
440
477
|
}
|
|
441
478
|
process.exit(0);
|
|
442
479
|
} else if (args[i] === '--node-pty') {
|