swixter 0.0.9 → 0.0.10

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 +1028 -174
  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.10";
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;
@@ -21682,15 +21731,7 @@ async function cmdRun(args) {
21682
21731
  env[key] = value;
21683
21732
  }
21684
21733
  }
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
- }
21734
+ Object.assign(env, buildProfileEnv(profile, CODER_CONFIG.envVarMapping, baseURL));
21694
21735
  const claudeArgs = args.filter((arg, idx) => {
21695
21736
  if (arg === "--profile") {
21696
21737
  return false;
@@ -22420,15 +22461,7 @@ async function cmdRun2(args) {
22420
22461
  env[key] = value;
22421
22462
  }
22422
22463
  }
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
- }
22464
+ Object.assign(env, buildProfileEnv(profile, CODER_CONFIG2.envVarMapping, baseURL));
22432
22465
  const qwenArgs = [];
22433
22466
  if (profile.apiKey) {
22434
22467
  qwenArgs.push("--openai-api-key", profile.apiKey);
@@ -23316,12 +23349,9 @@ async function cmdRun3(args) {
23316
23349
  env[key] = value;
23317
23350
  }
23318
23351
  }
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
- }
23352
+ Object.assign(env, buildProfileEnv(profile, CODER_CONFIG3.envVarMapping, "", {
23353
+ apiKeyEnvName: envKey
23354
+ }));
23325
23355
  const codexArgs = args.filter((arg, idx) => {
23326
23356
  if (arg === "--profile") {
23327
23357
  return false;
@@ -23364,6 +23394,611 @@ async function cmdUpdate3(args) {
23364
23394
  await handleUpdateCommand(CODER_NAME3, CODER_CONFIG3, args);
23365
23395
  }
23366
23396
 
23397
+ // src/cli/ui.ts
23398
+ var import_picocolors12 = __toESM(require_picocolors(), 1);
23399
+
23400
+ // src/server/index.ts
23401
+ var import_picocolors11 = __toESM(require_picocolors(), 1);
23402
+ import { createServer } from "node:http";
23403
+ import { dirname as dirname7, join as join6 } from "node:path";
23404
+ import { fileURLToPath } from "node:url";
23405
+ import { exec } from "node:child_process";
23406
+
23407
+ // src/server/middleware.ts
23408
+ function corsMiddleware(req, res, next) {
23409
+ const origin = req.headers.origin;
23410
+ if (origin && (origin.startsWith("http://127.0.0.1:") || origin.startsWith("http://localhost:"))) {
23411
+ res.setHeader("Access-Control-Allow-Origin", origin);
23412
+ }
23413
+ if (req.method === "OPTIONS") {
23414
+ res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
23415
+ res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
23416
+ res.setHeader("Access-Control-Max-Age", "86400");
23417
+ res.statusCode = 204;
23418
+ res.end();
23419
+ return;
23420
+ }
23421
+ next();
23422
+ }
23423
+ function jsonBodyMiddleware(req, res, next) {
23424
+ if (!["POST", "PUT", "PATCH"].includes(req.method || "")) {
23425
+ next();
23426
+ return;
23427
+ }
23428
+ const contentType = req.headers["content-type"];
23429
+ if (!contentType?.includes("application/json")) {
23430
+ next();
23431
+ return;
23432
+ }
23433
+ const chunks = [];
23434
+ req.on("data", (chunk) => {
23435
+ chunks.push(chunk);
23436
+ });
23437
+ req.on("end", () => {
23438
+ try {
23439
+ if (chunks.length === 0) {
23440
+ next();
23441
+ return;
23442
+ }
23443
+ const body = Buffer.concat(chunks).toString("utf-8");
23444
+ req.body = JSON.parse(body);
23445
+ next();
23446
+ } catch (error46) {
23447
+ next(new Error("Invalid JSON body"));
23448
+ }
23449
+ });
23450
+ req.on("error", (error46) => {
23451
+ next(error46);
23452
+ });
23453
+ }
23454
+ function sendError(res, error46, statusCode = 400) {
23455
+ res.setHeader("Content-Type", "application/json");
23456
+ if (error46 instanceof Error) {
23457
+ res.statusCode = statusCode;
23458
+ res.end(JSON.stringify({
23459
+ error: {
23460
+ code: "UNKNOWN_ERROR",
23461
+ message: error46.message
23462
+ }
23463
+ }));
23464
+ return;
23465
+ }
23466
+ res.statusCode = statusCode;
23467
+ res.end(JSON.stringify({
23468
+ error: error46
23469
+ }));
23470
+ }
23471
+ function sendJson(res, data, statusCode = 200) {
23472
+ res.setHeader("Content-Type", "application/json");
23473
+ res.statusCode = statusCode;
23474
+ res.end(JSON.stringify(data));
23475
+ }
23476
+ function notFoundHandler(req, res) {
23477
+ res.setHeader("Content-Type", "application/json");
23478
+ res.statusCode = 404;
23479
+ res.end(JSON.stringify({
23480
+ error: {
23481
+ code: "NOT_FOUND",
23482
+ message: `Path ${req.url} not found`
23483
+ }
23484
+ }));
23485
+ }
23486
+
23487
+ // src/server/router.ts
23488
+ function extractParams(pattern, path) {
23489
+ const patternParts = pattern.replace(/\/$/, "").split("/").filter(Boolean);
23490
+ const pathParts = path.replace(/\/$/, "").split("/").filter(Boolean);
23491
+ if (patternParts.length !== pathParts.length) {
23492
+ return null;
23493
+ }
23494
+ const params = {};
23495
+ for (let i2 = 0;i2 < patternParts.length; i2++) {
23496
+ const patternPart = patternParts[i2];
23497
+ const pathPart = pathParts[i2];
23498
+ if (patternPart.startsWith(":")) {
23499
+ const paramName = patternPart.slice(1);
23500
+ params[paramName] = pathPart;
23501
+ } else if (patternPart !== pathPart) {
23502
+ return null;
23503
+ }
23504
+ }
23505
+ return params;
23506
+ }
23507
+
23508
+ class Router {
23509
+ routes = [];
23510
+ middleware = [];
23511
+ use(middleware) {
23512
+ this.middleware.push(middleware);
23513
+ }
23514
+ get(pattern, handler) {
23515
+ this.routes.push({ method: "GET", pattern, handler });
23516
+ }
23517
+ post(pattern, handler) {
23518
+ this.routes.push({ method: "POST", pattern, handler });
23519
+ }
23520
+ put(pattern, handler) {
23521
+ this.routes.push({ method: "PUT", pattern, handler });
23522
+ }
23523
+ delete(pattern, handler) {
23524
+ this.routes.push({ method: "DELETE", pattern, handler });
23525
+ }
23526
+ matchRoute(req) {
23527
+ const method = (req.method || "GET").toUpperCase();
23528
+ const url2 = new URL(req.url || "", `http://${req.headers.host || "localhost"}`);
23529
+ const path = url2.pathname;
23530
+ for (const route of this.routes) {
23531
+ if (route.method !== method) {
23532
+ continue;
23533
+ }
23534
+ const params = extractParams(route.pattern, path);
23535
+ if (params !== null) {
23536
+ return { route, params };
23537
+ }
23538
+ }
23539
+ return null;
23540
+ }
23541
+ async handle(req, res) {
23542
+ let middlewareIndex = 0;
23543
+ const runMiddleware = (error46) => {
23544
+ if (error46) {
23545
+ this.finalize(req, res, error46);
23546
+ return;
23547
+ }
23548
+ if (middlewareIndex < this.middleware.length) {
23549
+ const middleware = this.middleware[middlewareIndex++];
23550
+ Promise.resolve(middleware(req, res, runMiddleware)).catch(runMiddleware);
23551
+ return;
23552
+ }
23553
+ this.executeRoute(req, res).catch((error47) => {
23554
+ this.finalize(req, res, error47);
23555
+ });
23556
+ };
23557
+ runMiddleware();
23558
+ }
23559
+ async executeRoute(req, res) {
23560
+ const match = this.matchRoute(req);
23561
+ if (!match) {
23562
+ return;
23563
+ }
23564
+ const { route, params } = match;
23565
+ await route.handler(req, res, params);
23566
+ }
23567
+ finalize(req, res, error46) {
23568
+ if (error46) {
23569
+ sendError(res, error46, 500);
23570
+ return;
23571
+ }
23572
+ if (!res.writableEnded) {
23573
+ notFoundHandler(req, res);
23574
+ }
23575
+ }
23576
+ }
23577
+
23578
+ // src/server/static.ts
23579
+ import { createReadStream } from "node:fs";
23580
+ import { stat } from "node:fs/promises";
23581
+ import { extname, join as join4 } from "node:path";
23582
+ var MIME_TYPES = {
23583
+ ".html": "text/html; charset=utf-8",
23584
+ ".js": "application/javascript; charset=utf-8",
23585
+ ".mjs": "application/javascript; charset=utf-8",
23586
+ ".css": "text/css; charset=utf-8",
23587
+ ".json": "application/json; charset=utf-8",
23588
+ ".png": "image/png",
23589
+ ".jpg": "image/jpeg",
23590
+ ".jpeg": "image/jpeg",
23591
+ ".gif": "image/gif",
23592
+ ".svg": "image/svg+xml",
23593
+ ".ico": "image/x-icon",
23594
+ ".woff": "font/woff",
23595
+ ".woff2": "font/woff2",
23596
+ ".ttf": "font/ttf",
23597
+ ".eot": "application/vnd.ms-fontobject",
23598
+ ".mp4": "video/mp4",
23599
+ ".webm": "video/webm",
23600
+ ".ogg": "audio/ogg",
23601
+ ".mp3": "audio/mpeg",
23602
+ ".wav": "audio/wav",
23603
+ ".webp": "image/webp",
23604
+ ".avif": "image/avif"
23605
+ };
23606
+ function createStaticServe(options) {
23607
+ const { root, index = "index.html", spa = true } = options;
23608
+ return async (req, res) => {
23609
+ const url2 = new URL(req.url || "", `http://${req.headers.host || "localhost"}`);
23610
+ let filePath = join4(root, url2.pathname);
23611
+ try {
23612
+ const stats = await stat(filePath);
23613
+ if (stats.isDirectory()) {
23614
+ filePath = join4(filePath, index);
23615
+ await stat(filePath);
23616
+ }
23617
+ const ext = extname(filePath);
23618
+ const contentType = MIME_TYPES[ext] || "application/octet-stream";
23619
+ res.setHeader("Content-Type", contentType);
23620
+ const stream = createReadStream(filePath);
23621
+ stream.on("error", (error46) => {
23622
+ if (!res.writableEnded) {
23623
+ res.statusCode = 500;
23624
+ res.end("Internal Server Error");
23625
+ }
23626
+ });
23627
+ stream.pipe(res);
23628
+ } catch (error46) {
23629
+ if (spa) {
23630
+ try {
23631
+ const indexPath = join4(root, index);
23632
+ const stats = await stat(indexPath);
23633
+ if (stats.isFile()) {
23634
+ res.setHeader("Content-Type", "text/html; charset=utf-8");
23635
+ const stream = createReadStream(indexPath);
23636
+ stream.pipe(res);
23637
+ return;
23638
+ }
23639
+ } catch {}
23640
+ }
23641
+ if (!res.writableEnded) {
23642
+ res.statusCode = 404;
23643
+ res.setHeader("Content-Type", "text/plain; charset=utf-8");
23644
+ res.end("Not Found");
23645
+ }
23646
+ }
23647
+ };
23648
+ }
23649
+
23650
+ // src/server/api/profiles.ts
23651
+ init_manager();
23652
+
23653
+ // src/server/api/util.ts
23654
+ function maskApiKey(apiKey) {
23655
+ if (!apiKey || apiKey.length <= 8) {
23656
+ return "****";
23657
+ }
23658
+ const first = apiKey.slice(0, 4);
23659
+ const last = apiKey.slice(-4);
23660
+ return `${first}${"*".repeat(Math.min(apiKey.length - 8, 20))}${last}`;
23661
+ }
23662
+ function maskAuthToken(token) {
23663
+ if (!token || token.length <= 8) {
23664
+ return "****";
23665
+ }
23666
+ const first = token.slice(0, 4);
23667
+ const last = token.slice(-4);
23668
+ return `${first}${"*".repeat(Math.min(token.length - 8, 20))}${last}`;
23669
+ }
23670
+ function sanitizeProfile(profile) {
23671
+ return {
23672
+ ...profile,
23673
+ apiKey: maskApiKey(profile.apiKey),
23674
+ authToken: profile.authToken ? maskAuthToken(profile.authToken) : undefined
23675
+ };
23676
+ }
23677
+ function generateETag(mtime, size) {
23678
+ const mtimeMs = Math.floor(mtime.getTime() / 1000);
23679
+ return `"${mtimeMs}-${size}"`;
23680
+ }
23681
+ function parseIfNoneMatch(header) {
23682
+ if (!header) {
23683
+ return null;
23684
+ }
23685
+ return header.replace(/^"|"$/g, "");
23686
+ }
23687
+ function setETagHeaders(res, mtime, size) {
23688
+ const etag = generateETag(mtime, size);
23689
+ res.setHeader("ETag", etag);
23690
+ res.setHeader("Cache-Control", "no-cache");
23691
+ }
23692
+
23693
+ // src/server/api/profiles.ts
23694
+ init_presets();
23695
+ async function listProfiles2(req, res) {
23696
+ const profiles = await listProfiles();
23697
+ sendJson(res, profiles.map(sanitizeProfile));
23698
+ }
23699
+ async function getProfile2(req, res, params) {
23700
+ const { name } = params;
23701
+ if (!name) {
23702
+ sendError(res, { code: "INVALID_PARAMS", message: "Profile name is required" }, 400);
23703
+ return;
23704
+ }
23705
+ const profile = await getProfile(name);
23706
+ if (!profile) {
23707
+ sendError(res, { code: "PROFILE_NOT_FOUND", message: `Profile "${name}" does not exist` }, 404);
23708
+ return;
23709
+ }
23710
+ sendJson(res, sanitizeProfile(profile));
23711
+ }
23712
+ async function createProfile(req, res) {
23713
+ const body = req.body;
23714
+ if (!body || !body.name || !body.providerId) {
23715
+ sendError(res, { code: "INVALID_PARAMS", message: "name and providerId are required" }, 400);
23716
+ return;
23717
+ }
23718
+ const providers = await getAllPresets();
23719
+ const provider = providers.find((p2) => p2.id === body.providerId);
23720
+ if (!provider) {
23721
+ sendError(res, { code: "UNKNOWN_PROVIDER", message: `Provider "${body.providerId}" not found` }, 400);
23722
+ return;
23723
+ }
23724
+ const existing = await getProfile(body.name);
23725
+ if (existing) {
23726
+ sendError(res, { code: "PROFILE_EXISTS", message: `Profile "${body.name}" already exists` }, 409);
23727
+ return;
23728
+ }
23729
+ try {
23730
+ const now = new Date().toISOString();
23731
+ const profile = {
23732
+ name: body.name,
23733
+ providerId: body.providerId,
23734
+ apiKey: body.apiKey || "",
23735
+ authToken: body.authToken || "",
23736
+ baseURL: body.baseURL || provider.baseURL,
23737
+ model: body.model,
23738
+ openaiModel: body.openaiModel,
23739
+ models: body.models,
23740
+ envKey: body.envKey,
23741
+ headers: body.headers,
23742
+ createdAt: now,
23743
+ updatedAt: now
23744
+ };
23745
+ await upsertProfile(profile, body.coder);
23746
+ sendJson(res, sanitizeProfile(profile), 201);
23747
+ } catch (error46) {
23748
+ sendError(res, { code: "CREATE_FAILED", message: error46 instanceof Error ? error46.message : "Failed to create profile" }, 500);
23749
+ }
23750
+ }
23751
+ async function updateProfile(req, res, params) {
23752
+ const { name } = params;
23753
+ const body = req.body;
23754
+ if (!name) {
23755
+ sendError(res, { code: "INVALID_PARAMS", message: "Profile name is required" }, 400);
23756
+ return;
23757
+ }
23758
+ const existing = await getProfile(name);
23759
+ if (!existing) {
23760
+ sendError(res, { code: "PROFILE_NOT_FOUND", message: `Profile "${name}" does not exist` }, 404);
23761
+ return;
23762
+ }
23763
+ try {
23764
+ const now = new Date().toISOString();
23765
+ const profile = {
23766
+ ...existing,
23767
+ ...body,
23768
+ name,
23769
+ updatedAt: now
23770
+ };
23771
+ await upsertProfile(profile);
23772
+ sendJson(res, sanitizeProfile(profile));
23773
+ } catch (error46) {
23774
+ sendError(res, { code: "UPDATE_FAILED", message: error46 instanceof Error ? error46.message : "Failed to update profile" }, 500);
23775
+ }
23776
+ }
23777
+ async function deleteProfile2(req, res, params) {
23778
+ const { name } = params;
23779
+ if (!name) {
23780
+ sendError(res, { code: "INVALID_PARAMS", message: "Profile name is required" }, 400);
23781
+ return;
23782
+ }
23783
+ try {
23784
+ await deleteProfile(name);
23785
+ sendJson(res, { success: true, message: `Profile "${name}" deleted` });
23786
+ } catch (error46) {
23787
+ sendError(res, { code: "DELETE_FAILED", message: error46 instanceof Error ? error46.message : "Failed to delete profile" }, 500);
23788
+ }
23789
+ }
23790
+
23791
+ // src/server/api/providers.ts
23792
+ init_presets();
23793
+ init_user_providers();
23794
+ async function listProviders(req, res) {
23795
+ const providers = await getAllPresets();
23796
+ const userProviders = await loadUserProviders();
23797
+ const userIds = new Set(userProviders.map((p2) => p2.id));
23798
+ const result = providers.map((p2) => ({
23799
+ ...p2,
23800
+ isUser: userIds.has(p2.id)
23801
+ }));
23802
+ sendJson(res, result);
23803
+ }
23804
+ async function createProvider(req, res) {
23805
+ const body = req.body;
23806
+ if (!body || !body.id || !body.name || !body.displayName) {
23807
+ sendError(res, { code: "INVALID_PARAMS", message: "id, name, and displayName are required" }, 400);
23808
+ return;
23809
+ }
23810
+ const providers = await getAllPresets();
23811
+ const existing = providers.find((p2) => p2.id === body.id);
23812
+ if (existing) {
23813
+ sendError(res, { code: "PROVIDER_EXISTS", message: `Provider "${body.id}" already exists` }, 409);
23814
+ return;
23815
+ }
23816
+ try {
23817
+ const provider = {
23818
+ id: body.id,
23819
+ name: body.name,
23820
+ displayName: body.displayName,
23821
+ baseURL: body.baseURL || "",
23822
+ defaultModels: body.defaultModels || [],
23823
+ authType: body.authType || "api-key",
23824
+ headers: body.headers,
23825
+ rateLimit: body.rateLimit,
23826
+ docs: body.docs,
23827
+ isChinese: body.isChinese,
23828
+ wire_api: body.wire_api,
23829
+ env_key: body.env_key
23830
+ };
23831
+ await upsertUserProvider(provider);
23832
+ sendJson(res, { ...provider, isUser: true }, 201);
23833
+ } catch (error46) {
23834
+ sendError(res, { code: "CREATE_FAILED", message: error46 instanceof Error ? error46.message : "Failed to create provider" }, 500);
23835
+ }
23836
+ }
23837
+ async function updateProvider(req, res, params) {
23838
+ const { id } = params;
23839
+ const body = req.body;
23840
+ if (!id) {
23841
+ sendError(res, { code: "INVALID_PARAMS", message: "Provider ID is required" }, 400);
23842
+ return;
23843
+ }
23844
+ const userProviders = await loadUserProviders();
23845
+ const existing = userProviders.find((p2) => p2.id === id);
23846
+ if (!existing) {
23847
+ sendError(res, { code: "NOT_USER_PROVIDER", message: `Provider "${id}" is not a user-defined provider` }, 400);
23848
+ return;
23849
+ }
23850
+ try {
23851
+ const provider = {
23852
+ ...existing,
23853
+ ...body,
23854
+ id
23855
+ };
23856
+ await upsertUserProvider(provider);
23857
+ sendJson(res, { ...provider, isUser: true });
23858
+ } catch (error46) {
23859
+ sendError(res, { code: "UPDATE_FAILED", message: error46 instanceof Error ? error46.message : "Failed to update provider" }, 500);
23860
+ }
23861
+ }
23862
+ async function deleteProvider(req, res, params) {
23863
+ const { id } = params;
23864
+ if (!id) {
23865
+ sendError(res, { code: "INVALID_PARAMS", message: "Provider ID is required" }, 400);
23866
+ return;
23867
+ }
23868
+ const userProviders = await loadUserProviders();
23869
+ const existing = userProviders.find((p2) => p2.id === id);
23870
+ if (!existing) {
23871
+ sendError(res, { code: "NOT_USER_PROVIDER", message: `Provider "${id}" is not a user-defined provider` }, 400);
23872
+ return;
23873
+ }
23874
+ try {
23875
+ const deleted = await deleteUserProvider(id);
23876
+ if (!deleted) {
23877
+ sendError(res, { code: "DELETE_FAILED", message: `Failed to delete provider "${id}"` }, 500);
23878
+ return;
23879
+ }
23880
+ sendJson(res, { success: true, message: `Provider "${id}" deleted` });
23881
+ } catch (error46) {
23882
+ sendError(res, { code: "DELETE_FAILED", message: error46 instanceof Error ? error46.message : "Failed to delete provider" }, 500);
23883
+ }
23884
+ }
23885
+
23886
+ // src/server/api/coders.ts
23887
+ init_coders();
23888
+ init_manager();
23889
+ init_adapters();
23890
+ async function listCoders(req, res) {
23891
+ const result = [];
23892
+ for (const [coderId, coderConfig] of Object.entries(CODER_REGISTRY)) {
23893
+ const activeProfile = await getActiveProfileForCoder(coderId);
23894
+ result.push({
23895
+ id: coderId,
23896
+ displayName: coderConfig.displayName,
23897
+ executable: coderConfig.executable,
23898
+ activeProfile: activeProfile ? {
23899
+ name: activeProfile.name,
23900
+ providerId: activeProfile.providerId,
23901
+ baseURL: activeProfile.baseURL
23902
+ } : null
23903
+ });
23904
+ }
23905
+ sendJson(res, result);
23906
+ }
23907
+ async function getActiveProfile2(req, res, params) {
23908
+ const { coder } = params;
23909
+ if (!coder) {
23910
+ sendError(res, { code: "INVALID_PARAMS", message: "Coder ID is required" }, 400);
23911
+ return;
23912
+ }
23913
+ if (!CODER_REGISTRY[coder]) {
23914
+ sendError(res, { code: "UNKNOWN_CODER", message: `Coder "${coder}" not found` }, 404);
23915
+ return;
23916
+ }
23917
+ const profile = await getActiveProfileForCoder(coder);
23918
+ if (!profile) {
23919
+ sendJson(res, { activeProfile: null });
23920
+ return;
23921
+ }
23922
+ sendJson(res, { activeProfile: sanitizeProfile(profile) });
23923
+ }
23924
+ async function setActiveProfile2(req, res, params) {
23925
+ const { coder } = params;
23926
+ const body = req.body;
23927
+ if (!coder) {
23928
+ sendError(res, { code: "INVALID_PARAMS", message: "Coder ID is required" }, 400);
23929
+ return;
23930
+ }
23931
+ if (!CODER_REGISTRY[coder]) {
23932
+ sendError(res, { code: "UNKNOWN_CODER", message: `Coder "${coder}" not found` }, 404);
23933
+ return;
23934
+ }
23935
+ if (!body || !body.profileName) {
23936
+ sendError(res, { code: "INVALID_PARAMS", message: "profileName is required" }, 400);
23937
+ return;
23938
+ }
23939
+ try {
23940
+ await setActiveProfileForCoder(coder, body.profileName);
23941
+ const profile = await getActiveProfileForCoder(coder);
23942
+ sendJson(res, { activeProfile: profile ? sanitizeProfile(profile) : null });
23943
+ } catch (error46) {
23944
+ sendError(res, { code: "SWITCH_FAILED", message: error46 instanceof Error ? error46.message : "Failed to switch profile" }, 500);
23945
+ }
23946
+ }
23947
+ async function applyProfile(req, res, params) {
23948
+ const { coder } = params;
23949
+ if (!coder) {
23950
+ sendError(res, { code: "INVALID_PARAMS", message: "Coder ID is required" }, 400);
23951
+ return;
23952
+ }
23953
+ if (!CODER_REGISTRY[coder]) {
23954
+ sendError(res, { code: "UNKNOWN_CODER", message: `Coder "${coder}" not found` }, 404);
23955
+ return;
23956
+ }
23957
+ const profile = await getActiveProfileForCoder(coder);
23958
+ if (!profile) {
23959
+ sendError(res, { code: "NO_ACTIVE_PROFILE", message: `No active profile for coder "${coder}"` }, 400);
23960
+ return;
23961
+ }
23962
+ try {
23963
+ const adapter = getAdapter(coder);
23964
+ await adapter.apply(profile);
23965
+ sendJson(res, { success: true, message: `Profile applied to ${coder}` });
23966
+ } catch (error46) {
23967
+ sendError(res, { code: "APPLY_FAILED", message: error46 instanceof Error ? error46.message : "Failed to apply profile" }, 500);
23968
+ }
23969
+ }
23970
+ async function verifyConfig(req, res, params) {
23971
+ const { coder } = params;
23972
+ if (!coder) {
23973
+ sendError(res, { code: "INVALID_PARAMS", message: "Coder ID is required" }, 400);
23974
+ return;
23975
+ }
23976
+ if (!CODER_REGISTRY[coder]) {
23977
+ sendError(res, { code: "UNKNOWN_CODER", message: `Coder "${coder}" not found` }, 404);
23978
+ return;
23979
+ }
23980
+ const profile = await getActiveProfileForCoder(coder);
23981
+ if (!profile) {
23982
+ sendJson(res, { verified: false, message: "No active profile" });
23983
+ return;
23984
+ }
23985
+ try {
23986
+ const adapter = getAdapter(coder);
23987
+ const verified = await adapter.verify(profile);
23988
+ sendJson(res, { verified, message: verified ? "Configuration verified" : "Verification failed" });
23989
+ } catch (error46) {
23990
+ sendJson(res, { verified: false, message: error46 instanceof Error ? error46.message : "Verification failed" });
23991
+ }
23992
+ }
23993
+
23994
+ // src/server/api/config.ts
23995
+ init_meta();
23996
+ init_versions2();
23997
+ init_paths();
23998
+ import { existsSync as existsSync7, statSync } from "node:fs";
23999
+ import { readFile as readFile7, writeFile as writeFile7, unlink } from "node:fs/promises";
24000
+ import { join as join5 } from "node:path";
24001
+
23367
24002
  // src/config/export.ts
23368
24003
  init_types();
23369
24004
  init_manager();
@@ -23453,47 +24088,262 @@ async function importConfig(filePath, options = {}) {
23453
24088
  return { imported, skipped, errors: errors3 };
23454
24089
  }
23455
24090
 
24091
+ // src/server/api/config.ts
24092
+ async function getVersion(req, res) {
24093
+ sendJson(res, {
24094
+ appVersion: APP_VERSION,
24095
+ configVersion: CONFIG_VERSION,
24096
+ exportVersion: EXPORT_VERSION
24097
+ });
24098
+ }
24099
+ async function getConfigMeta(req, res) {
24100
+ const configPath = getConfigPath("swixter");
24101
+ if (!existsSync7(configPath)) {
24102
+ sendJson(res, {
24103
+ exists: false,
24104
+ profiles: [],
24105
+ mtime: null,
24106
+ size: 0
24107
+ });
24108
+ return;
24109
+ }
24110
+ try {
24111
+ const stats = statSync(configPath);
24112
+ const etag = generateETag(stats.mtime, stats.size);
24113
+ const ifNoneMatch = parseIfNoneMatch(req.headers["if-none-match"]);
24114
+ if (ifNoneMatch === etag) {
24115
+ res.statusCode = 304;
24116
+ res.end();
24117
+ return;
24118
+ }
24119
+ setETagHeaders(res, stats.mtime, stats.size);
24120
+ const { listProfiles: listProfiles3 } = await Promise.resolve().then(() => (init_manager(), exports_manager));
24121
+ const profiles = await listProfiles3();
24122
+ sendJson(res, {
24123
+ exists: true,
24124
+ profiles: profiles.map((p2) => ({
24125
+ name: p2.name,
24126
+ providerId: p2.providerId,
24127
+ updatedAt: p2.updatedAt
24128
+ })),
24129
+ mtime: stats.mtime.toISOString(),
24130
+ size: stats.size,
24131
+ etag
24132
+ });
24133
+ } catch (error46) {
24134
+ sendError(res, { code: "STAT_FAILED", message: "Failed to read config metadata" }, 500);
24135
+ }
24136
+ }
24137
+ async function exportConfigFile(req, res) {
24138
+ try {
24139
+ const configPath = getConfigPath("swixter");
24140
+ const content = await readFile7(configPath, "utf-8");
24141
+ res.setHeader("Content-Type", "application/json");
24142
+ res.setHeader("Content-Disposition", 'attachment; filename="swixter-config.json"');
24143
+ res.statusCode = 200;
24144
+ res.end(content);
24145
+ } catch (error46) {
24146
+ sendError(res, { code: "EXPORT_FAILED", message: "Failed to export configuration" }, 500);
24147
+ }
24148
+ }
24149
+ async function importConfigFile(req, res) {
24150
+ const body = req.body;
24151
+ if (!body || !body.config) {
24152
+ sendError(res, { code: "INVALID_PARAMS", message: "config is required" }, 400);
24153
+ return;
24154
+ }
24155
+ try {
24156
+ const tempDir = getConfigDir("swixter");
24157
+ const tempPath = join5(tempDir, `.import-${Date.now()}.json`);
24158
+ await writeFile7(tempPath, JSON.stringify(body.config), "utf-8");
24159
+ try {
24160
+ const result = await importConfig(tempPath, { overwrite: body.overwrite !== false });
24161
+ sendJson(res, { success: true, ...result });
24162
+ } finally {
24163
+ try {
24164
+ await unlink(tempPath);
24165
+ } catch {}
24166
+ }
24167
+ } catch (error46) {
24168
+ sendError(res, { code: "IMPORT_FAILED", message: error46 instanceof Error ? error46.message : "Failed to import configuration" }, 500);
24169
+ }
24170
+ }
24171
+
24172
+ // src/server/index.ts
24173
+ var __dirname2 = dirname7(fileURLToPath(import.meta.url));
24174
+ async function findAvailablePort(startPort = 3141) {
24175
+ const net = await import("node:net");
24176
+ return new Promise((resolve) => {
24177
+ const server = net.createServer();
24178
+ server.listen(startPort, "127.0.0.1", () => {
24179
+ const port = server.address().port;
24180
+ server.close(() => resolve(port));
24181
+ });
24182
+ server.on("error", () => {
24183
+ server.close();
24184
+ resolve(findAvailablePort(startPort + 1));
24185
+ });
24186
+ });
24187
+ }
24188
+ function openBrowser(url2) {
24189
+ const command = process.platform === "win32" ? "start" : process.platform === "darwin" ? "open" : "xdg-open";
24190
+ exec(`${command} ${url2}`, (error46) => {
24191
+ if (error46) {
24192
+ console.warn(import_picocolors11.default.yellow(`Could not open browser automatically: ${error46.message}`));
24193
+ }
24194
+ });
24195
+ }
24196
+ function getUiDir() {
24197
+ const isDev = true;
24198
+ if (isDev) {
24199
+ return join6(__dirname2, "..", "..", "ui", "dist");
24200
+ }
24201
+ return join6(__dirname2, "..", "..", "ui");
24202
+ }
24203
+ async function startServer(portArg) {
24204
+ const port = portArg || await findAvailablePort(3141);
24205
+ const host = "127.0.0.1";
24206
+ const router = new Router;
24207
+ router.use(corsMiddleware);
24208
+ router.use(jsonBodyMiddleware);
24209
+ router.get("/api/profiles", listProfiles2);
24210
+ router.get("/api/profiles/:name", getProfile2);
24211
+ router.post("/api/profiles", createProfile);
24212
+ router.put("/api/profiles/:name", updateProfile);
24213
+ router.delete("/api/profiles/:name", deleteProfile2);
24214
+ router.get("/api/providers", listProviders);
24215
+ router.post("/api/providers", createProvider);
24216
+ router.put("/api/providers/:id", updateProvider);
24217
+ router.delete("/api/providers/:id", deleteProvider);
24218
+ router.get("/api/coders", listCoders);
24219
+ router.get("/api/coders/:coder/active", getActiveProfile2);
24220
+ router.put("/api/coders/:coder/active", setActiveProfile2);
24221
+ router.post("/api/coders/:coder/apply", applyProfile);
24222
+ router.get("/api/coders/:coder/verify", verifyConfig);
24223
+ router.get("/api/version", getVersion);
24224
+ router.get("/api/config", getConfigMeta);
24225
+ router.get("/api/config/export", exportConfigFile);
24226
+ router.post("/api/config/import", importConfigFile);
24227
+ const uiDir = getUiDir();
24228
+ const serveStatic = createStaticServe({ root: uiDir, index: "index.html", spa: true });
24229
+ const server = createServer(async (req, res) => {
24230
+ const url2 = req.url || "";
24231
+ if (url2.startsWith("/api/") || url2 === "/api") {
24232
+ await router.handle(req, res);
24233
+ } else {
24234
+ await serveStatic(req, res);
24235
+ }
24236
+ });
24237
+ server.listen(port, host, () => {
24238
+ const url2 = `http://${host}:${port}`;
24239
+ console.log();
24240
+ console.log(import_picocolors11.default.bold(import_picocolors11.default.cyan("Swixter Web UI")));
24241
+ console.log();
24242
+ console.log(` Server: ${import_picocolors11.default.cyan(url2)}`);
24243
+ console.log(` Press ${import_picocolors11.default.bold("Ctrl+C")} to stop`);
24244
+ console.log();
24245
+ openBrowser(url2);
24246
+ });
24247
+ server.on("error", (error46) => {
24248
+ if (error46.code === "EADDRINUSE") {
24249
+ console.error(import_picocolors11.default.red(`Error: Port ${port} is already in use`));
24250
+ console.log(import_picocolors11.default.dim("Try specifying a different port with --port"));
24251
+ process.exit(1);
24252
+ } else {
24253
+ console.error(import_picocolors11.default.red(`Server error: ${error46.message}`));
24254
+ process.exit(1);
24255
+ }
24256
+ });
24257
+ server.on("close", () => {
24258
+ console.log();
24259
+ console.log(import_picocolors11.default.dim("Server closed"));
24260
+ });
24261
+ return server;
24262
+ }
24263
+
24264
+ // src/cli/ui.ts
24265
+ async function handleUiCommand(args) {
24266
+ const port = getPortFromArgs(args);
24267
+ try {
24268
+ const server = await startServer(port);
24269
+ process.on("SIGINT", () => {
24270
+ console.log();
24271
+ console.log(import_picocolors12.default.dim("Shutting down..."));
24272
+ server.close(() => {
24273
+ process.exit(0);
24274
+ });
24275
+ });
24276
+ process.stdin.resume();
24277
+ } catch (error46) {
24278
+ console.error(import_picocolors12.default.red(`Failed to start server: ${error46}`));
24279
+ process.exit(1);
24280
+ }
24281
+ }
24282
+ function getPortFromArgs(args) {
24283
+ if (!args || args.length === 0) {
24284
+ return;
24285
+ }
24286
+ for (let i2 = 0;i2 < args.length; i2++) {
24287
+ const arg = args[i2];
24288
+ if (arg === "--port" || arg === "-p") {
24289
+ const portStr = args[i2 + 1];
24290
+ if (!portStr) {
24291
+ console.error(import_picocolors12.default.red("Error: --port requires a value"));
24292
+ process.exit(1);
24293
+ }
24294
+ const port = parseInt(portStr, 10);
24295
+ if (isNaN(port) || port < 1 || port > 65535) {
24296
+ console.error(import_picocolors12.default.red("Error: Invalid port number"));
24297
+ process.exit(1);
24298
+ }
24299
+ return port;
24300
+ }
24301
+ }
24302
+ return;
24303
+ }
24304
+
23456
24305
  // src/cli/help.ts
23457
- var import_picocolors11 = __toESM(require_picocolors(), 1);
24306
+ var import_picocolors13 = __toESM(require_picocolors(), 1);
23458
24307
  function showGlobalHelp() {
23459
24308
  console.log(`
23460
- ${import_picocolors11.default.bold(import_picocolors11.default.cyan("Swixter - AI Coder Configuration Manager"))}
24309
+ ${import_picocolors13.default.bold(import_picocolors13.default.cyan("Swixter - AI Coder Configuration Manager"))}
23461
24310
 
23462
- ${import_picocolors11.default.bold("Usage:")}
23463
- ${import_picocolors11.default.green("swixter <coder> <command> [options]")}
23464
- ${import_picocolors11.default.green("swixter <global-command> [options]")}
24311
+ ${import_picocolors13.default.bold("Usage:")}
24312
+ ${import_picocolors13.default.green("swixter <coder> <command> [options]")}
24313
+ ${import_picocolors13.default.green("swixter <global-command> [options]")}
23465
24314
 
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")}
24315
+ ${import_picocolors13.default.bold("Supported Coders:")}
24316
+ ${import_picocolors13.default.cyan("claude")} ${import_picocolors13.default.dim("Claude Code configuration management")}
24317
+ ${import_picocolors13.default.cyan("codex")} ${import_picocolors13.default.dim("Codex configuration management")}
24318
+ ${import_picocolors13.default.cyan("qwen")} ${import_picocolors13.default.dim("Continue/Qwen configuration management")}
23470
24319
 
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")}
24320
+ ${import_picocolors13.default.bold("Web UI:")}
24321
+ ${import_picocolors13.default.cyan("ui")} ${import_picocolors13.default.dim("Launch local Web UI")}
24322
+ ${import_picocolors13.default.dim("swixter ui [--port <port>]")}
24323
+ ${import_picocolors13.default.dim("Start local HTTP server and open browser")}
23478
24324
 
23479
- ${import_picocolors11.default.bold("Examples:")}
23480
- ${import_picocolors11.default.dim("# View Claude Code commands")}
23481
- ${import_picocolors11.default.green("swixter claude --help")}
24325
+ ${import_picocolors13.default.bold("Global Commands:")}
24326
+ ${import_picocolors13.default.cyan("providers")} ${import_picocolors13.default.dim("List all available API providers")}
24327
+ ${import_picocolors13.default.cyan("export <file>")} ${import_picocolors13.default.dim("Export all configurations to file")}
24328
+ ${import_picocolors13.default.cyan("import <file>")} ${import_picocolors13.default.dim("Import configurations from file")}
24329
+ ${import_picocolors13.default.cyan("completion <shell>")} ${import_picocolors13.default.dim("Generate shell auto-completion script")}
24330
+ ${import_picocolors13.default.cyan("help")} ${import_picocolors13.default.dim("Show help information")}
24331
+ ${import_picocolors13.default.cyan("version")} ${import_picocolors13.default.dim("Show version information")}
23482
24332
 
23483
- ${import_picocolors11.default.dim("# Create Claude Code configuration")}
23484
- ${import_picocolors11.default.green("swixter claude create")}
24333
+ ${import_picocolors13.default.bold("Examples:")}
24334
+ ${import_picocolors13.default.dim("# View Claude Code commands")}
24335
+ ${import_picocolors13.default.green("swixter claude --help")}
23485
24336
 
23486
- ${import_picocolors11.default.dim("# View all providers")}
23487
- ${import_picocolors11.default.green("swixter providers")}
24337
+ ${import_picocolors13.default.dim("# Create Claude Code configuration")}
24338
+ ${import_picocolors13.default.green("swixter claude create")}
23488
24339
 
23489
- ${import_picocolors11.default.dim("# Export configurations")}
23490
- ${import_picocolors11.default.green("swixter export my-config.json")}
24340
+ ${import_picocolors13.default.dim("# Launch Web UI")}
24341
+ ${import_picocolors13.default.green("swixter ui")}
23491
24342
 
23492
- ${import_picocolors11.default.dim("# Install bash auto-completion")}
23493
- ${import_picocolors11.default.green("swixter completion bash > ~/.local/share/bash-completion/completions/swixter")}
24343
+ ${import_picocolors13.default.dim("# View all providers")}
24344
+ ${import_picocolors13.default.green("swixter providers")}
23494
24345
 
23495
- ${import_picocolors11.default.dim("Documentation: https://github.com/dawnswwwww/swixter")}
23496
- `);
24346
+ ${import_picocolors13.default.dim("Documentation: https://github.com/dawnswwwww/swixter")}`);
23497
24347
  }
23498
24348
 
23499
24349
  // src/cli/completions.ts
@@ -23856,37 +24706,37 @@ function generateCompletion(shell) {
23856
24706
  // src/cli/providers.ts
23857
24707
  init_presets();
23858
24708
  init_user_providers();
23859
- var import_picocolors12 = __toESM(require_picocolors(), 1);
24709
+ var import_picocolors14 = __toESM(require_picocolors(), 1);
23860
24710
  init_formatting();
23861
- async function listProviders() {
24711
+ async function listProviders2() {
23862
24712
  console.log();
23863
- Ie(import_picocolors12.default.cyan("Available Providers"));
24713
+ Ie(import_picocolors14.default.cyan("Available Providers"));
23864
24714
  const allPresets2 = await getAllPresets();
23865
24715
  const userProviders = await loadUserProviders();
23866
24716
  const userProviderIds = new Set(userProviders.map((p2) => p2.id));
23867
24717
  const builtInProviderIds = new Set(getBuiltInPresets().map((p2) => p2.id));
23868
24718
  if (allPresets2.length === 0) {
23869
- console.log(import_picocolors12.default.yellow("No providers configured"));
24719
+ console.log(import_picocolors14.default.yellow("No providers configured"));
23870
24720
  console.log();
23871
24721
  return;
23872
24722
  }
23873
24723
  console.log();
23874
- console.log(import_picocolors12.default.bold("Built-in Providers:"));
24724
+ console.log(import_picocolors14.default.bold("Built-in Providers:"));
23875
24725
  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")}`);
24726
+ 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
24727
  });
23878
24728
  const userOnlyProviders = allPresets2.filter((p2) => userProviderIds.has(p2.id));
23879
24729
  if (userOnlyProviders.length > 0) {
23880
24730
  console.log();
23881
- console.log(import_picocolors12.default.bold("User-defined Providers:"));
24731
+ console.log(import_picocolors14.default.bold("User-defined Providers:"));
23882
24732
  userOnlyProviders.forEach((preset) => {
23883
24733
  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}`);
24734
+ const marker = isOverride ? import_picocolors14.default.yellow(" (override)") : "";
24735
+ 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
24736
  });
23887
24737
  }
23888
24738
  console.log();
23889
- console.log(import_picocolors12.default.dim(`Total: ${allPresets2.length} providers`));
24739
+ console.log(import_picocolors14.default.dim(`Total: ${allPresets2.length} providers`));
23890
24740
  console.log();
23891
24741
  }
23892
24742
  async function addProvider(options) {
@@ -23898,7 +24748,7 @@ async function addProvider(options) {
23898
24748
  let models = options.models;
23899
24749
  if (!options.quiet) {
23900
24750
  console.log();
23901
- Ie(import_picocolors12.default.cyan("Add Custom Provider"));
24751
+ Ie(import_picocolors14.default.cyan("Add Custom Provider"));
23902
24752
  const existing = providerId ? await getUserProvider(providerId) : undefined;
23903
24753
  providerId = await he({
23904
24754
  message: "Provider ID (unique identifier, e.g., 'openrouter', 'deepseek')",
@@ -23993,7 +24843,7 @@ async function addProvider(options) {
23993
24843
  try {
23994
24844
  await upsertUserProvider(provider);
23995
24845
  if (!options.quiet) {
23996
- Se(import_picocolors12.default.green(`${MARKERS.success} Provider "${providerId}" added successfully!`));
24846
+ Se(import_picocolors14.default.green(`${MARKERS.success} Provider "${providerId}" added successfully!`));
23997
24847
  } else {
23998
24848
  showSuccess(`Provider "${providerId}" added successfully!`, {
23999
24849
  ID: providerId,
@@ -24012,10 +24862,10 @@ async function removeProvider(providerId, options) {
24012
24862
  showError("Error: Provider ID is required", "Usage: swixter providers remove <provider-id>");
24013
24863
  }
24014
24864
  console.log();
24015
- Ie(import_picocolors12.default.cyan("Remove Custom Provider"));
24865
+ Ie(import_picocolors14.default.cyan("Remove Custom Provider"));
24016
24866
  const userProviders = await loadUserProviders();
24017
24867
  if (userProviders.length === 0) {
24018
- Se(import_picocolors12.default.yellow("No user-defined providers to remove"));
24868
+ Se(import_picocolors14.default.yellow("No user-defined providers to remove"));
24019
24869
  return;
24020
24870
  }
24021
24871
  providerId = await ve({
@@ -24042,7 +24892,7 @@ async function removeProvider(providerId, options) {
24042
24892
  showError(`Error: Provider "${providerId}" not found`, "Use 'swixter providers list' to see all providers");
24043
24893
  }
24044
24894
  if (!options?.quiet) {
24045
- Se(import_picocolors12.default.green(`${MARKERS.success} Provider "${providerId}" removed successfully!`));
24895
+ Se(import_picocolors14.default.green(`${MARKERS.success} Provider "${providerId}" removed successfully!`));
24046
24896
  } else {
24047
24897
  showSuccess(`Provider "${providerId}" removed successfully!`);
24048
24898
  }
@@ -24056,19 +24906,19 @@ async function showProvider(providerId) {
24056
24906
  showError(`Error: Provider "${providerId}" not found`, "Use 'swixter providers list' to see all providers");
24057
24907
  }
24058
24908
  console.log();
24059
- Ie(import_picocolors12.default.cyan(`Provider: ${provider.displayName}`));
24909
+ Ie(import_picocolors14.default.cyan(`Provider: ${provider.displayName}`));
24060
24910
  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)}`);
24911
+ console.log(` ID: ${import_picocolors14.default.cyan(provider.id)}`);
24912
+ console.log(` Name: ${import_picocolors14.default.yellow(provider.name)}`);
24913
+ console.log(` Display Name: ${import_picocolors14.default.yellow(provider.displayName)}`);
24914
+ console.log(` Base URL: ${import_picocolors14.default.yellow(provider.baseURL)}`);
24915
+ console.log(` Auth Type: ${import_picocolors14.default.yellow(provider.authType)}`);
24066
24916
  if (provider.defaultModels && provider.defaultModels.length > 0) {
24067
24917
  console.log(` Default Models:`);
24068
- provider.defaultModels.forEach((model) => console.log(` - ${import_picocolors12.default.dim(model)}`));
24918
+ provider.defaultModels.forEach((model) => console.log(` - ${import_picocolors14.default.dim(model)}`));
24069
24919
  }
24070
24920
  if (provider.docs) {
24071
- console.log(` Documentation: ${import_picocolors12.default.blue(provider.docs)}`);
24921
+ console.log(` Documentation: ${import_picocolors14.default.blue(provider.docs)}`);
24072
24922
  }
24073
24923
  console.log();
24074
24924
  }
@@ -24078,7 +24928,7 @@ init_meta();
24078
24928
  init_versions2();
24079
24929
  async function cmdProviders(subcommand, args) {
24080
24930
  if (!subcommand || subcommand === "list" || subcommand === "ls") {
24081
- await listProviders();
24931
+ await listProviders2();
24082
24932
  return;
24083
24933
  }
24084
24934
  if (subcommand === "add" || subcommand === "new") {
@@ -24120,104 +24970,104 @@ async function cmdProviders(subcommand, args) {
24120
24970
  await showProvider(providerId);
24121
24971
  return;
24122
24972
  }
24123
- console.log(import_picocolors13.default.red(`Unknown providers subcommand: ${subcommand}`));
24973
+ console.log(import_picocolors15.default.red(`Unknown providers subcommand: ${subcommand}`));
24124
24974
  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`);
24975
+ console.log(import_picocolors15.default.bold("Available subcommands:"));
24976
+ console.log(` ${import_picocolors15.default.cyan("list, ls")} - List all providers`);
24977
+ console.log(` ${import_picocolors15.default.cyan("add, new")} - Add a custom provider`);
24978
+ console.log(` ${import_picocolors15.default.cyan("remove, rm, delete")} - Remove a custom provider`);
24979
+ console.log(` ${import_picocolors15.default.cyan("show, info")} - Show provider details`);
24130
24980
  console.log();
24131
24981
  process.exit(1);
24132
24982
  }
24133
24983
  async function cmdExport(filePath) {
24134
24984
  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>"));
24985
+ console.log(import_picocolors15.default.red("Error: Please specify export file path"));
24986
+ console.log(import_picocolors15.default.dim("Usage: swixter export <file>"));
24137
24987
  process.exit(1);
24138
24988
  }
24139
24989
  try {
24140
24990
  await exportConfig(filePath, { sanitizeKeys: false });
24141
24991
  console.log();
24142
- console.log(import_picocolors13.default.green("✓") + " Export successful!");
24143
- console.log(` File: ${import_picocolors13.default.cyan(filePath)}`);
24992
+ console.log(import_picocolors15.default.green("✓") + " Export successful!");
24993
+ console.log(` File: ${import_picocolors15.default.cyan(filePath)}`);
24144
24994
  console.log();
24145
24995
  } catch (error46) {
24146
24996
  console.log();
24147
- console.log(import_picocolors13.default.red(`✗ Export failed: ${error46}`));
24997
+ console.log(import_picocolors15.default.red(`✗ Export failed: ${error46}`));
24148
24998
  console.log();
24149
24999
  process.exit(1);
24150
25000
  }
24151
25001
  }
24152
25002
  async function cmdCompletion(shell) {
24153
25003
  if (!shell) {
24154
- console.log(import_picocolors13.default.yellow("Please specify shell type"));
25004
+ console.log(import_picocolors15.default.yellow("Please specify shell type"));
24155
25005
  console.log();
24156
- console.log(import_picocolors13.default.bold("Usage:"));
24157
- console.log(` ${import_picocolors13.default.green("swixter completion <shell>")}`);
25006
+ console.log(import_picocolors15.default.bold("Usage:"));
25007
+ console.log(` ${import_picocolors15.default.green("swixter completion <shell>")}`);
24158
25008
  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`);
25009
+ console.log(import_picocolors15.default.bold("Supported shells:"));
25010
+ console.log(` ${import_picocolors15.default.cyan("bash")} - Bash shell`);
25011
+ console.log(` ${import_picocolors15.default.cyan("zsh")} - Z shell`);
25012
+ console.log(` ${import_picocolors15.default.cyan("fish")} - Fish shell`);
24163
25013
  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")}`);
25014
+ console.log(import_picocolors15.default.bold("Examples:"));
25015
+ console.log(` ${import_picocolors15.default.green("swixter completion bash > ~/.local/share/bash-completion/completions/swixter")}`);
25016
+ console.log(` ${import_picocolors15.default.green("swixter completion zsh > ~/.zfunc/_swixter")}`);
25017
+ console.log(` ${import_picocolors15.default.green("swixter completion fish > ~/.config/fish/completions/swixter.fish")}`);
24168
25018
  process.exit(1);
24169
25019
  }
24170
25020
  const supportedShells = ["bash", "zsh", "fish"];
24171
25021
  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(", ")}`));
25022
+ console.log(import_picocolors15.default.red(`Unsupported shell: ${shell}`));
25023
+ console.log(import_picocolors15.default.dim(`Supported shells: ${supportedShells.join(", ")}`));
24174
25024
  process.exit(1);
24175
25025
  }
24176
25026
  try {
24177
25027
  const script = generateCompletion(shell);
24178
25028
  console.log(script);
24179
25029
  } catch (error46) {
24180
- console.error(import_picocolors13.default.red("Failed to generate completion script:"), error46);
25030
+ console.error(import_picocolors15.default.red("Failed to generate completion script:"), error46);
24181
25031
  process.exit(1);
24182
25032
  }
24183
25033
  }
24184
25034
  async function cmdImport(filePath) {
24185
25035
  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>"));
25036
+ console.log(import_picocolors15.default.red("Error: Please specify import file path"));
25037
+ console.log(import_picocolors15.default.dim("Usage: swixter import <file>"));
24188
25038
  process.exit(1);
24189
25039
  }
24190
25040
  try {
24191
25041
  const result = await importConfig(filePath, { overwrite: false });
24192
25042
  console.log();
24193
- console.log(import_picocolors13.default.green("✓") + " Import completed!");
25043
+ console.log(import_picocolors15.default.green("✓") + " Import completed!");
24194
25044
  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`);
25045
+ console.log(` Successfully imported: ${import_picocolors15.default.green(result.imported)} items`);
25046
+ console.log(` Skipped: ${import_picocolors15.default.yellow(result.skipped)} items`);
25047
+ console.log(` Errors: ${import_picocolors15.default.red(result.errors.length)} items`);
24198
25048
  console.log();
24199
25049
  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}`)));
25050
+ console.log(import_picocolors15.default.red("Error details:"));
25051
+ result.errors.forEach((err) => console.log(import_picocolors15.default.red(` - ${err}`)));
24202
25052
  console.log();
24203
25053
  }
24204
25054
  } catch (error46) {
24205
25055
  console.log();
24206
- console.log(import_picocolors13.default.red(`✗ Import failed: ${error46}`));
25056
+ console.log(import_picocolors15.default.red(`✗ Import failed: ${error46}`));
24207
25057
  console.log();
24208
25058
  process.exit(1);
24209
25059
  }
24210
25060
  }
24211
25061
  async function cmdVersion() {
24212
25062
  console.log();
24213
- console.log(import_picocolors13.default.bold(import_picocolors13.default.cyan("Swixter")) + import_picocolors13.default.dim(" - AI Coder Configuration Manager"));
25063
+ console.log(import_picocolors15.default.bold(import_picocolors15.default.cyan("Swixter")) + import_picocolors15.default.dim(" - AI Coder Configuration Manager"));
24214
25064
  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)}`);
25065
+ console.log(` ${import_picocolors15.default.bold("Version:")} ${import_picocolors15.default.green(APP_VERSION)}`);
25066
+ console.log(` ${import_picocolors15.default.bold("Config Version:")} ${import_picocolors15.default.cyan(CONFIG_VERSION)}`);
25067
+ console.log(` ${import_picocolors15.default.bold("Export Version:")} ${import_picocolors15.default.cyan(EXPORT_VERSION)}`);
24218
25068
  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"));
25069
+ console.log(import_picocolors15.default.dim(" GitHub: https://github.com/dawnswwwww/swixter"));
25070
+ console.log(import_picocolors15.default.dim(" NPM: https://www.npmjs.com/package/swixter"));
24221
25071
  console.log();
24222
25072
  }
24223
25073
  async function main() {
@@ -24228,6 +25078,10 @@ async function main() {
24228
25078
  showGlobalHelp();
24229
25079
  return;
24230
25080
  }
25081
+ if (firstArg === "ui") {
25082
+ await handleUiCommand(args.slice(1));
25083
+ return;
25084
+ }
24231
25085
  if (firstArg === "claude") {
24232
25086
  await handleClaudeCommand(args.slice(1));
24233
25087
  return;
@@ -24260,11 +25114,11 @@ async function main() {
24260
25114
  await cmdVersion();
24261
25115
  return;
24262
25116
  }
24263
- console.log(import_picocolors13.default.red(`Unknown command: ${firstArg}`));
24264
- console.log(import_picocolors13.default.dim("Run 'swixter --help' for help"));
25117
+ console.log(import_picocolors15.default.red(`Unknown command: ${firstArg}`));
25118
+ console.log(import_picocolors15.default.dim("Run 'swixter --help' for help"));
24265
25119
  process.exit(1);
24266
25120
  } catch (error46) {
24267
- console.error(import_picocolors13.default.red("An error occurred:"), error46);
25121
+ console.error(import_picocolors15.default.red("An error occurred:"), error46);
24268
25122
  process.exit(1);
24269
25123
  }
24270
25124
  }