swixter 0.0.8 → 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.
- package/README.md +29 -18
- package/dist/cli/index.js +1259 -413
- 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: (
|
|
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: (
|
|
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) => {
|
|
@@ -12951,7 +12971,9 @@ var init_types = __esm(() => {
|
|
|
12951
12971
|
tokensPerMinute: exports_external.number().optional()
|
|
12952
12972
|
}).optional(),
|
|
12953
12973
|
docs: exports_external.string().url().optional(),
|
|
12954
|
-
isChinese: exports_external.boolean().optional()
|
|
12974
|
+
isChinese: exports_external.boolean().optional(),
|
|
12975
|
+
wire_api: exports_external.enum(["chat", "responses"]).optional(),
|
|
12976
|
+
env_key: exports_external.string().optional()
|
|
12955
12977
|
});
|
|
12956
12978
|
ClaudeCodeProfileSchema = exports_external.object({
|
|
12957
12979
|
name: exports_external.string().min(1),
|
|
@@ -13132,7 +13154,8 @@ var init_messages = __esm(() => {
|
|
|
13132
13154
|
authToken: "Auth Token",
|
|
13133
13155
|
configFile: "Config File",
|
|
13134
13156
|
createdAt: "Created At",
|
|
13135
|
-
updatedAt: "Updated At"
|
|
13157
|
+
updatedAt: "Updated At",
|
|
13158
|
+
profileList: "Profiles"
|
|
13136
13159
|
};
|
|
13137
13160
|
INSTALL = {
|
|
13138
13161
|
cliNotInstalled: (name) => `${name} CLI is not installed`,
|
|
@@ -13161,6 +13184,10 @@ function getConfigPath(type) {
|
|
|
13161
13184
|
const config2 = PATH_CONFIG[type];
|
|
13162
13185
|
return join(homedir(), config2.dir, config2.file);
|
|
13163
13186
|
}
|
|
13187
|
+
function getConfigDir(type) {
|
|
13188
|
+
const config2 = PATH_CONFIG[type];
|
|
13189
|
+
return join(homedir(), config2.dir);
|
|
13190
|
+
}
|
|
13164
13191
|
var PATH_CONFIG;
|
|
13165
13192
|
var init_paths = __esm(() => {
|
|
13166
13193
|
PATH_CONFIG = {
|
|
@@ -13234,7 +13261,7 @@ var CONFIG_VERSION = "2.0.0", EXPORT_VERSION = "1.0.0";
|
|
|
13234
13261
|
var init_versions2 = () => {};
|
|
13235
13262
|
|
|
13236
13263
|
// src/constants/meta.ts
|
|
13237
|
-
var APP_VERSION = "0.0.
|
|
13264
|
+
var APP_VERSION = "0.0.10";
|
|
13238
13265
|
var init_meta = () => {};
|
|
13239
13266
|
|
|
13240
13267
|
// src/constants/install.ts
|
|
@@ -13530,6 +13557,42 @@ var init_presets = __esm(() => {
|
|
|
13530
13557
|
allPresets = builtInPresets;
|
|
13531
13558
|
});
|
|
13532
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
|
+
|
|
13533
13596
|
// src/adapters/claude.ts
|
|
13534
13597
|
import { existsSync as existsSync2 } from "node:fs";
|
|
13535
13598
|
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "node:fs/promises";
|
|
@@ -13540,7 +13603,7 @@ class ClaudeCodeAdapter {
|
|
|
13540
13603
|
configPath = getConfigPath("claude");
|
|
13541
13604
|
coderConfig = CODER_REGISTRY.claude;
|
|
13542
13605
|
async apply(profile) {
|
|
13543
|
-
const preset =
|
|
13606
|
+
const preset = await getPresetByIdAsync(profile.providerId);
|
|
13544
13607
|
const baseURL = profile.baseURL || preset?.baseURL || "";
|
|
13545
13608
|
let existingConfig = {};
|
|
13546
13609
|
if (existsSync2(this.configPath)) {
|
|
@@ -13552,32 +13615,19 @@ class ClaudeCodeAdapter {
|
|
|
13552
13615
|
}
|
|
13553
13616
|
}
|
|
13554
13617
|
const envVars = this.coderConfig.envVarMapping;
|
|
13555
|
-
const newEnv =
|
|
13556
|
-
|
|
13557
|
-
};
|
|
13558
|
-
if (
|
|
13559
|
-
|
|
13560
|
-
|
|
13561
|
-
|
|
13562
|
-
|
|
13563
|
-
}
|
|
13564
|
-
if (profile.models) {
|
|
13565
|
-
if (profile.models.anthropicModel && envVars.anthropicModel) {
|
|
13566
|
-
newEnv[envVars.anthropicModel] = profile.models.anthropicModel;
|
|
13567
|
-
}
|
|
13568
|
-
if (profile.models.defaultHaikuModel && envVars.defaultHaikuModel) {
|
|
13569
|
-
newEnv[envVars.defaultHaikuModel] = profile.models.defaultHaikuModel;
|
|
13570
|
-
}
|
|
13571
|
-
if (profile.models.defaultOpusModel && envVars.defaultOpusModel) {
|
|
13572
|
-
newEnv[envVars.defaultOpusModel] = profile.models.defaultOpusModel;
|
|
13573
|
-
}
|
|
13574
|
-
if (profile.models.defaultSonnetModel && envVars.defaultSonnetModel) {
|
|
13575
|
-
newEnv[envVars.defaultSonnetModel] = profile.models.defaultSonnetModel;
|
|
13618
|
+
const newEnv = buildProfileEnv(profile, envVars, baseURL);
|
|
13619
|
+
const managedKeys = Object.values(envVars).filter(Boolean);
|
|
13620
|
+
const preservedEnv = {};
|
|
13621
|
+
if (existingConfig.env) {
|
|
13622
|
+
for (const [key, value] of Object.entries(existingConfig.env)) {
|
|
13623
|
+
if (!managedKeys.includes(key)) {
|
|
13624
|
+
preservedEnv[key] = value;
|
|
13625
|
+
}
|
|
13576
13626
|
}
|
|
13577
13627
|
}
|
|
13578
13628
|
const newConfig = {
|
|
13579
13629
|
...existingConfig,
|
|
13580
|
-
env: newEnv
|
|
13630
|
+
env: { ...preservedEnv, ...newEnv }
|
|
13581
13631
|
};
|
|
13582
13632
|
await mkdir2(dirname2(this.configPath), { recursive: true });
|
|
13583
13633
|
const content = JSON.stringify(newConfig, null, SERIALIZATION.jsonIndent);
|
|
@@ -13590,27 +13640,16 @@ class ClaudeCodeAdapter {
|
|
|
13590
13640
|
try {
|
|
13591
13641
|
const content = await readFile2(this.configPath, "utf-8");
|
|
13592
13642
|
const config2 = JSON.parse(content);
|
|
13593
|
-
const preset =
|
|
13643
|
+
const preset = await getPresetByIdAsync(profile.providerId);
|
|
13594
13644
|
const expectedBaseURL = profile.baseURL || preset?.baseURL || "";
|
|
13595
13645
|
const envVars = this.coderConfig.envVarMapping;
|
|
13596
|
-
const
|
|
13597
|
-
const
|
|
13598
|
-
|
|
13599
|
-
|
|
13600
|
-
if (profile.models.anthropicModel && envVars.anthropicModel) {
|
|
13601
|
-
hasMatchingModels = hasMatchingModels && config2.env?.[envVars.anthropicModel] === profile.models.anthropicModel;
|
|
13602
|
-
}
|
|
13603
|
-
if (profile.models.defaultHaikuModel && envVars.defaultHaikuModel) {
|
|
13604
|
-
hasMatchingModels = hasMatchingModels && config2.env?.[envVars.defaultHaikuModel] === profile.models.defaultHaikuModel;
|
|
13605
|
-
}
|
|
13606
|
-
if (profile.models.defaultOpusModel && envVars.defaultOpusModel) {
|
|
13607
|
-
hasMatchingModels = hasMatchingModels && config2.env?.[envVars.defaultOpusModel] === profile.models.defaultOpusModel;
|
|
13608
|
-
}
|
|
13609
|
-
if (profile.models.defaultSonnetModel && envVars.defaultSonnetModel) {
|
|
13610
|
-
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;
|
|
13611
13650
|
}
|
|
13612
13651
|
}
|
|
13613
|
-
return (
|
|
13652
|
+
return Object.keys(expectedEnv).length > 0;
|
|
13614
13653
|
} catch (error46) {
|
|
13615
13654
|
return false;
|
|
13616
13655
|
}
|
|
@@ -16234,14 +16273,6 @@ var init_js_yaml = __esm(() => {
|
|
|
16234
16273
|
safeDump = renamed("safeDump", "dump");
|
|
16235
16274
|
});
|
|
16236
16275
|
|
|
16237
|
-
// src/utils/model-helper.ts
|
|
16238
|
-
function getOpenAIModel(profile) {
|
|
16239
|
-
if (profile.models) {
|
|
16240
|
-
return;
|
|
16241
|
-
}
|
|
16242
|
-
return profile.model || profile.openaiModel;
|
|
16243
|
-
}
|
|
16244
|
-
|
|
16245
16276
|
// src/adapters/continue.ts
|
|
16246
16277
|
import { existsSync as existsSync3 } from "node:fs";
|
|
16247
16278
|
import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir3 } from "node:fs/promises";
|
|
@@ -16251,7 +16282,7 @@ class ContinueAdapter {
|
|
|
16251
16282
|
name = "continue";
|
|
16252
16283
|
configPath = getConfigPath("continue");
|
|
16253
16284
|
async apply(profile) {
|
|
16254
|
-
const preset =
|
|
16285
|
+
const preset = await getPresetByIdAsync(profile.providerId);
|
|
16255
16286
|
const baseURL = profile.baseURL || preset?.baseURL || "";
|
|
16256
16287
|
const continueProvider = PROVIDER_MAP[profile.providerId] || "openai";
|
|
16257
16288
|
let existingConfig = {};
|
|
@@ -16305,7 +16336,7 @@ class ContinueAdapter {
|
|
|
16305
16336
|
if (!model) {
|
|
16306
16337
|
return false;
|
|
16307
16338
|
}
|
|
16308
|
-
const preset =
|
|
16339
|
+
const preset = await getPresetByIdAsync(profile.providerId);
|
|
16309
16340
|
const expectedBaseURL = profile.baseURL || preset?.baseURL || "";
|
|
16310
16341
|
const expectedModel = getOpenAIModel(profile);
|
|
16311
16342
|
if (model.apiBase !== expectedBaseURL) {
|
|
@@ -16332,7 +16363,11 @@ class ContinueAdapter {
|
|
|
16332
16363
|
const initialLength = config2.models.length;
|
|
16333
16364
|
config2.models = config2.models.filter((m2) => m2.title !== profileName);
|
|
16334
16365
|
if (config2.models.length < initialLength) {
|
|
16335
|
-
const yamlContent = dump(config2
|
|
16366
|
+
const yamlContent = dump(config2, {
|
|
16367
|
+
indent: SERIALIZATION.yamlIndent,
|
|
16368
|
+
lineWidth: -1,
|
|
16369
|
+
noRefs: true
|
|
16370
|
+
});
|
|
16336
16371
|
await writeFile3(this.configPath, yamlContent, "utf-8");
|
|
16337
16372
|
}
|
|
16338
16373
|
} catch (error46) {
|
|
@@ -17500,13 +17535,13 @@ var init_dist = __esm(() => {
|
|
|
17500
17535
|
});
|
|
17501
17536
|
|
|
17502
17537
|
// src/utils/env-key-helper.ts
|
|
17503
|
-
function getEnvKey(profile) {
|
|
17504
|
-
const preset =
|
|
17538
|
+
async function getEnvKey(profile) {
|
|
17539
|
+
const preset = await getPresetByIdAsync(profile.providerId);
|
|
17505
17540
|
return profile.envKey || preset?.env_key || "OPENAI_API_KEY";
|
|
17506
17541
|
}
|
|
17507
|
-
function getEnvExportCommands(profile) {
|
|
17542
|
+
async function getEnvExportCommands(profile) {
|
|
17508
17543
|
const commands = [];
|
|
17509
|
-
const envKey = getEnvKey(profile);
|
|
17544
|
+
const envKey = await getEnvKey(profile);
|
|
17510
17545
|
if (profile.apiKey) {
|
|
17511
17546
|
commands.push(`export ${envKey}="${profile.apiKey}"`);
|
|
17512
17547
|
}
|
|
@@ -17546,7 +17581,7 @@ class CodexAdapter {
|
|
|
17546
17581
|
config2 = {};
|
|
17547
17582
|
}
|
|
17548
17583
|
}
|
|
17549
|
-
const preset =
|
|
17584
|
+
const preset = await getPresetByIdAsync(profile.providerId);
|
|
17550
17585
|
if (!preset) {
|
|
17551
17586
|
throw new Error(`Unknown provider: ${profile.providerId}`);
|
|
17552
17587
|
}
|
|
@@ -17555,11 +17590,11 @@ class CodexAdapter {
|
|
|
17555
17590
|
if (!config2.model_providers) {
|
|
17556
17591
|
config2.model_providers = {};
|
|
17557
17592
|
}
|
|
17558
|
-
config2.model_providers[providerName] = this.createProviderTable(profile, preset);
|
|
17593
|
+
config2.model_providers[providerName] = await this.createProviderTable(profile, preset);
|
|
17559
17594
|
if (!config2.profiles) {
|
|
17560
17595
|
config2.profiles = {};
|
|
17561
17596
|
}
|
|
17562
|
-
config2.profiles[profileName] = this.createProfileTable(profile, providerName);
|
|
17597
|
+
config2.profiles[profileName] = await this.createProfileTable(profile, providerName);
|
|
17563
17598
|
config2.profile = profileName;
|
|
17564
17599
|
config2.model_provider = providerName;
|
|
17565
17600
|
const tomlContent = stringify(config2);
|
|
@@ -17591,19 +17626,19 @@ class CodexAdapter {
|
|
|
17591
17626
|
return false;
|
|
17592
17627
|
}
|
|
17593
17628
|
}
|
|
17594
|
-
createProviderTable(profile, preset) {
|
|
17629
|
+
async createProviderTable(profile, preset) {
|
|
17595
17630
|
const providerTable = {
|
|
17596
17631
|
name: preset.displayName,
|
|
17597
17632
|
base_url: profile.baseURL || preset.baseURL,
|
|
17598
17633
|
wire_api: preset.wire_api || "chat"
|
|
17599
17634
|
};
|
|
17600
|
-
providerTable.env_key = getEnvKey(profile);
|
|
17635
|
+
providerTable.env_key = await getEnvKey(profile);
|
|
17601
17636
|
if (preset.headers) {
|
|
17602
17637
|
providerTable.http_headers = preset.headers;
|
|
17603
17638
|
}
|
|
17604
17639
|
return providerTable;
|
|
17605
17640
|
}
|
|
17606
|
-
createProfileTable(profile, providerName) {
|
|
17641
|
+
async createProfileTable(profile, providerName) {
|
|
17607
17642
|
const profileTable = {
|
|
17608
17643
|
model_provider: providerName
|
|
17609
17644
|
};
|
|
@@ -17611,15 +17646,15 @@ class CodexAdapter {
|
|
|
17611
17646
|
if (modelValue) {
|
|
17612
17647
|
profileTable.model = modelValue;
|
|
17613
17648
|
} else {
|
|
17614
|
-
const preset =
|
|
17649
|
+
const preset = await getPresetByIdAsync(profile.providerId);
|
|
17615
17650
|
if (preset && preset.defaultModels && preset.defaultModels.length > 0) {
|
|
17616
17651
|
profileTable.model = preset.defaultModels[0];
|
|
17617
17652
|
}
|
|
17618
17653
|
}
|
|
17619
17654
|
return profileTable;
|
|
17620
17655
|
}
|
|
17621
|
-
getEnvExportCommands(profile) {
|
|
17622
|
-
const commands = getEnvExportCommands(profile);
|
|
17656
|
+
async getEnvExportCommands(profile) {
|
|
17657
|
+
const commands = await getEnvExportCommands(profile);
|
|
17623
17658
|
const modelValue = getOpenAIModel(profile);
|
|
17624
17659
|
if (modelValue) {
|
|
17625
17660
|
commands.push(`export OPENAI_MODEL="${modelValue}"`);
|
|
@@ -17684,6 +17719,21 @@ var init_adapters = __esm(() => {
|
|
|
17684
17719
|
});
|
|
17685
17720
|
|
|
17686
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
|
+
});
|
|
17687
17737
|
import { existsSync as existsSync5 } from "node:fs";
|
|
17688
17738
|
import { mkdir as mkdir5, readFile as readFile5, writeFile as writeFile5 } from "node:fs/promises";
|
|
17689
17739
|
import { dirname as dirname5 } from "node:path";
|
|
@@ -17741,6 +17791,9 @@ async function saveConfig(config2) {
|
|
|
17741
17791
|
throw new Error(`Failed to save configuration: ${error46}`);
|
|
17742
17792
|
}
|
|
17743
17793
|
}
|
|
17794
|
+
async function getActiveProfile() {
|
|
17795
|
+
return getActiveProfileForCoder("claude");
|
|
17796
|
+
}
|
|
17744
17797
|
async function getActiveProfileForCoder(coder) {
|
|
17745
17798
|
const config2 = await loadConfig();
|
|
17746
17799
|
const coderConfig = config2.coders[coder];
|
|
@@ -17749,6 +17802,9 @@ async function getActiveProfileForCoder(coder) {
|
|
|
17749
17802
|
}
|
|
17750
17803
|
return config2.profiles[coderConfig.activeProfile];
|
|
17751
17804
|
}
|
|
17805
|
+
async function setActiveProfile(profileName) {
|
|
17806
|
+
return setActiveProfileForCoder("claude", profileName);
|
|
17807
|
+
}
|
|
17752
17808
|
async function setActiveProfileForCoder(coder, profileName) {
|
|
17753
17809
|
const config2 = await loadConfig();
|
|
17754
17810
|
if (!config2.profiles[profileName]) {
|
|
@@ -17784,7 +17840,7 @@ async function deleteProfile(profileName) {
|
|
|
17784
17840
|
if (!config2.profiles[profileName]) {
|
|
17785
17841
|
throw new Error(`Profile "${profileName}" does not exist`);
|
|
17786
17842
|
}
|
|
17787
|
-
const allCoders =
|
|
17843
|
+
const allCoders = Object.keys(CODER_REGISTRY);
|
|
17788
17844
|
for (const coder of allCoders) {
|
|
17789
17845
|
try {
|
|
17790
17846
|
const adapter = getAdapter(coder);
|
|
@@ -17806,6 +17862,14 @@ async function listProfiles() {
|
|
|
17806
17862
|
const config2 = await loadConfig();
|
|
17807
17863
|
return Object.values(config2.profiles);
|
|
17808
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
|
+
}
|
|
17809
17873
|
var init_manager = __esm(() => {
|
|
17810
17874
|
init_types();
|
|
17811
17875
|
init_constants();
|
|
@@ -19597,7 +19661,7 @@ var require_semver2 = __commonJS((exports, module) => {
|
|
|
19597
19661
|
});
|
|
19598
19662
|
|
|
19599
19663
|
// src/cli/index.ts
|
|
19600
|
-
var
|
|
19664
|
+
var import_picocolors15 = __toESM(require_picocolors(), 1);
|
|
19601
19665
|
|
|
19602
19666
|
// node_modules/@clack/core/dist/index.mjs
|
|
19603
19667
|
var import_sisteransi = __toESM(require_src(), 1);
|
|
@@ -20292,25 +20356,106 @@ var ProfileValidators = {
|
|
|
20292
20356
|
|
|
20293
20357
|
// src/utils/commands.ts
|
|
20294
20358
|
var import_picocolors4 = __toESM(require_picocolors(), 1);
|
|
20295
|
-
|
|
20296
|
-
|
|
20297
|
-
|
|
20298
|
-
|
|
20299
|
-
|
|
20300
|
-
|
|
20301
|
-
|
|
20302
|
-
|
|
20303
|
-
|
|
20304
|
-
|
|
20305
|
-
|
|
20359
|
+
|
|
20360
|
+
// src/constants/commands.ts
|
|
20361
|
+
var COMMAND_ALIASES = {
|
|
20362
|
+
r: "run",
|
|
20363
|
+
ls: "list",
|
|
20364
|
+
sw: "switch",
|
|
20365
|
+
rm: "delete",
|
|
20366
|
+
new: "create",
|
|
20367
|
+
"create-profile": "create",
|
|
20368
|
+
"delete-profile": "delete",
|
|
20369
|
+
"list-profiles": "list",
|
|
20370
|
+
"switch-profile": "switch"
|
|
20371
|
+
};
|
|
20372
|
+
var FLAG_ALIASES = {
|
|
20373
|
+
"-n": "--name",
|
|
20374
|
+
"-p": "--provider",
|
|
20375
|
+
"-k": "--api-key",
|
|
20376
|
+
"-t": "--auth-token",
|
|
20377
|
+
"-u": "--base-url",
|
|
20378
|
+
"-m": "--model",
|
|
20379
|
+
"-a": "--apply",
|
|
20380
|
+
"-q": "--quiet",
|
|
20381
|
+
"-f": "--force",
|
|
20382
|
+
"-h": "--help",
|
|
20383
|
+
"-o": "--output",
|
|
20384
|
+
"-i": "--input",
|
|
20385
|
+
"-y": "--yes",
|
|
20386
|
+
"-v": "--verbose",
|
|
20387
|
+
"-P": "--port"
|
|
20388
|
+
};
|
|
20389
|
+
var VALID_COMMANDS = [
|
|
20390
|
+
"create",
|
|
20391
|
+
"list",
|
|
20392
|
+
"switch",
|
|
20393
|
+
"edit",
|
|
20394
|
+
"apply",
|
|
20395
|
+
"current",
|
|
20396
|
+
"delete",
|
|
20397
|
+
"run",
|
|
20398
|
+
"install",
|
|
20399
|
+
"update-cli",
|
|
20400
|
+
"upgrade"
|
|
20401
|
+
];
|
|
20402
|
+
var GLOBAL_COMMANDS = [
|
|
20403
|
+
"providers",
|
|
20404
|
+
"export",
|
|
20405
|
+
"import",
|
|
20406
|
+
"completion",
|
|
20407
|
+
"help",
|
|
20408
|
+
"version",
|
|
20409
|
+
"ui"
|
|
20410
|
+
];
|
|
20411
|
+
function resolveFlagAlias(flag) {
|
|
20412
|
+
return FLAG_ALIASES[flag] || flag;
|
|
20413
|
+
}
|
|
20414
|
+
|
|
20415
|
+
// src/cli/commands/parsers.ts
|
|
20416
|
+
function parseFlags(args) {
|
|
20417
|
+
const flags = {};
|
|
20418
|
+
let i2 = 0;
|
|
20419
|
+
while (i2 < args.length) {
|
|
20420
|
+
let arg = args[i2];
|
|
20421
|
+
if (!arg.startsWith("-")) {
|
|
20422
|
+
i2++;
|
|
20423
|
+
continue;
|
|
20424
|
+
}
|
|
20425
|
+
if (arg.includes("=")) {
|
|
20426
|
+
const [flag, value] = arg.split("=", 2);
|
|
20427
|
+
const resolvedFlag = resolveFlagAlias(flag).substring(2);
|
|
20428
|
+
flags[resolvedFlag] = value;
|
|
20429
|
+
i2++;
|
|
20430
|
+
continue;
|
|
20431
|
+
}
|
|
20432
|
+
if (arg.startsWith("-") && !arg.startsWith("--") && arg.length > 2) {
|
|
20433
|
+
const chars = arg.substring(1);
|
|
20434
|
+
for (const char of chars) {
|
|
20435
|
+
const resolved = resolveFlagAlias(`-${char}`).substring(2);
|
|
20436
|
+
flags[resolved] = true;
|
|
20306
20437
|
}
|
|
20438
|
+
i2++;
|
|
20439
|
+
continue;
|
|
20440
|
+
}
|
|
20441
|
+
const resolvedArg = resolveFlagAlias(arg);
|
|
20442
|
+
const flagName = resolvedArg.substring(2);
|
|
20443
|
+
const nextArg = args[i2 + 1];
|
|
20444
|
+
if (nextArg && !nextArg.startsWith("-")) {
|
|
20445
|
+
flags[flagName] = nextArg;
|
|
20446
|
+
i2 += 2;
|
|
20447
|
+
} else {
|
|
20448
|
+
flags[flagName] = true;
|
|
20449
|
+
i2++;
|
|
20307
20450
|
}
|
|
20308
20451
|
}
|
|
20309
|
-
return
|
|
20452
|
+
return flags;
|
|
20310
20453
|
}
|
|
20454
|
+
|
|
20455
|
+
// src/utils/commands.ts
|
|
20311
20456
|
async function handleApplyPrompt(options) {
|
|
20312
20457
|
const { args, applyFn, coderDisplayName, coderName } = options;
|
|
20313
|
-
const params =
|
|
20458
|
+
const params = parseFlags(args);
|
|
20314
20459
|
const shouldApply = params.apply;
|
|
20315
20460
|
const noApply = params["no-apply"];
|
|
20316
20461
|
if (shouldApply) {
|
|
@@ -20651,7 +20796,7 @@ async function handleInstallCommand(coderId, coderConfig, args) {
|
|
|
20651
20796
|
process.exit(EXIT_CODES.generalError);
|
|
20652
20797
|
}
|
|
20653
20798
|
let selectedMethod;
|
|
20654
|
-
const params =
|
|
20799
|
+
const params = parseFlags(args);
|
|
20655
20800
|
if (params.method !== undefined) {
|
|
20656
20801
|
const methodIndex = parseInt(params.method, 10) - 1;
|
|
20657
20802
|
if (methodIndex < 0 || methodIndex >= methods.length) {
|
|
@@ -20791,22 +20936,6 @@ async function handleUpdateCommand(coderId, coderConfig, args) {
|
|
|
20791
20936
|
}
|
|
20792
20937
|
console.log();
|
|
20793
20938
|
}
|
|
20794
|
-
function parseArgs2(args) {
|
|
20795
|
-
const parsed = {};
|
|
20796
|
-
for (let i2 = 0;i2 < args.length; i2++) {
|
|
20797
|
-
if (args[i2].startsWith("--")) {
|
|
20798
|
-
const key = args[i2].slice(2);
|
|
20799
|
-
const value = args[i2 + 1];
|
|
20800
|
-
if (!value || value.startsWith("--")) {
|
|
20801
|
-
parsed[key] = true;
|
|
20802
|
-
} else {
|
|
20803
|
-
parsed[key] = value;
|
|
20804
|
-
i2++;
|
|
20805
|
-
}
|
|
20806
|
-
}
|
|
20807
|
-
}
|
|
20808
|
-
return parsed;
|
|
20809
|
-
}
|
|
20810
20939
|
|
|
20811
20940
|
// src/cli/claude.ts
|
|
20812
20941
|
var CODER_NAME = "claude";
|
|
@@ -20863,6 +20992,7 @@ async function handleClaudeCommand(args) {
|
|
|
20863
20992
|
break;
|
|
20864
20993
|
default:
|
|
20865
20994
|
showError(ERRORS.unknownCommand(command), USAGE.checkHelp(CODER_NAME));
|
|
20995
|
+
process.exit(EXIT_CODES.generalError);
|
|
20866
20996
|
}
|
|
20867
20997
|
}
|
|
20868
20998
|
function showClaudeHelp() {
|
|
@@ -20915,24 +21045,8 @@ ${import_picocolors8.default.bold("Examples:")}
|
|
|
20915
21045
|
${import_picocolors8.default.green(`swixter ${CODER_NAME} r --print "What is 2+2?"`)}
|
|
20916
21046
|
`);
|
|
20917
21047
|
}
|
|
20918
|
-
function parseArgs3(args) {
|
|
20919
|
-
const parsed = {};
|
|
20920
|
-
for (let i2 = 0;i2 < args.length; i2++) {
|
|
20921
|
-
if (args[i2].startsWith("--")) {
|
|
20922
|
-
const key = args[i2].slice(2);
|
|
20923
|
-
const value = args[i2 + 1];
|
|
20924
|
-
if (!value || value.startsWith("--")) {
|
|
20925
|
-
parsed[key] = true;
|
|
20926
|
-
} else {
|
|
20927
|
-
parsed[key] = value;
|
|
20928
|
-
i2++;
|
|
20929
|
-
}
|
|
20930
|
-
}
|
|
20931
|
-
}
|
|
20932
|
-
return parsed;
|
|
20933
|
-
}
|
|
20934
21048
|
async function cmdCreate(args) {
|
|
20935
|
-
const params =
|
|
21049
|
+
const params = parseFlags(args);
|
|
20936
21050
|
if (params.quiet) {
|
|
20937
21051
|
await cmdCreateQuiet(params);
|
|
20938
21052
|
return;
|
|
@@ -20952,7 +21066,7 @@ async function cmdCreateInteractive() {
|
|
|
20952
21066
|
});
|
|
20953
21067
|
if (pD(name)) {
|
|
20954
21068
|
xe(ERRORS.cancelled);
|
|
20955
|
-
process.exit(EXIT_CODES.
|
|
21069
|
+
process.exit(EXIT_CODES.cancelled);
|
|
20956
21070
|
}
|
|
20957
21071
|
const providerId = await ve({
|
|
20958
21072
|
message: PROMPTS.selectProvider,
|
|
@@ -20964,7 +21078,7 @@ async function cmdCreateInteractive() {
|
|
|
20964
21078
|
});
|
|
20965
21079
|
if (pD(providerId)) {
|
|
20966
21080
|
xe(ERRORS.cancelled);
|
|
20967
|
-
process.exit(EXIT_CODES.
|
|
21081
|
+
process.exit(EXIT_CODES.cancelled);
|
|
20968
21082
|
}
|
|
20969
21083
|
const preset = presets.find((p2) => p2.id === providerId);
|
|
20970
21084
|
const apiKey = await he({
|
|
@@ -20973,7 +21087,7 @@ async function cmdCreateInteractive() {
|
|
|
20973
21087
|
});
|
|
20974
21088
|
if (pD(apiKey)) {
|
|
20975
21089
|
xe(ERRORS.cancelled);
|
|
20976
|
-
process.exit(EXIT_CODES.
|
|
21090
|
+
process.exit(EXIT_CODES.cancelled);
|
|
20977
21091
|
}
|
|
20978
21092
|
const authToken = await he({
|
|
20979
21093
|
message: "Auth Token (corresponds to ANTHROPIC_AUTH_TOKEN, optional)",
|
|
@@ -20981,7 +21095,7 @@ async function cmdCreateInteractive() {
|
|
|
20981
21095
|
});
|
|
20982
21096
|
if (pD(authToken)) {
|
|
20983
21097
|
xe(ERRORS.cancelled);
|
|
20984
|
-
process.exit(EXIT_CODES.
|
|
21098
|
+
process.exit(EXIT_CODES.cancelled);
|
|
20985
21099
|
}
|
|
20986
21100
|
const customBaseURL = await he({
|
|
20987
21101
|
message: "Base URL (optional, leave empty for default)",
|
|
@@ -20995,58 +21109,56 @@ async function cmdCreateInteractive() {
|
|
|
20995
21109
|
});
|
|
20996
21110
|
if (pD(customBaseURL)) {
|
|
20997
21111
|
xe(ERRORS.cancelled);
|
|
20998
|
-
process.exit(EXIT_CODES.
|
|
21112
|
+
process.exit(EXIT_CODES.cancelled);
|
|
20999
21113
|
}
|
|
21000
21114
|
let models = undefined;
|
|
21001
|
-
|
|
21002
|
-
|
|
21003
|
-
|
|
21004
|
-
|
|
21115
|
+
const configureModels = await ye({
|
|
21116
|
+
message: PROMPTS.configureModels,
|
|
21117
|
+
initialValue: false
|
|
21118
|
+
});
|
|
21119
|
+
if (pD(configureModels)) {
|
|
21120
|
+
xe(ERRORS.cancelled);
|
|
21121
|
+
process.exit(EXIT_CODES.cancelled);
|
|
21122
|
+
}
|
|
21123
|
+
if (configureModels) {
|
|
21124
|
+
const anthropicModel = await he({
|
|
21125
|
+
message: PROMPTS.anthropicModel,
|
|
21126
|
+
placeholder: "claude-3-5-sonnet-20241022"
|
|
21005
21127
|
});
|
|
21006
|
-
if (pD(
|
|
21128
|
+
if (pD(anthropicModel)) {
|
|
21007
21129
|
xe(ERRORS.cancelled);
|
|
21008
|
-
process.exit(EXIT_CODES.
|
|
21130
|
+
process.exit(EXIT_CODES.cancelled);
|
|
21009
21131
|
}
|
|
21010
|
-
|
|
21011
|
-
|
|
21012
|
-
|
|
21013
|
-
|
|
21014
|
-
|
|
21015
|
-
|
|
21016
|
-
|
|
21017
|
-
|
|
21018
|
-
|
|
21019
|
-
|
|
21020
|
-
|
|
21021
|
-
|
|
21022
|
-
|
|
21023
|
-
|
|
21024
|
-
|
|
21025
|
-
|
|
21026
|
-
|
|
21027
|
-
|
|
21028
|
-
|
|
21029
|
-
|
|
21030
|
-
|
|
21031
|
-
|
|
21032
|
-
|
|
21033
|
-
process.exit(EXIT_CODES.userCancelled);
|
|
21034
|
-
}
|
|
21035
|
-
const defaultSonnetModel = await he({
|
|
21036
|
-
message: PROMPTS.defaultSonnetModel,
|
|
21037
|
-
placeholder: "claude-3-5-sonnet-20241022"
|
|
21038
|
-
});
|
|
21039
|
-
if (pD(defaultSonnetModel)) {
|
|
21040
|
-
xe(ERRORS.cancelled);
|
|
21041
|
-
process.exit(EXIT_CODES.userCancelled);
|
|
21042
|
-
}
|
|
21043
|
-
models = {
|
|
21044
|
-
...anthropicModel && { anthropicModel },
|
|
21045
|
-
...defaultHaikuModel && { defaultHaikuModel },
|
|
21046
|
-
...defaultOpusModel && { defaultOpusModel },
|
|
21047
|
-
...defaultSonnetModel && { defaultSonnetModel }
|
|
21048
|
-
};
|
|
21132
|
+
const defaultHaikuModel = await he({
|
|
21133
|
+
message: PROMPTS.defaultHaikuModel,
|
|
21134
|
+
placeholder: "claude-3-5-haiku-20241022"
|
|
21135
|
+
});
|
|
21136
|
+
if (pD(defaultHaikuModel)) {
|
|
21137
|
+
xe(ERRORS.cancelled);
|
|
21138
|
+
process.exit(EXIT_CODES.cancelled);
|
|
21139
|
+
}
|
|
21140
|
+
const defaultOpusModel = await he({
|
|
21141
|
+
message: PROMPTS.defaultOpusModel,
|
|
21142
|
+
placeholder: "claude-3-opus-20240229"
|
|
21143
|
+
});
|
|
21144
|
+
if (pD(defaultOpusModel)) {
|
|
21145
|
+
xe(ERRORS.cancelled);
|
|
21146
|
+
process.exit(EXIT_CODES.cancelled);
|
|
21147
|
+
}
|
|
21148
|
+
const defaultSonnetModel = await he({
|
|
21149
|
+
message: PROMPTS.defaultSonnetModel,
|
|
21150
|
+
placeholder: "claude-3-5-sonnet-20241022"
|
|
21151
|
+
});
|
|
21152
|
+
if (pD(defaultSonnetModel)) {
|
|
21153
|
+
xe(ERRORS.cancelled);
|
|
21154
|
+
process.exit(EXIT_CODES.cancelled);
|
|
21049
21155
|
}
|
|
21156
|
+
models = {
|
|
21157
|
+
...anthropicModel && { anthropicModel },
|
|
21158
|
+
...defaultHaikuModel && { defaultHaikuModel },
|
|
21159
|
+
...defaultOpusModel && { defaultOpusModel },
|
|
21160
|
+
...defaultSonnetModel && { defaultSonnetModel }
|
|
21161
|
+
};
|
|
21050
21162
|
}
|
|
21051
21163
|
const shouldApply = await ye({
|
|
21052
21164
|
message: "Apply this profile to Claude Code now?",
|
|
@@ -21054,7 +21166,7 @@ async function cmdCreateInteractive() {
|
|
|
21054
21166
|
});
|
|
21055
21167
|
if (pD(shouldApply)) {
|
|
21056
21168
|
xe(ERRORS.cancelled);
|
|
21057
|
-
process.exit(EXIT_CODES.
|
|
21169
|
+
process.exit(EXIT_CODES.cancelled);
|
|
21058
21170
|
}
|
|
21059
21171
|
const spinner = Y2();
|
|
21060
21172
|
spinner.start("Creating profile...");
|
|
@@ -21172,7 +21284,7 @@ async function cmdList() {
|
|
|
21172
21284
|
const preset = getPresetById(profile.providerId);
|
|
21173
21285
|
const isCurrent = current?.name === profile.name;
|
|
21174
21286
|
const marker = isCurrent ? import_picocolors8.default.green(MARKERS.active) : import_picocolors8.default.dim(MARKERS.inactive);
|
|
21175
|
-
const baseUrl = profile.baseURL || preset?.baseURL || MISC_DEFAULTS.
|
|
21287
|
+
const baseUrl = profile.baseURL || preset?.baseURL || MISC_DEFAULTS.baseUrlFallback;
|
|
21176
21288
|
console.log(`${marker} ${import_picocolors8.default.cyan(profile.name.padEnd(20))} ${import_picocolors8.default.dim("|")} ${preset?.displayName.padEnd(25)} ${import_picocolors8.default.dim("|")} ${import_picocolors8.default.yellow(baseUrl)}`);
|
|
21177
21289
|
}
|
|
21178
21290
|
console.log();
|
|
@@ -21471,7 +21583,9 @@ async function cmdCurrent() {
|
|
|
21471
21583
|
console.log(` Name: ${import_picocolors8.default.cyan(profile.name)}`);
|
|
21472
21584
|
console.log(` Provider: ${import_picocolors8.default.yellow(preset?.displayName)}`);
|
|
21473
21585
|
console.log(` Base URL: ${import_picocolors8.default.yellow(baseUrl)}`);
|
|
21474
|
-
|
|
21586
|
+
if (profile.apiKey) {
|
|
21587
|
+
console.log(` API Key: ${import_picocolors8.default.dim(profile.apiKey.slice(0, 10) + "...")}`);
|
|
21588
|
+
}
|
|
21475
21589
|
console.log();
|
|
21476
21590
|
}
|
|
21477
21591
|
async function cmdMainMenu() {
|
|
@@ -21496,7 +21610,7 @@ async function cmdMainMenu() {
|
|
|
21496
21610
|
});
|
|
21497
21611
|
if (pD(action)) {
|
|
21498
21612
|
xe(ERRORS.cancelled);
|
|
21499
|
-
process.exit(EXIT_CODES.
|
|
21613
|
+
process.exit(EXIT_CODES.cancelled);
|
|
21500
21614
|
}
|
|
21501
21615
|
console.log();
|
|
21502
21616
|
switch (action) {
|
|
@@ -21532,7 +21646,7 @@ async function cmdMainMenu() {
|
|
|
21532
21646
|
break;
|
|
21533
21647
|
case "exit":
|
|
21534
21648
|
console.log(import_picocolors8.default.green("Goodbye!"));
|
|
21535
|
-
process.exit(EXIT_CODES.
|
|
21649
|
+
process.exit(EXIT_CODES.cancelled);
|
|
21536
21650
|
}
|
|
21537
21651
|
}
|
|
21538
21652
|
async function cmdSwitchInteractive() {
|
|
@@ -21591,7 +21705,7 @@ async function cmdRun(args) {
|
|
|
21591
21705
|
process.exit(EXIT_CODES.generalError);
|
|
21592
21706
|
}
|
|
21593
21707
|
await ensureCliAvailable(CODER_NAME, CODER_CONFIG);
|
|
21594
|
-
const params =
|
|
21708
|
+
const params = parseFlags(args);
|
|
21595
21709
|
let profile = null;
|
|
21596
21710
|
if (params.profile) {
|
|
21597
21711
|
const profiles = await listProfiles();
|
|
@@ -21617,15 +21731,7 @@ async function cmdRun(args) {
|
|
|
21617
21731
|
env[key] = value;
|
|
21618
21732
|
}
|
|
21619
21733
|
}
|
|
21620
|
-
|
|
21621
|
-
env.ANTHROPIC_API_KEY = profile.apiKey;
|
|
21622
|
-
}
|
|
21623
|
-
if (profile.authToken) {
|
|
21624
|
-
env.ANTHROPIC_AUTH_TOKEN = profile.authToken;
|
|
21625
|
-
}
|
|
21626
|
-
if (baseURL) {
|
|
21627
|
-
env.ANTHROPIC_BASE_URL = baseURL;
|
|
21628
|
-
}
|
|
21734
|
+
Object.assign(env, buildProfileEnv(profile, CODER_CONFIG.envVarMapping, baseURL));
|
|
21629
21735
|
const claudeArgs = args.filter((arg, idx) => {
|
|
21630
21736
|
if (arg === "--profile") {
|
|
21631
21737
|
return false;
|
|
@@ -21721,6 +21827,7 @@ async function handleQwenCommand(args) {
|
|
|
21721
21827
|
break;
|
|
21722
21828
|
default:
|
|
21723
21829
|
showError(ERRORS.unknownCommand(command), USAGE.checkHelp(CODER_NAME2));
|
|
21830
|
+
process.exit(EXIT_CODES.generalError);
|
|
21724
21831
|
}
|
|
21725
21832
|
}
|
|
21726
21833
|
function showQwenHelp() {
|
|
@@ -21770,24 +21877,8 @@ ${import_picocolors9.default.bold("Examples:")}
|
|
|
21770
21877
|
${import_picocolors9.default.green('swixter qwen r --prompt "What is 2+2?"')}
|
|
21771
21878
|
`);
|
|
21772
21879
|
}
|
|
21773
|
-
function parseArgs4(args) {
|
|
21774
|
-
const parsed = {};
|
|
21775
|
-
for (let i2 = 0;i2 < args.length; i2++) {
|
|
21776
|
-
if (args[i2].startsWith("--")) {
|
|
21777
|
-
const key = args[i2].slice(2);
|
|
21778
|
-
const value = args[i2 + 1];
|
|
21779
|
-
if (!value || value.startsWith("--")) {
|
|
21780
|
-
parsed[key] = true;
|
|
21781
|
-
} else {
|
|
21782
|
-
parsed[key] = value;
|
|
21783
|
-
i2++;
|
|
21784
|
-
}
|
|
21785
|
-
}
|
|
21786
|
-
}
|
|
21787
|
-
return parsed;
|
|
21788
|
-
}
|
|
21789
21880
|
async function cmdCreate2(args) {
|
|
21790
|
-
const params =
|
|
21881
|
+
const params = parseFlags(args);
|
|
21791
21882
|
if (params.quiet) {
|
|
21792
21883
|
await cmdCreateQuiet2(params);
|
|
21793
21884
|
return;
|
|
@@ -21803,17 +21894,11 @@ async function cmdCreateInteractive2() {
|
|
|
21803
21894
|
const name = await he({
|
|
21804
21895
|
message: "Profile name",
|
|
21805
21896
|
placeholder: "my-qwen-config",
|
|
21806
|
-
validate:
|
|
21807
|
-
if (!value)
|
|
21808
|
-
return "Profile name cannot be empty";
|
|
21809
|
-
if (value.length < 2)
|
|
21810
|
-
return "Profile name must be at least 2 characters";
|
|
21811
|
-
return;
|
|
21812
|
-
}
|
|
21897
|
+
validate: ProfileValidators.name
|
|
21813
21898
|
});
|
|
21814
21899
|
if (pD(name)) {
|
|
21815
21900
|
xe(ERRORS.cancelled);
|
|
21816
|
-
process.exit(EXIT_CODES.
|
|
21901
|
+
process.exit(EXIT_CODES.cancelled);
|
|
21817
21902
|
}
|
|
21818
21903
|
const providerId = await ve({
|
|
21819
21904
|
message: "Select API provider",
|
|
@@ -21825,7 +21910,7 @@ async function cmdCreateInteractive2() {
|
|
|
21825
21910
|
});
|
|
21826
21911
|
if (pD(providerId)) {
|
|
21827
21912
|
xe(ERRORS.cancelled);
|
|
21828
|
-
process.exit(EXIT_CODES.
|
|
21913
|
+
process.exit(EXIT_CODES.cancelled);
|
|
21829
21914
|
}
|
|
21830
21915
|
const preset = presets.find((p2) => p2.id === providerId);
|
|
21831
21916
|
const apiKey = await he({
|
|
@@ -21839,7 +21924,7 @@ async function cmdCreateInteractive2() {
|
|
|
21839
21924
|
});
|
|
21840
21925
|
if (pD(apiKey)) {
|
|
21841
21926
|
xe(ERRORS.cancelled);
|
|
21842
|
-
process.exit(EXIT_CODES.
|
|
21927
|
+
process.exit(EXIT_CODES.cancelled);
|
|
21843
21928
|
}
|
|
21844
21929
|
const customBaseURL = await he({
|
|
21845
21930
|
message: "Base URL (optional, leave empty for default)",
|
|
@@ -21853,7 +21938,7 @@ async function cmdCreateInteractive2() {
|
|
|
21853
21938
|
});
|
|
21854
21939
|
if (pD(customBaseURL)) {
|
|
21855
21940
|
xe(ERRORS.cancelled);
|
|
21856
|
-
process.exit(EXIT_CODES.
|
|
21941
|
+
process.exit(EXIT_CODES.cancelled);
|
|
21857
21942
|
}
|
|
21858
21943
|
const modelName = await he({
|
|
21859
21944
|
message: PROMPTS.enterQwenModel,
|
|
@@ -21866,7 +21951,7 @@ async function cmdCreateInteractive2() {
|
|
|
21866
21951
|
});
|
|
21867
21952
|
if (pD(modelName)) {
|
|
21868
21953
|
xe(ERRORS.cancelled);
|
|
21869
|
-
process.exit(EXIT_CODES.
|
|
21954
|
+
process.exit(EXIT_CODES.cancelled);
|
|
21870
21955
|
}
|
|
21871
21956
|
const shouldApply = await ye({
|
|
21872
21957
|
message: "Apply this profile to Continue now?",
|
|
@@ -21874,7 +21959,7 @@ async function cmdCreateInteractive2() {
|
|
|
21874
21959
|
});
|
|
21875
21960
|
if (pD(shouldApply)) {
|
|
21876
21961
|
xe(ERRORS.cancelled);
|
|
21877
|
-
process.exit(EXIT_CODES.
|
|
21962
|
+
process.exit(EXIT_CODES.cancelled);
|
|
21878
21963
|
}
|
|
21879
21964
|
const spinner = Y2();
|
|
21880
21965
|
spinner.start("Creating profile...");
|
|
@@ -21980,7 +22065,7 @@ async function cmdList2() {
|
|
|
21980
22065
|
const preset = getPresetById(profile.providerId);
|
|
21981
22066
|
const isCurrent = current?.name === profile.name;
|
|
21982
22067
|
const marker = isCurrent ? import_picocolors9.default.green(MARKERS.active) : import_picocolors9.default.dim(MARKERS.inactive);
|
|
21983
|
-
const baseUrl = profile.baseURL || preset?.baseURL || MISC_DEFAULTS.
|
|
22068
|
+
const baseUrl = profile.baseURL || preset?.baseURL || MISC_DEFAULTS.baseUrlFallback;
|
|
21984
22069
|
console.log(`${marker} ${import_picocolors9.default.cyan(profile.name.padEnd(20))} ${import_picocolors9.default.dim("|")} ${preset?.displayName.padEnd(25)} ${import_picocolors9.default.dim("|")} ${import_picocolors9.default.yellow(baseUrl)}`);
|
|
21985
22070
|
}
|
|
21986
22071
|
console.log();
|
|
@@ -22255,7 +22340,7 @@ async function cmdMainMenu2() {
|
|
|
22255
22340
|
});
|
|
22256
22341
|
if (pD(action)) {
|
|
22257
22342
|
xe(ERRORS.cancelled);
|
|
22258
|
-
process.exit(EXIT_CODES.
|
|
22343
|
+
process.exit(EXIT_CODES.cancelled);
|
|
22259
22344
|
}
|
|
22260
22345
|
console.log();
|
|
22261
22346
|
switch (action) {
|
|
@@ -22291,7 +22376,7 @@ async function cmdMainMenu2() {
|
|
|
22291
22376
|
break;
|
|
22292
22377
|
case "exit":
|
|
22293
22378
|
console.log(import_picocolors9.default.green("Goodbye!"));
|
|
22294
|
-
process.exit(EXIT_CODES.
|
|
22379
|
+
process.exit(EXIT_CODES.cancelled);
|
|
22295
22380
|
}
|
|
22296
22381
|
}
|
|
22297
22382
|
async function cmdSwitchInteractive2() {
|
|
@@ -22350,7 +22435,7 @@ async function cmdRun2(args) {
|
|
|
22350
22435
|
process.exit(EXIT_CODES.generalError);
|
|
22351
22436
|
}
|
|
22352
22437
|
await ensureCliAvailable(CODER_NAME2, CODER_CONFIG2);
|
|
22353
|
-
const params =
|
|
22438
|
+
const params = parseFlags(args);
|
|
22354
22439
|
let profile = null;
|
|
22355
22440
|
if (params.profile) {
|
|
22356
22441
|
const profiles = await listProfiles();
|
|
@@ -22376,15 +22461,7 @@ async function cmdRun2(args) {
|
|
|
22376
22461
|
env[key] = value;
|
|
22377
22462
|
}
|
|
22378
22463
|
}
|
|
22379
|
-
|
|
22380
|
-
env.OPENAI_API_KEY = profile.apiKey;
|
|
22381
|
-
}
|
|
22382
|
-
if (baseURL) {
|
|
22383
|
-
env.OPENAI_BASE_URL = baseURL;
|
|
22384
|
-
}
|
|
22385
|
-
if (profile.model || profile.openaiModel) {
|
|
22386
|
-
env.OPENAI_MODEL = profile.model || profile.openaiModel;
|
|
22387
|
-
}
|
|
22464
|
+
Object.assign(env, buildProfileEnv(profile, CODER_CONFIG2.envVarMapping, baseURL));
|
|
22388
22465
|
const qwenArgs = [];
|
|
22389
22466
|
if (profile.apiKey) {
|
|
22390
22467
|
qwenArgs.push("--openai-api-key", profile.apiKey);
|
|
@@ -22492,6 +22569,7 @@ async function handleCodexCommand(args) {
|
|
|
22492
22569
|
break;
|
|
22493
22570
|
default:
|
|
22494
22571
|
showError(ERRORS.unknownCommand(command), USAGE.checkHelp(CODER_NAME3));
|
|
22572
|
+
process.exit(EXIT_CODES.generalError);
|
|
22495
22573
|
}
|
|
22496
22574
|
}
|
|
22497
22575
|
function showCodexHelp() {
|
|
@@ -22547,24 +22625,8 @@ ${import_picocolors10.default.bold("Examples:")}
|
|
|
22547
22625
|
${import_picocolors10.default.green(`swixter ${CODER_NAME3} run --profile my-config`)}
|
|
22548
22626
|
`);
|
|
22549
22627
|
}
|
|
22550
|
-
function parseArgs5(args) {
|
|
22551
|
-
const parsed = {};
|
|
22552
|
-
for (let i2 = 0;i2 < args.length; i2++) {
|
|
22553
|
-
if (args[i2].startsWith("--")) {
|
|
22554
|
-
const key = args[i2].slice(2);
|
|
22555
|
-
const value = args[i2 + 1];
|
|
22556
|
-
if (!value || value.startsWith("--")) {
|
|
22557
|
-
parsed[key] = true;
|
|
22558
|
-
} else {
|
|
22559
|
-
parsed[key] = value;
|
|
22560
|
-
i2++;
|
|
22561
|
-
}
|
|
22562
|
-
}
|
|
22563
|
-
}
|
|
22564
|
-
return parsed;
|
|
22565
|
-
}
|
|
22566
22628
|
async function cmdCreate3(args) {
|
|
22567
|
-
const params =
|
|
22629
|
+
const params = parseFlags(args);
|
|
22568
22630
|
if (params.quiet) {
|
|
22569
22631
|
await cmdCreateQuiet3(params);
|
|
22570
22632
|
return;
|
|
@@ -22584,7 +22646,7 @@ async function cmdCreateInteractive3() {
|
|
|
22584
22646
|
});
|
|
22585
22647
|
if (pD(name)) {
|
|
22586
22648
|
xe(ERRORS.cancelled);
|
|
22587
|
-
process.exit(EXIT_CODES.
|
|
22649
|
+
process.exit(EXIT_CODES.cancelled);
|
|
22588
22650
|
}
|
|
22589
22651
|
const providerId = await ve({
|
|
22590
22652
|
message: PROMPTS.selectProvider,
|
|
@@ -22596,7 +22658,7 @@ async function cmdCreateInteractive3() {
|
|
|
22596
22658
|
});
|
|
22597
22659
|
if (pD(providerId)) {
|
|
22598
22660
|
xe(ERRORS.cancelled);
|
|
22599
|
-
process.exit(EXIT_CODES.
|
|
22661
|
+
process.exit(EXIT_CODES.cancelled);
|
|
22600
22662
|
}
|
|
22601
22663
|
const preset = presets.find((p2) => p2.id === providerId);
|
|
22602
22664
|
const apiKey = await he({
|
|
@@ -22610,7 +22672,7 @@ async function cmdCreateInteractive3() {
|
|
|
22610
22672
|
});
|
|
22611
22673
|
if (pD(apiKey)) {
|
|
22612
22674
|
xe(ERRORS.cancelled);
|
|
22613
|
-
process.exit(EXIT_CODES.
|
|
22675
|
+
process.exit(EXIT_CODES.cancelled);
|
|
22614
22676
|
}
|
|
22615
22677
|
const customBaseURL = await he({
|
|
22616
22678
|
message: "Base URL (optional, leave empty for default)",
|
|
@@ -22624,7 +22686,7 @@ async function cmdCreateInteractive3() {
|
|
|
22624
22686
|
});
|
|
22625
22687
|
if (pD(customBaseURL)) {
|
|
22626
22688
|
xe(ERRORS.cancelled);
|
|
22627
|
-
process.exit(EXIT_CODES.
|
|
22689
|
+
process.exit(EXIT_CODES.cancelled);
|
|
22628
22690
|
}
|
|
22629
22691
|
let modelName = "";
|
|
22630
22692
|
if (preset && preset.defaultModels && preset.defaultModels.length > 0) {
|
|
@@ -22643,7 +22705,7 @@ async function cmdCreateInteractive3() {
|
|
|
22643
22705
|
});
|
|
22644
22706
|
if (pD(modelName)) {
|
|
22645
22707
|
xe(ERRORS.cancelled);
|
|
22646
|
-
process.exit(EXIT_CODES.
|
|
22708
|
+
process.exit(EXIT_CODES.cancelled);
|
|
22647
22709
|
}
|
|
22648
22710
|
if (modelName === "__custom__") {
|
|
22649
22711
|
modelName = await he({
|
|
@@ -22657,7 +22719,7 @@ async function cmdCreateInteractive3() {
|
|
|
22657
22719
|
});
|
|
22658
22720
|
if (pD(modelName)) {
|
|
22659
22721
|
xe(ERRORS.cancelled);
|
|
22660
|
-
process.exit(EXIT_CODES.
|
|
22722
|
+
process.exit(EXIT_CODES.cancelled);
|
|
22661
22723
|
}
|
|
22662
22724
|
}
|
|
22663
22725
|
} else {
|
|
@@ -22670,7 +22732,7 @@ async function cmdCreateInteractive3() {
|
|
|
22670
22732
|
});
|
|
22671
22733
|
if (pD(modelName)) {
|
|
22672
22734
|
xe(ERRORS.cancelled);
|
|
22673
|
-
process.exit(EXIT_CODES.
|
|
22735
|
+
process.exit(EXIT_CODES.cancelled);
|
|
22674
22736
|
}
|
|
22675
22737
|
}
|
|
22676
22738
|
const customEnvKey = await he({
|
|
@@ -22682,7 +22744,7 @@ async function cmdCreateInteractive3() {
|
|
|
22682
22744
|
});
|
|
22683
22745
|
if (pD(customEnvKey)) {
|
|
22684
22746
|
xe(ERRORS.cancelled);
|
|
22685
|
-
process.exit(EXIT_CODES.
|
|
22747
|
+
process.exit(EXIT_CODES.cancelled);
|
|
22686
22748
|
}
|
|
22687
22749
|
const shouldApply = await ye({
|
|
22688
22750
|
message: `Apply this profile to ${CODER_CONFIG3.displayName} now?`,
|
|
@@ -22690,7 +22752,7 @@ async function cmdCreateInteractive3() {
|
|
|
22690
22752
|
});
|
|
22691
22753
|
if (pD(shouldApply)) {
|
|
22692
22754
|
xe(ERRORS.cancelled);
|
|
22693
|
-
process.exit(EXIT_CODES.
|
|
22755
|
+
process.exit(EXIT_CODES.cancelled);
|
|
22694
22756
|
}
|
|
22695
22757
|
const spinner = Y2();
|
|
22696
22758
|
spinner.start("Creating profile...");
|
|
@@ -22814,7 +22876,7 @@ async function cmdList3() {
|
|
|
22814
22876
|
const preset = getPresetById(profile.providerId);
|
|
22815
22877
|
const isCurrent = current?.name === profile.name;
|
|
22816
22878
|
const marker = isCurrent ? import_picocolors10.default.green(MARKERS.active) : import_picocolors10.default.dim(MARKERS.inactive);
|
|
22817
|
-
const baseUrl = profile.baseURL || preset?.baseURL || MISC_DEFAULTS.
|
|
22879
|
+
const baseUrl = profile.baseURL || preset?.baseURL || MISC_DEFAULTS.baseUrlFallback;
|
|
22818
22880
|
console.log(`${marker} ${import_picocolors10.default.cyan(profile.name.padEnd(20))} ${import_picocolors10.default.dim("|")} ${preset?.displayName.padEnd(25)} ${import_picocolors10.default.dim("|")} ${import_picocolors10.default.yellow(baseUrl)}`);
|
|
22819
22881
|
}
|
|
22820
22882
|
console.log();
|
|
@@ -23080,7 +23142,7 @@ async function cmdApply3() {
|
|
|
23080
23142
|
const profile = await getActiveProfileForCoder(CODER_NAME3);
|
|
23081
23143
|
if (!profile) {
|
|
23082
23144
|
console.log(import_picocolors10.default.yellow("No active profile"));
|
|
23083
|
-
console.log(import_picocolors10.default.dim("Run 'swixter
|
|
23145
|
+
console.log(import_picocolors10.default.dim("Run 'swixter codex create' to create a profile"));
|
|
23084
23146
|
return;
|
|
23085
23147
|
}
|
|
23086
23148
|
try {
|
|
@@ -23098,7 +23160,7 @@ async function cmdApply3() {
|
|
|
23098
23160
|
console.log(` Config file: ${import_picocolors10.default.dim(adapter.configPath)}`);
|
|
23099
23161
|
console.log();
|
|
23100
23162
|
if (adapter.name === "codex" && "getEnvExportCommands" in adapter) {
|
|
23101
|
-
const envCommands = adapter.getEnvExportCommands(profile);
|
|
23163
|
+
const envCommands = await adapter.getEnvExportCommands(profile);
|
|
23102
23164
|
if (envCommands.length > 0) {
|
|
23103
23165
|
console.log(import_picocolors10.default.bold("To use this profile, set environment variables:"));
|
|
23104
23166
|
console.log();
|
|
@@ -23136,7 +23198,9 @@ async function cmdCurrent3() {
|
|
|
23136
23198
|
console.log(` Name: ${import_picocolors10.default.cyan(profile.name)}`);
|
|
23137
23199
|
console.log(` Provider: ${import_picocolors10.default.yellow(preset?.displayName)}`);
|
|
23138
23200
|
console.log(` Base URL: ${import_picocolors10.default.yellow(baseUrl)}`);
|
|
23139
|
-
|
|
23201
|
+
if (profile.apiKey) {
|
|
23202
|
+
console.log(` API Key: ${import_picocolors10.default.dim(profile.apiKey.slice(0, 10) + "...")}`);
|
|
23203
|
+
}
|
|
23140
23204
|
console.log();
|
|
23141
23205
|
}
|
|
23142
23206
|
async function cmdMainMenu3() {
|
|
@@ -23161,7 +23225,7 @@ async function cmdMainMenu3() {
|
|
|
23161
23225
|
});
|
|
23162
23226
|
if (pD(action)) {
|
|
23163
23227
|
xe(ERRORS.cancelled);
|
|
23164
|
-
process.exit(EXIT_CODES.
|
|
23228
|
+
process.exit(EXIT_CODES.cancelled);
|
|
23165
23229
|
}
|
|
23166
23230
|
console.log();
|
|
23167
23231
|
switch (action) {
|
|
@@ -23197,7 +23261,7 @@ async function cmdMainMenu3() {
|
|
|
23197
23261
|
break;
|
|
23198
23262
|
case "exit":
|
|
23199
23263
|
console.log(import_picocolors10.default.green("Goodbye!"));
|
|
23200
|
-
process.exit(EXIT_CODES.
|
|
23264
|
+
process.exit(EXIT_CODES.cancelled);
|
|
23201
23265
|
}
|
|
23202
23266
|
}
|
|
23203
23267
|
async function cmdSwitchInteractive3() {
|
|
@@ -23256,7 +23320,7 @@ async function cmdRun3(args) {
|
|
|
23256
23320
|
process.exit(EXIT_CODES.generalError);
|
|
23257
23321
|
}
|
|
23258
23322
|
await ensureCliAvailable(CODER_NAME3, CODER_CONFIG3);
|
|
23259
|
-
const params =
|
|
23323
|
+
const params = parseFlags(args);
|
|
23260
23324
|
let profile = null;
|
|
23261
23325
|
if (params.profile) {
|
|
23262
23326
|
const profiles = await listProfiles();
|
|
@@ -23285,17 +23349,14 @@ async function cmdRun3(args) {
|
|
|
23285
23349
|
env[key] = value;
|
|
23286
23350
|
}
|
|
23287
23351
|
}
|
|
23288
|
-
|
|
23289
|
-
|
|
23290
|
-
}
|
|
23291
|
-
if (profile.model || profile.openaiModel) {
|
|
23292
|
-
env["OPENAI_MODEL"] = profile.model || profile.openaiModel;
|
|
23293
|
-
}
|
|
23352
|
+
Object.assign(env, buildProfileEnv(profile, CODER_CONFIG3.envVarMapping, "", {
|
|
23353
|
+
apiKeyEnvName: envKey
|
|
23354
|
+
}));
|
|
23294
23355
|
const codexArgs = args.filter((arg, idx) => {
|
|
23295
|
-
if (arg === "--profile"
|
|
23356
|
+
if (arg === "--profile") {
|
|
23296
23357
|
return false;
|
|
23297
23358
|
}
|
|
23298
|
-
if (idx > 0 &&
|
|
23359
|
+
if (idx > 0 && args[idx - 1] === "--profile") {
|
|
23299
23360
|
return false;
|
|
23300
23361
|
}
|
|
23301
23362
|
return true;
|
|
@@ -23333,18 +23394,623 @@ async function cmdUpdate3(args) {
|
|
|
23333
23394
|
await handleUpdateCommand(CODER_NAME3, CODER_CONFIG3, args);
|
|
23334
23395
|
}
|
|
23335
23396
|
|
|
23336
|
-
// src/
|
|
23337
|
-
|
|
23338
|
-
|
|
23339
|
-
|
|
23340
|
-
|
|
23341
|
-
import {
|
|
23342
|
-
|
|
23343
|
-
|
|
23344
|
-
|
|
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;
|
|
23345
23420
|
}
|
|
23346
|
-
|
|
23347
|
-
|
|
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
|
+
|
|
24002
|
+
// src/config/export.ts
|
|
24003
|
+
init_types();
|
|
24004
|
+
init_manager();
|
|
24005
|
+
init_constants();
|
|
24006
|
+
import { existsSync as existsSync6 } from "node:fs";
|
|
24007
|
+
import { readFile as readFile6, writeFile as writeFile6 } from "node:fs/promises";
|
|
24008
|
+
function sanitizeApiKey(apiKey) {
|
|
24009
|
+
if (apiKey.length <= API_KEY_FORMAT.sanitizeLength) {
|
|
24010
|
+
return "***";
|
|
24011
|
+
}
|
|
24012
|
+
const start = apiKey.slice(0, API_KEY_FORMAT.prefixLength);
|
|
24013
|
+
const end = apiKey.slice(-API_KEY_FORMAT.suffixLength);
|
|
23348
24014
|
return `${start}***${end}`;
|
|
23349
24015
|
}
|
|
23350
24016
|
async function exportConfig(filePath, options = {}) {
|
|
@@ -23422,90 +24088,266 @@ async function importConfig(filePath, options = {}) {
|
|
|
23422
24088
|
return { imported, skipped, errors: errors3 };
|
|
23423
24089
|
}
|
|
23424
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
|
+
|
|
23425
24305
|
// src/cli/help.ts
|
|
23426
|
-
var
|
|
24306
|
+
var import_picocolors13 = __toESM(require_picocolors(), 1);
|
|
23427
24307
|
function showGlobalHelp() {
|
|
23428
24308
|
console.log(`
|
|
23429
|
-
${
|
|
24309
|
+
${import_picocolors13.default.bold(import_picocolors13.default.cyan("Swixter - AI Coder Configuration Manager"))}
|
|
23430
24310
|
|
|
23431
|
-
${
|
|
23432
|
-
${
|
|
23433
|
-
${
|
|
24311
|
+
${import_picocolors13.default.bold("Usage:")}
|
|
24312
|
+
${import_picocolors13.default.green("swixter <coder> <command> [options]")}
|
|
24313
|
+
${import_picocolors13.default.green("swixter <global-command> [options]")}
|
|
23434
24314
|
|
|
23435
|
-
${
|
|
23436
|
-
${
|
|
23437
|
-
${
|
|
23438
|
-
${
|
|
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")}
|
|
23439
24319
|
|
|
23440
|
-
${
|
|
23441
|
-
${
|
|
23442
|
-
|
|
23443
|
-
|
|
23444
|
-
${import_picocolors11.default.cyan("completion <shell>")} ${import_picocolors11.default.dim("Generate shell auto-completion script")}
|
|
23445
|
-
${import_picocolors11.default.cyan("doctor")} ${import_picocolors11.default.dim("Diagnose system configuration")}
|
|
23446
|
-
${import_picocolors11.default.cyan("help")} ${import_picocolors11.default.dim("Show help information")}
|
|
23447
|
-
${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")}
|
|
23448
24324
|
|
|
23449
|
-
${
|
|
23450
|
-
${
|
|
23451
|
-
${
|
|
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")}
|
|
23452
24332
|
|
|
23453
|
-
|
|
23454
|
-
${
|
|
24333
|
+
${import_picocolors13.default.bold("Examples:")}
|
|
24334
|
+
${import_picocolors13.default.dim("# View Claude Code commands")}
|
|
24335
|
+
${import_picocolors13.default.green("swixter claude --help")}
|
|
23455
24336
|
|
|
23456
|
-
${
|
|
23457
|
-
${
|
|
24337
|
+
${import_picocolors13.default.dim("# Create Claude Code configuration")}
|
|
24338
|
+
${import_picocolors13.default.green("swixter claude create")}
|
|
23458
24339
|
|
|
23459
|
-
${
|
|
23460
|
-
${
|
|
24340
|
+
${import_picocolors13.default.dim("# Launch Web UI")}
|
|
24341
|
+
${import_picocolors13.default.green("swixter ui")}
|
|
23461
24342
|
|
|
23462
|
-
${
|
|
23463
|
-
${
|
|
24343
|
+
${import_picocolors13.default.dim("# View all providers")}
|
|
24344
|
+
${import_picocolors13.default.green("swixter providers")}
|
|
23464
24345
|
|
|
23465
|
-
${
|
|
23466
|
-
`);
|
|
24346
|
+
${import_picocolors13.default.dim("Documentation: https://github.com/dawnswwwww/swixter")}`);
|
|
23467
24347
|
}
|
|
23468
24348
|
|
|
23469
24349
|
// src/cli/completions.ts
|
|
23470
24350
|
init_presets();
|
|
23471
|
-
|
|
23472
|
-
// src/constants/commands.ts
|
|
23473
|
-
var COMMAND_ALIASES = {
|
|
23474
|
-
r: "run",
|
|
23475
|
-
ls: "list",
|
|
23476
|
-
sw: "switch",
|
|
23477
|
-
rm: "delete",
|
|
23478
|
-
new: "create",
|
|
23479
|
-
"create-profile": "create",
|
|
23480
|
-
"delete-profile": "delete",
|
|
23481
|
-
"list-profiles": "list",
|
|
23482
|
-
"switch-profile": "switch"
|
|
23483
|
-
};
|
|
23484
|
-
var VALID_COMMANDS = [
|
|
23485
|
-
"create",
|
|
23486
|
-
"list",
|
|
23487
|
-
"switch",
|
|
23488
|
-
"edit",
|
|
23489
|
-
"apply",
|
|
23490
|
-
"current",
|
|
23491
|
-
"delete",
|
|
23492
|
-
"run",
|
|
23493
|
-
"install",
|
|
23494
|
-
"update-cli",
|
|
23495
|
-
"upgrade",
|
|
23496
|
-
"doctor"
|
|
23497
|
-
];
|
|
23498
|
-
var GLOBAL_COMMANDS = [
|
|
23499
|
-
"providers",
|
|
23500
|
-
"export",
|
|
23501
|
-
"import",
|
|
23502
|
-
"completion",
|
|
23503
|
-
"doctor",
|
|
23504
|
-
"help",
|
|
23505
|
-
"version"
|
|
23506
|
-
];
|
|
23507
|
-
|
|
23508
|
-
// src/cli/completions.ts
|
|
23509
24351
|
function generateBashCompletion() {
|
|
23510
24352
|
const coders2 = ["claude", "qwen", "codex"];
|
|
23511
24353
|
const commands = [...VALID_COMMANDS];
|
|
@@ -23864,37 +24706,37 @@ function generateCompletion(shell) {
|
|
|
23864
24706
|
// src/cli/providers.ts
|
|
23865
24707
|
init_presets();
|
|
23866
24708
|
init_user_providers();
|
|
23867
|
-
var
|
|
24709
|
+
var import_picocolors14 = __toESM(require_picocolors(), 1);
|
|
23868
24710
|
init_formatting();
|
|
23869
|
-
async function
|
|
24711
|
+
async function listProviders2() {
|
|
23870
24712
|
console.log();
|
|
23871
|
-
Ie(
|
|
24713
|
+
Ie(import_picocolors14.default.cyan("Available Providers"));
|
|
23872
24714
|
const allPresets2 = await getAllPresets();
|
|
23873
24715
|
const userProviders = await loadUserProviders();
|
|
23874
24716
|
const userProviderIds = new Set(userProviders.map((p2) => p2.id));
|
|
23875
24717
|
const builtInProviderIds = new Set(getBuiltInPresets().map((p2) => p2.id));
|
|
23876
24718
|
if (allPresets2.length === 0) {
|
|
23877
|
-
console.log(
|
|
24719
|
+
console.log(import_picocolors14.default.yellow("No providers configured"));
|
|
23878
24720
|
console.log();
|
|
23879
24721
|
return;
|
|
23880
24722
|
}
|
|
23881
24723
|
console.log();
|
|
23882
|
-
console.log(
|
|
24724
|
+
console.log(import_picocolors14.default.bold("Built-in Providers:"));
|
|
23883
24725
|
allPresets2.filter((p2) => builtInProviderIds.has(p2.id) && !userProviderIds.has(p2.id)).forEach((preset) => {
|
|
23884
|
-
console.log(` ${
|
|
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")}`);
|
|
23885
24727
|
});
|
|
23886
24728
|
const userOnlyProviders = allPresets2.filter((p2) => userProviderIds.has(p2.id));
|
|
23887
24729
|
if (userOnlyProviders.length > 0) {
|
|
23888
24730
|
console.log();
|
|
23889
|
-
console.log(
|
|
24731
|
+
console.log(import_picocolors14.default.bold("User-defined Providers:"));
|
|
23890
24732
|
userOnlyProviders.forEach((preset) => {
|
|
23891
24733
|
const isOverride = builtInProviderIds.has(preset.id);
|
|
23892
|
-
const marker = isOverride ?
|
|
23893
|
-
console.log(` ${
|
|
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}`);
|
|
23894
24736
|
});
|
|
23895
24737
|
}
|
|
23896
24738
|
console.log();
|
|
23897
|
-
console.log(
|
|
24739
|
+
console.log(import_picocolors14.default.dim(`Total: ${allPresets2.length} providers`));
|
|
23898
24740
|
console.log();
|
|
23899
24741
|
}
|
|
23900
24742
|
async function addProvider(options) {
|
|
@@ -23906,7 +24748,7 @@ async function addProvider(options) {
|
|
|
23906
24748
|
let models = options.models;
|
|
23907
24749
|
if (!options.quiet) {
|
|
23908
24750
|
console.log();
|
|
23909
|
-
Ie(
|
|
24751
|
+
Ie(import_picocolors14.default.cyan("Add Custom Provider"));
|
|
23910
24752
|
const existing = providerId ? await getUserProvider(providerId) : undefined;
|
|
23911
24753
|
providerId = await he({
|
|
23912
24754
|
message: "Provider ID (unique identifier, e.g., 'openrouter', 'deepseek')",
|
|
@@ -24001,7 +24843,7 @@ async function addProvider(options) {
|
|
|
24001
24843
|
try {
|
|
24002
24844
|
await upsertUserProvider(provider);
|
|
24003
24845
|
if (!options.quiet) {
|
|
24004
|
-
Se(
|
|
24846
|
+
Se(import_picocolors14.default.green(`${MARKERS.success} Provider "${providerId}" added successfully!`));
|
|
24005
24847
|
} else {
|
|
24006
24848
|
showSuccess(`Provider "${providerId}" added successfully!`, {
|
|
24007
24849
|
ID: providerId,
|
|
@@ -24020,10 +24862,10 @@ async function removeProvider(providerId, options) {
|
|
|
24020
24862
|
showError("Error: Provider ID is required", "Usage: swixter providers remove <provider-id>");
|
|
24021
24863
|
}
|
|
24022
24864
|
console.log();
|
|
24023
|
-
Ie(
|
|
24865
|
+
Ie(import_picocolors14.default.cyan("Remove Custom Provider"));
|
|
24024
24866
|
const userProviders = await loadUserProviders();
|
|
24025
24867
|
if (userProviders.length === 0) {
|
|
24026
|
-
Se(
|
|
24868
|
+
Se(import_picocolors14.default.yellow("No user-defined providers to remove"));
|
|
24027
24869
|
return;
|
|
24028
24870
|
}
|
|
24029
24871
|
providerId = await ve({
|
|
@@ -24050,7 +24892,7 @@ async function removeProvider(providerId, options) {
|
|
|
24050
24892
|
showError(`Error: Provider "${providerId}" not found`, "Use 'swixter providers list' to see all providers");
|
|
24051
24893
|
}
|
|
24052
24894
|
if (!options?.quiet) {
|
|
24053
|
-
Se(
|
|
24895
|
+
Se(import_picocolors14.default.green(`${MARKERS.success} Provider "${providerId}" removed successfully!`));
|
|
24054
24896
|
} else {
|
|
24055
24897
|
showSuccess(`Provider "${providerId}" removed successfully!`);
|
|
24056
24898
|
}
|
|
@@ -24064,19 +24906,19 @@ async function showProvider(providerId) {
|
|
|
24064
24906
|
showError(`Error: Provider "${providerId}" not found`, "Use 'swixter providers list' to see all providers");
|
|
24065
24907
|
}
|
|
24066
24908
|
console.log();
|
|
24067
|
-
Ie(
|
|
24909
|
+
Ie(import_picocolors14.default.cyan(`Provider: ${provider.displayName}`));
|
|
24068
24910
|
console.log();
|
|
24069
|
-
console.log(` ID: ${
|
|
24070
|
-
console.log(` Name: ${
|
|
24071
|
-
console.log(` Display Name: ${
|
|
24072
|
-
console.log(` Base URL: ${
|
|
24073
|
-
console.log(` Auth Type: ${
|
|
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)}`);
|
|
24074
24916
|
if (provider.defaultModels && provider.defaultModels.length > 0) {
|
|
24075
24917
|
console.log(` Default Models:`);
|
|
24076
|
-
provider.defaultModels.forEach((model) => console.log(` - ${
|
|
24918
|
+
provider.defaultModels.forEach((model) => console.log(` - ${import_picocolors14.default.dim(model)}`));
|
|
24077
24919
|
}
|
|
24078
24920
|
if (provider.docs) {
|
|
24079
|
-
console.log(` Documentation: ${
|
|
24921
|
+
console.log(` Documentation: ${import_picocolors14.default.blue(provider.docs)}`);
|
|
24080
24922
|
}
|
|
24081
24923
|
console.log();
|
|
24082
24924
|
}
|
|
@@ -24086,7 +24928,7 @@ init_meta();
|
|
|
24086
24928
|
init_versions2();
|
|
24087
24929
|
async function cmdProviders(subcommand, args) {
|
|
24088
24930
|
if (!subcommand || subcommand === "list" || subcommand === "ls") {
|
|
24089
|
-
await
|
|
24931
|
+
await listProviders2();
|
|
24090
24932
|
return;
|
|
24091
24933
|
}
|
|
24092
24934
|
if (subcommand === "add" || subcommand === "new") {
|
|
@@ -24128,104 +24970,104 @@ async function cmdProviders(subcommand, args) {
|
|
|
24128
24970
|
await showProvider(providerId);
|
|
24129
24971
|
return;
|
|
24130
24972
|
}
|
|
24131
|
-
console.log(
|
|
24973
|
+
console.log(import_picocolors15.default.red(`Unknown providers subcommand: ${subcommand}`));
|
|
24132
24974
|
console.log();
|
|
24133
|
-
console.log(
|
|
24134
|
-
console.log(` ${
|
|
24135
|
-
console.log(` ${
|
|
24136
|
-
console.log(` ${
|
|
24137
|
-
console.log(` ${
|
|
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`);
|
|
24138
24980
|
console.log();
|
|
24139
24981
|
process.exit(1);
|
|
24140
24982
|
}
|
|
24141
24983
|
async function cmdExport(filePath) {
|
|
24142
24984
|
if (!filePath) {
|
|
24143
|
-
console.log(
|
|
24144
|
-
console.log(
|
|
24985
|
+
console.log(import_picocolors15.default.red("Error: Please specify export file path"));
|
|
24986
|
+
console.log(import_picocolors15.default.dim("Usage: swixter export <file>"));
|
|
24145
24987
|
process.exit(1);
|
|
24146
24988
|
}
|
|
24147
24989
|
try {
|
|
24148
24990
|
await exportConfig(filePath, { sanitizeKeys: false });
|
|
24149
24991
|
console.log();
|
|
24150
|
-
console.log(
|
|
24151
|
-
console.log(` File: ${
|
|
24992
|
+
console.log(import_picocolors15.default.green("✓") + " Export successful!");
|
|
24993
|
+
console.log(` File: ${import_picocolors15.default.cyan(filePath)}`);
|
|
24152
24994
|
console.log();
|
|
24153
24995
|
} catch (error46) {
|
|
24154
24996
|
console.log();
|
|
24155
|
-
console.log(
|
|
24997
|
+
console.log(import_picocolors15.default.red(`✗ Export failed: ${error46}`));
|
|
24156
24998
|
console.log();
|
|
24157
24999
|
process.exit(1);
|
|
24158
25000
|
}
|
|
24159
25001
|
}
|
|
24160
25002
|
async function cmdCompletion(shell) {
|
|
24161
25003
|
if (!shell) {
|
|
24162
|
-
console.log(
|
|
25004
|
+
console.log(import_picocolors15.default.yellow("Please specify shell type"));
|
|
24163
25005
|
console.log();
|
|
24164
|
-
console.log(
|
|
24165
|
-
console.log(` ${
|
|
25006
|
+
console.log(import_picocolors15.default.bold("Usage:"));
|
|
25007
|
+
console.log(` ${import_picocolors15.default.green("swixter completion <shell>")}`);
|
|
24166
25008
|
console.log();
|
|
24167
|
-
console.log(
|
|
24168
|
-
console.log(` ${
|
|
24169
|
-
console.log(` ${
|
|
24170
|
-
console.log(` ${
|
|
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`);
|
|
24171
25013
|
console.log();
|
|
24172
|
-
console.log(
|
|
24173
|
-
console.log(` ${
|
|
24174
|
-
console.log(` ${
|
|
24175
|
-
console.log(` ${
|
|
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")}`);
|
|
24176
25018
|
process.exit(1);
|
|
24177
25019
|
}
|
|
24178
25020
|
const supportedShells = ["bash", "zsh", "fish"];
|
|
24179
25021
|
if (!supportedShells.includes(shell)) {
|
|
24180
|
-
console.log(
|
|
24181
|
-
console.log(
|
|
25022
|
+
console.log(import_picocolors15.default.red(`Unsupported shell: ${shell}`));
|
|
25023
|
+
console.log(import_picocolors15.default.dim(`Supported shells: ${supportedShells.join(", ")}`));
|
|
24182
25024
|
process.exit(1);
|
|
24183
25025
|
}
|
|
24184
25026
|
try {
|
|
24185
25027
|
const script = generateCompletion(shell);
|
|
24186
25028
|
console.log(script);
|
|
24187
25029
|
} catch (error46) {
|
|
24188
|
-
console.error(
|
|
25030
|
+
console.error(import_picocolors15.default.red("Failed to generate completion script:"), error46);
|
|
24189
25031
|
process.exit(1);
|
|
24190
25032
|
}
|
|
24191
25033
|
}
|
|
24192
25034
|
async function cmdImport(filePath) {
|
|
24193
25035
|
if (!filePath) {
|
|
24194
|
-
console.log(
|
|
24195
|
-
console.log(
|
|
25036
|
+
console.log(import_picocolors15.default.red("Error: Please specify import file path"));
|
|
25037
|
+
console.log(import_picocolors15.default.dim("Usage: swixter import <file>"));
|
|
24196
25038
|
process.exit(1);
|
|
24197
25039
|
}
|
|
24198
25040
|
try {
|
|
24199
25041
|
const result = await importConfig(filePath, { overwrite: false });
|
|
24200
25042
|
console.log();
|
|
24201
|
-
console.log(
|
|
25043
|
+
console.log(import_picocolors15.default.green("✓") + " Import completed!");
|
|
24202
25044
|
console.log();
|
|
24203
|
-
console.log(` Successfully imported: ${
|
|
24204
|
-
console.log(` Skipped: ${
|
|
24205
|
-
console.log(` Errors: ${
|
|
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`);
|
|
24206
25048
|
console.log();
|
|
24207
25049
|
if (result.errors.length > 0) {
|
|
24208
|
-
console.log(
|
|
24209
|
-
result.errors.forEach((err) => console.log(
|
|
25050
|
+
console.log(import_picocolors15.default.red("Error details:"));
|
|
25051
|
+
result.errors.forEach((err) => console.log(import_picocolors15.default.red(` - ${err}`)));
|
|
24210
25052
|
console.log();
|
|
24211
25053
|
}
|
|
24212
25054
|
} catch (error46) {
|
|
24213
25055
|
console.log();
|
|
24214
|
-
console.log(
|
|
25056
|
+
console.log(import_picocolors15.default.red(`✗ Import failed: ${error46}`));
|
|
24215
25057
|
console.log();
|
|
24216
25058
|
process.exit(1);
|
|
24217
25059
|
}
|
|
24218
25060
|
}
|
|
24219
25061
|
async function cmdVersion() {
|
|
24220
25062
|
console.log();
|
|
24221
|
-
console.log(
|
|
25063
|
+
console.log(import_picocolors15.default.bold(import_picocolors15.default.cyan("Swixter")) + import_picocolors15.default.dim(" - AI Coder Configuration Manager"));
|
|
24222
25064
|
console.log();
|
|
24223
|
-
console.log(` ${
|
|
24224
|
-
console.log(` ${
|
|
24225
|
-
console.log(` ${
|
|
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)}`);
|
|
24226
25068
|
console.log();
|
|
24227
|
-
console.log(
|
|
24228
|
-
console.log(
|
|
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"));
|
|
24229
25071
|
console.log();
|
|
24230
25072
|
}
|
|
24231
25073
|
async function main() {
|
|
@@ -24236,6 +25078,10 @@ async function main() {
|
|
|
24236
25078
|
showGlobalHelp();
|
|
24237
25079
|
return;
|
|
24238
25080
|
}
|
|
25081
|
+
if (firstArg === "ui") {
|
|
25082
|
+
await handleUiCommand(args.slice(1));
|
|
25083
|
+
return;
|
|
25084
|
+
}
|
|
24239
25085
|
if (firstArg === "claude") {
|
|
24240
25086
|
await handleClaudeCommand(args.slice(1));
|
|
24241
25087
|
return;
|
|
@@ -24268,11 +25114,11 @@ async function main() {
|
|
|
24268
25114
|
await cmdVersion();
|
|
24269
25115
|
return;
|
|
24270
25116
|
}
|
|
24271
|
-
console.log(
|
|
24272
|
-
console.log(
|
|
25117
|
+
console.log(import_picocolors15.default.red(`Unknown command: ${firstArg}`));
|
|
25118
|
+
console.log(import_picocolors15.default.dim("Run 'swixter --help' for help"));
|
|
24273
25119
|
process.exit(1);
|
|
24274
25120
|
} catch (error46) {
|
|
24275
|
-
console.error(
|
|
25121
|
+
console.error(import_picocolors15.default.red("An error occurred:"), error46);
|
|
24276
25122
|
process.exit(1);
|
|
24277
25123
|
}
|
|
24278
25124
|
}
|