swixter 0.0.9 → 0.0.11

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/README.md +7 -2
  2. package/dist/cli/index.js +1042 -176
  3. package/package.json +4 -1
package/dist/cli/index.js CHANGED
@@ -1,31 +1,51 @@
1
1
  #!/usr/bin/env node
2
+ import { createRequire } from "node:module";
2
3
  var __create = Object.create;
3
4
  var __getProtoOf = Object.getPrototypeOf;
4
5
  var __defProp = Object.defineProperty;
5
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ function __accessProp(key) {
9
+ return this[key];
10
+ }
11
+ var __toESMCache_node;
12
+ var __toESMCache_esm;
7
13
  var __toESM = (mod, isNodeMode, target) => {
14
+ var canCache = mod != null && typeof mod === "object";
15
+ if (canCache) {
16
+ var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
17
+ var cached = cache.get(mod);
18
+ if (cached)
19
+ return cached;
20
+ }
8
21
  target = mod != null ? __create(__getProtoOf(mod)) : {};
9
22
  const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
10
23
  for (let key of __getOwnPropNames(mod))
11
24
  if (!__hasOwnProp.call(to, key))
12
25
  __defProp(to, key, {
13
- get: () => mod[key],
26
+ get: __accessProp.bind(mod, key),
14
27
  enumerable: true
15
28
  });
29
+ if (canCache)
30
+ cache.set(mod, to);
16
31
  return to;
17
32
  };
18
33
  var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
34
+ var __returnValue = (v) => v;
35
+ function __exportSetter(name, newValue) {
36
+ this[name] = __returnValue.bind(null, newValue);
37
+ }
19
38
  var __export = (target, all) => {
20
39
  for (var name in all)
21
40
  __defProp(target, name, {
22
41
  get: all[name],
23
42
  enumerable: true,
24
43
  configurable: true,
25
- set: (newValue) => all[name] = () => newValue
44
+ set: __exportSetter.bind(all, name)
26
45
  });
27
46
  };
28
47
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
48
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
29
49
 
30
50
  // node_modules/picocolors/picocolors.js
31
51
  var require_picocolors = __commonJS((exports, module) => {
@@ -13164,6 +13184,10 @@ function getConfigPath(type) {
13164
13184
  const config2 = PATH_CONFIG[type];
13165
13185
  return join(homedir(), config2.dir, config2.file);
13166
13186
  }
13187
+ function getConfigDir(type) {
13188
+ const config2 = PATH_CONFIG[type];
13189
+ return join(homedir(), config2.dir);
13190
+ }
13167
13191
  var PATH_CONFIG;
13168
13192
  var init_paths = __esm(() => {
13169
13193
  PATH_CONFIG = {
@@ -13237,7 +13261,7 @@ var CONFIG_VERSION = "2.0.0", EXPORT_VERSION = "1.0.0";
13237
13261
  var init_versions2 = () => {};
13238
13262
 
13239
13263
  // src/constants/meta.ts
13240
- var APP_VERSION = "0.0.9";
13264
+ var APP_VERSION = "0.0.11";
13241
13265
  var init_meta = () => {};
13242
13266
 
13243
13267
  // src/constants/install.ts
@@ -13533,6 +13557,42 @@ var init_presets = __esm(() => {
13533
13557
  allPresets = builtInPresets;
13534
13558
  });
13535
13559
 
13560
+ // src/utils/model-helper.ts
13561
+ function getOpenAIModel(profile) {
13562
+ if (profile.models) {
13563
+ return;
13564
+ }
13565
+ return profile.model || profile.openaiModel;
13566
+ }
13567
+ function buildProfileEnv(profile, envVarMapping, baseURL, options) {
13568
+ const env = {};
13569
+ if (baseURL && envVarMapping.baseURL) {
13570
+ env[envVarMapping.baseURL] = baseURL;
13571
+ }
13572
+ if (profile.apiKey) {
13573
+ const apiKeyEnvName = options?.apiKeyEnvName || envVarMapping.apiKey;
13574
+ if (apiKeyEnvName) {
13575
+ env[apiKeyEnvName] = profile.apiKey;
13576
+ }
13577
+ }
13578
+ if (profile.authToken && envVarMapping.authToken) {
13579
+ env[envVarMapping.authToken] = profile.authToken;
13580
+ }
13581
+ if (profile.models) {
13582
+ for (const [key, value] of Object.entries(profile.models)) {
13583
+ const envName = envVarMapping[key];
13584
+ if (value && envName) {
13585
+ env[envName] = value;
13586
+ }
13587
+ }
13588
+ }
13589
+ const openaiModel = profile.model || profile.openaiModel;
13590
+ if (openaiModel && envVarMapping.openaiModel) {
13591
+ env[envVarMapping.openaiModel] = openaiModel;
13592
+ }
13593
+ return env;
13594
+ }
13595
+
13536
13596
  // src/adapters/claude.ts
13537
13597
  import { existsSync as existsSync2 } from "node:fs";
13538
13598
  import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "node:fs/promises";
@@ -13555,29 +13615,7 @@ class ClaudeCodeAdapter {
13555
13615
  }
13556
13616
  }
13557
13617
  const envVars = this.coderConfig.envVarMapping;
13558
- const newEnv = {
13559
- [envVars.baseURL]: baseURL
13560
- };
13561
- if (profile.apiKey) {
13562
- newEnv[envVars.apiKey] = profile.apiKey;
13563
- }
13564
- if (profile.authToken && envVars.authToken) {
13565
- newEnv[envVars.authToken] = profile.authToken;
13566
- }
13567
- if (profile.models) {
13568
- if (profile.models.anthropicModel && envVars.anthropicModel) {
13569
- newEnv[envVars.anthropicModel] = profile.models.anthropicModel;
13570
- }
13571
- if (profile.models.defaultHaikuModel && envVars.defaultHaikuModel) {
13572
- newEnv[envVars.defaultHaikuModel] = profile.models.defaultHaikuModel;
13573
- }
13574
- if (profile.models.defaultOpusModel && envVars.defaultOpusModel) {
13575
- newEnv[envVars.defaultOpusModel] = profile.models.defaultOpusModel;
13576
- }
13577
- if (profile.models.defaultSonnetModel && envVars.defaultSonnetModel) {
13578
- newEnv[envVars.defaultSonnetModel] = profile.models.defaultSonnetModel;
13579
- }
13580
- }
13618
+ const newEnv = buildProfileEnv(profile, envVars, baseURL);
13581
13619
  const managedKeys = Object.values(envVars).filter(Boolean);
13582
13620
  const preservedEnv = {};
13583
13621
  if (existingConfig.env) {
@@ -13605,25 +13643,13 @@ class ClaudeCodeAdapter {
13605
13643
  const preset = await getPresetByIdAsync(profile.providerId);
13606
13644
  const expectedBaseURL = profile.baseURL || preset?.baseURL || "";
13607
13645
  const envVars = this.coderConfig.envVarMapping;
13608
- const hasApiKey = profile.apiKey && config2.env?.[envVars.apiKey] === profile.apiKey;
13609
- const hasAuthToken = profile.authToken && envVars.authToken && config2.env?.[envVars.authToken] === profile.authToken;
13610
- let hasMatchingModels = true;
13611
- if (profile.models) {
13612
- if (profile.models.anthropicModel && envVars.anthropicModel) {
13613
- hasMatchingModels = hasMatchingModels && config2.env?.[envVars.anthropicModel] === profile.models.anthropicModel;
13614
- }
13615
- if (profile.models.defaultHaikuModel && envVars.defaultHaikuModel) {
13616
- hasMatchingModels = hasMatchingModels && config2.env?.[envVars.defaultHaikuModel] === profile.models.defaultHaikuModel;
13617
- }
13618
- if (profile.models.defaultOpusModel && envVars.defaultOpusModel) {
13619
- hasMatchingModels = hasMatchingModels && config2.env?.[envVars.defaultOpusModel] === profile.models.defaultOpusModel;
13620
- }
13621
- if (profile.models.defaultSonnetModel && envVars.defaultSonnetModel) {
13622
- hasMatchingModels = hasMatchingModels && config2.env?.[envVars.defaultSonnetModel] === profile.models.defaultSonnetModel;
13646
+ const expectedEnv = buildProfileEnv(profile, envVars, expectedBaseURL);
13647
+ for (const [key, value] of Object.entries(expectedEnv)) {
13648
+ if (config2.env?.[key] !== value) {
13649
+ return false;
13623
13650
  }
13624
13651
  }
13625
- const noCredentials = !profile.apiKey && !profile.authToken;
13626
- return (noCredentials || hasApiKey || hasAuthToken) && config2.env?.[envVars.baseURL] === expectedBaseURL && hasMatchingModels;
13652
+ return Object.keys(expectedEnv).length > 0;
13627
13653
  } catch (error46) {
13628
13654
  return false;
13629
13655
  }
@@ -16247,14 +16273,6 @@ var init_js_yaml = __esm(() => {
16247
16273
  safeDump = renamed("safeDump", "dump");
16248
16274
  });
16249
16275
 
16250
- // src/utils/model-helper.ts
16251
- function getOpenAIModel(profile) {
16252
- if (profile.models) {
16253
- return;
16254
- }
16255
- return profile.model || profile.openaiModel;
16256
- }
16257
-
16258
16276
  // src/adapters/continue.ts
16259
16277
  import { existsSync as existsSync3 } from "node:fs";
16260
16278
  import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir3 } from "node:fs/promises";
@@ -17701,6 +17719,21 @@ var init_adapters = __esm(() => {
17701
17719
  });
17702
17720
 
17703
17721
  // src/config/manager.ts
17722
+ var exports_manager = {};
17723
+ __export(exports_manager, {
17724
+ upsertProfile: () => upsertProfile,
17725
+ setActiveProfileForCoder: () => setActiveProfileForCoder,
17726
+ setActiveProfile: () => setActiveProfile,
17727
+ saveConfig: () => saveConfig,
17728
+ profileExists: () => profileExists,
17729
+ loadConfig: () => loadConfig,
17730
+ listProfiles: () => listProfiles,
17731
+ getProfile: () => getProfile,
17732
+ getConfigPath: () => getConfigPath2,
17733
+ getActiveProfileForCoder: () => getActiveProfileForCoder,
17734
+ getActiveProfile: () => getActiveProfile,
17735
+ deleteProfile: () => deleteProfile
17736
+ });
17704
17737
  import { existsSync as existsSync5 } from "node:fs";
17705
17738
  import { mkdir as mkdir5, readFile as readFile5, writeFile as writeFile5 } from "node:fs/promises";
17706
17739
  import { dirname as dirname5 } from "node:path";
@@ -17758,6 +17791,9 @@ async function saveConfig(config2) {
17758
17791
  throw new Error(`Failed to save configuration: ${error46}`);
17759
17792
  }
17760
17793
  }
17794
+ async function getActiveProfile() {
17795
+ return getActiveProfileForCoder("claude");
17796
+ }
17761
17797
  async function getActiveProfileForCoder(coder) {
17762
17798
  const config2 = await loadConfig();
17763
17799
  const coderConfig = config2.coders[coder];
@@ -17766,6 +17802,9 @@ async function getActiveProfileForCoder(coder) {
17766
17802
  }
17767
17803
  return config2.profiles[coderConfig.activeProfile];
17768
17804
  }
17805
+ async function setActiveProfile(profileName) {
17806
+ return setActiveProfileForCoder("claude", profileName);
17807
+ }
17769
17808
  async function setActiveProfileForCoder(coder, profileName) {
17770
17809
  const config2 = await loadConfig();
17771
17810
  if (!config2.profiles[profileName]) {
@@ -17823,6 +17862,14 @@ async function listProfiles() {
17823
17862
  const config2 = await loadConfig();
17824
17863
  return Object.values(config2.profiles);
17825
17864
  }
17865
+ async function getProfile(profileName) {
17866
+ const config2 = await loadConfig();
17867
+ return config2.profiles[profileName] || null;
17868
+ }
17869
+ async function profileExists(profileName) {
17870
+ const config2 = await loadConfig();
17871
+ return profileName in config2.profiles;
17872
+ }
17826
17873
  var init_manager = __esm(() => {
17827
17874
  init_types();
17828
17875
  init_constants();
@@ -19614,7 +19661,7 @@ var require_semver2 = __commonJS((exports, module) => {
19614
19661
  });
19615
19662
 
19616
19663
  // src/cli/index.ts
19617
- var import_picocolors13 = __toESM(require_picocolors(), 1);
19664
+ var import_picocolors15 = __toESM(require_picocolors(), 1);
19618
19665
 
19619
19666
  // node_modules/@clack/core/dist/index.mjs
19620
19667
  var import_sisteransi = __toESM(require_src(), 1);
@@ -20336,7 +20383,8 @@ var FLAG_ALIASES = {
20336
20383
  "-o": "--output",
20337
20384
  "-i": "--input",
20338
20385
  "-y": "--yes",
20339
- "-v": "--verbose"
20386
+ "-v": "--verbose",
20387
+ "-P": "--port"
20340
20388
  };
20341
20389
  var VALID_COMMANDS = [
20342
20390
  "create",
@@ -20357,7 +20405,8 @@ var GLOBAL_COMMANDS = [
20357
20405
  "import",
20358
20406
  "completion",
20359
20407
  "help",
20360
- "version"
20408
+ "version",
20409
+ "ui"
20361
20410
  ];
20362
20411
  function resolveFlagAlias(flag) {
20363
20412
  return FLAG_ALIASES[flag] || flag;
@@ -20436,7 +20485,7 @@ async function handleApplyPrompt(options) {
20436
20485
  var import_picocolors5 = __toESM(require_picocolors(), 1);
20437
20486
  import { spawn } from "node:child_process";
20438
20487
  function spawnCLI(options) {
20439
- const { command, args, env, displayName } = options;
20488
+ const { command, args, env, displayName, onExit } = options;
20440
20489
  const finalEnv = env ? { ...process.env, ...env } : process.env;
20441
20490
  const child = spawn(command, args, {
20442
20491
  env: finalEnv,
@@ -20444,6 +20493,7 @@ function spawnCLI(options) {
20444
20493
  shell: true
20445
20494
  });
20446
20495
  child.on("exit", (code) => {
20496
+ onExit?.();
20447
20497
  process.exit(code || 0);
20448
20498
  });
20449
20499
  child.on("error", (error46) => {
@@ -20451,6 +20501,7 @@ function spawnCLI(options) {
20451
20501
  console.log(import_picocolors5.default.red(`✗ Run failed: ${error46.message}`));
20452
20502
  console.log(import_picocolors5.default.dim(`Please ensure ${displayName} CLI is installed`));
20453
20503
  console.log();
20504
+ onExit?.();
20454
20505
  process.exit(1);
20455
20506
  });
20456
20507
  }
@@ -21682,15 +21733,7 @@ async function cmdRun(args) {
21682
21733
  env[key] = value;
21683
21734
  }
21684
21735
  }
21685
- if (profile.apiKey) {
21686
- env.ANTHROPIC_API_KEY = profile.apiKey;
21687
- }
21688
- if (profile.authToken) {
21689
- env.ANTHROPIC_AUTH_TOKEN = profile.authToken;
21690
- }
21691
- if (baseURL) {
21692
- env.ANTHROPIC_BASE_URL = baseURL;
21693
- }
21736
+ Object.assign(env, buildProfileEnv(profile, CODER_CONFIG.envVarMapping, baseURL));
21694
21737
  const claudeArgs = args.filter((arg, idx) => {
21695
21738
  if (arg === "--profile") {
21696
21739
  return false;
@@ -21700,6 +21743,13 @@ async function cmdRun(args) {
21700
21743
  }
21701
21744
  return true;
21702
21745
  });
21746
+ const tmp = await import("node:os");
21747
+ const path = await import("node:path");
21748
+ const fs = await import("node:fs/promises");
21749
+ const settingsContent = JSON.stringify({ env }, null, 2);
21750
+ const tmpFile = path.join(tmp.tmpdir(), `swixter-settings-${Date.now()}.json`);
21751
+ await fs.writeFile(tmpFile, settingsContent, "utf-8");
21752
+ claudeArgs.push("--settings", tmpFile);
21703
21753
  console.log();
21704
21754
  console.log(import_picocolors8.default.dim(`Using profile: ${import_picocolors8.default.cyan(profile.name)} (${preset?.displayName})`));
21705
21755
  console.log(import_picocolors8.default.dim(`Base URL: ${import_picocolors8.default.yellow(baseURL || "Default")}`));
@@ -21708,7 +21758,10 @@ async function cmdRun(args) {
21708
21758
  command: "claude",
21709
21759
  args: claudeArgs,
21710
21760
  env,
21711
- displayName: CODER_CONFIG.displayName
21761
+ displayName: CODER_CONFIG.displayName,
21762
+ onExit: () => {
21763
+ fs.unlink(tmpFile).catch(() => {});
21764
+ }
21712
21765
  });
21713
21766
  }
21714
21767
  async function cmdInstall(args) {
@@ -22420,15 +22473,7 @@ async function cmdRun2(args) {
22420
22473
  env[key] = value;
22421
22474
  }
22422
22475
  }
22423
- if (profile.apiKey) {
22424
- env.OPENAI_API_KEY = profile.apiKey;
22425
- }
22426
- if (baseURL) {
22427
- env.OPENAI_BASE_URL = baseURL;
22428
- }
22429
- if (profile.model || profile.openaiModel) {
22430
- env.OPENAI_MODEL = profile.model || profile.openaiModel;
22431
- }
22476
+ Object.assign(env, buildProfileEnv(profile, CODER_CONFIG2.envVarMapping, baseURL));
22432
22477
  const qwenArgs = [];
22433
22478
  if (profile.apiKey) {
22434
22479
  qwenArgs.push("--openai-api-key", profile.apiKey);
@@ -23316,12 +23361,9 @@ async function cmdRun3(args) {
23316
23361
  env[key] = value;
23317
23362
  }
23318
23363
  }
23319
- if (profile.apiKey) {
23320
- env[envKey] = profile.apiKey;
23321
- }
23322
- if (profile.model || profile.openaiModel) {
23323
- env["OPENAI_MODEL"] = profile.model || profile.openaiModel;
23324
- }
23364
+ Object.assign(env, buildProfileEnv(profile, CODER_CONFIG3.envVarMapping, "", {
23365
+ apiKeyEnvName: envKey
23366
+ }));
23325
23367
  const codexArgs = args.filter((arg, idx) => {
23326
23368
  if (arg === "--profile") {
23327
23369
  return false;
@@ -23364,6 +23406,611 @@ async function cmdUpdate3(args) {
23364
23406
  await handleUpdateCommand(CODER_NAME3, CODER_CONFIG3, args);
23365
23407
  }
23366
23408
 
23409
+ // src/cli/ui.ts
23410
+ var import_picocolors12 = __toESM(require_picocolors(), 1);
23411
+
23412
+ // src/server/index.ts
23413
+ var import_picocolors11 = __toESM(require_picocolors(), 1);
23414
+ import { createServer } from "node:http";
23415
+ import { dirname as dirname7, join as join6 } from "node:path";
23416
+ import { fileURLToPath } from "node:url";
23417
+ import { exec } from "node:child_process";
23418
+
23419
+ // src/server/middleware.ts
23420
+ function corsMiddleware(req, res, next) {
23421
+ const origin = req.headers.origin;
23422
+ if (origin && (origin.startsWith("http://127.0.0.1:") || origin.startsWith("http://localhost:"))) {
23423
+ res.setHeader("Access-Control-Allow-Origin", origin);
23424
+ }
23425
+ if (req.method === "OPTIONS") {
23426
+ res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
23427
+ res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
23428
+ res.setHeader("Access-Control-Max-Age", "86400");
23429
+ res.statusCode = 204;
23430
+ res.end();
23431
+ return;
23432
+ }
23433
+ next();
23434
+ }
23435
+ function jsonBodyMiddleware(req, res, next) {
23436
+ if (!["POST", "PUT", "PATCH"].includes(req.method || "")) {
23437
+ next();
23438
+ return;
23439
+ }
23440
+ const contentType = req.headers["content-type"];
23441
+ if (!contentType?.includes("application/json")) {
23442
+ next();
23443
+ return;
23444
+ }
23445
+ const chunks = [];
23446
+ req.on("data", (chunk) => {
23447
+ chunks.push(chunk);
23448
+ });
23449
+ req.on("end", () => {
23450
+ try {
23451
+ if (chunks.length === 0) {
23452
+ next();
23453
+ return;
23454
+ }
23455
+ const body = Buffer.concat(chunks).toString("utf-8");
23456
+ req.body = JSON.parse(body);
23457
+ next();
23458
+ } catch (error46) {
23459
+ next(new Error("Invalid JSON body"));
23460
+ }
23461
+ });
23462
+ req.on("error", (error46) => {
23463
+ next(error46);
23464
+ });
23465
+ }
23466
+ function sendError(res, error46, statusCode = 400) {
23467
+ res.setHeader("Content-Type", "application/json");
23468
+ if (error46 instanceof Error) {
23469
+ res.statusCode = statusCode;
23470
+ res.end(JSON.stringify({
23471
+ error: {
23472
+ code: "UNKNOWN_ERROR",
23473
+ message: error46.message
23474
+ }
23475
+ }));
23476
+ return;
23477
+ }
23478
+ res.statusCode = statusCode;
23479
+ res.end(JSON.stringify({
23480
+ error: error46
23481
+ }));
23482
+ }
23483
+ function sendJson(res, data, statusCode = 200) {
23484
+ res.setHeader("Content-Type", "application/json");
23485
+ res.statusCode = statusCode;
23486
+ res.end(JSON.stringify(data));
23487
+ }
23488
+ function notFoundHandler(req, res) {
23489
+ res.setHeader("Content-Type", "application/json");
23490
+ res.statusCode = 404;
23491
+ res.end(JSON.stringify({
23492
+ error: {
23493
+ code: "NOT_FOUND",
23494
+ message: `Path ${req.url} not found`
23495
+ }
23496
+ }));
23497
+ }
23498
+
23499
+ // src/server/router.ts
23500
+ function extractParams(pattern, path) {
23501
+ const patternParts = pattern.replace(/\/$/, "").split("/").filter(Boolean);
23502
+ const pathParts = path.replace(/\/$/, "").split("/").filter(Boolean);
23503
+ if (patternParts.length !== pathParts.length) {
23504
+ return null;
23505
+ }
23506
+ const params = {};
23507
+ for (let i2 = 0;i2 < patternParts.length; i2++) {
23508
+ const patternPart = patternParts[i2];
23509
+ const pathPart = pathParts[i2];
23510
+ if (patternPart.startsWith(":")) {
23511
+ const paramName = patternPart.slice(1);
23512
+ params[paramName] = pathPart;
23513
+ } else if (patternPart !== pathPart) {
23514
+ return null;
23515
+ }
23516
+ }
23517
+ return params;
23518
+ }
23519
+
23520
+ class Router {
23521
+ routes = [];
23522
+ middleware = [];
23523
+ use(middleware) {
23524
+ this.middleware.push(middleware);
23525
+ }
23526
+ get(pattern, handler) {
23527
+ this.routes.push({ method: "GET", pattern, handler });
23528
+ }
23529
+ post(pattern, handler) {
23530
+ this.routes.push({ method: "POST", pattern, handler });
23531
+ }
23532
+ put(pattern, handler) {
23533
+ this.routes.push({ method: "PUT", pattern, handler });
23534
+ }
23535
+ delete(pattern, handler) {
23536
+ this.routes.push({ method: "DELETE", pattern, handler });
23537
+ }
23538
+ matchRoute(req) {
23539
+ const method = (req.method || "GET").toUpperCase();
23540
+ const url2 = new URL(req.url || "", `http://${req.headers.host || "localhost"}`);
23541
+ const path = url2.pathname;
23542
+ for (const route of this.routes) {
23543
+ if (route.method !== method) {
23544
+ continue;
23545
+ }
23546
+ const params = extractParams(route.pattern, path);
23547
+ if (params !== null) {
23548
+ return { route, params };
23549
+ }
23550
+ }
23551
+ return null;
23552
+ }
23553
+ async handle(req, res) {
23554
+ let middlewareIndex = 0;
23555
+ const runMiddleware = (error46) => {
23556
+ if (error46) {
23557
+ this.finalize(req, res, error46);
23558
+ return;
23559
+ }
23560
+ if (middlewareIndex < this.middleware.length) {
23561
+ const middleware = this.middleware[middlewareIndex++];
23562
+ Promise.resolve(middleware(req, res, runMiddleware)).catch(runMiddleware);
23563
+ return;
23564
+ }
23565
+ this.executeRoute(req, res).catch((error47) => {
23566
+ this.finalize(req, res, error47);
23567
+ });
23568
+ };
23569
+ runMiddleware();
23570
+ }
23571
+ async executeRoute(req, res) {
23572
+ const match = this.matchRoute(req);
23573
+ if (!match) {
23574
+ return;
23575
+ }
23576
+ const { route, params } = match;
23577
+ await route.handler(req, res, params);
23578
+ }
23579
+ finalize(req, res, error46) {
23580
+ if (error46) {
23581
+ sendError(res, error46, 500);
23582
+ return;
23583
+ }
23584
+ if (!res.writableEnded) {
23585
+ notFoundHandler(req, res);
23586
+ }
23587
+ }
23588
+ }
23589
+
23590
+ // src/server/static.ts
23591
+ import { createReadStream } from "node:fs";
23592
+ import { stat } from "node:fs/promises";
23593
+ import { extname, join as join4 } from "node:path";
23594
+ var MIME_TYPES = {
23595
+ ".html": "text/html; charset=utf-8",
23596
+ ".js": "application/javascript; charset=utf-8",
23597
+ ".mjs": "application/javascript; charset=utf-8",
23598
+ ".css": "text/css; charset=utf-8",
23599
+ ".json": "application/json; charset=utf-8",
23600
+ ".png": "image/png",
23601
+ ".jpg": "image/jpeg",
23602
+ ".jpeg": "image/jpeg",
23603
+ ".gif": "image/gif",
23604
+ ".svg": "image/svg+xml",
23605
+ ".ico": "image/x-icon",
23606
+ ".woff": "font/woff",
23607
+ ".woff2": "font/woff2",
23608
+ ".ttf": "font/ttf",
23609
+ ".eot": "application/vnd.ms-fontobject",
23610
+ ".mp4": "video/mp4",
23611
+ ".webm": "video/webm",
23612
+ ".ogg": "audio/ogg",
23613
+ ".mp3": "audio/mpeg",
23614
+ ".wav": "audio/wav",
23615
+ ".webp": "image/webp",
23616
+ ".avif": "image/avif"
23617
+ };
23618
+ function createStaticServe(options) {
23619
+ const { root, index = "index.html", spa = true } = options;
23620
+ return async (req, res) => {
23621
+ const url2 = new URL(req.url || "", `http://${req.headers.host || "localhost"}`);
23622
+ let filePath = join4(root, url2.pathname);
23623
+ try {
23624
+ const stats = await stat(filePath);
23625
+ if (stats.isDirectory()) {
23626
+ filePath = join4(filePath, index);
23627
+ await stat(filePath);
23628
+ }
23629
+ const ext = extname(filePath);
23630
+ const contentType = MIME_TYPES[ext] || "application/octet-stream";
23631
+ res.setHeader("Content-Type", contentType);
23632
+ const stream = createReadStream(filePath);
23633
+ stream.on("error", (error46) => {
23634
+ if (!res.writableEnded) {
23635
+ res.statusCode = 500;
23636
+ res.end("Internal Server Error");
23637
+ }
23638
+ });
23639
+ stream.pipe(res);
23640
+ } catch (error46) {
23641
+ if (spa) {
23642
+ try {
23643
+ const indexPath = join4(root, index);
23644
+ const stats = await stat(indexPath);
23645
+ if (stats.isFile()) {
23646
+ res.setHeader("Content-Type", "text/html; charset=utf-8");
23647
+ const stream = createReadStream(indexPath);
23648
+ stream.pipe(res);
23649
+ return;
23650
+ }
23651
+ } catch {}
23652
+ }
23653
+ if (!res.writableEnded) {
23654
+ res.statusCode = 404;
23655
+ res.setHeader("Content-Type", "text/plain; charset=utf-8");
23656
+ res.end("Not Found");
23657
+ }
23658
+ }
23659
+ };
23660
+ }
23661
+
23662
+ // src/server/api/profiles.ts
23663
+ init_manager();
23664
+
23665
+ // src/server/api/util.ts
23666
+ function maskApiKey(apiKey) {
23667
+ if (!apiKey || apiKey.length <= 8) {
23668
+ return "****";
23669
+ }
23670
+ const first = apiKey.slice(0, 4);
23671
+ const last = apiKey.slice(-4);
23672
+ return `${first}${"*".repeat(Math.min(apiKey.length - 8, 20))}${last}`;
23673
+ }
23674
+ function maskAuthToken(token) {
23675
+ if (!token || token.length <= 8) {
23676
+ return "****";
23677
+ }
23678
+ const first = token.slice(0, 4);
23679
+ const last = token.slice(-4);
23680
+ return `${first}${"*".repeat(Math.min(token.length - 8, 20))}${last}`;
23681
+ }
23682
+ function sanitizeProfile(profile) {
23683
+ return {
23684
+ ...profile,
23685
+ apiKey: maskApiKey(profile.apiKey),
23686
+ authToken: profile.authToken ? maskAuthToken(profile.authToken) : undefined
23687
+ };
23688
+ }
23689
+ function generateETag(mtime, size) {
23690
+ const mtimeMs = Math.floor(mtime.getTime() / 1000);
23691
+ return `"${mtimeMs}-${size}"`;
23692
+ }
23693
+ function parseIfNoneMatch(header) {
23694
+ if (!header) {
23695
+ return null;
23696
+ }
23697
+ return header.replace(/^"|"$/g, "");
23698
+ }
23699
+ function setETagHeaders(res, mtime, size) {
23700
+ const etag = generateETag(mtime, size);
23701
+ res.setHeader("ETag", etag);
23702
+ res.setHeader("Cache-Control", "no-cache");
23703
+ }
23704
+
23705
+ // src/server/api/profiles.ts
23706
+ init_presets();
23707
+ async function listProfiles2(req, res) {
23708
+ const profiles = await listProfiles();
23709
+ sendJson(res, profiles.map(sanitizeProfile));
23710
+ }
23711
+ async function getProfile2(req, res, params) {
23712
+ const { name } = params;
23713
+ if (!name) {
23714
+ sendError(res, { code: "INVALID_PARAMS", message: "Profile name is required" }, 400);
23715
+ return;
23716
+ }
23717
+ const profile = await getProfile(name);
23718
+ if (!profile) {
23719
+ sendError(res, { code: "PROFILE_NOT_FOUND", message: `Profile "${name}" does not exist` }, 404);
23720
+ return;
23721
+ }
23722
+ sendJson(res, sanitizeProfile(profile));
23723
+ }
23724
+ async function createProfile(req, res) {
23725
+ const body = req.body;
23726
+ if (!body || !body.name || !body.providerId) {
23727
+ sendError(res, { code: "INVALID_PARAMS", message: "name and providerId are required" }, 400);
23728
+ return;
23729
+ }
23730
+ const providers = await getAllPresets();
23731
+ const provider = providers.find((p2) => p2.id === body.providerId);
23732
+ if (!provider) {
23733
+ sendError(res, { code: "UNKNOWN_PROVIDER", message: `Provider "${body.providerId}" not found` }, 400);
23734
+ return;
23735
+ }
23736
+ const existing = await getProfile(body.name);
23737
+ if (existing) {
23738
+ sendError(res, { code: "PROFILE_EXISTS", message: `Profile "${body.name}" already exists` }, 409);
23739
+ return;
23740
+ }
23741
+ try {
23742
+ const now = new Date().toISOString();
23743
+ const profile = {
23744
+ name: body.name,
23745
+ providerId: body.providerId,
23746
+ apiKey: body.apiKey || "",
23747
+ authToken: body.authToken || "",
23748
+ baseURL: body.baseURL || provider.baseURL,
23749
+ model: body.model,
23750
+ openaiModel: body.openaiModel,
23751
+ models: body.models,
23752
+ envKey: body.envKey,
23753
+ headers: body.headers,
23754
+ createdAt: now,
23755
+ updatedAt: now
23756
+ };
23757
+ await upsertProfile(profile, body.coder);
23758
+ sendJson(res, sanitizeProfile(profile), 201);
23759
+ } catch (error46) {
23760
+ sendError(res, { code: "CREATE_FAILED", message: error46 instanceof Error ? error46.message : "Failed to create profile" }, 500);
23761
+ }
23762
+ }
23763
+ async function updateProfile(req, res, params) {
23764
+ const { name } = params;
23765
+ const body = req.body;
23766
+ if (!name) {
23767
+ sendError(res, { code: "INVALID_PARAMS", message: "Profile name is required" }, 400);
23768
+ return;
23769
+ }
23770
+ const existing = await getProfile(name);
23771
+ if (!existing) {
23772
+ sendError(res, { code: "PROFILE_NOT_FOUND", message: `Profile "${name}" does not exist` }, 404);
23773
+ return;
23774
+ }
23775
+ try {
23776
+ const now = new Date().toISOString();
23777
+ const profile = {
23778
+ ...existing,
23779
+ ...body,
23780
+ name,
23781
+ updatedAt: now
23782
+ };
23783
+ await upsertProfile(profile);
23784
+ sendJson(res, sanitizeProfile(profile));
23785
+ } catch (error46) {
23786
+ sendError(res, { code: "UPDATE_FAILED", message: error46 instanceof Error ? error46.message : "Failed to update profile" }, 500);
23787
+ }
23788
+ }
23789
+ async function deleteProfile2(req, res, params) {
23790
+ const { name } = params;
23791
+ if (!name) {
23792
+ sendError(res, { code: "INVALID_PARAMS", message: "Profile name is required" }, 400);
23793
+ return;
23794
+ }
23795
+ try {
23796
+ await deleteProfile(name);
23797
+ sendJson(res, { success: true, message: `Profile "${name}" deleted` });
23798
+ } catch (error46) {
23799
+ sendError(res, { code: "DELETE_FAILED", message: error46 instanceof Error ? error46.message : "Failed to delete profile" }, 500);
23800
+ }
23801
+ }
23802
+
23803
+ // src/server/api/providers.ts
23804
+ init_presets();
23805
+ init_user_providers();
23806
+ async function listProviders(req, res) {
23807
+ const providers = await getAllPresets();
23808
+ const userProviders = await loadUserProviders();
23809
+ const userIds = new Set(userProviders.map((p2) => p2.id));
23810
+ const result = providers.map((p2) => ({
23811
+ ...p2,
23812
+ isUser: userIds.has(p2.id)
23813
+ }));
23814
+ sendJson(res, result);
23815
+ }
23816
+ async function createProvider(req, res) {
23817
+ const body = req.body;
23818
+ if (!body || !body.id || !body.name || !body.displayName) {
23819
+ sendError(res, { code: "INVALID_PARAMS", message: "id, name, and displayName are required" }, 400);
23820
+ return;
23821
+ }
23822
+ const providers = await getAllPresets();
23823
+ const existing = providers.find((p2) => p2.id === body.id);
23824
+ if (existing) {
23825
+ sendError(res, { code: "PROVIDER_EXISTS", message: `Provider "${body.id}" already exists` }, 409);
23826
+ return;
23827
+ }
23828
+ try {
23829
+ const provider = {
23830
+ id: body.id,
23831
+ name: body.name,
23832
+ displayName: body.displayName,
23833
+ baseURL: body.baseURL || "",
23834
+ defaultModels: body.defaultModels || [],
23835
+ authType: body.authType || "api-key",
23836
+ headers: body.headers,
23837
+ rateLimit: body.rateLimit,
23838
+ docs: body.docs,
23839
+ isChinese: body.isChinese,
23840
+ wire_api: body.wire_api,
23841
+ env_key: body.env_key
23842
+ };
23843
+ await upsertUserProvider(provider);
23844
+ sendJson(res, { ...provider, isUser: true }, 201);
23845
+ } catch (error46) {
23846
+ sendError(res, { code: "CREATE_FAILED", message: error46 instanceof Error ? error46.message : "Failed to create provider" }, 500);
23847
+ }
23848
+ }
23849
+ async function updateProvider(req, res, params) {
23850
+ const { id } = params;
23851
+ const body = req.body;
23852
+ if (!id) {
23853
+ sendError(res, { code: "INVALID_PARAMS", message: "Provider ID is required" }, 400);
23854
+ return;
23855
+ }
23856
+ const userProviders = await loadUserProviders();
23857
+ const existing = userProviders.find((p2) => p2.id === id);
23858
+ if (!existing) {
23859
+ sendError(res, { code: "NOT_USER_PROVIDER", message: `Provider "${id}" is not a user-defined provider` }, 400);
23860
+ return;
23861
+ }
23862
+ try {
23863
+ const provider = {
23864
+ ...existing,
23865
+ ...body,
23866
+ id
23867
+ };
23868
+ await upsertUserProvider(provider);
23869
+ sendJson(res, { ...provider, isUser: true });
23870
+ } catch (error46) {
23871
+ sendError(res, { code: "UPDATE_FAILED", message: error46 instanceof Error ? error46.message : "Failed to update provider" }, 500);
23872
+ }
23873
+ }
23874
+ async function deleteProvider(req, res, params) {
23875
+ const { id } = params;
23876
+ if (!id) {
23877
+ sendError(res, { code: "INVALID_PARAMS", message: "Provider ID is required" }, 400);
23878
+ return;
23879
+ }
23880
+ const userProviders = await loadUserProviders();
23881
+ const existing = userProviders.find((p2) => p2.id === id);
23882
+ if (!existing) {
23883
+ sendError(res, { code: "NOT_USER_PROVIDER", message: `Provider "${id}" is not a user-defined provider` }, 400);
23884
+ return;
23885
+ }
23886
+ try {
23887
+ const deleted = await deleteUserProvider(id);
23888
+ if (!deleted) {
23889
+ sendError(res, { code: "DELETE_FAILED", message: `Failed to delete provider "${id}"` }, 500);
23890
+ return;
23891
+ }
23892
+ sendJson(res, { success: true, message: `Provider "${id}" deleted` });
23893
+ } catch (error46) {
23894
+ sendError(res, { code: "DELETE_FAILED", message: error46 instanceof Error ? error46.message : "Failed to delete provider" }, 500);
23895
+ }
23896
+ }
23897
+
23898
+ // src/server/api/coders.ts
23899
+ init_coders();
23900
+ init_manager();
23901
+ init_adapters();
23902
+ async function listCoders(req, res) {
23903
+ const result = [];
23904
+ for (const [coderId, coderConfig] of Object.entries(CODER_REGISTRY)) {
23905
+ const activeProfile = await getActiveProfileForCoder(coderId);
23906
+ result.push({
23907
+ id: coderId,
23908
+ displayName: coderConfig.displayName,
23909
+ executable: coderConfig.executable,
23910
+ activeProfile: activeProfile ? {
23911
+ name: activeProfile.name,
23912
+ providerId: activeProfile.providerId,
23913
+ baseURL: activeProfile.baseURL
23914
+ } : null
23915
+ });
23916
+ }
23917
+ sendJson(res, result);
23918
+ }
23919
+ async function getActiveProfile2(req, res, params) {
23920
+ const { coder } = params;
23921
+ if (!coder) {
23922
+ sendError(res, { code: "INVALID_PARAMS", message: "Coder ID is required" }, 400);
23923
+ return;
23924
+ }
23925
+ if (!CODER_REGISTRY[coder]) {
23926
+ sendError(res, { code: "UNKNOWN_CODER", message: `Coder "${coder}" not found` }, 404);
23927
+ return;
23928
+ }
23929
+ const profile = await getActiveProfileForCoder(coder);
23930
+ if (!profile) {
23931
+ sendJson(res, { activeProfile: null });
23932
+ return;
23933
+ }
23934
+ sendJson(res, { activeProfile: sanitizeProfile(profile) });
23935
+ }
23936
+ async function setActiveProfile2(req, res, params) {
23937
+ const { coder } = params;
23938
+ const body = req.body;
23939
+ if (!coder) {
23940
+ sendError(res, { code: "INVALID_PARAMS", message: "Coder ID is required" }, 400);
23941
+ return;
23942
+ }
23943
+ if (!CODER_REGISTRY[coder]) {
23944
+ sendError(res, { code: "UNKNOWN_CODER", message: `Coder "${coder}" not found` }, 404);
23945
+ return;
23946
+ }
23947
+ if (!body || !body.profileName) {
23948
+ sendError(res, { code: "INVALID_PARAMS", message: "profileName is required" }, 400);
23949
+ return;
23950
+ }
23951
+ try {
23952
+ await setActiveProfileForCoder(coder, body.profileName);
23953
+ const profile = await getActiveProfileForCoder(coder);
23954
+ sendJson(res, { activeProfile: profile ? sanitizeProfile(profile) : null });
23955
+ } catch (error46) {
23956
+ sendError(res, { code: "SWITCH_FAILED", message: error46 instanceof Error ? error46.message : "Failed to switch profile" }, 500);
23957
+ }
23958
+ }
23959
+ async function applyProfile(req, res, params) {
23960
+ const { coder } = params;
23961
+ if (!coder) {
23962
+ sendError(res, { code: "INVALID_PARAMS", message: "Coder ID is required" }, 400);
23963
+ return;
23964
+ }
23965
+ if (!CODER_REGISTRY[coder]) {
23966
+ sendError(res, { code: "UNKNOWN_CODER", message: `Coder "${coder}" not found` }, 404);
23967
+ return;
23968
+ }
23969
+ const profile = await getActiveProfileForCoder(coder);
23970
+ if (!profile) {
23971
+ sendError(res, { code: "NO_ACTIVE_PROFILE", message: `No active profile for coder "${coder}"` }, 400);
23972
+ return;
23973
+ }
23974
+ try {
23975
+ const adapter = getAdapter(coder);
23976
+ await adapter.apply(profile);
23977
+ sendJson(res, { success: true, message: `Profile applied to ${coder}` });
23978
+ } catch (error46) {
23979
+ sendError(res, { code: "APPLY_FAILED", message: error46 instanceof Error ? error46.message : "Failed to apply profile" }, 500);
23980
+ }
23981
+ }
23982
+ async function verifyConfig(req, res, params) {
23983
+ const { coder } = params;
23984
+ if (!coder) {
23985
+ sendError(res, { code: "INVALID_PARAMS", message: "Coder ID is required" }, 400);
23986
+ return;
23987
+ }
23988
+ if (!CODER_REGISTRY[coder]) {
23989
+ sendError(res, { code: "UNKNOWN_CODER", message: `Coder "${coder}" not found` }, 404);
23990
+ return;
23991
+ }
23992
+ const profile = await getActiveProfileForCoder(coder);
23993
+ if (!profile) {
23994
+ sendJson(res, { verified: false, message: "No active profile" });
23995
+ return;
23996
+ }
23997
+ try {
23998
+ const adapter = getAdapter(coder);
23999
+ const verified = await adapter.verify(profile);
24000
+ sendJson(res, { verified, message: verified ? "Configuration verified" : "Verification failed" });
24001
+ } catch (error46) {
24002
+ sendJson(res, { verified: false, message: error46 instanceof Error ? error46.message : "Verification failed" });
24003
+ }
24004
+ }
24005
+
24006
+ // src/server/api/config.ts
24007
+ init_meta();
24008
+ init_versions2();
24009
+ init_paths();
24010
+ import { existsSync as existsSync7, statSync } from "node:fs";
24011
+ import { readFile as readFile7, writeFile as writeFile7, unlink } from "node:fs/promises";
24012
+ import { join as join5 } from "node:path";
24013
+
23367
24014
  // src/config/export.ts
23368
24015
  init_types();
23369
24016
  init_manager();
@@ -23453,47 +24100,262 @@ async function importConfig(filePath, options = {}) {
23453
24100
  return { imported, skipped, errors: errors3 };
23454
24101
  }
23455
24102
 
24103
+ // src/server/api/config.ts
24104
+ async function getVersion(req, res) {
24105
+ sendJson(res, {
24106
+ appVersion: APP_VERSION,
24107
+ configVersion: CONFIG_VERSION,
24108
+ exportVersion: EXPORT_VERSION
24109
+ });
24110
+ }
24111
+ async function getConfigMeta(req, res) {
24112
+ const configPath = getConfigPath("swixter");
24113
+ if (!existsSync7(configPath)) {
24114
+ sendJson(res, {
24115
+ exists: false,
24116
+ profiles: [],
24117
+ mtime: null,
24118
+ size: 0
24119
+ });
24120
+ return;
24121
+ }
24122
+ try {
24123
+ const stats = statSync(configPath);
24124
+ const etag = generateETag(stats.mtime, stats.size);
24125
+ const ifNoneMatch = parseIfNoneMatch(req.headers["if-none-match"]);
24126
+ if (ifNoneMatch === etag) {
24127
+ res.statusCode = 304;
24128
+ res.end();
24129
+ return;
24130
+ }
24131
+ setETagHeaders(res, stats.mtime, stats.size);
24132
+ const { listProfiles: listProfiles3 } = await Promise.resolve().then(() => (init_manager(), exports_manager));
24133
+ const profiles = await listProfiles3();
24134
+ sendJson(res, {
24135
+ exists: true,
24136
+ profiles: profiles.map((p2) => ({
24137
+ name: p2.name,
24138
+ providerId: p2.providerId,
24139
+ updatedAt: p2.updatedAt
24140
+ })),
24141
+ mtime: stats.mtime.toISOString(),
24142
+ size: stats.size,
24143
+ etag
24144
+ });
24145
+ } catch (error46) {
24146
+ sendError(res, { code: "STAT_FAILED", message: "Failed to read config metadata" }, 500);
24147
+ }
24148
+ }
24149
+ async function exportConfigFile(req, res) {
24150
+ try {
24151
+ const configPath = getConfigPath("swixter");
24152
+ const content = await readFile7(configPath, "utf-8");
24153
+ res.setHeader("Content-Type", "application/json");
24154
+ res.setHeader("Content-Disposition", 'attachment; filename="swixter-config.json"');
24155
+ res.statusCode = 200;
24156
+ res.end(content);
24157
+ } catch (error46) {
24158
+ sendError(res, { code: "EXPORT_FAILED", message: "Failed to export configuration" }, 500);
24159
+ }
24160
+ }
24161
+ async function importConfigFile(req, res) {
24162
+ const body = req.body;
24163
+ if (!body || !body.config) {
24164
+ sendError(res, { code: "INVALID_PARAMS", message: "config is required" }, 400);
24165
+ return;
24166
+ }
24167
+ try {
24168
+ const tempDir = getConfigDir("swixter");
24169
+ const tempPath = join5(tempDir, `.import-${Date.now()}.json`);
24170
+ await writeFile7(tempPath, JSON.stringify(body.config), "utf-8");
24171
+ try {
24172
+ const result = await importConfig(tempPath, { overwrite: body.overwrite !== false });
24173
+ sendJson(res, { success: true, ...result });
24174
+ } finally {
24175
+ try {
24176
+ await unlink(tempPath);
24177
+ } catch {}
24178
+ }
24179
+ } catch (error46) {
24180
+ sendError(res, { code: "IMPORT_FAILED", message: error46 instanceof Error ? error46.message : "Failed to import configuration" }, 500);
24181
+ }
24182
+ }
24183
+
24184
+ // src/server/index.ts
24185
+ var __dirname2 = dirname7(fileURLToPath(import.meta.url));
24186
+ async function findAvailablePort(startPort = 3141) {
24187
+ const net = await import("node:net");
24188
+ return new Promise((resolve) => {
24189
+ const server = net.createServer();
24190
+ server.listen(startPort, "127.0.0.1", () => {
24191
+ const port = server.address().port;
24192
+ server.close(() => resolve(port));
24193
+ });
24194
+ server.on("error", () => {
24195
+ server.close();
24196
+ resolve(findAvailablePort(startPort + 1));
24197
+ });
24198
+ });
24199
+ }
24200
+ function openBrowser(url2) {
24201
+ const command = process.platform === "win32" ? "start" : process.platform === "darwin" ? "open" : "xdg-open";
24202
+ exec(`${command} ${url2}`, (error46) => {
24203
+ if (error46) {
24204
+ console.warn(import_picocolors11.default.yellow(`Could not open browser automatically: ${error46.message}`));
24205
+ }
24206
+ });
24207
+ }
24208
+ function getUiDir() {
24209
+ const isDev = true;
24210
+ if (isDev) {
24211
+ return join6(__dirname2, "..", "..", "ui", "dist");
24212
+ }
24213
+ return join6(__dirname2, "..", "..", "ui");
24214
+ }
24215
+ async function startServer(portArg) {
24216
+ const port = portArg || await findAvailablePort(3141);
24217
+ const host = "127.0.0.1";
24218
+ const router = new Router;
24219
+ router.use(corsMiddleware);
24220
+ router.use(jsonBodyMiddleware);
24221
+ router.get("/api/profiles", listProfiles2);
24222
+ router.get("/api/profiles/:name", getProfile2);
24223
+ router.post("/api/profiles", createProfile);
24224
+ router.put("/api/profiles/:name", updateProfile);
24225
+ router.delete("/api/profiles/:name", deleteProfile2);
24226
+ router.get("/api/providers", listProviders);
24227
+ router.post("/api/providers", createProvider);
24228
+ router.put("/api/providers/:id", updateProvider);
24229
+ router.delete("/api/providers/:id", deleteProvider);
24230
+ router.get("/api/coders", listCoders);
24231
+ router.get("/api/coders/:coder/active", getActiveProfile2);
24232
+ router.put("/api/coders/:coder/active", setActiveProfile2);
24233
+ router.post("/api/coders/:coder/apply", applyProfile);
24234
+ router.get("/api/coders/:coder/verify", verifyConfig);
24235
+ router.get("/api/version", getVersion);
24236
+ router.get("/api/config", getConfigMeta);
24237
+ router.get("/api/config/export", exportConfigFile);
24238
+ router.post("/api/config/import", importConfigFile);
24239
+ const uiDir = getUiDir();
24240
+ const serveStatic = createStaticServe({ root: uiDir, index: "index.html", spa: true });
24241
+ const server = createServer(async (req, res) => {
24242
+ const url2 = req.url || "";
24243
+ if (url2.startsWith("/api/") || url2 === "/api") {
24244
+ await router.handle(req, res);
24245
+ } else {
24246
+ await serveStatic(req, res);
24247
+ }
24248
+ });
24249
+ server.listen(port, host, () => {
24250
+ const url2 = `http://${host}:${port}`;
24251
+ console.log();
24252
+ console.log(import_picocolors11.default.bold(import_picocolors11.default.cyan("Swixter Web UI")));
24253
+ console.log();
24254
+ console.log(` Server: ${import_picocolors11.default.cyan(url2)}`);
24255
+ console.log(` Press ${import_picocolors11.default.bold("Ctrl+C")} to stop`);
24256
+ console.log();
24257
+ openBrowser(url2);
24258
+ });
24259
+ server.on("error", (error46) => {
24260
+ if (error46.code === "EADDRINUSE") {
24261
+ console.error(import_picocolors11.default.red(`Error: Port ${port} is already in use`));
24262
+ console.log(import_picocolors11.default.dim("Try specifying a different port with --port"));
24263
+ process.exit(1);
24264
+ } else {
24265
+ console.error(import_picocolors11.default.red(`Server error: ${error46.message}`));
24266
+ process.exit(1);
24267
+ }
24268
+ });
24269
+ server.on("close", () => {
24270
+ console.log();
24271
+ console.log(import_picocolors11.default.dim("Server closed"));
24272
+ });
24273
+ return server;
24274
+ }
24275
+
24276
+ // src/cli/ui.ts
24277
+ async function handleUiCommand(args) {
24278
+ const port = getPortFromArgs(args);
24279
+ try {
24280
+ const server = await startServer(port);
24281
+ process.on("SIGINT", () => {
24282
+ console.log();
24283
+ console.log(import_picocolors12.default.dim("Shutting down..."));
24284
+ server.close(() => {
24285
+ process.exit(0);
24286
+ });
24287
+ });
24288
+ process.stdin.resume();
24289
+ } catch (error46) {
24290
+ console.error(import_picocolors12.default.red(`Failed to start server: ${error46}`));
24291
+ process.exit(1);
24292
+ }
24293
+ }
24294
+ function getPortFromArgs(args) {
24295
+ if (!args || args.length === 0) {
24296
+ return;
24297
+ }
24298
+ for (let i2 = 0;i2 < args.length; i2++) {
24299
+ const arg = args[i2];
24300
+ if (arg === "--port" || arg === "-p") {
24301
+ const portStr = args[i2 + 1];
24302
+ if (!portStr) {
24303
+ console.error(import_picocolors12.default.red("Error: --port requires a value"));
24304
+ process.exit(1);
24305
+ }
24306
+ const port = parseInt(portStr, 10);
24307
+ if (isNaN(port) || port < 1 || port > 65535) {
24308
+ console.error(import_picocolors12.default.red("Error: Invalid port number"));
24309
+ process.exit(1);
24310
+ }
24311
+ return port;
24312
+ }
24313
+ }
24314
+ return;
24315
+ }
24316
+
23456
24317
  // src/cli/help.ts
23457
- var import_picocolors11 = __toESM(require_picocolors(), 1);
24318
+ var import_picocolors13 = __toESM(require_picocolors(), 1);
23458
24319
  function showGlobalHelp() {
23459
24320
  console.log(`
23460
- ${import_picocolors11.default.bold(import_picocolors11.default.cyan("Swixter - AI Coder Configuration Manager"))}
24321
+ ${import_picocolors13.default.bold(import_picocolors13.default.cyan("Swixter - AI Coder Configuration Manager"))}
23461
24322
 
23462
- ${import_picocolors11.default.bold("Usage:")}
23463
- ${import_picocolors11.default.green("swixter <coder> <command> [options]")}
23464
- ${import_picocolors11.default.green("swixter <global-command> [options]")}
24323
+ ${import_picocolors13.default.bold("Usage:")}
24324
+ ${import_picocolors13.default.green("swixter <coder> <command> [options]")}
24325
+ ${import_picocolors13.default.green("swixter <global-command> [options]")}
23465
24326
 
23466
- ${import_picocolors11.default.bold("Supported Coders:")}
23467
- ${import_picocolors11.default.cyan("claude")} ${import_picocolors11.default.dim("Claude Code configuration management")}
23468
- ${import_picocolors11.default.cyan("codex")} ${import_picocolors11.default.dim("Codex configuration management")}
23469
- ${import_picocolors11.default.cyan("qwen")} ${import_picocolors11.default.dim("Continue/Qwen configuration management")}
24327
+ ${import_picocolors13.default.bold("Supported Coders:")}
24328
+ ${import_picocolors13.default.cyan("claude")} ${import_picocolors13.default.dim("Claude Code configuration management")}
24329
+ ${import_picocolors13.default.cyan("codex")} ${import_picocolors13.default.dim("Codex configuration management")}
24330
+ ${import_picocolors13.default.cyan("qwen")} ${import_picocolors13.default.dim("Continue/Qwen configuration management")}
23470
24331
 
23471
- ${import_picocolors11.default.bold("Global Commands:")}
23472
- ${import_picocolors11.default.cyan("providers")} ${import_picocolors11.default.dim("List all available API providers")}
23473
- ${import_picocolors11.default.cyan("export <file>")} ${import_picocolors11.default.dim("Export all configurations to file")}
23474
- ${import_picocolors11.default.cyan("import <file>")} ${import_picocolors11.default.dim("Import configurations from file")}
23475
- ${import_picocolors11.default.cyan("completion <shell>")} ${import_picocolors11.default.dim("Generate shell auto-completion script")}
23476
- ${import_picocolors11.default.cyan("help")} ${import_picocolors11.default.dim("Show help information")}
23477
- ${import_picocolors11.default.cyan("version")} ${import_picocolors11.default.dim("Show version information")}
24332
+ ${import_picocolors13.default.bold("Web UI:")}
24333
+ ${import_picocolors13.default.cyan("ui")} ${import_picocolors13.default.dim("Launch local Web UI")}
24334
+ ${import_picocolors13.default.dim("swixter ui [--port <port>]")}
24335
+ ${import_picocolors13.default.dim("Start local HTTP server and open browser")}
23478
24336
 
23479
- ${import_picocolors11.default.bold("Examples:")}
23480
- ${import_picocolors11.default.dim("# View Claude Code commands")}
23481
- ${import_picocolors11.default.green("swixter claude --help")}
24337
+ ${import_picocolors13.default.bold("Global Commands:")}
24338
+ ${import_picocolors13.default.cyan("providers")} ${import_picocolors13.default.dim("List all available API providers")}
24339
+ ${import_picocolors13.default.cyan("export <file>")} ${import_picocolors13.default.dim("Export all configurations to file")}
24340
+ ${import_picocolors13.default.cyan("import <file>")} ${import_picocolors13.default.dim("Import configurations from file")}
24341
+ ${import_picocolors13.default.cyan("completion <shell>")} ${import_picocolors13.default.dim("Generate shell auto-completion script")}
24342
+ ${import_picocolors13.default.cyan("help")} ${import_picocolors13.default.dim("Show help information")}
24343
+ ${import_picocolors13.default.cyan("version")} ${import_picocolors13.default.dim("Show version information")}
23482
24344
 
23483
- ${import_picocolors11.default.dim("# Create Claude Code configuration")}
23484
- ${import_picocolors11.default.green("swixter claude create")}
24345
+ ${import_picocolors13.default.bold("Examples:")}
24346
+ ${import_picocolors13.default.dim("# View Claude Code commands")}
24347
+ ${import_picocolors13.default.green("swixter claude --help")}
23485
24348
 
23486
- ${import_picocolors11.default.dim("# View all providers")}
23487
- ${import_picocolors11.default.green("swixter providers")}
24349
+ ${import_picocolors13.default.dim("# Create Claude Code configuration")}
24350
+ ${import_picocolors13.default.green("swixter claude create")}
23488
24351
 
23489
- ${import_picocolors11.default.dim("# Export configurations")}
23490
- ${import_picocolors11.default.green("swixter export my-config.json")}
24352
+ ${import_picocolors13.default.dim("# Launch Web UI")}
24353
+ ${import_picocolors13.default.green("swixter ui")}
23491
24354
 
23492
- ${import_picocolors11.default.dim("# Install bash auto-completion")}
23493
- ${import_picocolors11.default.green("swixter completion bash > ~/.local/share/bash-completion/completions/swixter")}
24355
+ ${import_picocolors13.default.dim("# View all providers")}
24356
+ ${import_picocolors13.default.green("swixter providers")}
23494
24357
 
23495
- ${import_picocolors11.default.dim("Documentation: https://github.com/dawnswwwww/swixter")}
23496
- `);
24358
+ ${import_picocolors13.default.dim("Documentation: https://github.com/dawnswwwww/swixter")}`);
23497
24359
  }
23498
24360
 
23499
24361
  // src/cli/completions.ts
@@ -23856,37 +24718,37 @@ function generateCompletion(shell) {
23856
24718
  // src/cli/providers.ts
23857
24719
  init_presets();
23858
24720
  init_user_providers();
23859
- var import_picocolors12 = __toESM(require_picocolors(), 1);
24721
+ var import_picocolors14 = __toESM(require_picocolors(), 1);
23860
24722
  init_formatting();
23861
- async function listProviders() {
24723
+ async function listProviders2() {
23862
24724
  console.log();
23863
- Ie(import_picocolors12.default.cyan("Available Providers"));
24725
+ Ie(import_picocolors14.default.cyan("Available Providers"));
23864
24726
  const allPresets2 = await getAllPresets();
23865
24727
  const userProviders = await loadUserProviders();
23866
24728
  const userProviderIds = new Set(userProviders.map((p2) => p2.id));
23867
24729
  const builtInProviderIds = new Set(getBuiltInPresets().map((p2) => p2.id));
23868
24730
  if (allPresets2.length === 0) {
23869
- console.log(import_picocolors12.default.yellow("No providers configured"));
24731
+ console.log(import_picocolors14.default.yellow("No providers configured"));
23870
24732
  console.log();
23871
24733
  return;
23872
24734
  }
23873
24735
  console.log();
23874
- console.log(import_picocolors12.default.bold("Built-in Providers:"));
24736
+ console.log(import_picocolors14.default.bold("Built-in Providers:"));
23875
24737
  allPresets2.filter((p2) => builtInProviderIds.has(p2.id) && !userProviderIds.has(p2.id)).forEach((preset) => {
23876
- console.log(` ${import_picocolors12.default.cyan(preset.id.padEnd(15))} ${import_picocolors12.default.dim("|")} ${preset.displayName.padEnd(30)} ${import_picocolors12.default.dim("|")} ${import_picocolors12.default.yellow(preset.baseURL || "N/A")}`);
24738
+ console.log(` ${import_picocolors14.default.cyan(preset.id.padEnd(15))} ${import_picocolors14.default.dim("|")} ${preset.displayName.padEnd(30)} ${import_picocolors14.default.dim("|")} ${import_picocolors14.default.yellow(preset.baseURL || "N/A")}`);
23877
24739
  });
23878
24740
  const userOnlyProviders = allPresets2.filter((p2) => userProviderIds.has(p2.id));
23879
24741
  if (userOnlyProviders.length > 0) {
23880
24742
  console.log();
23881
- console.log(import_picocolors12.default.bold("User-defined Providers:"));
24743
+ console.log(import_picocolors14.default.bold("User-defined Providers:"));
23882
24744
  userOnlyProviders.forEach((preset) => {
23883
24745
  const isOverride = builtInProviderIds.has(preset.id);
23884
- const marker = isOverride ? import_picocolors12.default.yellow(" (override)") : "";
23885
- console.log(` ${import_picocolors12.default.green(preset.id.padEnd(15))} ${import_picocolors12.default.dim("|")} ${preset.displayName.padEnd(30)} ${import_picocolors12.default.dim("|")} ${import_picocolors12.default.yellow(preset.baseURL || "N/A")}${marker}`);
24746
+ const marker = isOverride ? import_picocolors14.default.yellow(" (override)") : "";
24747
+ console.log(` ${import_picocolors14.default.green(preset.id.padEnd(15))} ${import_picocolors14.default.dim("|")} ${preset.displayName.padEnd(30)} ${import_picocolors14.default.dim("|")} ${import_picocolors14.default.yellow(preset.baseURL || "N/A")}${marker}`);
23886
24748
  });
23887
24749
  }
23888
24750
  console.log();
23889
- console.log(import_picocolors12.default.dim(`Total: ${allPresets2.length} providers`));
24751
+ console.log(import_picocolors14.default.dim(`Total: ${allPresets2.length} providers`));
23890
24752
  console.log();
23891
24753
  }
23892
24754
  async function addProvider(options) {
@@ -23898,7 +24760,7 @@ async function addProvider(options) {
23898
24760
  let models = options.models;
23899
24761
  if (!options.quiet) {
23900
24762
  console.log();
23901
- Ie(import_picocolors12.default.cyan("Add Custom Provider"));
24763
+ Ie(import_picocolors14.default.cyan("Add Custom Provider"));
23902
24764
  const existing = providerId ? await getUserProvider(providerId) : undefined;
23903
24765
  providerId = await he({
23904
24766
  message: "Provider ID (unique identifier, e.g., 'openrouter', 'deepseek')",
@@ -23993,7 +24855,7 @@ async function addProvider(options) {
23993
24855
  try {
23994
24856
  await upsertUserProvider(provider);
23995
24857
  if (!options.quiet) {
23996
- Se(import_picocolors12.default.green(`${MARKERS.success} Provider "${providerId}" added successfully!`));
24858
+ Se(import_picocolors14.default.green(`${MARKERS.success} Provider "${providerId}" added successfully!`));
23997
24859
  } else {
23998
24860
  showSuccess(`Provider "${providerId}" added successfully!`, {
23999
24861
  ID: providerId,
@@ -24012,10 +24874,10 @@ async function removeProvider(providerId, options) {
24012
24874
  showError("Error: Provider ID is required", "Usage: swixter providers remove <provider-id>");
24013
24875
  }
24014
24876
  console.log();
24015
- Ie(import_picocolors12.default.cyan("Remove Custom Provider"));
24877
+ Ie(import_picocolors14.default.cyan("Remove Custom Provider"));
24016
24878
  const userProviders = await loadUserProviders();
24017
24879
  if (userProviders.length === 0) {
24018
- Se(import_picocolors12.default.yellow("No user-defined providers to remove"));
24880
+ Se(import_picocolors14.default.yellow("No user-defined providers to remove"));
24019
24881
  return;
24020
24882
  }
24021
24883
  providerId = await ve({
@@ -24042,7 +24904,7 @@ async function removeProvider(providerId, options) {
24042
24904
  showError(`Error: Provider "${providerId}" not found`, "Use 'swixter providers list' to see all providers");
24043
24905
  }
24044
24906
  if (!options?.quiet) {
24045
- Se(import_picocolors12.default.green(`${MARKERS.success} Provider "${providerId}" removed successfully!`));
24907
+ Se(import_picocolors14.default.green(`${MARKERS.success} Provider "${providerId}" removed successfully!`));
24046
24908
  } else {
24047
24909
  showSuccess(`Provider "${providerId}" removed successfully!`);
24048
24910
  }
@@ -24056,19 +24918,19 @@ async function showProvider(providerId) {
24056
24918
  showError(`Error: Provider "${providerId}" not found`, "Use 'swixter providers list' to see all providers");
24057
24919
  }
24058
24920
  console.log();
24059
- Ie(import_picocolors12.default.cyan(`Provider: ${provider.displayName}`));
24921
+ Ie(import_picocolors14.default.cyan(`Provider: ${provider.displayName}`));
24060
24922
  console.log();
24061
- console.log(` ID: ${import_picocolors12.default.cyan(provider.id)}`);
24062
- console.log(` Name: ${import_picocolors12.default.yellow(provider.name)}`);
24063
- console.log(` Display Name: ${import_picocolors12.default.yellow(provider.displayName)}`);
24064
- console.log(` Base URL: ${import_picocolors12.default.yellow(provider.baseURL)}`);
24065
- console.log(` Auth Type: ${import_picocolors12.default.yellow(provider.authType)}`);
24923
+ console.log(` ID: ${import_picocolors14.default.cyan(provider.id)}`);
24924
+ console.log(` Name: ${import_picocolors14.default.yellow(provider.name)}`);
24925
+ console.log(` Display Name: ${import_picocolors14.default.yellow(provider.displayName)}`);
24926
+ console.log(` Base URL: ${import_picocolors14.default.yellow(provider.baseURL)}`);
24927
+ console.log(` Auth Type: ${import_picocolors14.default.yellow(provider.authType)}`);
24066
24928
  if (provider.defaultModels && provider.defaultModels.length > 0) {
24067
24929
  console.log(` Default Models:`);
24068
- provider.defaultModels.forEach((model) => console.log(` - ${import_picocolors12.default.dim(model)}`));
24930
+ provider.defaultModels.forEach((model) => console.log(` - ${import_picocolors14.default.dim(model)}`));
24069
24931
  }
24070
24932
  if (provider.docs) {
24071
- console.log(` Documentation: ${import_picocolors12.default.blue(provider.docs)}`);
24933
+ console.log(` Documentation: ${import_picocolors14.default.blue(provider.docs)}`);
24072
24934
  }
24073
24935
  console.log();
24074
24936
  }
@@ -24078,7 +24940,7 @@ init_meta();
24078
24940
  init_versions2();
24079
24941
  async function cmdProviders(subcommand, args) {
24080
24942
  if (!subcommand || subcommand === "list" || subcommand === "ls") {
24081
- await listProviders();
24943
+ await listProviders2();
24082
24944
  return;
24083
24945
  }
24084
24946
  if (subcommand === "add" || subcommand === "new") {
@@ -24120,104 +24982,104 @@ async function cmdProviders(subcommand, args) {
24120
24982
  await showProvider(providerId);
24121
24983
  return;
24122
24984
  }
24123
- console.log(import_picocolors13.default.red(`Unknown providers subcommand: ${subcommand}`));
24985
+ console.log(import_picocolors15.default.red(`Unknown providers subcommand: ${subcommand}`));
24124
24986
  console.log();
24125
- console.log(import_picocolors13.default.bold("Available subcommands:"));
24126
- console.log(` ${import_picocolors13.default.cyan("list, ls")} - List all providers`);
24127
- console.log(` ${import_picocolors13.default.cyan("add, new")} - Add a custom provider`);
24128
- console.log(` ${import_picocolors13.default.cyan("remove, rm, delete")} - Remove a custom provider`);
24129
- console.log(` ${import_picocolors13.default.cyan("show, info")} - Show provider details`);
24987
+ console.log(import_picocolors15.default.bold("Available subcommands:"));
24988
+ console.log(` ${import_picocolors15.default.cyan("list, ls")} - List all providers`);
24989
+ console.log(` ${import_picocolors15.default.cyan("add, new")} - Add a custom provider`);
24990
+ console.log(` ${import_picocolors15.default.cyan("remove, rm, delete")} - Remove a custom provider`);
24991
+ console.log(` ${import_picocolors15.default.cyan("show, info")} - Show provider details`);
24130
24992
  console.log();
24131
24993
  process.exit(1);
24132
24994
  }
24133
24995
  async function cmdExport(filePath) {
24134
24996
  if (!filePath) {
24135
- console.log(import_picocolors13.default.red("Error: Please specify export file path"));
24136
- console.log(import_picocolors13.default.dim("Usage: swixter export <file>"));
24997
+ console.log(import_picocolors15.default.red("Error: Please specify export file path"));
24998
+ console.log(import_picocolors15.default.dim("Usage: swixter export <file>"));
24137
24999
  process.exit(1);
24138
25000
  }
24139
25001
  try {
24140
25002
  await exportConfig(filePath, { sanitizeKeys: false });
24141
25003
  console.log();
24142
- console.log(import_picocolors13.default.green("✓") + " Export successful!");
24143
- console.log(` File: ${import_picocolors13.default.cyan(filePath)}`);
25004
+ console.log(import_picocolors15.default.green("✓") + " Export successful!");
25005
+ console.log(` File: ${import_picocolors15.default.cyan(filePath)}`);
24144
25006
  console.log();
24145
25007
  } catch (error46) {
24146
25008
  console.log();
24147
- console.log(import_picocolors13.default.red(`✗ Export failed: ${error46}`));
25009
+ console.log(import_picocolors15.default.red(`✗ Export failed: ${error46}`));
24148
25010
  console.log();
24149
25011
  process.exit(1);
24150
25012
  }
24151
25013
  }
24152
25014
  async function cmdCompletion(shell) {
24153
25015
  if (!shell) {
24154
- console.log(import_picocolors13.default.yellow("Please specify shell type"));
25016
+ console.log(import_picocolors15.default.yellow("Please specify shell type"));
24155
25017
  console.log();
24156
- console.log(import_picocolors13.default.bold("Usage:"));
24157
- console.log(` ${import_picocolors13.default.green("swixter completion <shell>")}`);
25018
+ console.log(import_picocolors15.default.bold("Usage:"));
25019
+ console.log(` ${import_picocolors15.default.green("swixter completion <shell>")}`);
24158
25020
  console.log();
24159
- console.log(import_picocolors13.default.bold("Supported shells:"));
24160
- console.log(` ${import_picocolors13.default.cyan("bash")} - Bash shell`);
24161
- console.log(` ${import_picocolors13.default.cyan("zsh")} - Z shell`);
24162
- console.log(` ${import_picocolors13.default.cyan("fish")} - Fish shell`);
25021
+ console.log(import_picocolors15.default.bold("Supported shells:"));
25022
+ console.log(` ${import_picocolors15.default.cyan("bash")} - Bash shell`);
25023
+ console.log(` ${import_picocolors15.default.cyan("zsh")} - Z shell`);
25024
+ console.log(` ${import_picocolors15.default.cyan("fish")} - Fish shell`);
24163
25025
  console.log();
24164
- console.log(import_picocolors13.default.bold("Examples:"));
24165
- console.log(` ${import_picocolors13.default.green("swixter completion bash > ~/.local/share/bash-completion/completions/swixter")}`);
24166
- console.log(` ${import_picocolors13.default.green("swixter completion zsh > ~/.zfunc/_swixter")}`);
24167
- console.log(` ${import_picocolors13.default.green("swixter completion fish > ~/.config/fish/completions/swixter.fish")}`);
25026
+ console.log(import_picocolors15.default.bold("Examples:"));
25027
+ console.log(` ${import_picocolors15.default.green("swixter completion bash > ~/.local/share/bash-completion/completions/swixter")}`);
25028
+ console.log(` ${import_picocolors15.default.green("swixter completion zsh > ~/.zfunc/_swixter")}`);
25029
+ console.log(` ${import_picocolors15.default.green("swixter completion fish > ~/.config/fish/completions/swixter.fish")}`);
24168
25030
  process.exit(1);
24169
25031
  }
24170
25032
  const supportedShells = ["bash", "zsh", "fish"];
24171
25033
  if (!supportedShells.includes(shell)) {
24172
- console.log(import_picocolors13.default.red(`Unsupported shell: ${shell}`));
24173
- console.log(import_picocolors13.default.dim(`Supported shells: ${supportedShells.join(", ")}`));
25034
+ console.log(import_picocolors15.default.red(`Unsupported shell: ${shell}`));
25035
+ console.log(import_picocolors15.default.dim(`Supported shells: ${supportedShells.join(", ")}`));
24174
25036
  process.exit(1);
24175
25037
  }
24176
25038
  try {
24177
25039
  const script = generateCompletion(shell);
24178
25040
  console.log(script);
24179
25041
  } catch (error46) {
24180
- console.error(import_picocolors13.default.red("Failed to generate completion script:"), error46);
25042
+ console.error(import_picocolors15.default.red("Failed to generate completion script:"), error46);
24181
25043
  process.exit(1);
24182
25044
  }
24183
25045
  }
24184
25046
  async function cmdImport(filePath) {
24185
25047
  if (!filePath) {
24186
- console.log(import_picocolors13.default.red("Error: Please specify import file path"));
24187
- console.log(import_picocolors13.default.dim("Usage: swixter import <file>"));
25048
+ console.log(import_picocolors15.default.red("Error: Please specify import file path"));
25049
+ console.log(import_picocolors15.default.dim("Usage: swixter import <file>"));
24188
25050
  process.exit(1);
24189
25051
  }
24190
25052
  try {
24191
25053
  const result = await importConfig(filePath, { overwrite: false });
24192
25054
  console.log();
24193
- console.log(import_picocolors13.default.green("✓") + " Import completed!");
25055
+ console.log(import_picocolors15.default.green("✓") + " Import completed!");
24194
25056
  console.log();
24195
- console.log(` Successfully imported: ${import_picocolors13.default.green(result.imported)} items`);
24196
- console.log(` Skipped: ${import_picocolors13.default.yellow(result.skipped)} items`);
24197
- console.log(` Errors: ${import_picocolors13.default.red(result.errors.length)} items`);
25057
+ console.log(` Successfully imported: ${import_picocolors15.default.green(result.imported)} items`);
25058
+ console.log(` Skipped: ${import_picocolors15.default.yellow(result.skipped)} items`);
25059
+ console.log(` Errors: ${import_picocolors15.default.red(result.errors.length)} items`);
24198
25060
  console.log();
24199
25061
  if (result.errors.length > 0) {
24200
- console.log(import_picocolors13.default.red("Error details:"));
24201
- result.errors.forEach((err) => console.log(import_picocolors13.default.red(` - ${err}`)));
25062
+ console.log(import_picocolors15.default.red("Error details:"));
25063
+ result.errors.forEach((err) => console.log(import_picocolors15.default.red(` - ${err}`)));
24202
25064
  console.log();
24203
25065
  }
24204
25066
  } catch (error46) {
24205
25067
  console.log();
24206
- console.log(import_picocolors13.default.red(`✗ Import failed: ${error46}`));
25068
+ console.log(import_picocolors15.default.red(`✗ Import failed: ${error46}`));
24207
25069
  console.log();
24208
25070
  process.exit(1);
24209
25071
  }
24210
25072
  }
24211
25073
  async function cmdVersion() {
24212
25074
  console.log();
24213
- console.log(import_picocolors13.default.bold(import_picocolors13.default.cyan("Swixter")) + import_picocolors13.default.dim(" - AI Coder Configuration Manager"));
25075
+ console.log(import_picocolors15.default.bold(import_picocolors15.default.cyan("Swixter")) + import_picocolors15.default.dim(" - AI Coder Configuration Manager"));
24214
25076
  console.log();
24215
- console.log(` ${import_picocolors13.default.bold("Version:")} ${import_picocolors13.default.green(APP_VERSION)}`);
24216
- console.log(` ${import_picocolors13.default.bold("Config Version:")} ${import_picocolors13.default.cyan(CONFIG_VERSION)}`);
24217
- console.log(` ${import_picocolors13.default.bold("Export Version:")} ${import_picocolors13.default.cyan(EXPORT_VERSION)}`);
25077
+ console.log(` ${import_picocolors15.default.bold("Version:")} ${import_picocolors15.default.green(APP_VERSION)}`);
25078
+ console.log(` ${import_picocolors15.default.bold("Config Version:")} ${import_picocolors15.default.cyan(CONFIG_VERSION)}`);
25079
+ console.log(` ${import_picocolors15.default.bold("Export Version:")} ${import_picocolors15.default.cyan(EXPORT_VERSION)}`);
24218
25080
  console.log();
24219
- console.log(import_picocolors13.default.dim(" GitHub: https://github.com/dawnswwwww/swixter"));
24220
- console.log(import_picocolors13.default.dim(" NPM: https://www.npmjs.com/package/swixter"));
25081
+ console.log(import_picocolors15.default.dim(" GitHub: https://github.com/dawnswwwww/swixter"));
25082
+ console.log(import_picocolors15.default.dim(" NPM: https://www.npmjs.com/package/swixter"));
24221
25083
  console.log();
24222
25084
  }
24223
25085
  async function main() {
@@ -24228,6 +25090,10 @@ async function main() {
24228
25090
  showGlobalHelp();
24229
25091
  return;
24230
25092
  }
25093
+ if (firstArg === "ui") {
25094
+ await handleUiCommand(args.slice(1));
25095
+ return;
25096
+ }
24231
25097
  if (firstArg === "claude") {
24232
25098
  await handleClaudeCommand(args.slice(1));
24233
25099
  return;
@@ -24260,11 +25126,11 @@ async function main() {
24260
25126
  await cmdVersion();
24261
25127
  return;
24262
25128
  }
24263
- console.log(import_picocolors13.default.red(`Unknown command: ${firstArg}`));
24264
- console.log(import_picocolors13.default.dim("Run 'swixter --help' for help"));
25129
+ console.log(import_picocolors15.default.red(`Unknown command: ${firstArg}`));
25130
+ console.log(import_picocolors15.default.dim("Run 'swixter --help' for help"));
24265
25131
  process.exit(1);
24266
25132
  } catch (error46) {
24267
- console.error(import_picocolors13.default.red("An error occurred:"), error46);
25133
+ console.error(import_picocolors15.default.red("An error occurred:"), error46);
24268
25134
  process.exit(1);
24269
25135
  }
24270
25136
  }