@rehpic/vcli 0.1.0-beta.40.1 → 0.1.0-beta.42.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 CHANGED
@@ -1386,7 +1386,7 @@ function installLaunchAgent(vcliPath) {
1386
1386
  <array>
1387
1387
  <string>${vcliPath}</string>
1388
1388
  <string>service</string>
1389
- <string>start</string>
1389
+ <string>run</string>
1390
1390
  </array>
1391
1391
  <key>RunAtLoad</key>
1392
1392
  <true/>
@@ -1466,6 +1466,68 @@ function uninstallLaunchAgent() {
1466
1466
  } catch {
1467
1467
  }
1468
1468
  }
1469
+ async function compileMenuBar() {
1470
+ if (platform() !== "darwin") return null;
1471
+ const binaryPath = join(CONFIG_DIR, "VectorMenuBar");
1472
+ if (existsSync(binaryPath)) return binaryPath;
1473
+ const sourceCandidates = [
1474
+ join(CONFIG_DIR, "VectorMenuBar.swift"),
1475
+ // In the repo checkout (dev mode)
1476
+ join(process.cwd(), "cli", "macos", "VectorMenuBar.swift")
1477
+ ];
1478
+ const source = sourceCandidates.find((p) => existsSync(p));
1479
+ if (!source) return null;
1480
+ try {
1481
+ execSync("which swiftc", { stdio: "pipe" });
1482
+ } catch {
1483
+ return null;
1484
+ }
1485
+ try {
1486
+ console.log("Compiling menu bar app...");
1487
+ execSync(`swiftc -o "${binaryPath}" "${source}" -framework AppKit`, {
1488
+ stdio: "pipe",
1489
+ timeout: 3e4
1490
+ });
1491
+ const sourceDir = join(source, "..", "assets");
1492
+ const destDir = join(CONFIG_DIR, "assets");
1493
+ if (existsSync(sourceDir)) {
1494
+ mkdirSync(destDir, { recursive: true });
1495
+ for (const f of ["vector-menubar.png", "vector-menubar@2x.png"]) {
1496
+ const src = join(sourceDir, f);
1497
+ if (existsSync(src)) {
1498
+ writeFileSync(join(destDir, f), readFileSync(src));
1499
+ }
1500
+ }
1501
+ }
1502
+ console.log("Menu bar app compiled.");
1503
+ return binaryPath;
1504
+ } catch {
1505
+ console.error(
1506
+ "Failed to compile menu bar app (Xcode CLI tools may be needed)."
1507
+ );
1508
+ return null;
1509
+ }
1510
+ }
1511
+ async function launchMenuBar() {
1512
+ if (platform() !== "darwin") return;
1513
+ const candidates = [
1514
+ join(CONFIG_DIR, "VectorMenuBar"),
1515
+ "/usr/local/bin/VectorMenuBar",
1516
+ join(homedir2(), ".local", "bin", "VectorMenuBar")
1517
+ ];
1518
+ let binary = candidates.find((p) => existsSync(p));
1519
+ if (!binary) {
1520
+ binary = await compileMenuBar() ?? void 0;
1521
+ }
1522
+ if (!binary) return;
1523
+ try {
1524
+ const { spawn: spawnProcess } = await import("child_process");
1525
+ const child = spawnProcess(binary, [], { detached: true, stdio: "ignore" });
1526
+ child.unref();
1527
+ console.log("Menu bar started.");
1528
+ } catch {
1529
+ }
1530
+ }
1469
1531
  function getBridgeStatus() {
1470
1532
  const config = loadBridgeConfig();
1471
1533
  if (!config) return { configured: false, running: false };
@@ -3489,7 +3551,46 @@ folderCommand.command("delete <folderId>").action(async (folderId, _options, com
3489
3551
  printOutput(result, runtime.json);
3490
3552
  });
3491
3553
  var serviceCommand = program.command("service").description("Manage the local bridge service");
3492
- serviceCommand.command("start").description("Run the bridge service in the foreground").action(async (_options, command) => {
3554
+ serviceCommand.command("start").description("Start the bridge service via LaunchAgent (macOS) or foreground").action(async (_options, command) => {
3555
+ const existing = getBridgeStatus();
3556
+ if (existing.running) {
3557
+ console.log(`Bridge is already running (PID ${existing.pid}).`);
3558
+ return;
3559
+ }
3560
+ let config = loadBridgeConfig();
3561
+ if (!config) {
3562
+ const runtime = await getRuntime(command);
3563
+ const session = requireSession(runtime);
3564
+ const client = await createConvexClient(
3565
+ session,
3566
+ runtime.appUrl,
3567
+ runtime.convexUrl
3568
+ );
3569
+ const user = await runQuery(client, api.users.currentUser);
3570
+ if (!user) throw new Error("Not logged in. Run `vcli auth login` first.");
3571
+ config = await setupBridgeDevice(runtime.convexUrl, user._id);
3572
+ console.log(
3573
+ `Device registered: ${config.displayName} (${config.deviceId})`
3574
+ );
3575
+ }
3576
+ if (osPlatform() === "darwin") {
3577
+ const vcliPath = process.argv[1] ?? "vcli";
3578
+ installLaunchAgent(vcliPath);
3579
+ loadLaunchAgent();
3580
+ await launchMenuBar();
3581
+ console.log("Bridge service started.");
3582
+ console.log("");
3583
+ console.log("Run `vcli service status` to check.");
3584
+ console.log("Run `vcli service stop` to stop.");
3585
+ } else {
3586
+ console.log(
3587
+ "Starting bridge in foreground (use systemd for background)..."
3588
+ );
3589
+ const bridge = new BridgeService(config);
3590
+ await bridge.run();
3591
+ }
3592
+ });
3593
+ serviceCommand.command("run").description("Run the bridge service in the foreground (used by LaunchAgent)").action(async (_options, command) => {
3493
3594
  let config = loadBridgeConfig();
3494
3595
  if (!config) {
3495
3596
  const runtime = await getRuntime(command);
@@ -3502,15 +3603,17 @@ serviceCommand.command("start").description("Run the bridge service in the foreg
3502
3603
  const user = await runQuery(client, api.users.currentUser);
3503
3604
  if (!user) throw new Error("Not logged in. Run `vcli auth login` first.");
3504
3605
  config = await setupBridgeDevice(runtime.convexUrl, user._id);
3505
- console.log(`Device registered: ${config.deviceId}`);
3506
3606
  }
3507
3607
  const bridge = new BridgeService(config);
3508
3608
  await bridge.run();
3509
3609
  });
3510
- serviceCommand.command("stop").description("Stop the running bridge service").action(() => {
3610
+ serviceCommand.command("stop").description("Stop the bridge service and menu bar").action(() => {
3611
+ if (osPlatform() === "darwin") {
3612
+ unloadLaunchAgent();
3613
+ }
3511
3614
  if (stopBridge()) {
3512
3615
  console.log("Bridge stopped.");
3513
- } else {
3616
+ } else if (osPlatform() !== "darwin") {
3514
3617
  console.log("Bridge is not running.");
3515
3618
  }
3516
3619
  });