minivibe 0.2.6 → 0.2.9

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.
Files changed (3) hide show
  1. package/agent/agent.js +3 -3
  2. package/package.json +1 -1
  3. package/vibe.js +36 -25
package/agent/agent.js CHANGED
@@ -9,7 +9,7 @@
9
9
  * - Stop running sessions
10
10
  *
11
11
  * Usage:
12
- * vibe-agent --login Sign in (one-time)
12
+ * vibe-agent login Sign in (one-time)
13
13
  * vibe-agent Start agent daemon
14
14
  */
15
15
 
@@ -736,7 +736,7 @@ function handleMessage(msg) {
736
736
  authToken = newToken;
737
737
  send({ type: 'authenticate', token: newToken });
738
738
  } else {
739
- log('Please re-login: vibe-agent --login', colors.red);
739
+ log('Please re-login: vibe-agent login', colors.red);
740
740
  }
741
741
  })();
742
742
  break;
@@ -1345,7 +1345,7 @@ ${colors.cyan}${colors.bold}vibe-agent${colors.reset} - Persistent daemon for re
1345
1345
 
1346
1346
  ${colors.bold}Usage:${colors.reset}
1347
1347
  vibe-agent Start agent daemon
1348
- vibe-agent login Sign in with Google (one-time)
1348
+ vibe-agent login Sign in (one-time)
1349
1349
  vibe-agent logout Sign out and clear credentials
1350
1350
  vibe-agent status Show agent status
1351
1351
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "minivibe",
3
- "version": "0.2.6",
3
+ "version": "0.2.9",
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
@@ -38,9 +38,9 @@ MiniVibe lets you control Claude Code from your iPhone.
38
38
 
39
39
  To get started:
40
40
  1. Download MiniVibe from the App Store
41
- 2. Run: vibe --login
41
+ 2. Run: vibe login
42
42
 
43
- For help: vibe --help
43
+ For help: vibe help
44
44
  `);
45
45
  }
46
46
 
@@ -55,7 +55,7 @@ Install Claude Code:
55
55
  https://claude.ai/download
56
56
 
57
57
  After installing, run:
58
- vibe --login
58
+ vibe login
59
59
  `);
60
60
  }
61
61
 
@@ -353,6 +353,7 @@ let skipPermissions = false; // --dangerously-skip-permissions mode
353
353
  let listSessions = false; // --list mode: list running sessions
354
354
  let remoteAttachMode = false; // --remote with --bridge: pure remote control (no local Claude)
355
355
  let e2eEnabled = false; // --e2e mode: enable end-to-end encryption
356
+ let verboseMode = false; // --verbose mode: show [vibe] debug messages
356
357
 
357
358
  for (let i = 0; i < args.length; i++) {
358
359
  if (args[i] === '--help' || args[i] === '-h') {
@@ -362,7 +363,7 @@ vibe - Claude Code with mobile remote control
362
363
  Usage:
363
364
  vibe Start session (connects to bridge)
364
365
  vibe "prompt" Start with initial prompt
365
- vibe login Sign in with Google
366
+ vibe login Sign in (Apple or Google)
366
367
  vibe logout Sign out
367
368
 
368
369
  Commands:
@@ -376,6 +377,7 @@ Options:
376
377
  --name <name> Name this session (shown in mobile app)
377
378
  --resume <id> Resume a previous session
378
379
  --e2e Enable end-to-end encryption
380
+ --verbose, -v Show detailed [vibe] status messages
379
381
 
380
382
  Advanced:
381
383
  --bridge <url> Override bridge URL (default: wss://ws.minivibeapp.com)
@@ -399,6 +401,8 @@ For local-only use without remote control, run 'claude' directly.
399
401
  process.exit(0);
400
402
  } else if (args[i] === '--headless') {
401
403
  headlessMode = true;
404
+ } else if (args[i] === '--verbose' || args[i] === '-v') {
405
+ verboseMode = true;
402
406
  } else if (args[i] === '--login') {
403
407
  // Defer login handling until we know if --headless is also present
404
408
  // Will be handled after the loop
@@ -558,7 +562,11 @@ if (e2eEnabled) {
558
562
  // Note: E2E key exchange now works automatically since bridge is defaulted when authenticated
559
563
 
560
564
  // Session state
565
+ // Support VIBE_SESSION_ID env var for fixed session IDs (e.g., playground)
566
+ // Bridge session ID can be any string, but Claude needs a valid UUID
567
+ const bridgeSessionId = process.env.VIBE_SESSION_ID;
561
568
  const sessionId = resumeSessionId || uuidv4();
569
+ const effectiveSessionId = bridgeSessionId || sessionId; // Use for bridge registration
562
570
  let claudeProcess = null;
563
571
  let isRunning = false;
564
572
  let isShuttingDown = false;
@@ -600,6 +608,9 @@ function logStderr(msg, color = '') {
600
608
  }
601
609
 
602
610
  function logStatus(msg) {
611
+ // Only log status messages in verbose mode
612
+ if (!verboseMode) return;
613
+
603
614
  // Use stderr when Claude is running to avoid corrupting PTY output
604
615
  if (isRunning) {
605
616
  logStderr(`[vibe] ${msg}`, colors.dim);
@@ -852,7 +863,7 @@ function connectToBridge() {
852
863
  Cannot connect to vibe-agent at ${targetUrl}
853
864
 
854
865
  Make sure vibe-agent is running:
855
- vibe-agent --login # First time
866
+ vibe-agent login # First time
856
867
  vibe-agent # Start daemon
857
868
  `);
858
869
  process.exit(1);
@@ -928,7 +939,7 @@ function handleBridgeMessage(msg) {
928
939
  // This is required before E2E key exchange so our keys can reach viewers
929
940
  bridgeSocket.send(JSON.stringify({
930
941
  type: 'register_session',
931
- sessionId,
942
+ sessionId: effectiveSessionId, // Use VIBE_SESSION_ID if set for fixed playground IDs
932
943
  path: process.cwd(),
933
944
  name: sessionName || path.basename(process.cwd()), // Use --name or fallback to directory name
934
945
  e2e: e2eEnabled // Indicate if this session has E2E enabled
@@ -942,7 +953,7 @@ function handleBridgeMessage(msg) {
942
953
  // Must be AFTER register_session so our type is 'provider' and keys reach viewers
943
954
  if (e2eEnabled && e2e.isEnabled()) {
944
955
  const keyExchangeMsg = e2e.createKeyExchangeMessage(true); // needsResponse=true
945
- keyExchangeMsg.sessionId = sessionId; // Include sessionId for routing
956
+ keyExchangeMsg.sessionId = effectiveSessionId; // Include sessionId for routing
946
957
  bridgeSocket.send(JSON.stringify(keyExchangeMsg));
947
958
  log('[E2E] Sent public key to bridge (waiting for peer)', colors.cyan);
948
959
  }
@@ -981,7 +992,7 @@ function handleBridgeMessage(msg) {
981
992
  log('║ Your token is invalid or expired. ║', colors.red);
982
993
  log('║ Please re-login: ║', colors.red);
983
994
  log('║ ║', colors.red);
984
- log('║ vibe --login ║', colors.red);
995
+ log('║ vibe login ║', colors.red);
985
996
  log('║ ║', colors.red);
986
997
  log('╚════════════════════════════════════════════╝', colors.red);
987
998
  log('', colors.red);
@@ -1042,7 +1053,7 @@ function handleBridgeMessage(msg) {
1042
1053
  if (!msg.data || msg.data.length === 0 || !msg.fileName) {
1043
1054
  sendToBridge({
1044
1055
  type: 'error',
1045
- sessionId: sessionId,
1056
+ sessionId: effectiveSessionId,
1046
1057
  message: 'Invalid file upload: missing data or fileName'
1047
1058
  });
1048
1059
  break;
@@ -1053,7 +1064,7 @@ function handleBridgeMessage(msg) {
1053
1064
  if (msg.data.length > MAX_BASE64_SIZE) {
1054
1065
  sendToBridge({
1055
1066
  type: 'error',
1056
- sessionId: sessionId,
1067
+ sessionId: effectiveSessionId,
1057
1068
  message: 'File too large (max 10MB)'
1058
1069
  });
1059
1070
  break;
@@ -1147,7 +1158,7 @@ function handleBridgeMessage(msg) {
1147
1158
  // Echo the message back using claude_message type (matches iOS handler)
1148
1159
  sendToBridge({
1149
1160
  type: 'claude_message',
1150
- sessionId: sessionId,
1161
+ sessionId: effectiveSessionId,
1151
1162
  message: {
1152
1163
  id: uuidv4(),
1153
1164
  sender: 'user',
@@ -1167,7 +1178,7 @@ function handleBridgeMessage(msg) {
1167
1178
  // Also send file_received confirmation
1168
1179
  sendToBridge({
1169
1180
  type: 'file_received',
1170
- sessionId: sessionId,
1181
+ sessionId: effectiveSessionId,
1171
1182
  fileName: safeName,
1172
1183
  localPath: filePath,
1173
1184
  size: fileBuffer.length
@@ -1177,7 +1188,7 @@ function handleBridgeMessage(msg) {
1177
1188
  log(`❌ Failed to save file: ${err.message}`, colors.red);
1178
1189
  sendToBridge({
1179
1190
  type: 'error',
1180
- sessionId: sessionId,
1191
+ sessionId: effectiveSessionId,
1181
1192
  message: `Failed to upload file: ${err.message}`
1182
1193
  });
1183
1194
  }
@@ -1192,7 +1203,7 @@ function handleBridgeMessage(msg) {
1192
1203
  if (!msg.images || !Array.isArray(msg.images) || msg.images.length === 0) {
1193
1204
  sendToBridge({
1194
1205
  type: 'error',
1195
- sessionId: sessionId,
1206
+ sessionId: effectiveSessionId,
1196
1207
  message: 'Invalid file upload: missing or empty images array'
1197
1208
  });
1198
1209
  break;
@@ -1204,7 +1215,7 @@ function handleBridgeMessage(msg) {
1204
1215
  if (totalBase64Size > MAX_TOTAL_BASE64_SIZE) {
1205
1216
  sendToBridge({
1206
1217
  type: 'error',
1207
- sessionId: sessionId,
1218
+ sessionId: effectiveSessionId,
1208
1219
  message: 'Total file size too large (max 50MB combined)'
1209
1220
  });
1210
1221
  break;
@@ -1319,7 +1330,7 @@ function handleBridgeMessage(msg) {
1319
1330
  // Echo the message back with attachments array
1320
1331
  sendToBridge({
1321
1332
  type: 'claude_message',
1322
- sessionId: sessionId,
1333
+ sessionId: effectiveSessionId,
1323
1334
  message: {
1324
1335
  id: uuidv4(),
1325
1336
  sender: 'user',
@@ -1332,7 +1343,7 @@ function handleBridgeMessage(msg) {
1332
1343
  // Send confirmation
1333
1344
  sendToBridge({
1334
1345
  type: 'files_received',
1335
- sessionId: sessionId,
1346
+ sessionId: effectiveSessionId,
1336
1347
  count: savedFiles.length,
1337
1348
  files: savedFiles.map(f => ({ fileName: f.name, localPath: f.path }))
1338
1349
  });
@@ -1343,7 +1354,7 @@ function handleBridgeMessage(msg) {
1343
1354
  log(`❌ Failed to process files: ${err.message}`, colors.red);
1344
1355
  sendToBridge({
1345
1356
  type: 'error',
1346
- sessionId: sessionId,
1357
+ sessionId: effectiveSessionId,
1347
1358
  message: `Failed to upload files: ${err.message}`
1348
1359
  });
1349
1360
  }
@@ -1472,7 +1483,7 @@ function handleBridgeMessage(msg) {
1472
1483
  log(`║ ${(msg.message || 'Invalid token').padEnd(42)}║`, colors.red);
1473
1484
  log('║ ║', colors.red);
1474
1485
  log('║ Please re-login: ║', colors.red);
1475
- log('║ vibe --login ║', colors.red);
1486
+ log('║ vibe login ║', colors.red);
1476
1487
  log('║ ║', colors.red);
1477
1488
  log('╚════════════════════════════════════════════╝', colors.red);
1478
1489
  log('', colors.red);
@@ -1867,7 +1878,7 @@ function processSessionMessage(msg) {
1867
1878
 
1868
1879
  sendToBridge({
1869
1880
  type: 'permission_request',
1870
- sessionId: sessionId,
1881
+ sessionId: effectiveSessionId,
1871
1882
  requestId: tool.id,
1872
1883
  command: tool.name,
1873
1884
  question: question,
@@ -1958,7 +1969,7 @@ function processSessionMessage(msg) {
1958
1969
  const usage = msg.message.usage;
1959
1970
  sendToBridge({
1960
1971
  type: 'token_usage',
1961
- sessionId: sessionId,
1972
+ sessionId: effectiveSessionId,
1962
1973
  model: msg.message.model || null,
1963
1974
  usage: {
1964
1975
  input_tokens: usage.input_tokens || 0,
@@ -2300,7 +2311,7 @@ function handleRemoteAttachMessage(msg) {
2300
2311
 
2301
2312
  case 'auth_error':
2302
2313
  log(`✗ Authentication failed: ${msg.message}`, colors.red);
2303
- log(' Run: vibe --login --bridge ' + bridgeUrl, colors.dim);
2314
+ log(' Run: vibe login --bridge ' + bridgeUrl, colors.dim);
2304
2315
  process.exit(1);
2305
2316
  break;
2306
2317
 
@@ -2455,7 +2466,7 @@ function setupRemoteAttachInput() {
2455
2466
  if (pendingPermission) {
2456
2467
  sendRemoteCommand({
2457
2468
  type: 'approve_permission',
2458
- sessionId: sessionId,
2469
+ sessionId: effectiveSessionId,
2459
2470
  requestId: pendingPermission.id
2460
2471
  });
2461
2472
  log('Sent approval', colors.green);
@@ -2467,7 +2478,7 @@ function setupRemoteAttachInput() {
2467
2478
  if (pendingPermission) {
2468
2479
  sendRemoteCommand({
2469
2480
  type: 'deny_permission',
2470
- sessionId: sessionId,
2481
+ sessionId: effectiveSessionId,
2471
2482
  requestId: pendingPermission.id
2472
2483
  });
2473
2484
  log('Sent denial', colors.yellow);
@@ -2503,7 +2514,7 @@ function setupRemoteAttachInput() {
2503
2514
  // Send message to Claude
2504
2515
  sendRemoteCommand({
2505
2516
  type: 'send_message',
2506
- sessionId: sessionId,
2517
+ sessionId: effectiveSessionId,
2507
2518
  content: input
2508
2519
  });
2509
2520
  log(`📤 Sent: ${truncateText(input, 50)}`, colors.dim);