anygate 0.5.11 → 0.6.0

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.
@@ -29,8 +29,6 @@ import {
29
29
  getServerMaskGatewayIds,
30
30
  getUiDebugLogPath,
31
31
  guiCallbackRedirectUri,
32
- init_config,
33
- init_paths,
34
32
  loadPreferences,
35
33
  loadRegistry,
36
34
  loadServerModels,
@@ -66,23 +64,29 @@ import {
66
64
  summarizeServerProviders,
67
65
  validateCustomEndpointUrl,
68
66
  writeSecureLogLine
69
- } from "./chunk-55RHVPE4.js";
67
+ } from "./chunk-CRK6YGKY.js";
70
68
  import {
71
69
  BACKENDS,
72
70
  MAX_MODEL_CATALOG
73
- } from "./chunk-5UF4TVCM.js";
71
+ } from "./chunk-QLHVQYQN.js";
74
72
  import {
75
73
  getTemplateById,
76
74
  listSupportedTemplates,
77
75
  listVisibleOAuthTemplates
78
- } from "./chunk-6AFYEDSU.js";
79
- import "./chunk-72WNE2IK.js";
76
+ } from "./chunk-VGM6EBG4.js";
77
+ import "./chunk-UT3JLF3M.js";
80
78
 
81
79
  // src/ui/command.ts
82
- init_paths();
83
80
  import { createServer } from "http";
84
81
  import { execSync } from "child_process";
85
- import { readFileSync, readdirSync, writeFileSync as writeFileSync2, unlinkSync, existsSync as existsSync3, mkdirSync } from "fs";
82
+ import {
83
+ readFileSync,
84
+ readdirSync,
85
+ writeFileSync as writeFileSync2,
86
+ unlinkSync,
87
+ existsSync as existsSync3,
88
+ mkdirSync
89
+ } from "fs";
86
90
  import { join as join2 } from "path";
87
91
  import { fileURLToPath } from "url";
88
92
  import { dirname } from "path";
@@ -90,7 +94,6 @@ import pc from "picocolors";
90
94
  import * as p from "@clack/prompts";
91
95
 
92
96
  // src/apps/shared/native-launcher.ts
93
- init_config();
94
97
  import { chmodSync, existsSync, mkdtempSync, writeFileSync } from "fs";
95
98
  import { homedir } from "os";
96
99
  import { tmpdir } from "os";
@@ -98,10 +101,38 @@ import { join } from "path";
98
101
  var isWindows = process.platform === "win32";
99
102
  var isMac = process.platform === "darwin";
100
103
  var SUPPORTED_APPS = [
101
- { id: "claude", name: "Claude Code CLI", type: "cli", detectId: "claude", gatewayCommand: "claude", installHint: "npm install -g @anthropic-ai/claude-code" },
102
- { id: "codex", name: "Codex CLI", type: "cli", detectId: "codex", gatewayCommand: "codex", installHint: "npm install -g @openai/codex" },
103
- { id: "gemini", name: "Gemini CLI", type: "cli", detectId: "gemini", gatewayCommand: "gemini", installHint: "npm install -g @google/gemini-cli" },
104
- { id: "agy", name: "Antigravity CLI", type: "cli", detectId: "agy", gatewayCommand: "agy", installHint: "npm install -g @google/antigravity-cli" },
104
+ {
105
+ id: "claude",
106
+ name: "Claude Code CLI",
107
+ type: "cli",
108
+ detectId: "claude",
109
+ gatewayCommand: "claude",
110
+ installHint: "npm install -g @anthropic-ai/claude-code"
111
+ },
112
+ {
113
+ id: "codex",
114
+ name: "Codex CLI",
115
+ type: "cli",
116
+ detectId: "codex",
117
+ gatewayCommand: "codex",
118
+ installHint: "npm install -g @openai/codex"
119
+ },
120
+ {
121
+ id: "gemini",
122
+ name: "Gemini CLI",
123
+ type: "cli",
124
+ detectId: "gemini",
125
+ gatewayCommand: "gemini",
126
+ installHint: "npm install -g @google/gemini-cli"
127
+ },
128
+ {
129
+ id: "agy",
130
+ name: "Antigravity CLI",
131
+ type: "cli",
132
+ detectId: "agy",
133
+ gatewayCommand: "agy",
134
+ installHint: "npm install -g @google/antigravity-cli"
135
+ },
105
136
  {
106
137
  id: "antigravity",
107
138
  name: "Antigravity (App)",
@@ -142,30 +173,21 @@ function fallbackPathsForApp(id, platform = process.platform) {
142
173
  const localAppData = process.env["LOCALAPPDATA"] ?? join(homedir(), "AppData", "Local");
143
174
  switch (id) {
144
175
  case "claude":
145
- return windows ? [
146
- join(appData, "npm", "claude.cmd"),
147
- join(appData, "npm", "claude")
148
- ] : [
176
+ return windows ? [join(appData, "npm", "claude.cmd"), join(appData, "npm", "claude")] : [
149
177
  join(homedir(), ".local", "bin", "claude"),
150
178
  join(homedir(), ".npm", "bin", "claude"),
151
179
  "/usr/local/bin/claude",
152
180
  "/opt/homebrew/bin/claude"
153
181
  ];
154
182
  case "codex":
155
- return windows ? [
156
- join(appData, "npm", "codex.cmd"),
157
- join(appData, "npm", "codex")
158
- ] : [
183
+ return windows ? [join(appData, "npm", "codex.cmd"), join(appData, "npm", "codex")] : [
159
184
  join(homedir(), ".local", "bin", "codex"),
160
185
  join(homedir(), ".npm", "bin", "codex"),
161
186
  "/usr/local/bin/codex",
162
187
  "/opt/homebrew/bin/codex"
163
188
  ];
164
189
  case "gemini":
165
- return windows ? [
166
- join(appData, "npm", "gemini.cmd"),
167
- join(appData, "npm", "gemini")
168
- ] : [
190
+ return windows ? [join(appData, "npm", "gemini.cmd"), join(appData, "npm", "gemini")] : [
169
191
  join(homedir(), ".local", "bin", "gemini"),
170
192
  join(homedir(), ".npm", "bin", "gemini"),
171
193
  "/usr/local/bin/gemini",
@@ -186,7 +208,16 @@ function fallbackPathsForApp(id, platform = process.platform) {
186
208
  if (mac) {
187
209
  return [
188
210
  "/Applications/Antigravity IDE.app/Contents/Resources/app/bin/antigravity-ide",
189
- join(homedir(), "Applications", "Antigravity IDE.app", "Contents", "Resources", "app", "bin", "antigravity-ide")
211
+ join(
212
+ homedir(),
213
+ "Applications",
214
+ "Antigravity IDE.app",
215
+ "Contents",
216
+ "Resources",
217
+ "app",
218
+ "bin",
219
+ "antigravity-ide"
220
+ )
190
221
  ];
191
222
  }
192
223
  if (windows) {
@@ -205,15 +236,9 @@ function fallbackPathsForApp(id, platform = process.platform) {
205
236
  ];
206
237
  }
207
238
  if (windows) {
208
- return [
209
- join(localAppData, "Programs", "Antigravity", "Antigravity.exe")
210
- ];
239
+ return [join(localAppData, "Programs", "Antigravity", "Antigravity.exe")];
211
240
  }
212
- return [
213
- "/opt/antigravity/antigravity",
214
- "/usr/local/bin/antigravity",
215
- "/usr/bin/antigravity"
216
- ];
241
+ return ["/opt/antigravity/antigravity", "/usr/local/bin/antigravity", "/usr/bin/antigravity"];
217
242
  case "claude-app":
218
243
  if (mac) {
219
244
  return [
@@ -278,19 +303,23 @@ function getTerminalLaunchCommand(binPath, args, opts = {}) {
278
303
  const dir2 = mkdtempSync(join(tmpdir(), "anygate-launch-"));
279
304
  const scriptPath2 = join(dir2, "launch.command");
280
305
  const displayCommand = opts.displayCommand ?? [binPath, ...args].join(" ");
281
- writeFileSync(scriptPath2, [
282
- "#!/bin/sh",
283
- `trap 'rm -f "$0"; rmdir "$(dirname "$0")" 2>/dev/null' EXIT`,
284
- "clear",
285
- opts.cwd ? `cd ${quoteShellArg(opts.cwd)} || exit 1` : "",
286
- `printf '%s\\n\\n' ${quoteShellArg(`$ ${displayCommand}`)}`,
287
- fullCmd,
288
- "status=$?",
289
- 'printf "\\nanygate session exited with code %s. Press Return to close this window. " "$status"',
290
- "read _",
291
- 'exit "$status"',
292
- ""
293
- ].join("\n"), { encoding: "utf8", mode: 448 });
306
+ writeFileSync(
307
+ scriptPath2,
308
+ [
309
+ "#!/bin/sh",
310
+ `trap 'rm -f "$0"; rmdir "$(dirname "$0")" 2>/dev/null' EXIT`,
311
+ "clear",
312
+ opts.cwd ? `cd ${quoteShellArg(opts.cwd)} || exit 1` : "",
313
+ `printf '%s\\n\\n' ${quoteShellArg(`$ ${displayCommand}`)}`,
314
+ fullCmd,
315
+ "status=$?",
316
+ 'printf "\\nanygate session exited with code %s. Press Return to close this window. " "$status"',
317
+ "read _",
318
+ 'exit "$status"',
319
+ ""
320
+ ].join("\n"),
321
+ { encoding: "utf8", mode: 448 }
322
+ );
294
323
  chmodSync(scriptPath2, 448);
295
324
  return `open -a Terminal ${quoteShellArg(scriptPath2)}`;
296
325
  }
@@ -300,12 +329,10 @@ function getTerminalLaunchCommand(binPath, args, opts = {}) {
300
329
  }
301
330
  const dir = mkdtempSync(join(tmpdir(), "anygate-launch-"));
302
331
  const scriptPath = join(dir, "launch.sh");
303
- writeFileSync(scriptPath, [
304
- "#!/bin/sh",
305
- runCmd,
306
- "exec sh",
307
- ""
308
- ].join("\n"), { encoding: "utf8", mode: 448 });
332
+ writeFileSync(scriptPath, ["#!/bin/sh", runCmd, "exec sh", ""].join("\n"), {
333
+ encoding: "utf8",
334
+ mode: 448
335
+ });
309
336
  chmodSync(scriptPath, 448);
310
337
  const scriptArg = quoteShellArg(scriptPath);
311
338
  return `x-terminal-emulator -e sh ${scriptArg} || gnome-terminal -- sh ${scriptArg} || xterm -e sh ${scriptArg}`;
@@ -355,21 +382,20 @@ function getSupportedApps() {
355
382
  }
356
383
 
357
384
  // src/ui/api.ts
358
- init_config();
359
385
  import { exec } from "child_process";
360
386
  import { promisify } from "util";
361
387
  import { existsSync as existsSync2, statSync } from "fs";
362
388
  import { randomUUID } from "crypto";
363
389
 
364
390
  // src/ui/server-control.ts
365
- init_config();
366
391
  var running = null;
367
392
  var startInFlight = null;
368
393
  var SAVED_PASSWORD_CACHE_TTL_MS = 3e4;
369
394
  var hasSavedPasswordCache = null;
370
395
  async function hasSavedPasswordCached() {
371
396
  const now = Date.now();
372
- if (hasSavedPasswordCache && hasSavedPasswordCache.expiresAt > now) return hasSavedPasswordCache.value;
397
+ if (hasSavedPasswordCache && hasSavedPasswordCache.expiresAt > now)
398
+ return hasSavedPasswordCache.value;
373
399
  const value = Boolean(await getSavedServerPassword());
374
400
  hasSavedPasswordCache = { value, expiresAt: now + SAVED_PASSWORD_CACHE_TTL_MS };
375
401
  return value;
@@ -384,9 +410,12 @@ function buildModelRows(models, gateway) {
384
410
  }
385
411
  const rows = [];
386
412
  for (const [providerLabel, groupModels] of groups) {
387
- for (const row of buildDedupedModelRows(groupModels, gateway)) rows.push({ providerLabel, ...row });
413
+ for (const row of buildDedupedModelRows(groupModels, gateway))
414
+ rows.push({ providerLabel, ...row });
388
415
  }
389
- return rows.sort((a, b) => a.providerLabel.localeCompare(b.providerLabel) || a.name.localeCompare(b.name));
416
+ return rows.sort(
417
+ (a, b) => a.providerLabel.localeCompare(b.providerLabel) || a.name.localeCompare(b.name)
418
+ );
390
419
  }
391
420
  async function buildSavedConfig() {
392
421
  return {
@@ -416,11 +445,13 @@ async function getServerStatus() {
416
445
  models: modelRows
417
446
  };
418
447
  if (config.listenMode === "network") {
419
- payload.networkUrls = getLocalIps().map(({ name, address }) => ({
420
- name,
421
- anthropicUrl: `http://${address}:${handle.port}/anthropic`,
422
- openaiUrl: `http://${address}:${handle.port}/openai/v1`
423
- }));
448
+ payload.networkUrls = getLocalIps().map(
449
+ ({ name, address }) => ({
450
+ name,
451
+ anthropicUrl: `http://${address}:${handle.port}/anthropic`,
452
+ openaiUrl: `http://${address}:${handle.port}/openai/v1`
453
+ })
454
+ );
424
455
  payload.apiKey = serverPassword ?? void 0;
425
456
  } else {
426
457
  payload.apiKey = "any non-empty value";
@@ -428,7 +459,8 @@ async function getServerStatus() {
428
459
  return payload;
429
460
  }
430
461
  function startGatewayServer(req) {
431
- if (running) return Promise.resolve({ ok: false, error: "Server is already running. Stop it first." });
462
+ if (running)
463
+ return Promise.resolve({ ok: false, error: "Server is already running. Stop it first." });
432
464
  if (startInFlight) return startInFlight;
433
465
  startInFlight = doStartGatewayServer(req).finally(() => {
434
466
  startInFlight = null;
@@ -441,7 +473,10 @@ async function doStartGatewayServer(req) {
441
473
  }
442
474
  const apiKey = await resolveServerUpstreamApiKey();
443
475
  if (!apiKey) {
444
- return { ok: false, error: "No providers configured. Add a provider in Providers & Keys first." };
476
+ return {
477
+ ok: false,
478
+ error: "No providers configured. Add a provider in Providers & Keys first."
479
+ };
445
480
  }
446
481
  let serverPassword = null;
447
482
  if (req.listenMode === "network") {
@@ -463,13 +498,19 @@ async function doStartGatewayServer(req) {
463
498
  try {
464
499
  models = await loadServerModels();
465
500
  } catch (err) {
466
- return { ok: false, error: `Failed to load models: ${err instanceof Error ? err.message : String(err)}` };
501
+ return {
502
+ ok: false,
503
+ error: `Failed to load models: ${err instanceof Error ? err.message : String(err)}`
504
+ };
467
505
  }
468
506
  if (req.exposedProviders) models = filterServerModelsByProviders(models, req.exposedProviders);
469
507
  if (req.favoritesOnly) {
470
508
  const favorites = loadPreferences().favoriteModels ?? [];
471
509
  if (favorites.length === 0) {
472
- return { ok: false, error: "No favorite models configured. Add favorites in the Favorites tab first." };
510
+ return {
511
+ ok: false,
512
+ error: "No favorite models configured. Add favorites in the Favorites tab first."
513
+ };
473
514
  }
474
515
  models = filterServerModelsByFavorites(models, favorites).slice(0, MAX_MODEL_CATALOG);
475
516
  if (models.length === 0) {
@@ -483,7 +524,10 @@ async function doStartGatewayServer(req) {
483
524
  }
484
525
  }
485
526
  if (models.length === 0) {
486
- return { ok: false, error: "No models to expose. Add providers or adjust the exposed-provider filter." };
527
+ return {
528
+ ok: false,
529
+ error: "No models to expose. Add providers or adjust the exposed-provider filter."
530
+ };
487
531
  }
488
532
  setServerFavoritesOnly(req.favoritesOnly);
489
533
  setServerFreeModelsOnly(req.freeModelsOnly);
@@ -650,7 +694,8 @@ async function handlePostConfig(req, res) {
650
694
  const body = JSON.parse(await readBody(req));
651
695
  const update = {};
652
696
  if (Array.isArray(body.favoriteModels)) update.favoriteModels = body.favoriteModels;
653
- if (Array.isArray(body.antigravityCliFavoriteModels)) update.antigravityCliFavoriteModels = body.antigravityCliFavoriteModels;
697
+ if (Array.isArray(body.antigravityCliFavoriteModels))
698
+ update.antigravityCliFavoriteModels = body.antigravityCliFavoriteModels;
654
699
  if (Object.keys(update).length > 0) savePreferences(update);
655
700
  sendJson(res, 200, { ok: true });
656
701
  } catch (err) {
@@ -671,7 +716,9 @@ async function handleGetModels(res) {
671
716
  try {
672
717
  const catalog = await fetchModelsWithTimeout();
673
718
  const registry = loadRegistry();
674
- const rawCountById = new Map(registry.providers.map((p2) => [p2.id, p2.modelsCache?.models.length ?? 0]));
719
+ const rawCountById = new Map(
720
+ registry.providers.map((p2) => [p2.id, p2.modelsCache?.models.length ?? 0])
721
+ );
675
722
  const providers = catalog.map((p2) => ({
676
723
  id: p2.id,
677
724
  name: p2.name,
@@ -704,7 +751,11 @@ async function handleGetModels(res) {
704
751
  providers.push({
705
752
  id: rp.id,
706
753
  name: rp.name,
707
- favoriteName: favoriteProviderDisplayName({ id: rp.id, name: rp.name, authType: rp.authType }),
754
+ favoriteName: favoriteProviderDisplayName({
755
+ id: rp.id,
756
+ name: rp.name,
757
+ authType: rp.authType
758
+ }),
708
759
  hasKey: true,
709
760
  freeAccess: false,
710
761
  authType: "oauth",
@@ -1030,8 +1081,20 @@ async function handlePostKeys(req, res) {
1030
1081
  }
1031
1082
  }
1032
1083
  var CUSTOM_TEMPLATES = [
1033
- { id: "__custom_openai__", name: "Custom OpenAI-compatible", signupUrl: null, authType: "api", custom: true },
1034
- { id: "__custom_anthropic__", name: "Custom Anthropic-compatible", signupUrl: null, authType: "api", custom: true }
1084
+ {
1085
+ id: "__custom_openai__",
1086
+ name: "Custom OpenAI-compatible",
1087
+ signupUrl: null,
1088
+ authType: "api",
1089
+ custom: true
1090
+ },
1091
+ {
1092
+ id: "__custom_anthropic__",
1093
+ name: "Custom Anthropic-compatible",
1094
+ signupUrl: null,
1095
+ authType: "api",
1096
+ custom: true
1097
+ }
1035
1098
  ];
1036
1099
  function handleGetTemplates(res) {
1037
1100
  const registry = loadRegistry();
@@ -1040,6 +1103,7 @@ function handleGetTemplates(res) {
1040
1103
  id: t.id,
1041
1104
  name: t.name,
1042
1105
  signupUrl: t.signupUrl ?? null,
1106
+ signupNote: t.signupNote ?? null,
1043
1107
  authType: t.authType,
1044
1108
  anonymousFreeModels: t.anonymousFreeModels ?? false,
1045
1109
  urlPrompt: t.urlPrompt ?? null,
@@ -1098,7 +1162,7 @@ async function handleAddProvider(req, res) {
1098
1162
  sendJson(res, 400, { error: "templateId required" });
1099
1163
  return;
1100
1164
  }
1101
- const { listSupportedTemplates: listSupportedTemplates2 } = await import("./provider-templates-MNJZTG3Z.js");
1165
+ const { listSupportedTemplates: listSupportedTemplates2 } = await import("./provider-templates-CRQJII3Z.js");
1102
1166
  const template = listSupportedTemplates2().find((t) => t.id === templateId);
1103
1167
  if (!template) {
1104
1168
  sendJson(res, 404, { error: `Template '${templateId}' not found` });
@@ -1118,13 +1182,17 @@ async function handleAddProvider(req, res) {
1118
1182
  return;
1119
1183
  }
1120
1184
  const usesHttp = /^http:\/\//i.test(baseUrlOverride);
1121
- const valid = await validateCustomEndpointUrl(baseUrlOverride, { allowInsecureLocal: usesHttp });
1185
+ const valid = await validateCustomEndpointUrl(baseUrlOverride, {
1186
+ allowInsecureLocal: usesHttp
1187
+ });
1122
1188
  if (!valid.ok) {
1123
1189
  sendJson(res, 400, { error: valid.error ?? "Invalid URL", hint: valid.hint });
1124
1190
  return;
1125
1191
  }
1126
1192
  }
1127
- const result = await addProviderFromTemplate(template, keyText, { baseUrl: baseUrlOverride });
1193
+ const result = await addProviderFromTemplate(template, keyText, {
1194
+ baseUrl: baseUrlOverride
1195
+ });
1128
1196
  if (result.added) {
1129
1197
  sendJson(res, 200, { ok: true, name: template.name, count: result.modelCount ?? 0 });
1130
1198
  } else {
@@ -1152,7 +1220,11 @@ async function handleRefreshAll(res) {
1152
1220
  reason: r.reason
1153
1221
  };
1154
1222
  });
1155
- sendJson(res, 200, { ok: true, providers: summary, total: summary.reduce((n, p2) => n + p2.count, 0) });
1223
+ sendJson(res, 200, {
1224
+ ok: true,
1225
+ providers: summary,
1226
+ total: summary.reduce((n, p2) => n + p2.count, 0)
1227
+ });
1156
1228
  } catch (err) {
1157
1229
  sendJson(res, 500, { ok: false, error: String(err) });
1158
1230
  }
@@ -1215,14 +1287,21 @@ async function handleOAuthStart(req, res) {
1215
1287
  const body = JSON.parse(await readBody(req));
1216
1288
  const { providerId } = body;
1217
1289
  if (!providerId || !NATIVE_OAUTH_PROVIDER_IDS.has(providerId)) {
1218
- sendJson(res, 400, { error: `providerId must be one of: ${[...NATIVE_OAUTH_PROVIDER_IDS].join(", ")}` });
1290
+ sendJson(res, 400, {
1291
+ error: `providerId must be one of: ${[...NATIVE_OAUTH_PROVIDER_IDS].join(", ")}`
1292
+ });
1219
1293
  return;
1220
1294
  }
1221
1295
  const sessionId = randomUUID();
1222
1296
  if (providerId === "xai-oauth") {
1223
1297
  const device2 = await requestXaiDeviceCode();
1224
1298
  const url2 = device2.verification_uri_complete ?? device2.verification_uri;
1225
- const session2 = { status: "pending", url: url2, userCode: device2.user_code, providerId };
1299
+ const session2 = {
1300
+ status: "pending",
1301
+ url: url2,
1302
+ userCode: device2.user_code,
1303
+ providerId
1304
+ };
1226
1305
  oauthSessions.set(sessionId, session2);
1227
1306
  pollXaiDeviceCodeToken(device2).then(async (tokens) => {
1228
1307
  await saveNativeOAuthCredential(providerId, tokens);
@@ -1237,7 +1316,12 @@ async function handleOAuthStart(req, res) {
1237
1316
  if (providerId === "github-copilot") {
1238
1317
  const device2 = await requestGithubDeviceCode();
1239
1318
  const url2 = device2.verification_uri;
1240
- const session2 = { status: "pending", url: url2, userCode: device2.user_code, providerId };
1319
+ const session2 = {
1320
+ status: "pending",
1321
+ url: url2,
1322
+ userCode: device2.user_code,
1323
+ providerId
1324
+ };
1241
1325
  oauthSessions.set(sessionId, session2);
1242
1326
  pollGithubDeviceCodeToken(device2).then(async (tokens) => {
1243
1327
  await saveNativeOAuthCredential(providerId, tokens);
@@ -1405,7 +1489,9 @@ async function handleLaunchApp(req, res, opts) {
1405
1489
  return;
1406
1490
  }
1407
1491
  if (!favorites && (providerId || modelId) && (!providerId || !modelId)) {
1408
- sendJson(res, 400, { error: "Both providerId and modelId are required to launch a specific anygate model." });
1492
+ sendJson(res, 400, {
1493
+ error: "Both providerId and modelId are required to launch a specific anygate model."
1494
+ });
1409
1495
  return;
1410
1496
  }
1411
1497
  const fullCatalog = Boolean(favoritesCatalog);
@@ -1464,7 +1550,9 @@ async function handleSetAppPath(req, res) {
1464
1550
  return;
1465
1551
  }
1466
1552
  if (path !== null && (typeof path !== "string" || !path.trim())) {
1467
- sendJson(res, 400, { error: "path must be a non-empty string, or null to clear the override." });
1553
+ sendJson(res, 400, {
1554
+ error: "path must be a non-empty string, or null to clear the override."
1555
+ });
1468
1556
  return;
1469
1557
  }
1470
1558
  const trimmed = typeof path === "string" ? path.trim() : null;
@@ -1595,12 +1683,16 @@ async function handleBrowseFolder(res) {
1595
1683
  const { stdout } = await execAsync(`powershell -NoProfile -Sta -EncodedCommand ${encoded}`);
1596
1684
  resultPath = stdout.trim();
1597
1685
  } catch (err) {
1598
- sendJson(res, 500, { error: `Failed to open folder picker: ${err instanceof Error ? err.message : String(err)}` });
1686
+ sendJson(res, 500, {
1687
+ error: `Failed to open folder picker: ${err instanceof Error ? err.message : String(err)}`
1688
+ });
1599
1689
  return;
1600
1690
  }
1601
1691
  } else {
1602
1692
  try {
1603
- const { stdout } = await execAsync('zenity --file-selection --directory --title="Select launch folder"');
1693
+ const { stdout } = await execAsync(
1694
+ 'zenity --file-selection --directory --title="Select launch folder"'
1695
+ );
1604
1696
  resultPath = stdout.trim();
1605
1697
  } catch {
1606
1698
  try {
@@ -1679,7 +1771,10 @@ function checkExistingServer() {
1679
1771
  let processExists = false;
1680
1772
  if (isWindows2) {
1681
1773
  try {
1682
- const output = execSync(`tasklist /FI "PID eq ${pid}"`, { encoding: "utf8", stdio: ["pipe", "pipe", "ignore"] });
1774
+ const output = execSync(`tasklist /FI "PID eq ${pid}"`, {
1775
+ encoding: "utf8",
1776
+ stdio: ["pipe", "pipe", "ignore"]
1777
+ });
1683
1778
  processExists = output.includes(String(pid));
1684
1779
  } catch {
1685
1780
  processExists = false;
@@ -1796,10 +1891,12 @@ async function runUiCommand(opts = {}) {
1796
1891
  process.on("SIGTERM", () => {
1797
1892
  void handleSignal("SIGTERM");
1798
1893
  });
1799
- console.log(`
1894
+ console.log(
1895
+ `
1800
1896
  ${pc.bold("anygate UI")} ${pc.cyan(url)}
1801
1897
  ${pc.dim("Press Ctrl+C to stop")}
1802
- `);
1898
+ `
1899
+ );
1803
1900
  if (traceLogPath) {
1804
1901
  console.log(` ${pc.dim(`Trace log: ${traceLogPath}`)}
1805
1902
  `);
@@ -1822,4 +1919,4 @@ export {
1822
1919
  resolveUiShutdownDecision,
1823
1920
  runUiCommand
1824
1921
  };
1825
- //# sourceMappingURL=command-7AI36ICY.js.map
1922
+ //# sourceMappingURL=command-PFFQI5YC.js.map