@rehpic/vcli 0.1.0-beta.50.1 → 0.1.0-beta.52.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
@@ -9,248 +9,6 @@ var __export = (target, all) => {
9
9
  __defProp(target, name, { get: all[name], enumerable: true });
10
10
  };
11
11
 
12
- // src/menubar.ts
13
- var menubar_exports = {};
14
- __export(menubar_exports, {
15
- startMenuBar: () => startMenuBar
16
- });
17
- import SysTrayModule from "systray2";
18
- import { existsSync, readFileSync } from "fs";
19
- import { homedir as homedir2 } from "os";
20
- import { join } from "path";
21
- import { execSync } from "child_process";
22
- function loadIconBase64() {
23
- const iconPath = join(CONFIG_DIR, "assets", "vector-menubar.png");
24
- if (existsSync(iconPath)) {
25
- return readFileSync(iconPath).toString("base64");
26
- }
27
- return "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==";
28
- }
29
- function loadConfig() {
30
- try {
31
- return JSON.parse(readFileSync(BRIDGE_CONFIG_FILE, "utf-8"));
32
- } catch {
33
- return null;
34
- }
35
- }
36
- function loadActivities() {
37
- try {
38
- return JSON.parse(readFileSync(LIVE_ACTIVITIES_FILE, "utf-8"));
39
- } catch {
40
- return [];
41
- }
42
- }
43
- function isBridgeRunning() {
44
- try {
45
- const pid = Number(readFileSync(PID_FILE, "utf-8").trim());
46
- process.kill(pid, 0);
47
- return { running: true, pid };
48
- } catch {
49
- return { running: false };
50
- }
51
- }
52
- function getSessionInfo() {
53
- try {
54
- const session = JSON.parse(
55
- readFileSync(join(CONFIG_DIR, "cli-default.json"), "utf-8")
56
- );
57
- return {
58
- orgSlug: session.activeOrgSlug ?? "oss-lab",
59
- appUrl: session.appUrl
60
- };
61
- } catch {
62
- return { orgSlug: "oss-lab" };
63
- }
64
- }
65
- function getOrgSlug() {
66
- try {
67
- const session = JSON.parse(
68
- readFileSync(join(CONFIG_DIR, "cli-default.json"), "utf-8")
69
- );
70
- return session.activeOrgSlug ?? "oss-lab";
71
- } catch {
72
- return "oss-lab";
73
- }
74
- }
75
- function providerLabel(provider) {
76
- if (provider === "claude_code") return "Claude";
77
- if (provider === "codex") return "Codex";
78
- return provider;
79
- }
80
- function buildMenu() {
81
- const config = loadConfig();
82
- const { running, pid } = isBridgeRunning();
83
- const activities = loadActivities();
84
- const items = [];
85
- const actions = /* @__PURE__ */ new Map();
86
- let idx = 0;
87
- if (running && config) {
88
- items.push({
89
- title: `Vector Bridge \u2014 Running (PID ${pid})`,
90
- enabled: false
91
- });
92
- idx++;
93
- items.push({ title: ` ${config.displayName}`, enabled: false });
94
- idx++;
95
- } else if (config) {
96
- items.push({ title: "Vector Bridge \u2014 Offline", enabled: false });
97
- idx++;
98
- } else {
99
- items.push({ title: "Vector Bridge \u2014 Not Configured", enabled: false });
100
- idx++;
101
- items.push({
102
- title: " Run: vcli service start",
103
- enabled: false
104
- });
105
- idx++;
106
- }
107
- items.push({ title: "---", enabled: false });
108
- idx++;
109
- if (activities.length > 0) {
110
- items.push({ title: "Active Sessions", enabled: false });
111
- idx++;
112
- const orgSlug = getOrgSlug();
113
- for (const a of activities) {
114
- const label = `${a.issueKey} \u2014 ${a.title ?? a.issueTitle} (${providerLabel(a.provider)})`;
115
- items.push({ title: label, tooltip: a.latestSummary });
116
- const issueKey = a.issueKey;
117
- actions.set(idx, () => {
118
- const url = `http://localhost:3000/${orgSlug}/issues/${issueKey}`;
119
- try {
120
- execSync(`open "${url}"`, { stdio: "ignore" });
121
- } catch {
122
- }
123
- });
124
- idx++;
125
- }
126
- items.push({ title: "---", enabled: false });
127
- idx++;
128
- }
129
- if (running) {
130
- items.push({ title: "Stop Bridge" });
131
- actions.set(idx, () => {
132
- try {
133
- if (pid) process.kill(pid, "SIGTERM");
134
- } catch {
135
- }
136
- });
137
- idx++;
138
- items.push({ title: "Restart Bridge" });
139
- actions.set(idx, () => {
140
- try {
141
- if (pid) process.kill(pid, "SIGTERM");
142
- setTimeout(() => {
143
- execSync("vcli service start", { stdio: "ignore" });
144
- }, 2e3);
145
- } catch {
146
- }
147
- });
148
- idx++;
149
- } else if (config) {
150
- items.push({ title: "Start Bridge" });
151
- actions.set(idx, () => {
152
- try {
153
- execSync("vcli service start", { stdio: "ignore" });
154
- } catch {
155
- }
156
- });
157
- idx++;
158
- }
159
- items.push({ title: "---", enabled: false });
160
- idx++;
161
- if (config) {
162
- const { orgSlug, appUrl } = getSessionInfo();
163
- items.push({
164
- title: `Account: ${config.userId.slice(0, 12)}...`,
165
- enabled: false
166
- });
167
- idx++;
168
- if (orgSlug) {
169
- items.push({ title: `Org: ${orgSlug}`, enabled: false });
170
- idx++;
171
- }
172
- items.push({ title: "---", enabled: false });
173
- idx++;
174
- }
175
- items.push({ title: "Open Vector" });
176
- actions.set(idx, () => {
177
- const { appUrl } = getSessionInfo();
178
- const url = appUrl ?? "http://localhost:3000";
179
- try {
180
- execSync(`open "${url}"`, { stdio: "ignore" });
181
- } catch {
182
- }
183
- });
184
- idx++;
185
- items.push({ title: "Quit Vector" });
186
- actions.set(idx, () => {
187
- try {
188
- const { pid: bridgePid } = isBridgeRunning();
189
- if (bridgePid) process.kill(bridgePid, "SIGTERM");
190
- } catch {
191
- }
192
- process.exit(0);
193
- });
194
- idx++;
195
- return { items, actions };
196
- }
197
- async function startMenuBar() {
198
- try {
199
- const { fileURLToPath: fileURLToPath3 } = await import("url");
200
- const { dirname: dirname2, join: pjoin } = await import("path");
201
- const { chmodSync } = await import("fs");
202
- const systrayIndex = fileURLToPath3(import.meta.resolve("systray2"));
203
- const binName = process.platform === "darwin" ? "tray_darwin_release" : process.platform === "win32" ? "tray_windows_release.exe" : "tray_linux_release";
204
- const trayBin = pjoin(dirname2(systrayIndex), "traybin", binName);
205
- chmodSync(trayBin, 493);
206
- } catch {
207
- }
208
- const icon = loadIconBase64();
209
- const { items, actions } = buildMenu();
210
- const systray = new SysTray({
211
- menu: {
212
- icon,
213
- title: "",
214
- tooltip: "Vector Bridge",
215
- items: items.map((item) => ({
216
- title: item.title,
217
- tooltip: item.tooltip ?? "",
218
- checked: item.checked ?? false,
219
- enabled: item.enabled ?? true,
220
- hidden: false
221
- }))
222
- },
223
- debug: false,
224
- copyDir: false
225
- });
226
- void systray.onClick((action) => {
227
- const handler = actions.get(action.seq_id);
228
- if (handler) handler();
229
- });
230
- setInterval(() => {
231
- const { items: newItems, actions: newActions } = buildMenu();
232
- void newItems;
233
- void newActions;
234
- }, 15e3);
235
- }
236
- var SysTray, CONFIG_DIR, BRIDGE_CONFIG_FILE, PID_FILE, LIVE_ACTIVITIES_FILE;
237
- var init_menubar = __esm({
238
- "src/menubar.ts"() {
239
- "use strict";
240
- SysTray = typeof SysTrayModule.default === "function" ? SysTrayModule.default : SysTrayModule;
241
- CONFIG_DIR = join(homedir2(), ".vector");
242
- BRIDGE_CONFIG_FILE = join(CONFIG_DIR, "bridge.json");
243
- PID_FILE = join(CONFIG_DIR, "bridge.pid");
244
- LIVE_ACTIVITIES_FILE = join(CONFIG_DIR, "live-activities.json");
245
- if (process.argv[1]?.endsWith("menubar.ts") || process.argv[1]?.endsWith("menubar.js")) {
246
- startMenuBar().catch((e) => {
247
- console.error("Menu bar error:", e);
248
- process.exit(1);
249
- });
250
- }
251
- }
252
- });
253
-
254
12
  // ../../node_modules/.pnpm/is-docker@3.0.0/node_modules/is-docker/index.js
255
13
  import fs from "fs";
256
14
  function hasDockerEnv() {
@@ -978,9 +736,9 @@ var init_open = __esm({
978
736
  });
979
737
 
980
738
  // src/index.ts
981
- import { readFileSync as readFileSync3 } from "fs";
739
+ import { readFileSync as readFileSync2 } from "fs";
982
740
  import { readFile as readFile2 } from "fs/promises";
983
- import { dirname, extname, join as join3 } from "path";
741
+ import { dirname, extname, join as join2 } from "path";
984
742
  import { fileURLToPath as fileURLToPath2 } from "url";
985
743
  import { config as loadEnv } from "dotenv";
986
744
  import { Command } from "commander";
@@ -1338,38 +1096,43 @@ function createEmptySession() {
1338
1096
 
1339
1097
  // src/bridge-service.ts
1340
1098
  import { ConvexHttpClient as ConvexHttpClient2 } from "convex/browser";
1341
- import { execSync as execSync2 } from "child_process";
1099
+ import { execSync } from "child_process";
1342
1100
  import {
1343
- existsSync as existsSync2,
1101
+ existsSync,
1344
1102
  mkdirSync,
1345
- readFileSync as readFileSync2,
1103
+ readFileSync,
1346
1104
  writeFileSync,
1347
1105
  unlinkSync
1348
1106
  } from "fs";
1349
- import { homedir as homedir3, hostname, platform } from "os";
1350
- import { join as join2 } from "path";
1107
+ import { homedir as homedir2, hostname, platform } from "os";
1108
+ import { join } from "path";
1351
1109
  import { randomUUID } from "crypto";
1352
- var CONFIG_DIR2 = join2(homedir3(), ".vector");
1353
- var BRIDGE_CONFIG_FILE2 = join2(CONFIG_DIR2, "bridge.json");
1354
- var PID_FILE2 = join2(CONFIG_DIR2, "bridge.pid");
1355
- var LIVE_ACTIVITIES_CACHE = join2(CONFIG_DIR2, "live-activities.json");
1356
- var LAUNCHAGENT_DIR = join2(homedir3(), "Library", "LaunchAgents");
1357
- var LAUNCHAGENT_PLIST = join2(LAUNCHAGENT_DIR, "com.vector.bridge.plist");
1110
+ var CONFIG_DIR = join(homedir2(), ".vector");
1111
+ var BRIDGE_CONFIG_FILE = join(CONFIG_DIR, "bridge.json");
1112
+ var PID_FILE = join(CONFIG_DIR, "bridge.pid");
1113
+ var LIVE_ACTIVITIES_CACHE = join(CONFIG_DIR, "live-activities.json");
1114
+ var LAUNCHAGENT_DIR = join(homedir2(), "Library", "LaunchAgents");
1115
+ var LAUNCHAGENT_PLIST = join(LAUNCHAGENT_DIR, "com.vector.bridge.plist");
1358
1116
  var LAUNCHAGENT_LABEL = "com.vector.bridge";
1117
+ var LEGACY_MENUBAR_LAUNCHAGENT_LABEL = "com.vector.menubar";
1118
+ var LEGACY_MENUBAR_LAUNCHAGENT_PLIST = join(
1119
+ LAUNCHAGENT_DIR,
1120
+ `${LEGACY_MENUBAR_LAUNCHAGENT_LABEL}.plist`
1121
+ );
1359
1122
  var HEARTBEAT_INTERVAL_MS = 3e4;
1360
1123
  var COMMAND_POLL_INTERVAL_MS = 5e3;
1361
1124
  var PROCESS_DISCOVERY_INTERVAL_MS = 6e4;
1362
1125
  function loadBridgeConfig() {
1363
- if (!existsSync2(BRIDGE_CONFIG_FILE2)) return null;
1126
+ if (!existsSync(BRIDGE_CONFIG_FILE)) return null;
1364
1127
  try {
1365
- return JSON.parse(readFileSync2(BRIDGE_CONFIG_FILE2, "utf-8"));
1128
+ return JSON.parse(readFileSync(BRIDGE_CONFIG_FILE, "utf-8"));
1366
1129
  } catch {
1367
1130
  return null;
1368
1131
  }
1369
1132
  }
1370
1133
  function saveBridgeConfig(config) {
1371
- if (!existsSync2(CONFIG_DIR2)) mkdirSync(CONFIG_DIR2, { recursive: true });
1372
- writeFileSync(BRIDGE_CONFIG_FILE2, JSON.stringify(config, null, 2));
1134
+ if (!existsSync(CONFIG_DIR)) mkdirSync(CONFIG_DIR, { recursive: true });
1135
+ writeFileSync(BRIDGE_CONFIG_FILE, JSON.stringify(config, null, 2));
1373
1136
  }
1374
1137
  function discoverLocalProcesses() {
1375
1138
  const processes = [];
@@ -1384,7 +1147,7 @@ function discoverLocalProcesses() {
1384
1147
  ];
1385
1148
  for (const { grep, provider, label, prefix } of patterns) {
1386
1149
  try {
1387
- const ps = execSync2(
1150
+ const ps = execSync(
1388
1151
  `ps aux | grep -E '${grep}' | grep -v vector-bridge | grep -v grep`,
1389
1152
  { encoding: "utf-8", timeout: 5e3 }
1390
1153
  );
@@ -1393,7 +1156,7 @@ function discoverLocalProcesses() {
1393
1156
  if (!pid) continue;
1394
1157
  let cwd;
1395
1158
  try {
1396
- cwd = execSync2(
1159
+ cwd = execSync(
1397
1160
  `lsof -p ${pid} 2>/dev/null | grep cwd | awk '{print $NF}'`,
1398
1161
  { encoding: "utf-8", timeout: 3e3 }
1399
1162
  ).trim() || void 0;
@@ -1419,12 +1182,12 @@ function discoverLocalProcesses() {
1419
1182
  }
1420
1183
  function getGitInfo(cwd) {
1421
1184
  try {
1422
- const branch = execSync2("git rev-parse --abbrev-ref HEAD", {
1185
+ const branch = execSync("git rev-parse --abbrev-ref HEAD", {
1423
1186
  encoding: "utf-8",
1424
1187
  cwd,
1425
1188
  timeout: 3e3
1426
1189
  }).trim();
1427
- const repoRoot = execSync2("git rev-parse --show-toplevel", {
1190
+ const repoRoot = execSync("git rev-parse --show-toplevel", {
1428
1191
  encoding: "utf-8",
1429
1192
  cwd,
1430
1193
  timeout: 3e3
@@ -1537,8 +1300,8 @@ var BridgeService = class {
1537
1300
  console.log(` Convex: ${this.config.convexUrl}`);
1538
1301
  console.log(` PID: ${process.pid}`);
1539
1302
  console.log("");
1540
- if (!existsSync2(CONFIG_DIR2)) mkdirSync(CONFIG_DIR2, { recursive: true });
1541
- writeFileSync(PID_FILE2, String(process.pid));
1303
+ if (!existsSync(CONFIG_DIR)) mkdirSync(CONFIG_DIR, { recursive: true });
1304
+ writeFileSync(PID_FILE, String(process.pid));
1542
1305
  await this.heartbeat();
1543
1306
  await this.reportProcesses();
1544
1307
  await this.refreshLiveActivities();
@@ -1572,7 +1335,7 @@ var BridgeService = class {
1572
1335
  [${ts()}] Shutting down...`);
1573
1336
  for (const t of this.timers) clearInterval(t);
1574
1337
  try {
1575
- unlinkSync(PID_FILE2);
1338
+ unlinkSync(PID_FILE);
1576
1339
  } catch {
1577
1340
  }
1578
1341
  process.exit(0);
@@ -1635,9 +1398,9 @@ function installLaunchAgent(vcliPath) {
1635
1398
  <key>KeepAlive</key>
1636
1399
  <true/>
1637
1400
  <key>StandardOutPath</key>
1638
- <string>${CONFIG_DIR2}/bridge.log</string>
1401
+ <string>${CONFIG_DIR}/bridge.log</string>
1639
1402
  <key>StandardErrorPath</key>
1640
- <string>${CONFIG_DIR2}/bridge.err.log</string>
1403
+ <string>${CONFIG_DIR}/bridge.err.log</string>
1641
1404
  <key>EnvironmentVariables</key>
1642
1405
  <dict>
1643
1406
  <key>PATH</key>
@@ -1645,46 +1408,16 @@ function installLaunchAgent(vcliPath) {
1645
1408
  </dict>
1646
1409
  </dict>
1647
1410
  </plist>`;
1648
- const menuBarCandidates = [
1649
- join2(CONFIG_DIR2, "VectorMenuBar"),
1650
- "/usr/local/bin/VectorMenuBar",
1651
- join2(homedir3(), ".local", "bin", "VectorMenuBar")
1652
- ];
1653
- const menuBarBinary = menuBarCandidates.find((p) => existsSync2(p));
1654
- if (menuBarBinary) {
1655
- const menuBarPlist = `<?xml version="1.0" encoding="UTF-8"?>
1656
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
1657
- <plist version="1.0">
1658
- <dict>
1659
- <key>Label</key>
1660
- <string>com.vector.menubar</string>
1661
- <key>ProgramArguments</key>
1662
- <array>
1663
- <string>${menuBarBinary}</string>
1664
- </array>
1665
- <key>RunAtLoad</key>
1666
- <true/>
1667
- <key>KeepAlive</key>
1668
- <false/>
1669
- </dict>
1670
- </plist>`;
1671
- const menuBarPlistPath = join2(LAUNCHAGENT_DIR, "com.vector.menubar.plist");
1672
- writeFileSync(menuBarPlistPath, menuBarPlist);
1673
- try {
1674
- execSync2(`launchctl load ${menuBarPlistPath}`, { stdio: "pipe" });
1675
- console.log("Menu bar helper installed.");
1676
- } catch {
1677
- }
1678
- }
1679
- if (!existsSync2(LAUNCHAGENT_DIR)) {
1411
+ if (!existsSync(LAUNCHAGENT_DIR)) {
1680
1412
  mkdirSync(LAUNCHAGENT_DIR, { recursive: true });
1681
1413
  }
1414
+ removeLegacyMenuBarLaunchAgent();
1682
1415
  writeFileSync(LAUNCHAGENT_PLIST, plist);
1683
1416
  console.log(`Installed LaunchAgent: ${LAUNCHAGENT_PLIST}`);
1684
1417
  }
1685
1418
  function loadLaunchAgent() {
1686
1419
  try {
1687
- execSync2(`launchctl load ${LAUNCHAGENT_PLIST}`, { stdio: "inherit" });
1420
+ execSync(`launchctl load ${LAUNCHAGENT_PLIST}`, { stdio: "inherit" });
1688
1421
  console.log(
1689
1422
  "LaunchAgent loaded. Bridge will start automatically on login."
1690
1423
  );
@@ -1694,7 +1427,7 @@ function loadLaunchAgent() {
1694
1427
  }
1695
1428
  function unloadLaunchAgent() {
1696
1429
  try {
1697
- execSync2(`launchctl unload ${LAUNCHAGENT_PLIST}`, { stdio: "inherit" });
1430
+ execSync(`launchctl unload ${LAUNCHAGENT_PLIST}`, { stdio: "inherit" });
1698
1431
  console.log("LaunchAgent unloaded.");
1699
1432
  } catch {
1700
1433
  console.error("Failed to unload LaunchAgent (may not be loaded)");
@@ -1702,17 +1435,82 @@ function unloadLaunchAgent() {
1702
1435
  }
1703
1436
  function uninstallLaunchAgent() {
1704
1437
  unloadLaunchAgent();
1438
+ removeLegacyMenuBarLaunchAgent();
1705
1439
  try {
1706
1440
  unlinkSync(LAUNCHAGENT_PLIST);
1707
1441
  console.log("LaunchAgent removed.");
1708
1442
  } catch {
1709
1443
  }
1710
1444
  }
1445
+ var MENUBAR_PID_FILE = join(CONFIG_DIR, "menubar.pid");
1446
+ function removeLegacyMenuBarLaunchAgent() {
1447
+ if (platform() !== "darwin" || !existsSync(LEGACY_MENUBAR_LAUNCHAGENT_PLIST)) {
1448
+ return;
1449
+ }
1450
+ try {
1451
+ execSync(`launchctl unload ${LEGACY_MENUBAR_LAUNCHAGENT_PLIST}`, {
1452
+ stdio: "pipe"
1453
+ });
1454
+ } catch {
1455
+ }
1456
+ try {
1457
+ unlinkSync(LEGACY_MENUBAR_LAUNCHAGENT_PLIST);
1458
+ } catch {
1459
+ }
1460
+ }
1461
+ function findMenuBarScript() {
1462
+ const candidates = [
1463
+ join(import.meta.dirname ?? "", "menubar.js"),
1464
+ join(import.meta.dirname ?? "", "..", "dist", "menubar.js")
1465
+ ];
1466
+ for (const p of candidates) {
1467
+ if (existsSync(p)) return p;
1468
+ }
1469
+ return null;
1470
+ }
1471
+ function isKnownMenuBarProcess(pid) {
1472
+ try {
1473
+ const command = execSync(`ps -p ${pid} -o args=`, {
1474
+ encoding: "utf-8",
1475
+ timeout: 3e3
1476
+ });
1477
+ return command.includes("menubar.js") || command.includes("menubar.ts") || command.includes("VectorMenuBar");
1478
+ } catch {
1479
+ return false;
1480
+ }
1481
+ }
1482
+ function killExistingMenuBar() {
1483
+ if (existsSync(MENUBAR_PID_FILE)) {
1484
+ try {
1485
+ const pid = Number(readFileSync(MENUBAR_PID_FILE, "utf-8").trim());
1486
+ if (Number.isFinite(pid) && pid > 0 && isKnownMenuBarProcess(pid)) {
1487
+ process.kill(pid, "SIGTERM");
1488
+ }
1489
+ } catch {
1490
+ }
1491
+ try {
1492
+ unlinkSync(MENUBAR_PID_FILE);
1493
+ } catch {
1494
+ }
1495
+ }
1496
+ }
1711
1497
  async function launchMenuBar() {
1498
+ if (platform() !== "darwin") return;
1499
+ removeLegacyMenuBarLaunchAgent();
1500
+ const script = findMenuBarScript();
1501
+ if (!script) return;
1502
+ killExistingMenuBar();
1712
1503
  try {
1713
- const { startMenuBar: startMenuBar2 } = await Promise.resolve().then(() => (init_menubar(), menubar_exports));
1714
- void startMenuBar2();
1715
- console.log("Menu bar started.");
1504
+ const { spawn: spawnChild } = await import("child_process");
1505
+ const child = spawnChild(process.execPath, [script], {
1506
+ detached: true,
1507
+ stdio: "ignore",
1508
+ env: { ...process.env }
1509
+ });
1510
+ child.unref();
1511
+ if (child.pid) {
1512
+ writeFileSync(MENUBAR_PID_FILE, String(child.pid));
1513
+ }
1716
1514
  } catch {
1717
1515
  }
1718
1516
  }
@@ -1722,8 +1520,8 @@ function getBridgeStatus() {
1722
1520
  let running = false;
1723
1521
  let starting = false;
1724
1522
  let pid;
1725
- if (existsSync2(PID_FILE2)) {
1726
- const pidStr = readFileSync2(PID_FILE2, "utf-8").trim();
1523
+ if (existsSync(PID_FILE)) {
1524
+ const pidStr = readFileSync(PID_FILE, "utf-8").trim();
1727
1525
  pid = Number(pidStr);
1728
1526
  try {
1729
1527
  process.kill(pid, 0);
@@ -1734,7 +1532,7 @@ function getBridgeStatus() {
1734
1532
  }
1735
1533
  if (!running && platform() === "darwin") {
1736
1534
  try {
1737
- const result = execSync2(
1535
+ const result = execSync(
1738
1536
  `launchctl list ${LAUNCHAGENT_LABEL} 2>/dev/null`,
1739
1537
  { encoding: "utf-8", timeout: 3e3 }
1740
1538
  );
@@ -1747,8 +1545,9 @@ function getBridgeStatus() {
1747
1545
  return { configured: true, running, starting, pid, config };
1748
1546
  }
1749
1547
  function stopBridge() {
1750
- if (!existsSync2(PID_FILE2)) return false;
1751
- const pid = Number(readFileSync2(PID_FILE2, "utf-8").trim());
1548
+ killExistingMenuBar();
1549
+ if (!existsSync(PID_FILE)) return false;
1550
+ const pid = Number(readFileSync(PID_FILE, "utf-8").trim());
1752
1551
  try {
1753
1552
  process.kill(pid, "SIGTERM");
1754
1553
  return true;
@@ -2204,7 +2003,7 @@ var program = new Command();
2204
2003
  function readPackageVersionSync() {
2205
2004
  try {
2206
2005
  const dir = import.meta.dirname ?? dirname(fileURLToPath2(import.meta.url));
2207
- const raw = readFileSync3(join3(dir, "..", "package.json"), "utf8");
2006
+ const raw = readFileSync2(join2(dir, "..", "package.json"), "utf8");
2208
2007
  return JSON.parse(raw).version ?? "unknown";
2209
2008
  } catch {
2210
2009
  return "unknown";
@@ -3783,7 +3582,6 @@ serviceCommand.command("start").description("Start the bridge service via Launch
3783
3582
  const vcliPath = process.argv[1] ?? "vcli";
3784
3583
  installLaunchAgent(vcliPath);
3785
3584
  loadLaunchAgent();
3786
- await launchMenuBar();
3787
3585
  s.stop("Bridge service started.");
3788
3586
  } else {
3789
3587
  console.log(
@@ -3807,6 +3605,9 @@ serviceCommand.command("run").description("Run the bridge service in the foregro
3807
3605
  if (!user) throw new Error("Not logged in. Run `vcli auth login` first.");
3808
3606
  config = await setupBridgeDevice(runtime.convexUrl, user._id);
3809
3607
  }
3608
+ if (osPlatform() === "darwin") {
3609
+ await launchMenuBar();
3610
+ }
3810
3611
  const bridge = new BridgeService(config);
3811
3612
  await bridge.run();
3812
3613
  });
@@ -3868,9 +3669,6 @@ serviceCommand.command("install").description("Install the bridge as a system se
3868
3669
  s.start("Starting bridge service...");
3869
3670
  loadLaunchAgent();
3870
3671
  s.stop("Bridge service started");
3871
- s.start("Launching menu bar...");
3872
- await launchMenuBar();
3873
- s.stop("Menu bar ready");
3874
3672
  console.log("");
3875
3673
  console.log(
3876
3674
  "Bridge installed and running. Will start automatically on login."