switchboard-router 0.6.3 → 0.6.4

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 (144) hide show
  1. package/README.md +40 -0
  2. package/app/.next-cli-build/BUILD_ID +1 -1
  3. package/app/.next-cli-build/app-path-routes-manifest.json +11 -11
  4. package/app/.next-cli-build/build-manifest.json +2 -2
  5. package/app/.next-cli-build/prerender-manifest.json +3 -3
  6. package/app/.next-cli-build/server/app/(dashboard)/dashboard/agent-library/page_client-reference-manifest.js +1 -1
  7. package/app/.next-cli-build/server/app/(dashboard)/dashboard/basic-chat/page_client-reference-manifest.js +1 -1
  8. package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page_client-reference-manifest.js +1 -1
  9. package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/page_client-reference-manifest.js +1 -1
  10. package/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/page_client-reference-manifest.js +1 -1
  11. package/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/routing/page_client-reference-manifest.js +1 -1
  12. package/app/.next-cli-build/server/app/(dashboard)/dashboard/console-log/page_client-reference-manifest.js +1 -1
  13. package/app/.next-cli-build/server/app/(dashboard)/dashboard/endpoint/page_client-reference-manifest.js +1 -1
  14. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page_client-reference-manifest.js +1 -1
  15. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/page_client-reference-manifest.js +1 -1
  16. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page_client-reference-manifest.js +1 -1
  17. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/page_client-reference-manifest.js +1 -1
  18. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/web/page_client-reference-manifest.js +1 -1
  19. package/app/.next-cli-build/server/app/(dashboard)/dashboard/mitm/page_client-reference-manifest.js +1 -1
  20. package/app/.next-cli-build/server/app/(dashboard)/dashboard/page_client-reference-manifest.js +1 -1
  21. package/app/.next-cli-build/server/app/(dashboard)/dashboard/profile/page_client-reference-manifest.js +1 -1
  22. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/[id]/page_client-reference-manifest.js +1 -1
  23. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/new/page_client-reference-manifest.js +1 -1
  24. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/page_client-reference-manifest.js +1 -1
  25. package/app/.next-cli-build/server/app/(dashboard)/dashboard/quota/page_client-reference-manifest.js +1 -1
  26. package/app/.next-cli-build/server/app/(dashboard)/dashboard/skills/[id]/page_client-reference-manifest.js +1 -1
  27. package/app/.next-cli-build/server/app/(dashboard)/dashboard/skills/page_client-reference-manifest.js +1 -1
  28. package/app/.next-cli-build/server/app/(dashboard)/dashboard/token-saver/page_client-reference-manifest.js +1 -1
  29. package/app/.next-cli-build/server/app/(dashboard)/dashboard/translator/page_client-reference-manifest.js +1 -1
  30. package/app/.next-cli-build/server/app/(dashboard)/dashboard/usage/page_client-reference-manifest.js +1 -1
  31. package/app/.next-cli-build/server/app/_global-error/page_client-reference-manifest.js +1 -1
  32. package/app/.next-cli-build/server/app/_global-error.html +1 -1
  33. package/app/.next-cli-build/server/app/_global-error.rsc +1 -1
  34. package/app/.next-cli-build/server/app/_global-error.segments/_full.segment.rsc +1 -1
  35. package/app/.next-cli-build/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  36. package/app/.next-cli-build/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  37. package/app/.next-cli-build/server/app/_global-error.segments/_head.segment.rsc +1 -1
  38. package/app/.next-cli-build/server/app/_global-error.segments/_index.segment.rsc +1 -1
  39. package/app/.next-cli-build/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  40. package/app/.next-cli-build/server/app/_not-found/page_client-reference-manifest.js +1 -1
  41. package/app/.next-cli-build/server/app/_not-found.html +1 -1
  42. package/app/.next-cli-build/server/app/_not-found.rsc +3 -3
  43. package/app/.next-cli-build/server/app/_not-found.segments/_full.segment.rsc +3 -3
  44. package/app/.next-cli-build/server/app/_not-found.segments/_head.segment.rsc +1 -1
  45. package/app/.next-cli-build/server/app/_not-found.segments/_index.segment.rsc +3 -3
  46. package/app/.next-cli-build/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  47. package/app/.next-cli-build/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  48. package/app/.next-cli-build/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  49. package/app/.next-cli-build/server/app/api/cli-tools/aider-settings/route.js +2 -2
  50. package/app/.next-cli-build/server/app/api/cli-tools/all-statuses/route.js +4 -4
  51. package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/alias/route.js +2 -2
  52. package/app/.next-cli-build/server/app/api/cli-tools/claude-settings/route.js +2 -2
  53. package/app/.next-cli-build/server/app/api/cli-tools/cline-settings/route.js +2 -2
  54. package/app/.next-cli-build/server/app/api/cli-tools/codex-settings/route.js +2 -2
  55. package/app/.next-cli-build/server/app/api/cli-tools/cowork-mcp-registry/route.js +2 -2
  56. package/app/.next-cli-build/server/app/api/cli-tools/cowork-mcp-tools/route.js +1 -1
  57. package/app/.next-cli-build/server/app/api/cli-tools/cowork-settings/route.js +2 -2
  58. package/app/.next-cli-build/server/app/api/cli-tools/deepseek-tui-settings/route.js +1 -1
  59. package/app/.next-cli-build/server/app/api/cli-tools/droid-settings/route.js +2 -2
  60. package/app/.next-cli-build/server/app/api/cli-tools/gemini-cli-settings/route.js +2 -2
  61. package/app/.next-cli-build/server/app/api/cli-tools/grok-settings/route.js +2 -2
  62. package/app/.next-cli-build/server/app/api/cli-tools/hermes-settings/route.js +3 -3
  63. package/app/.next-cli-build/server/app/api/cli-tools/jcode-settings/route.js +2 -2
  64. package/app/.next-cli-build/server/app/api/cli-tools/kilo-settings/route.js +2 -2
  65. package/app/.next-cli-build/server/app/api/cli-tools/openclaw-settings/route.js +1 -1
  66. package/app/.next-cli-build/server/app/api/cli-tools/opencode-settings/route.js +2 -2
  67. package/app/.next-cli-build/server/app/api/cli-tools/pi-settings/route.js +1 -1
  68. package/app/.next-cli-build/server/app/api/version/route.js +1 -1
  69. package/app/.next-cli-build/server/app/api/version/shutdown/route.js +1 -1
  70. package/app/.next-cli-build/server/app/api/version/update/route.js +1 -1
  71. package/app/.next-cli-build/server/app/callback/page_client-reference-manifest.js +1 -1
  72. package/app/.next-cli-build/server/app/callback.html +1 -1
  73. package/app/.next-cli-build/server/app/callback.rsc +3 -3
  74. package/app/.next-cli-build/server/app/callback.segments/_full.segment.rsc +3 -3
  75. package/app/.next-cli-build/server/app/callback.segments/_head.segment.rsc +1 -1
  76. package/app/.next-cli-build/server/app/callback.segments/_index.segment.rsc +3 -3
  77. package/app/.next-cli-build/server/app/callback.segments/_tree.segment.rsc +1 -1
  78. package/app/.next-cli-build/server/app/callback.segments/callback/__PAGE__.segment.rsc +1 -1
  79. package/app/.next-cli-build/server/app/callback.segments/callback.segment.rsc +1 -1
  80. package/app/.next-cli-build/server/app/dashboard/settings/pricing/page_client-reference-manifest.js +1 -1
  81. package/app/.next-cli-build/server/app/dashboard/settings/pricing.html +1 -1
  82. package/app/.next-cli-build/server/app/dashboard/settings/pricing.rsc +3 -3
  83. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_full.segment.rsc +3 -3
  84. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_head.segment.rsc +1 -1
  85. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_index.segment.rsc +3 -3
  86. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_tree.segment.rsc +1 -1
  87. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing/__PAGE__.segment.rsc +1 -1
  88. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing.segment.rsc +1 -1
  89. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings.segment.rsc +1 -1
  90. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard.segment.rsc +1 -1
  91. package/app/.next-cli-build/server/app/index.html +1 -1
  92. package/app/.next-cli-build/server/app/index.rsc +3 -3
  93. package/app/.next-cli-build/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  94. package/app/.next-cli-build/server/app/index.segments/_full.segment.rsc +3 -3
  95. package/app/.next-cli-build/server/app/index.segments/_head.segment.rsc +1 -1
  96. package/app/.next-cli-build/server/app/index.segments/_index.segment.rsc +3 -3
  97. package/app/.next-cli-build/server/app/index.segments/_tree.segment.rsc +1 -1
  98. package/app/.next-cli-build/server/app/landing/page_client-reference-manifest.js +1 -1
  99. package/app/.next-cli-build/server/app/landing.html +1 -1
  100. package/app/.next-cli-build/server/app/landing.rsc +3 -3
  101. package/app/.next-cli-build/server/app/landing.segments/_full.segment.rsc +3 -3
  102. package/app/.next-cli-build/server/app/landing.segments/_head.segment.rsc +1 -1
  103. package/app/.next-cli-build/server/app/landing.segments/_index.segment.rsc +3 -3
  104. package/app/.next-cli-build/server/app/landing.segments/_tree.segment.rsc +1 -1
  105. package/app/.next-cli-build/server/app/landing.segments/landing/__PAGE__.segment.rsc +1 -1
  106. package/app/.next-cli-build/server/app/landing.segments/landing.segment.rsc +1 -1
  107. package/app/.next-cli-build/server/app/login/page_client-reference-manifest.js +1 -1
  108. package/app/.next-cli-build/server/app/login.html +1 -1
  109. package/app/.next-cli-build/server/app/login.rsc +3 -3
  110. package/app/.next-cli-build/server/app/login.segments/_full.segment.rsc +3 -3
  111. package/app/.next-cli-build/server/app/login.segments/_head.segment.rsc +1 -1
  112. package/app/.next-cli-build/server/app/login.segments/_index.segment.rsc +3 -3
  113. package/app/.next-cli-build/server/app/login.segments/_tree.segment.rsc +1 -1
  114. package/app/.next-cli-build/server/app/login.segments/login/__PAGE__.segment.rsc +1 -1
  115. package/app/.next-cli-build/server/app/login.segments/login.segment.rsc +1 -1
  116. package/app/.next-cli-build/server/app/page_client-reference-manifest.js +1 -1
  117. package/app/.next-cli-build/server/app-paths-manifest.json +11 -11
  118. package/app/.next-cli-build/server/chunks/194.js +1 -1
  119. package/app/.next-cli-build/server/chunks/4126.js +1 -1
  120. package/app/.next-cli-build/server/chunks/4746.js +1 -1
  121. package/app/.next-cli-build/server/chunks/869.js +1 -1
  122. package/app/.next-cli-build/server/chunks/8998.js +1 -1
  123. package/app/.next-cli-build/server/middleware-build-manifest.js +1 -1
  124. package/app/.next-cli-build/server/middleware.js +3 -3
  125. package/app/.next-cli-build/server/pages/404.html +1 -1
  126. package/app/.next-cli-build/server/pages/500.html +1 -1
  127. package/app/.next-cli-build/server/server-reference-manifest.js +1 -1
  128. package/app/.next-cli-build/server/server-reference-manifest.json +1 -1
  129. package/app/.next-cli-build/static/chunks/{1321-c8ffcb14dcf776aa.js → 1321-5429c7d81eb38c6f.js} +1 -1
  130. package/app/package.json +1 -1
  131. package/app/src/lib/updater/updater.js +41 -12
  132. package/cli.js +401 -320
  133. package/package.json +1 -1
  134. package/src/cli/cliOptions.js +139 -0
  135. package/src/cli/menus/settings.js +2 -2
  136. package/src/cli/processManager.js +186 -0
  137. package/src/cli/serverStatus.js +90 -0
  138. package/src/cli/terminalUI.js +12 -11
  139. package/src/cli/tray/autostart.js +35 -14
  140. package/src/cli/tray/tray.js +34 -32
  141. package/src/cli/tray/trayWin.js +23 -9
  142. package/src/cli/utils/input.js +10 -1
  143. /package/app/.next-cli-build/static/{emM_vF1dDbzWCO6J4_WjU → 88rQB4DdrBDjq9aWvSEH4}/_buildManifest.js +0 -0
  144. /package/app/.next-cli-build/static/{emM_vF1dDbzWCO6J4_WjU → 88rQB4DdrBDjq9aWvSEH4}/_ssgManifest.js +0 -0
@@ -1,6 +1,7 @@
1
1
  const fs = require("fs");
2
2
  const path = require("path");
3
3
  const { openBrowser } = require("../../shared/openBrowser");
4
+ const { isPidAlive } = require("../processManager");
4
5
 
5
6
  let trayInstance = null;
6
7
  let isWinTray = false;
@@ -88,7 +89,7 @@ function getAutostartEnabled() {
88
89
  * Handle menu item click (shared logic)
89
90
  */
90
91
  function handleClick(index, options, onAutostartToggle) {
91
- const { onQuit, onOpenDashboard, port } = options;
92
+ const { onQuit, onOpenDashboard, port, host } = options;
92
93
  if (index === MENU_INDEX.DASHBOARD) {
93
94
  if (onOpenDashboard) onOpenDashboard();
94
95
  else openBrowser(`http://localhost:${port}/dashboard`);
@@ -96,7 +97,7 @@ function handleClick(index, options, onAutostartToggle) {
96
97
  const enabled = getAutostartEnabled();
97
98
  try {
98
99
  const { enableAutoStart, disableAutoStart } = require("./autostart");
99
- const changed = enabled ? disableAutoStart() : enableAutoStart();
100
+ const changed = enabled ? disableAutoStart() : enableAutoStart(undefined, { port, host });
100
101
  if (changed) onAutostartToggle(!enabled);
101
102
  } catch (e) {}
102
103
  } else if (index === MENU_INDEX.QUIT) {
@@ -111,7 +112,7 @@ async function handleQuit(onQuit, killTrayImpl = killTray, exitImpl = process.ex
111
112
  } catch (error) {
112
113
  process.stderr.write(`[switchboard] tray cleanup error: ${error?.message || error}\n`);
113
114
  }
114
- if (onQuit) onQuit();
115
+ if (onQuit) await onQuit();
115
116
  else exitImpl(0);
116
117
  }
117
118
 
@@ -263,45 +264,45 @@ function killTray() {
263
264
  if (!instance) return Promise.resolve();
264
265
 
265
266
  if (wasWin) {
266
- try { instance.kill(); } catch (e) {}
267
- return Promise.resolve();
267
+ try { return Promise.resolve(instance.kill()); } catch (e) { return Promise.resolve(); }
268
268
  }
269
269
 
270
- // Unix: get the Go tray child process handle.
271
- let proc = null;
272
- try {
273
- proc = instance._process || (typeof instance.process === "function" ? instance.process() : null);
274
- } catch (e) {}
270
+ return stopUnixTrayInstance(instance);
271
+ }
275
272
 
276
- // Graceful shutdown: send {type:"exit"} via IPC so the Go binary can call
277
- // systray.Quit() and release NSStatusItem. SIGKILL leaves a ghost icon on
278
- // the macOS menubar until logout, causing duplicate icons after re-spawn.
279
- const gracefulQuit = () => { try { instance.kill(true); } catch (e) {} };
280
- const closeIpc = () => { try { instance.kill(false); } catch (e) {} };
273
+ async function stopUnixTrayInstance(instance, options = {}) {
274
+ const proc = options.proc || (() => {
275
+ try { return instance._process || (typeof instance.process === "function" ? instance.process() : null); }
276
+ catch { return null; }
277
+ })();
278
+ const isAlive = options.isAlive || isPidAlive;
279
+ const signal = options.signal || ((target, name) => target.kill(name));
281
280
 
282
281
  if (!proc || !proc.pid) {
283
- gracefulQuit();
284
- closeIpc();
285
- return Promise.resolve();
282
+ try { await instance.kill(false); } catch (e) {}
283
+ return;
286
284
  }
287
285
 
288
- return new Promise((resolve) => {
286
+ await new Promise((resolve) => {
289
287
  let done = false;
290
- const finish = () => { if (done) return; done = true; closeIpc(); resolve(); };
288
+ const timers = [];
289
+ const finish = () => {
290
+ if (done) return;
291
+ done = true;
292
+ timers.forEach(clearTimeout);
293
+ proc.removeListener("exit", finish);
294
+ resolve();
295
+ };
291
296
 
292
297
  proc.once("exit", finish);
293
- gracefulQuit();
294
-
295
- // Escalate: SIGTERM after 800ms, SIGKILL after 1600ms if still alive.
296
- setTimeout(() => { try { process.kill(proc.pid, 0); proc.kill("SIGTERM"); } catch (e) {} }, 800);
297
- setTimeout(() => { try { process.kill(proc.pid, 0); proc.kill("SIGKILL"); } catch (e) {} }, 1600);
298
-
299
- // Fallback poll in case "exit" never fires (detached child, pipe closed)
300
- const deadline = Date.now() + 3000;
301
- const poll = setInterval(() => {
302
- try { process.kill(proc.pid, 0); } catch { clearInterval(poll); finish(); return; }
303
- if (Date.now() > deadline) { clearInterval(poll); finish(); }
304
- }, 50);
298
+ // SIGKILL can leave a ghost icon, so give IPC and SIGTERM time first.
299
+ timers.push(setTimeout(() => { if (isAlive(proc.pid)) { try { signal(proc, "SIGTERM"); } catch (e) {} } }, 800));
300
+ timers.push(setTimeout(() => { if (isAlive(proc.pid)) { try { signal(proc, "SIGKILL"); } catch (e) {} } }, 1600));
301
+ timers.push(setTimeout(finish, 3000));
302
+ try {
303
+ const result = instance.kill(false);
304
+ if (result && typeof result.catch === "function") result.catch(() => {});
305
+ } catch (e) {}
305
306
  });
306
307
  }
307
308
 
@@ -310,5 +311,6 @@ module.exports = {
310
311
  killTray,
311
312
  handleClick,
312
313
  handleQuit,
314
+ stopUnixTrayInstance,
313
315
  MENU_INDEX,
314
316
  };
@@ -58,6 +58,7 @@ function initWinTray(options) {
58
58
  });
59
59
 
60
60
  psProcess.on("error", () => {});
61
+ psProcess.on("exit", () => { psProcess = null; });
61
62
  psProcess.stderr.on("data", () => {});
62
63
 
63
64
  // Send initial menu items
@@ -73,15 +74,28 @@ function initWinTray(options) {
73
74
  sendCommand({ action: "set-tooltip", text });
74
75
  },
75
76
  kill() {
76
- try {
77
- sendCommand({ action: "kill" });
78
- } catch (e) {}
79
- setTimeout(() => {
80
- if (psProcess && !psProcess.killed) {
81
- try { psProcess.kill(); } catch (e) {}
82
- }
83
- psProcess = null;
84
- }, 300);
77
+ const target = psProcess;
78
+ if (!target) return Promise.resolve();
79
+ return new Promise((resolve) => {
80
+ let done = false;
81
+ let fallback;
82
+ const finish = () => {
83
+ if (done) return;
84
+ done = true;
85
+ if (fallback) clearTimeout(fallback);
86
+ target.removeListener("exit", finish);
87
+ resolve();
88
+ };
89
+ target.once("exit", finish);
90
+ try { sendCommand({ action: "kill" }); } catch (e) {}
91
+ fallback = setTimeout(() => {
92
+ if (psProcess === target && !target.killed) {
93
+ try { target.kill(); } catch (e) {}
94
+ }
95
+ if (psProcess === target) psProcess = null;
96
+ finish();
97
+ }, 1000);
98
+ });
85
99
  }
86
100
  };
87
101
  }
@@ -21,6 +21,14 @@ const COLORS = {
21
21
  // Prime stdin once globally. Toggling raw mode between menus adds latency on
22
22
  // macOS, so we keep raw mode on for the whole TUI session.
23
23
  let rawPrimed = false;
24
+
25
+ function requestGracefulInterrupt(processLike = process) {
26
+ if (processLike.listenerCount("SIGINT") > 0) {
27
+ processLike.emit("SIGINT");
28
+ return;
29
+ }
30
+ processLike.exit(130);
31
+ }
24
32
  function primeRawOnce() {
25
33
  if (rawPrimed || !process.stdin.isTTY) return;
26
34
  try {
@@ -138,7 +146,7 @@ async function selectMenu(title, items, defaultIndex = 0, subtitle = "", headerC
138
146
  if (key.name === "down") return move(1);
139
147
  if (key.name === "return") { cleanup(); resolve(selectedIndex); return; }
140
148
  if (key.name === "escape") { cleanup(); resolve(-1); return; }
141
- if (key.ctrl && key.name === "c") { cleanup(); process.exit(0); }
149
+ if (key.ctrl && key.name === "c") { cleanup(); requestGracefulInterrupt(); }
142
150
  };
143
151
 
144
152
  process.stdin.on("keypress", onKeypress);
@@ -152,5 +160,6 @@ module.exports = {
152
160
  confirm,
153
161
  pause,
154
162
  selectMenu,
163
+ requestGracefulInterrupt,
155
164
  COLORS
156
165
  };