swixter 0.0.11 → 0.0.12
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 +248 -136
- package/dist/cli/index.js +806 -128
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -12973,7 +12973,12 @@ var init_types = __esm(() => {
|
|
|
12973
12973
|
docs: exports_external.string().url().optional(),
|
|
12974
12974
|
isChinese: exports_external.boolean().optional(),
|
|
12975
12975
|
wire_api: exports_external.enum(["chat", "responses"]).optional(),
|
|
12976
|
-
env_key: exports_external.string().optional()
|
|
12976
|
+
env_key: exports_external.string().optional(),
|
|
12977
|
+
modelFamilies: exports_external.array(exports_external.object({
|
|
12978
|
+
id: exports_external.string(),
|
|
12979
|
+
name: exports_external.string(),
|
|
12980
|
+
models: exports_external.array(exports_external.string()).min(1)
|
|
12981
|
+
})).optional()
|
|
12977
12982
|
});
|
|
12978
12983
|
ClaudeCodeProfileSchema = exports_external.object({
|
|
12979
12984
|
name: exports_external.string().min(1),
|
|
@@ -13032,7 +13037,8 @@ var init_coders = __esm(() => {
|
|
|
13032
13037
|
dir: ".claude",
|
|
13033
13038
|
file: "settings.json"
|
|
13034
13039
|
},
|
|
13035
|
-
supportsAuthToken: true
|
|
13040
|
+
supportsAuthToken: true,
|
|
13041
|
+
wireApi: "both"
|
|
13036
13042
|
},
|
|
13037
13043
|
qwen: {
|
|
13038
13044
|
id: "qwen",
|
|
@@ -13048,7 +13054,8 @@ var init_coders = __esm(() => {
|
|
|
13048
13054
|
dir: ".continue",
|
|
13049
13055
|
file: "config.yaml"
|
|
13050
13056
|
},
|
|
13051
|
-
supportsAuthToken: false
|
|
13057
|
+
supportsAuthToken: false,
|
|
13058
|
+
wireApi: "chat"
|
|
13052
13059
|
},
|
|
13053
13060
|
codex: {
|
|
13054
13061
|
id: "codex",
|
|
@@ -13064,7 +13071,8 @@ var init_coders = __esm(() => {
|
|
|
13064
13071
|
dir: ".codex",
|
|
13065
13072
|
file: "config.toml"
|
|
13066
13073
|
},
|
|
13067
|
-
supportsAuthToken: false
|
|
13074
|
+
supportsAuthToken: false,
|
|
13075
|
+
wireApi: "chat"
|
|
13068
13076
|
}
|
|
13069
13077
|
};
|
|
13070
13078
|
});
|
|
@@ -13261,7 +13269,7 @@ var CONFIG_VERSION = "2.0.0", EXPORT_VERSION = "1.0.0";
|
|
|
13261
13269
|
var init_versions2 = () => {};
|
|
13262
13270
|
|
|
13263
13271
|
// src/constants/meta.ts
|
|
13264
|
-
var APP_VERSION = "0.0.
|
|
13272
|
+
var APP_VERSION = "0.0.12";
|
|
13265
13273
|
var init_meta = () => {};
|
|
13266
13274
|
|
|
13267
13275
|
// src/constants/install.ts
|
|
@@ -13445,7 +13453,31 @@ var init_user_providers = __esm(() => {
|
|
|
13445
13453
|
// src/providers/presets.ts
|
|
13446
13454
|
var exports_presets = {};
|
|
13447
13455
|
__export(exports_presets, {
|
|
13456
|
+
zhipuGlobalPreset: () => zhipuGlobalPreset,
|
|
13457
|
+
zhipuCnPreset: () => zhipuCnPreset,
|
|
13458
|
+
zeroonePreset: () => zeroonePreset,
|
|
13459
|
+
xiaomiMimoPreset: () => xiaomiMimoPreset,
|
|
13460
|
+
xcodePreset: () => xcodePreset,
|
|
13461
|
+
togetherPreset: () => togetherPreset,
|
|
13462
|
+
stepfunPreset: () => stepfunPreset,
|
|
13463
|
+
sssaiCodePreset: () => sssaiCodePreset,
|
|
13464
|
+
siliconflowGlobalPreset: () => siliconflowGlobalPreset,
|
|
13465
|
+
siliconflowCnPreset: () => siliconflowCnPreset,
|
|
13466
|
+
rightcodePreset: () => rightcodePreset,
|
|
13467
|
+
packycodePreset: () => packycodePreset,
|
|
13468
|
+
openrouterPreset: () => openrouterPreset,
|
|
13448
13469
|
ollamaPreset: () => ollamaPreset,
|
|
13470
|
+
nvidiaPreset: () => nvidiaPreset,
|
|
13471
|
+
novitaPreset: () => novitaPreset,
|
|
13472
|
+
moonshotPreset: () => moonshotPreset,
|
|
13473
|
+
modelscopePreset: () => modelscopePreset,
|
|
13474
|
+
minimaxGlobalPreset: () => minimaxGlobalPreset,
|
|
13475
|
+
minimaxCnPreset: () => minimaxCnPreset,
|
|
13476
|
+
micuPreset: () => micuPreset,
|
|
13477
|
+
longcatPreset: () => longcatPreset,
|
|
13478
|
+
kimiForCodingPreset: () => kimiForCodingPreset,
|
|
13479
|
+
groqPreset: () => groqPreset,
|
|
13480
|
+
githubCopilotPreset: () => githubCopilotPreset,
|
|
13449
13481
|
getStandardPresets: () => getStandardPresets,
|
|
13450
13482
|
getProvidersByWireApi: () => getProvidersByWireApi,
|
|
13451
13483
|
getPresetByIdAsync: () => getPresetByIdAsync,
|
|
@@ -13454,10 +13486,25 @@ __export(exports_presets, {
|
|
|
13454
13486
|
getBuiltInPresets: () => getBuiltInPresets,
|
|
13455
13487
|
getBuiltInPresetById: () => getBuiltInPresetById,
|
|
13456
13488
|
getAllPresets: () => getAllPresets,
|
|
13489
|
+
fireworksPreset: () => fireworksPreset,
|
|
13490
|
+
doubaoSeedPreset: () => doubaoSeedPreset,
|
|
13491
|
+
dmxapiPreset: () => dmxapiPreset,
|
|
13492
|
+
deepseekPreset: () => deepseekPreset,
|
|
13493
|
+
dashscopePreset: () => dashscopePreset,
|
|
13457
13494
|
customPreset: () => customPreset,
|
|
13495
|
+
cubencePreset: () => cubencePreset,
|
|
13496
|
+
ctokPreset: () => ctokPreset,
|
|
13497
|
+
crazyrouterPreset: () => crazyrouterPreset,
|
|
13498
|
+
compsharePreset: () => compsharePreset,
|
|
13458
13499
|
builtInPresets: () => builtInPresets,
|
|
13500
|
+
bailingPreset: () => bailingPreset,
|
|
13501
|
+
bailianForCodingPreset: () => bailianForCodingPreset,
|
|
13459
13502
|
anthropicPreset: () => anthropicPreset,
|
|
13460
|
-
allPresets: () => allPresets
|
|
13503
|
+
allPresets: () => allPresets,
|
|
13504
|
+
aihubmixPreset: () => aihubmixPreset,
|
|
13505
|
+
aigocodePreset: () => aigocodePreset,
|
|
13506
|
+
aicodingPreset: () => aicodingPreset,
|
|
13507
|
+
aicodemirrorPreset: () => aicodemirrorPreset
|
|
13461
13508
|
});
|
|
13462
13509
|
async function getAllPresets() {
|
|
13463
13510
|
const userProviders = await loadUserProviders();
|
|
@@ -13499,7 +13546,7 @@ function getBuiltInPresets() {
|
|
|
13499
13546
|
function getBuiltInPresetById(id) {
|
|
13500
13547
|
return getPresetById(id);
|
|
13501
13548
|
}
|
|
13502
|
-
var anthropicPreset, ollamaPreset, customPreset, builtInPresets, allPresets;
|
|
13549
|
+
var anthropicPreset, ollamaPreset, groqPreset, deepseekPreset, moonshotPreset, togetherPreset, fireworksPreset, zeroonePreset, minimaxCnPreset, minimaxGlobalPreset, zhipuCnPreset, zhipuGlobalPreset, dashscopePreset, customPreset, stepfunPreset, modelscopePreset, longcatPreset, bailingPreset, siliconflowCnPreset, siliconflowGlobalPreset, dmxapiPreset, packycodePreset, cubencePreset, aigocodePreset, rightcodePreset, aicodemirrorPreset, aicodingPreset, crazyrouterPreset, sssaiCodePreset, compsharePreset, micuPreset, xcodePreset, ctokPreset, openrouterPreset, novitaPreset, githubCopilotPreset, nvidiaPreset, xiaomiMimoPreset, bailianForCodingPreset, kimiForCodingPreset, doubaoSeedPreset, aihubmixPreset, builtInPresets, allPresets;
|
|
13503
13550
|
var init_presets = __esm(() => {
|
|
13504
13551
|
init_user_providers();
|
|
13505
13552
|
anthropicPreset = {
|
|
@@ -13507,11 +13554,30 @@ var init_presets = __esm(() => {
|
|
|
13507
13554
|
name: "Anthropic",
|
|
13508
13555
|
displayName: "Anthropic (Official)",
|
|
13509
13556
|
baseURL: "https://api.anthropic.com",
|
|
13510
|
-
defaultModels: [
|
|
13511
|
-
|
|
13512
|
-
|
|
13513
|
-
|
|
13514
|
-
|
|
13557
|
+
defaultModels: [],
|
|
13558
|
+
modelFamilies: [
|
|
13559
|
+
{
|
|
13560
|
+
id: "sonnet",
|
|
13561
|
+
name: "Sonnet",
|
|
13562
|
+
models: [
|
|
13563
|
+
"claude-sonnet-4-20250514",
|
|
13564
|
+
"claude-3-5-sonnet-20241022"
|
|
13565
|
+
]
|
|
13566
|
+
},
|
|
13567
|
+
{
|
|
13568
|
+
id: "haiku",
|
|
13569
|
+
name: "Haiku",
|
|
13570
|
+
models: [
|
|
13571
|
+
"claude-3-5-haiku-20241022"
|
|
13572
|
+
]
|
|
13573
|
+
},
|
|
13574
|
+
{
|
|
13575
|
+
id: "opus",
|
|
13576
|
+
name: "Opus",
|
|
13577
|
+
models: [
|
|
13578
|
+
"claude-3-opus-20240229"
|
|
13579
|
+
]
|
|
13580
|
+
}
|
|
13515
13581
|
],
|
|
13516
13582
|
authType: "api-key",
|
|
13517
13583
|
headers: {
|
|
@@ -13538,6 +13604,160 @@ var init_presets = __esm(() => {
|
|
|
13538
13604
|
wire_api: "chat",
|
|
13539
13605
|
env_key: "OLLAMA_API_KEY"
|
|
13540
13606
|
};
|
|
13607
|
+
groqPreset = {
|
|
13608
|
+
id: "groq",
|
|
13609
|
+
name: "Groq",
|
|
13610
|
+
displayName: "Groq",
|
|
13611
|
+
baseURL: "https://api.groq.com/openai/v1",
|
|
13612
|
+
defaultModels: [
|
|
13613
|
+
"llama-3.3-70b-versatile",
|
|
13614
|
+
"llama-3.1-8b-instant",
|
|
13615
|
+
"gemma2-9b-it"
|
|
13616
|
+
],
|
|
13617
|
+
authType: "api-key",
|
|
13618
|
+
docs: "https://console.groq.com/docs",
|
|
13619
|
+
wire_api: "chat",
|
|
13620
|
+
env_key: "GROQ_API_KEY"
|
|
13621
|
+
};
|
|
13622
|
+
deepseekPreset = {
|
|
13623
|
+
id: "deepseek",
|
|
13624
|
+
name: "DeepSeek",
|
|
13625
|
+
displayName: "DeepSeek",
|
|
13626
|
+
baseURL: "https://api.deepseek.com",
|
|
13627
|
+
defaultModels: [
|
|
13628
|
+
"deepseek-chat",
|
|
13629
|
+
"deepseek-coder"
|
|
13630
|
+
],
|
|
13631
|
+
authType: "api-key",
|
|
13632
|
+
docs: "https://platform.deepseek.com/",
|
|
13633
|
+
wire_api: "chat",
|
|
13634
|
+
env_key: "DEEPSEEK_API_KEY"
|
|
13635
|
+
};
|
|
13636
|
+
moonshotPreset = {
|
|
13637
|
+
id: "moonshot",
|
|
13638
|
+
name: "Moonshot",
|
|
13639
|
+
displayName: "Moonshot (Kimi)",
|
|
13640
|
+
baseURL: "https://api.moonshot.cn/v1",
|
|
13641
|
+
defaultModels: [
|
|
13642
|
+
"moonshot-v1-128k",
|
|
13643
|
+
"moonshot-v1-32k",
|
|
13644
|
+
"moonshot-v1-8k"
|
|
13645
|
+
],
|
|
13646
|
+
authType: "api-key",
|
|
13647
|
+
docs: "https://platform.moonshot.cn/",
|
|
13648
|
+
wire_api: "chat",
|
|
13649
|
+
env_key: "MOONSHOT_API_KEY"
|
|
13650
|
+
};
|
|
13651
|
+
togetherPreset = {
|
|
13652
|
+
id: "together",
|
|
13653
|
+
name: "Together AI",
|
|
13654
|
+
displayName: "Together AI",
|
|
13655
|
+
baseURL: "https://api.together.xyz",
|
|
13656
|
+
defaultModels: [],
|
|
13657
|
+
authType: "api-key",
|
|
13658
|
+
docs: "https://docs.together.ai/",
|
|
13659
|
+
wire_api: "chat",
|
|
13660
|
+
env_key: "TOGETHER_API_KEY"
|
|
13661
|
+
};
|
|
13662
|
+
fireworksPreset = {
|
|
13663
|
+
id: "fireworks",
|
|
13664
|
+
name: "Fireworks AI",
|
|
13665
|
+
displayName: "Fireworks AI",
|
|
13666
|
+
baseURL: "https://api.fireworks.ai/v1",
|
|
13667
|
+
defaultModels: [
|
|
13668
|
+
"qwen2.5-72b-instruct",
|
|
13669
|
+
"accounts/fireworks/models/llama-3.3-70b-instruct"
|
|
13670
|
+
],
|
|
13671
|
+
authType: "api-key",
|
|
13672
|
+
docs: "https://docs.fireworks.ai/",
|
|
13673
|
+
wire_api: "chat",
|
|
13674
|
+
env_key: "FIREWORKS_API_KEY"
|
|
13675
|
+
};
|
|
13676
|
+
zeroonePreset = {
|
|
13677
|
+
id: "zeroone",
|
|
13678
|
+
name: "01.ai",
|
|
13679
|
+
displayName: "01.ai (零一万物)",
|
|
13680
|
+
baseURL: "https://api.01.ai/v1",
|
|
13681
|
+
defaultModels: [
|
|
13682
|
+
"yi-large",
|
|
13683
|
+
"yi-large-turbo"
|
|
13684
|
+
],
|
|
13685
|
+
authType: "api-key",
|
|
13686
|
+
docs: "https://platform.01.ai/",
|
|
13687
|
+
wire_api: "chat",
|
|
13688
|
+
env_key: "ZEROONE_API_KEY"
|
|
13689
|
+
};
|
|
13690
|
+
minimaxCnPreset = {
|
|
13691
|
+
id: "minimax-cn",
|
|
13692
|
+
name: "MiniMax CN",
|
|
13693
|
+
displayName: "MiniMax (CN)",
|
|
13694
|
+
baseURL: "https://api.minimaxi.com/anthropic",
|
|
13695
|
+
defaultModels: [
|
|
13696
|
+
"MiniMax-M2.7"
|
|
13697
|
+
],
|
|
13698
|
+
authType: "api-key",
|
|
13699
|
+
docs: "https://platform.minimaxi.com/",
|
|
13700
|
+
wire_api: "responses",
|
|
13701
|
+
env_key: "ANTHROPIC_API_KEY",
|
|
13702
|
+
isChinese: true
|
|
13703
|
+
};
|
|
13704
|
+
minimaxGlobalPreset = {
|
|
13705
|
+
id: "minimax-global",
|
|
13706
|
+
name: "MiniMax Global",
|
|
13707
|
+
displayName: "MiniMax (Global)",
|
|
13708
|
+
baseURL: "https://api.minimax.io/anthropic",
|
|
13709
|
+
defaultModels: [
|
|
13710
|
+
"MiniMax-M2.7"
|
|
13711
|
+
],
|
|
13712
|
+
authType: "api-key",
|
|
13713
|
+
docs: "https://platform.minimax.io/",
|
|
13714
|
+
wire_api: "responses",
|
|
13715
|
+
env_key: "ANTHROPIC_API_KEY"
|
|
13716
|
+
};
|
|
13717
|
+
zhipuCnPreset = {
|
|
13718
|
+
id: "zhipu-cn",
|
|
13719
|
+
name: "Zhipu AI CN",
|
|
13720
|
+
displayName: "Zhipu AI (CN)",
|
|
13721
|
+
baseURL: "https://open.bigmodel.cn/api/anthropic",
|
|
13722
|
+
defaultModels: [
|
|
13723
|
+
"glm-4",
|
|
13724
|
+
"glm-4-flash"
|
|
13725
|
+
],
|
|
13726
|
+
authType: "api-key",
|
|
13727
|
+
docs: "https://open.bigmodel.cn/",
|
|
13728
|
+
wire_api: "responses",
|
|
13729
|
+
env_key: "ANTHROPIC_API_KEY",
|
|
13730
|
+
isChinese: true
|
|
13731
|
+
};
|
|
13732
|
+
zhipuGlobalPreset = {
|
|
13733
|
+
id: "zhipu-global",
|
|
13734
|
+
name: "Zhipu AI Global",
|
|
13735
|
+
displayName: "Zhipu AI (Global)",
|
|
13736
|
+
baseURL: "https://api.z.ai/api/anthropic",
|
|
13737
|
+
defaultModels: [
|
|
13738
|
+
"glm-4",
|
|
13739
|
+
"glm-4-flash"
|
|
13740
|
+
],
|
|
13741
|
+
authType: "api-key",
|
|
13742
|
+
docs: "https://docs.z.ai/",
|
|
13743
|
+
wire_api: "responses",
|
|
13744
|
+
env_key: "ANTHROPIC_AUTH_TOKEN"
|
|
13745
|
+
};
|
|
13746
|
+
dashscopePreset = {
|
|
13747
|
+
id: "dashscope",
|
|
13748
|
+
name: "Dashscope",
|
|
13749
|
+
displayName: "阿里云 Dashscope",
|
|
13750
|
+
baseURL: "https://coding.dashscope.aliyuncs.com/v1",
|
|
13751
|
+
defaultModels: [
|
|
13752
|
+
"qwen-coder-plus",
|
|
13753
|
+
"qwen-plus"
|
|
13754
|
+
],
|
|
13755
|
+
authType: "api-key",
|
|
13756
|
+
docs: "https://bailian.console.aliyun.com/",
|
|
13757
|
+
wire_api: "chat",
|
|
13758
|
+
env_key: "DASHSCOPE_API_KEY",
|
|
13759
|
+
isChinese: true
|
|
13760
|
+
};
|
|
13541
13761
|
customPreset = {
|
|
13542
13762
|
id: "custom",
|
|
13543
13763
|
name: "Custom",
|
|
@@ -13549,10 +13769,381 @@ var init_presets = __esm(() => {
|
|
|
13549
13769
|
wire_api: "chat",
|
|
13550
13770
|
env_key: "OPENAI_API_KEY"
|
|
13551
13771
|
};
|
|
13772
|
+
stepfunPreset = {
|
|
13773
|
+
id: "stepfun",
|
|
13774
|
+
name: "StepFun",
|
|
13775
|
+
displayName: "StepFun",
|
|
13776
|
+
baseURL: "https://api.stepfun.ai/v1",
|
|
13777
|
+
defaultModels: ["step-3.5-flash"],
|
|
13778
|
+
authType: "api-key",
|
|
13779
|
+
docs: "https://platform.stepfun.ai",
|
|
13780
|
+
wire_api: "chat",
|
|
13781
|
+
env_key: "ANTHROPIC_AUTH_TOKEN",
|
|
13782
|
+
isChinese: true
|
|
13783
|
+
};
|
|
13784
|
+
modelscopePreset = {
|
|
13785
|
+
id: "modelscope",
|
|
13786
|
+
name: "ModelScope",
|
|
13787
|
+
displayName: "ModelScope (魔搭)",
|
|
13788
|
+
baseURL: "https://api-inference.modelscope.cn",
|
|
13789
|
+
defaultModels: ["ZhipuAI/GLM-5"],
|
|
13790
|
+
authType: "api-key",
|
|
13791
|
+
docs: "https://modelscope.cn",
|
|
13792
|
+
wire_api: "responses",
|
|
13793
|
+
env_key: "ANTHROPIC_AUTH_TOKEN",
|
|
13794
|
+
isChinese: true
|
|
13795
|
+
};
|
|
13796
|
+
longcatPreset = {
|
|
13797
|
+
id: "longcat",
|
|
13798
|
+
name: "Longcat",
|
|
13799
|
+
displayName: "Longcat",
|
|
13800
|
+
baseURL: "https://api.longcat.chat/anthropic",
|
|
13801
|
+
defaultModels: ["LongCat-Flash-Chat"],
|
|
13802
|
+
authType: "api-key",
|
|
13803
|
+
docs: "https://longcat.chat/platform",
|
|
13804
|
+
wire_api: "responses",
|
|
13805
|
+
env_key: "ANTHROPIC_AUTH_TOKEN",
|
|
13806
|
+
isChinese: true
|
|
13807
|
+
};
|
|
13808
|
+
bailingPreset = {
|
|
13809
|
+
id: "bailing",
|
|
13810
|
+
name: "BaiLing",
|
|
13811
|
+
displayName: "BaiLing (灵码)",
|
|
13812
|
+
baseURL: "https://api.tbox.cn/api/anthropic",
|
|
13813
|
+
defaultModels: ["Ling-2.5-1T"],
|
|
13814
|
+
authType: "api-key",
|
|
13815
|
+
docs: "https://alipaytbox.yuque.com/sxs0ba/ling/get_started",
|
|
13816
|
+
wire_api: "responses",
|
|
13817
|
+
env_key: "ANTHROPIC_AUTH_TOKEN",
|
|
13818
|
+
isChinese: true
|
|
13819
|
+
};
|
|
13820
|
+
siliconflowCnPreset = {
|
|
13821
|
+
id: "siliconflow-cn",
|
|
13822
|
+
name: "SiliconFlow CN",
|
|
13823
|
+
displayName: "SiliconFlow (CN)",
|
|
13824
|
+
baseURL: "https://api.siliconflow.cn",
|
|
13825
|
+
defaultModels: ["Pro/MiniMaxAI/MiniMax-M2.7"],
|
|
13826
|
+
authType: "api-key",
|
|
13827
|
+
docs: "https://siliconflow.cn",
|
|
13828
|
+
wire_api: "responses",
|
|
13829
|
+
env_key: "ANTHROPIC_AUTH_TOKEN",
|
|
13830
|
+
isChinese: true
|
|
13831
|
+
};
|
|
13832
|
+
siliconflowGlobalPreset = {
|
|
13833
|
+
id: "siliconflow-global",
|
|
13834
|
+
name: "SiliconFlow Global",
|
|
13835
|
+
displayName: "SiliconFlow (Global)",
|
|
13836
|
+
baseURL: "https://api.siliconflow.com",
|
|
13837
|
+
defaultModels: ["MiniMaxAI/MiniMax-M2.7"],
|
|
13838
|
+
authType: "api-key",
|
|
13839
|
+
docs: "https://siliconflow.com",
|
|
13840
|
+
wire_api: "responses",
|
|
13841
|
+
env_key: "ANTHROPIC_AUTH_TOKEN"
|
|
13842
|
+
};
|
|
13843
|
+
dmxapiPreset = {
|
|
13844
|
+
id: "dmxapi",
|
|
13845
|
+
name: "DMXAPI",
|
|
13846
|
+
displayName: "DMXAPI",
|
|
13847
|
+
baseURL: "https://www.dmxapi.cn",
|
|
13848
|
+
defaultModels: [],
|
|
13849
|
+
authType: "api-key",
|
|
13850
|
+
docs: "https://www.dmxapi.cn",
|
|
13851
|
+
wire_api: "responses",
|
|
13852
|
+
env_key: "ANTHROPIC_AUTH_TOKEN",
|
|
13853
|
+
isChinese: true
|
|
13854
|
+
};
|
|
13855
|
+
packycodePreset = {
|
|
13856
|
+
id: "packycode",
|
|
13857
|
+
name: "PackyCode",
|
|
13858
|
+
displayName: "PackyCode",
|
|
13859
|
+
baseURL: "https://www.packyapi.com",
|
|
13860
|
+
defaultModels: [],
|
|
13861
|
+
authType: "api-key",
|
|
13862
|
+
docs: "https://www.packyapi.com",
|
|
13863
|
+
wire_api: "responses",
|
|
13864
|
+
env_key: "ANTHROPIC_AUTH_TOKEN",
|
|
13865
|
+
isChinese: true
|
|
13866
|
+
};
|
|
13867
|
+
cubencePreset = {
|
|
13868
|
+
id: "cubence",
|
|
13869
|
+
name: "Cubence",
|
|
13870
|
+
displayName: "Cubence",
|
|
13871
|
+
baseURL: "https://api.cubence.com",
|
|
13872
|
+
defaultModels: [],
|
|
13873
|
+
authType: "api-key",
|
|
13874
|
+
docs: "https://cubence.com",
|
|
13875
|
+
wire_api: "responses",
|
|
13876
|
+
env_key: "ANTHROPIC_AUTH_TOKEN",
|
|
13877
|
+
isChinese: true
|
|
13878
|
+
};
|
|
13879
|
+
aigocodePreset = {
|
|
13880
|
+
id: "aigocode",
|
|
13881
|
+
name: "AIGoCode",
|
|
13882
|
+
displayName: "AIGoCode",
|
|
13883
|
+
baseURL: "https://api.aigocode.com",
|
|
13884
|
+
defaultModels: [],
|
|
13885
|
+
authType: "api-key",
|
|
13886
|
+
docs: "https://aigocode.com",
|
|
13887
|
+
wire_api: "responses",
|
|
13888
|
+
env_key: "ANTHROPIC_AUTH_TOKEN",
|
|
13889
|
+
isChinese: true
|
|
13890
|
+
};
|
|
13891
|
+
rightcodePreset = {
|
|
13892
|
+
id: "rightcode",
|
|
13893
|
+
name: "RightCode",
|
|
13894
|
+
displayName: "RightCode",
|
|
13895
|
+
baseURL: "https://www.right.codes/claude",
|
|
13896
|
+
defaultModels: [],
|
|
13897
|
+
authType: "api-key",
|
|
13898
|
+
docs: "https://www.right.codes",
|
|
13899
|
+
wire_api: "responses",
|
|
13900
|
+
env_key: "ANTHROPIC_AUTH_TOKEN",
|
|
13901
|
+
isChinese: true
|
|
13902
|
+
};
|
|
13903
|
+
aicodemirrorPreset = {
|
|
13904
|
+
id: "aicodemirror",
|
|
13905
|
+
name: "AICodeMirror",
|
|
13906
|
+
displayName: "AICodeMirror",
|
|
13907
|
+
baseURL: "https://api.aicodemirror.com/api/claudecode",
|
|
13908
|
+
defaultModels: [],
|
|
13909
|
+
authType: "api-key",
|
|
13910
|
+
docs: "https://www.aicodemirror.com",
|
|
13911
|
+
wire_api: "responses",
|
|
13912
|
+
env_key: "ANTHROPIC_AUTH_TOKEN",
|
|
13913
|
+
isChinese: true
|
|
13914
|
+
};
|
|
13915
|
+
aicodingPreset = {
|
|
13916
|
+
id: "aicoding",
|
|
13917
|
+
name: "AICoding",
|
|
13918
|
+
displayName: "AICoding",
|
|
13919
|
+
baseURL: "https://api.aicoding.sh",
|
|
13920
|
+
defaultModels: [],
|
|
13921
|
+
authType: "api-key",
|
|
13922
|
+
docs: "https://aicoding.sh",
|
|
13923
|
+
wire_api: "responses",
|
|
13924
|
+
env_key: "ANTHROPIC_AUTH_TOKEN",
|
|
13925
|
+
isChinese: true
|
|
13926
|
+
};
|
|
13927
|
+
crazyrouterPreset = {
|
|
13928
|
+
id: "crazyrouter",
|
|
13929
|
+
name: "CrazyRouter",
|
|
13930
|
+
displayName: "CrazyRouter",
|
|
13931
|
+
baseURL: "https://crazyrouter.com",
|
|
13932
|
+
defaultModels: [],
|
|
13933
|
+
authType: "api-key",
|
|
13934
|
+
docs: "https://www.crazyrouter.com",
|
|
13935
|
+
wire_api: "responses",
|
|
13936
|
+
env_key: "ANTHROPIC_AUTH_TOKEN",
|
|
13937
|
+
isChinese: true
|
|
13938
|
+
};
|
|
13939
|
+
sssaiCodePreset = {
|
|
13940
|
+
id: "sssaicode",
|
|
13941
|
+
name: "SSSAiCode",
|
|
13942
|
+
displayName: "SSSAiCode",
|
|
13943
|
+
baseURL: "https://node-hk.sssaicode.com/api",
|
|
13944
|
+
defaultModels: [],
|
|
13945
|
+
authType: "api-key",
|
|
13946
|
+
docs: "https://www.sssaicode.com",
|
|
13947
|
+
wire_api: "responses",
|
|
13948
|
+
env_key: "ANTHROPIC_AUTH_TOKEN",
|
|
13949
|
+
isChinese: true
|
|
13950
|
+
};
|
|
13951
|
+
compsharePreset = {
|
|
13952
|
+
id: "compshare",
|
|
13953
|
+
name: "Compshare",
|
|
13954
|
+
displayName: "Compshare (云算力)",
|
|
13955
|
+
baseURL: "https://api.modelverse.cn",
|
|
13956
|
+
defaultModels: [],
|
|
13957
|
+
authType: "api-key",
|
|
13958
|
+
docs: "https://www.compshare.cn",
|
|
13959
|
+
wire_api: "responses",
|
|
13960
|
+
env_key: "ANTHROPIC_AUTH_TOKEN",
|
|
13961
|
+
isChinese: true
|
|
13962
|
+
};
|
|
13963
|
+
micuPreset = {
|
|
13964
|
+
id: "micu",
|
|
13965
|
+
name: "Micu",
|
|
13966
|
+
displayName: "Micu",
|
|
13967
|
+
baseURL: "https://www.openclaudecode.cn",
|
|
13968
|
+
defaultModels: [],
|
|
13969
|
+
authType: "api-key",
|
|
13970
|
+
docs: "https://www.openclaudecode.cn",
|
|
13971
|
+
wire_api: "responses",
|
|
13972
|
+
env_key: "ANTHROPIC_AUTH_TOKEN",
|
|
13973
|
+
isChinese: true
|
|
13974
|
+
};
|
|
13975
|
+
xcodePreset = {
|
|
13976
|
+
id: "xcode",
|
|
13977
|
+
name: "X-Code API",
|
|
13978
|
+
displayName: "X-Code API",
|
|
13979
|
+
baseURL: "https://x-code.cc",
|
|
13980
|
+
defaultModels: [],
|
|
13981
|
+
authType: "api-key",
|
|
13982
|
+
docs: "https://x-code.cc",
|
|
13983
|
+
wire_api: "responses",
|
|
13984
|
+
env_key: "ANTHROPIC_AUTH_TOKEN",
|
|
13985
|
+
isChinese: true
|
|
13986
|
+
};
|
|
13987
|
+
ctokPreset = {
|
|
13988
|
+
id: "ctok",
|
|
13989
|
+
name: "CTok.ai",
|
|
13990
|
+
displayName: "CTok.ai",
|
|
13991
|
+
baseURL: "https://api.ctok.ai",
|
|
13992
|
+
defaultModels: [],
|
|
13993
|
+
authType: "api-key",
|
|
13994
|
+
docs: "https://ctok.ai",
|
|
13995
|
+
wire_api: "responses",
|
|
13996
|
+
env_key: "ANTHROPIC_AUTH_TOKEN",
|
|
13997
|
+
isChinese: true
|
|
13998
|
+
};
|
|
13999
|
+
openrouterPreset = {
|
|
14000
|
+
id: "openrouter",
|
|
14001
|
+
name: "OpenRouter",
|
|
14002
|
+
displayName: "OpenRouter",
|
|
14003
|
+
baseURL: "https://openrouter.ai/api",
|
|
14004
|
+
baseURLChat: "https://openrouter.ai/api/v1",
|
|
14005
|
+
defaultModels: ["anthropic/claude-sonnet-4.6"],
|
|
14006
|
+
authType: "api-key",
|
|
14007
|
+
docs: "https://openrouter.ai",
|
|
14008
|
+
wire_api: "chat",
|
|
14009
|
+
env_key: "OPENAI_API_KEY"
|
|
14010
|
+
};
|
|
14011
|
+
novitaPreset = {
|
|
14012
|
+
id: "novita",
|
|
14013
|
+
name: "Novita AI",
|
|
14014
|
+
displayName: "Novita AI",
|
|
14015
|
+
baseURL: "https://api.novita.ai/anthropic",
|
|
14016
|
+
defaultModels: ["zai-org/glm-5"],
|
|
14017
|
+
authType: "api-key",
|
|
14018
|
+
docs: "https://novita.ai",
|
|
14019
|
+
wire_api: "responses",
|
|
14020
|
+
env_key: "ANTHROPIC_AUTH_TOKEN"
|
|
14021
|
+
};
|
|
14022
|
+
githubCopilotPreset = {
|
|
14023
|
+
id: "github-copilot",
|
|
14024
|
+
name: "GitHub Copilot",
|
|
14025
|
+
displayName: "GitHub Copilot",
|
|
14026
|
+
baseURL: "https://api.githubcopilot.com",
|
|
14027
|
+
defaultModels: ["claude-opus-4.6"],
|
|
14028
|
+
authType: "api-key",
|
|
14029
|
+
docs: "https://github.com/features/copilot",
|
|
14030
|
+
wire_api: "chat",
|
|
14031
|
+
env_key: "ANTHROPIC_AUTH_TOKEN"
|
|
14032
|
+
};
|
|
14033
|
+
nvidiaPreset = {
|
|
14034
|
+
id: "nvidia",
|
|
14035
|
+
name: "Nvidia NIM",
|
|
14036
|
+
displayName: "Nvidia NIM",
|
|
14037
|
+
baseURL: "https://integrate.api.nvidia.com",
|
|
14038
|
+
defaultModels: ["moonshotai/kimi-k2.5"],
|
|
14039
|
+
authType: "api-key",
|
|
14040
|
+
docs: "https://build.nvidia.com",
|
|
14041
|
+
wire_api: "chat",
|
|
14042
|
+
env_key: "ANTHROPIC_AUTH_TOKEN"
|
|
14043
|
+
};
|
|
14044
|
+
xiaomiMimoPreset = {
|
|
14045
|
+
id: "xiaomi-mimo",
|
|
14046
|
+
name: "Xiaomi MiMo",
|
|
14047
|
+
displayName: "Xiaomi MiMo",
|
|
14048
|
+
baseURL: "https://api.xiaomimimo.com/anthropic",
|
|
14049
|
+
defaultModels: ["mimo-v2-pro"],
|
|
14050
|
+
authType: "api-key",
|
|
14051
|
+
docs: "https://platform.xiaomimimo.com",
|
|
14052
|
+
wire_api: "responses",
|
|
14053
|
+
env_key: "ANTHROPIC_AUTH_TOKEN",
|
|
14054
|
+
isChinese: true
|
|
14055
|
+
};
|
|
14056
|
+
bailianForCodingPreset = {
|
|
14057
|
+
id: "bailian-coding",
|
|
14058
|
+
name: "Bailian For Coding",
|
|
14059
|
+
displayName: "阿里云百炼 (Coding)",
|
|
14060
|
+
baseURL: "https://coding.dashscope.aliyuncs.com/apps/anthropic",
|
|
14061
|
+
defaultModels: [],
|
|
14062
|
+
authType: "api-key",
|
|
14063
|
+
docs: "https://bailian.console.aliyun.com",
|
|
14064
|
+
wire_api: "responses",
|
|
14065
|
+
env_key: "ANTHROPIC_AUTH_TOKEN",
|
|
14066
|
+
isChinese: true
|
|
14067
|
+
};
|
|
14068
|
+
kimiForCodingPreset = {
|
|
14069
|
+
id: "kimi-coding",
|
|
14070
|
+
name: "Kimi For Coding",
|
|
14071
|
+
displayName: "Kimi (Coding专用)",
|
|
14072
|
+
baseURL: "https://api.kimi.com/coding/",
|
|
14073
|
+
defaultModels: [],
|
|
14074
|
+
authType: "api-key",
|
|
14075
|
+
docs: "https://www.kimi.com/coding/docs/",
|
|
14076
|
+
wire_api: "responses",
|
|
14077
|
+
env_key: "ANTHROPIC_AUTH_TOKEN",
|
|
14078
|
+
isChinese: true
|
|
14079
|
+
};
|
|
14080
|
+
doubaoSeedPreset = {
|
|
14081
|
+
id: "doubao-seed",
|
|
14082
|
+
name: "DouBao Seed",
|
|
14083
|
+
displayName: "DouBao Seed (豆包)",
|
|
14084
|
+
baseURL: "https://ark.cn-beijing.volces.com/api/coding",
|
|
14085
|
+
defaultModels: ["doubao-seed-2-0-code-preview-latest"],
|
|
14086
|
+
authType: "api-key",
|
|
14087
|
+
docs: "https://www.volcengine.com/product/doubao",
|
|
14088
|
+
wire_api: "responses",
|
|
14089
|
+
env_key: "ANTHROPIC_AUTH_TOKEN",
|
|
14090
|
+
isChinese: true
|
|
14091
|
+
};
|
|
14092
|
+
aihubmixPreset = {
|
|
14093
|
+
id: "aihubmix",
|
|
14094
|
+
name: "AiHubMix",
|
|
14095
|
+
displayName: "AiHubMix",
|
|
14096
|
+
baseURL: "https://aihubmix.com",
|
|
14097
|
+
defaultModels: [],
|
|
14098
|
+
authType: "api-key",
|
|
14099
|
+
docs: "https://aihubmix.com",
|
|
14100
|
+
wire_api: "responses",
|
|
14101
|
+
env_key: "ANTHROPIC_API_KEY",
|
|
14102
|
+
isChinese: true
|
|
14103
|
+
};
|
|
13552
14104
|
builtInPresets = [
|
|
13553
14105
|
anthropicPreset,
|
|
13554
14106
|
ollamaPreset,
|
|
13555
|
-
customPreset
|
|
14107
|
+
customPreset,
|
|
14108
|
+
groqPreset,
|
|
14109
|
+
deepseekPreset,
|
|
14110
|
+
moonshotPreset,
|
|
14111
|
+
togetherPreset,
|
|
14112
|
+
fireworksPreset,
|
|
14113
|
+
zeroonePreset,
|
|
14114
|
+
minimaxCnPreset,
|
|
14115
|
+
minimaxGlobalPreset,
|
|
14116
|
+
zhipuCnPreset,
|
|
14117
|
+
zhipuGlobalPreset,
|
|
14118
|
+
dashscopePreset,
|
|
14119
|
+
stepfunPreset,
|
|
14120
|
+
modelscopePreset,
|
|
14121
|
+
longcatPreset,
|
|
14122
|
+
bailingPreset,
|
|
14123
|
+
siliconflowCnPreset,
|
|
14124
|
+
siliconflowGlobalPreset,
|
|
14125
|
+
dmxapiPreset,
|
|
14126
|
+
packycodePreset,
|
|
14127
|
+
cubencePreset,
|
|
14128
|
+
aigocodePreset,
|
|
14129
|
+
rightcodePreset,
|
|
14130
|
+
aicodemirrorPreset,
|
|
14131
|
+
aicodingPreset,
|
|
14132
|
+
crazyrouterPreset,
|
|
14133
|
+
sssaiCodePreset,
|
|
14134
|
+
compsharePreset,
|
|
14135
|
+
micuPreset,
|
|
14136
|
+
xcodePreset,
|
|
14137
|
+
ctokPreset,
|
|
14138
|
+
openrouterPreset,
|
|
14139
|
+
novitaPreset,
|
|
14140
|
+
githubCopilotPreset,
|
|
14141
|
+
nvidiaPreset,
|
|
14142
|
+
xiaomiMimoPreset,
|
|
14143
|
+
bailianForCodingPreset,
|
|
14144
|
+
kimiForCodingPreset,
|
|
14145
|
+
doubaoSeedPreset,
|
|
14146
|
+
aihubmixPreset
|
|
13556
14147
|
];
|
|
13557
14148
|
allPresets = builtInPresets;
|
|
13558
14149
|
});
|
|
@@ -17627,9 +18218,10 @@ class CodexAdapter {
|
|
|
17627
18218
|
}
|
|
17628
18219
|
}
|
|
17629
18220
|
async createProviderTable(profile, preset) {
|
|
18221
|
+
const baseUrl = preset.baseURLChat || preset.baseURL;
|
|
17630
18222
|
const providerTable = {
|
|
17631
18223
|
name: preset.displayName,
|
|
17632
|
-
base_url: profile.baseURL ||
|
|
18224
|
+
base_url: profile.baseURL || baseUrl,
|
|
17633
18225
|
wire_api: preset.wire_api || "chat"
|
|
17634
18226
|
};
|
|
17635
18227
|
providerTable.env_key = await getEnvKey(profile);
|
|
@@ -17725,6 +18317,7 @@ __export(exports_manager, {
|
|
|
17725
18317
|
setActiveProfileForCoder: () => setActiveProfileForCoder,
|
|
17726
18318
|
setActiveProfile: () => setActiveProfile,
|
|
17727
18319
|
saveConfig: () => saveConfig,
|
|
18320
|
+
resetAllData: () => resetAllData,
|
|
17728
18321
|
profileExists: () => profileExists,
|
|
17729
18322
|
loadConfig: () => loadConfig,
|
|
17730
18323
|
listProfiles: () => listProfiles,
|
|
@@ -17870,6 +18463,22 @@ async function profileExists(profileName) {
|
|
|
17870
18463
|
const config2 = await loadConfig();
|
|
17871
18464
|
return profileName in config2.profiles;
|
|
17872
18465
|
}
|
|
18466
|
+
async function resetAllData() {
|
|
18467
|
+
const config2 = await loadConfig();
|
|
18468
|
+
const allCoders = Object.keys(CODER_REGISTRY);
|
|
18469
|
+
for (const profileName of Object.keys(config2.profiles)) {
|
|
18470
|
+
for (const coder of allCoders) {
|
|
18471
|
+
try {
|
|
18472
|
+
const adapter = getAdapter(coder);
|
|
18473
|
+
await adapter.remove(profileName);
|
|
18474
|
+
} catch (error46) {
|
|
18475
|
+
console.warn(`Warning: Failed to cleanup ${coder} adapter configuration: ${error46}`);
|
|
18476
|
+
}
|
|
18477
|
+
}
|
|
18478
|
+
}
|
|
18479
|
+
const defaultConfig = createDefaultConfig();
|
|
18480
|
+
await saveConfig(defaultConfig);
|
|
18481
|
+
}
|
|
17873
18482
|
var init_manager = __esm(() => {
|
|
17874
18483
|
init_types();
|
|
17875
18484
|
init_constants();
|
|
@@ -19660,6 +20269,123 @@ var require_semver2 = __commonJS((exports, module) => {
|
|
|
19660
20269
|
};
|
|
19661
20270
|
});
|
|
19662
20271
|
|
|
20272
|
+
// src/config/export.ts
|
|
20273
|
+
var exports_export = {};
|
|
20274
|
+
__export(exports_export, {
|
|
20275
|
+
validateExportFile: () => validateExportFile,
|
|
20276
|
+
importConfig: () => importConfig,
|
|
20277
|
+
exportConfig: () => exportConfig
|
|
20278
|
+
});
|
|
20279
|
+
import { existsSync as existsSync6 } from "node:fs";
|
|
20280
|
+
import { readFile as readFile6, writeFile as writeFile6 } from "node:fs/promises";
|
|
20281
|
+
function sanitizeApiKey(apiKey) {
|
|
20282
|
+
if (apiKey.length <= API_KEY_FORMAT.sanitizeLength) {
|
|
20283
|
+
return "***";
|
|
20284
|
+
}
|
|
20285
|
+
const start = apiKey.slice(0, API_KEY_FORMAT.prefixLength);
|
|
20286
|
+
const end = apiKey.slice(-API_KEY_FORMAT.suffixLength);
|
|
20287
|
+
return `${start}***${end}`;
|
|
20288
|
+
}
|
|
20289
|
+
async function exportConfig(filePath, options = {}) {
|
|
20290
|
+
const { sanitizeKeys = false, profileNames } = options;
|
|
20291
|
+
const config2 = await loadConfig();
|
|
20292
|
+
let profilesToExport;
|
|
20293
|
+
if (profileNames && profileNames.length > 0) {
|
|
20294
|
+
profilesToExport = profileNames.map((name) => config2.profiles[name]).filter(Boolean);
|
|
20295
|
+
if (profilesToExport.length === 0) {
|
|
20296
|
+
throw new Error("No profiles found to export");
|
|
20297
|
+
}
|
|
20298
|
+
} else {
|
|
20299
|
+
profilesToExport = Object.values(config2.profiles);
|
|
20300
|
+
}
|
|
20301
|
+
if (profilesToExport.length === 0) {
|
|
20302
|
+
throw new Error("No profiles available to export");
|
|
20303
|
+
}
|
|
20304
|
+
if (sanitizeKeys) {
|
|
20305
|
+
profilesToExport = profilesToExport.map((profile) => ({
|
|
20306
|
+
...profile,
|
|
20307
|
+
apiKey: sanitizeApiKey(profile.apiKey)
|
|
20308
|
+
}));
|
|
20309
|
+
}
|
|
20310
|
+
const exportData = {
|
|
20311
|
+
profiles: profilesToExport,
|
|
20312
|
+
exportedAt: new Date().toISOString(),
|
|
20313
|
+
version: EXPORT_VERSION,
|
|
20314
|
+
sanitized: sanitizeKeys
|
|
20315
|
+
};
|
|
20316
|
+
ExportConfigSchema.parse(exportData);
|
|
20317
|
+
const content = JSON.stringify(exportData, null, SERIALIZATION.jsonIndent);
|
|
20318
|
+
await writeFile6(filePath, content, "utf-8");
|
|
20319
|
+
}
|
|
20320
|
+
async function importConfig(filePath, options = {}) {
|
|
20321
|
+
const { overwrite = false, skipSanitized = true } = options;
|
|
20322
|
+
if (!existsSync6(filePath)) {
|
|
20323
|
+
throw new Error(`File does not exist: ${filePath}`);
|
|
20324
|
+
}
|
|
20325
|
+
const content = await readFile6(filePath, "utf-8");
|
|
20326
|
+
const data = JSON.parse(content);
|
|
20327
|
+
let importData;
|
|
20328
|
+
try {
|
|
20329
|
+
importData = ExportConfigSchema.parse(data);
|
|
20330
|
+
} catch (error46) {
|
|
20331
|
+
throw new Error(`Invalid import file format: ${error46}`);
|
|
20332
|
+
}
|
|
20333
|
+
if (importData.sanitized && skipSanitized) {
|
|
20334
|
+
throw new Error("Import file contains sanitized API Keys and cannot be imported. Please use the complete configuration file or set skipSanitized=false");
|
|
20335
|
+
}
|
|
20336
|
+
const config2 = await loadConfig();
|
|
20337
|
+
let imported = 0;
|
|
20338
|
+
let skipped = 0;
|
|
20339
|
+
const errors3 = [];
|
|
20340
|
+
for (const profile of importData.profiles) {
|
|
20341
|
+
try {
|
|
20342
|
+
const exists = profile.name in config2.profiles;
|
|
20343
|
+
if (exists && !overwrite) {
|
|
20344
|
+
skipped++;
|
|
20345
|
+
continue;
|
|
20346
|
+
}
|
|
20347
|
+
const now = new Date().toISOString();
|
|
20348
|
+
config2.profiles[profile.name] = {
|
|
20349
|
+
...profile,
|
|
20350
|
+
createdAt: exists ? config2.profiles[profile.name].createdAt : now,
|
|
20351
|
+
updatedAt: now
|
|
20352
|
+
};
|
|
20353
|
+
imported++;
|
|
20354
|
+
} catch (error46) {
|
|
20355
|
+
errors3.push(`Failed to import "${profile.name}": ${error46}`);
|
|
20356
|
+
}
|
|
20357
|
+
}
|
|
20358
|
+
if (imported > 0) {
|
|
20359
|
+
await saveConfig(config2);
|
|
20360
|
+
}
|
|
20361
|
+
return { imported, skipped, errors: errors3 };
|
|
20362
|
+
}
|
|
20363
|
+
async function validateExportFile(filePath) {
|
|
20364
|
+
try {
|
|
20365
|
+
if (!existsSync6(filePath)) {
|
|
20366
|
+
return { valid: false, error: "File does not exist" };
|
|
20367
|
+
}
|
|
20368
|
+
const content = await readFile6(filePath, "utf-8");
|
|
20369
|
+
const data = JSON.parse(content);
|
|
20370
|
+
const importData = ExportConfigSchema.parse(data);
|
|
20371
|
+
return {
|
|
20372
|
+
valid: true,
|
|
20373
|
+
profileCount: importData.profiles.length,
|
|
20374
|
+
sanitized: importData.sanitized
|
|
20375
|
+
};
|
|
20376
|
+
} catch (error46) {
|
|
20377
|
+
return {
|
|
20378
|
+
valid: false,
|
|
20379
|
+
error: error46 instanceof Error ? error46.message : String(error46)
|
|
20380
|
+
};
|
|
20381
|
+
}
|
|
20382
|
+
}
|
|
20383
|
+
var init_export = __esm(() => {
|
|
20384
|
+
init_types();
|
|
20385
|
+
init_manager();
|
|
20386
|
+
init_constants();
|
|
20387
|
+
});
|
|
20388
|
+
|
|
19663
20389
|
// src/cli/index.ts
|
|
19664
20390
|
var import_picocolors15 = __toESM(require_picocolors(), 1);
|
|
19665
20391
|
|
|
@@ -21917,7 +22643,7 @@ async function cmdCreateInteractive2() {
|
|
|
21917
22643
|
options: presets.map((preset2) => ({
|
|
21918
22644
|
value: preset2.id,
|
|
21919
22645
|
label: preset2.displayName,
|
|
21920
|
-
hint: preset2.baseURL
|
|
22646
|
+
hint: preset2.baseURLChat || preset2.baseURL
|
|
21921
22647
|
}))
|
|
21922
22648
|
});
|
|
21923
22649
|
if (pD(providerId)) {
|
|
@@ -21940,7 +22666,7 @@ async function cmdCreateInteractive2() {
|
|
|
21940
22666
|
}
|
|
21941
22667
|
const customBaseURL = await he({
|
|
21942
22668
|
message: "Base URL (optional, leave empty for default)",
|
|
21943
|
-
placeholder: preset?.baseURL || "https://api.example.com",
|
|
22669
|
+
placeholder: preset?.baseURLChat || preset?.baseURL || "https://api.example.com",
|
|
21944
22670
|
validate: (value) => {
|
|
21945
22671
|
if (!value || value.trim() === "") {
|
|
21946
22672
|
return;
|
|
@@ -21976,7 +22702,7 @@ async function cmdCreateInteractive2() {
|
|
|
21976
22702
|
const spinner = Y2();
|
|
21977
22703
|
spinner.start("Creating profile...");
|
|
21978
22704
|
try {
|
|
21979
|
-
const finalBaseURL = customBaseURL || preset?.baseURL;
|
|
22705
|
+
const finalBaseURL = customBaseURL || preset?.baseURLChat || preset?.baseURL;
|
|
21980
22706
|
const profile = {
|
|
21981
22707
|
name,
|
|
21982
22708
|
providerId,
|
|
@@ -22028,7 +22754,7 @@ async function cmdCreateQuiet2(params) {
|
|
|
22028
22754
|
process.exit(1);
|
|
22029
22755
|
}
|
|
22030
22756
|
try {
|
|
22031
|
-
const finalBaseURL = params["base-url"] || preset.baseURL;
|
|
22757
|
+
const finalBaseURL = params["base-url"] || preset.baseURLChat || preset.baseURL;
|
|
22032
22758
|
const profile = {
|
|
22033
22759
|
name: params.name,
|
|
22034
22760
|
providerId: params.provider,
|
|
@@ -22077,7 +22803,7 @@ async function cmdList2() {
|
|
|
22077
22803
|
const preset = getPresetById(profile.providerId);
|
|
22078
22804
|
const isCurrent = current?.name === profile.name;
|
|
22079
22805
|
const marker = isCurrent ? import_picocolors9.default.green(MARKERS.active) : import_picocolors9.default.dim(MARKERS.inactive);
|
|
22080
|
-
const baseUrl = profile.baseURL || preset?.baseURL || MISC_DEFAULTS.baseUrlFallback;
|
|
22806
|
+
const baseUrl = profile.baseURL || preset?.baseURLChat || preset?.baseURL || MISC_DEFAULTS.baseUrlFallback;
|
|
22081
22807
|
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)}`);
|
|
22082
22808
|
}
|
|
22083
22809
|
console.log();
|
|
@@ -22097,7 +22823,7 @@ async function cmdSwitch2(profileName, args = []) {
|
|
|
22097
22823
|
await setActiveProfileForCoder(CODER_NAME2, profileName);
|
|
22098
22824
|
const profile = await getActiveProfileForCoder(CODER_NAME2);
|
|
22099
22825
|
const preset = getPresetById(profile.providerId);
|
|
22100
|
-
const baseUrl = profile.baseURL || preset?.baseURL || "Default";
|
|
22826
|
+
const baseUrl = profile.baseURL || preset?.baseURLChat || preset?.baseURL || "Default";
|
|
22101
22827
|
console.log();
|
|
22102
22828
|
console.log(import_picocolors9.default.green("✓") + " Switched successfully!");
|
|
22103
22829
|
console.log();
|
|
@@ -22187,7 +22913,7 @@ async function cmdEdit2(profileName) {
|
|
|
22187
22913
|
options: presets.map((preset) => ({
|
|
22188
22914
|
value: preset.id,
|
|
22189
22915
|
label: preset.displayName,
|
|
22190
|
-
hint: preset.baseURL
|
|
22916
|
+
hint: preset.baseURLChat || preset.baseURL
|
|
22191
22917
|
})),
|
|
22192
22918
|
initialValue: profile.providerId
|
|
22193
22919
|
});
|
|
@@ -22318,7 +23044,7 @@ async function cmdCurrent2() {
|
|
|
22318
23044
|
return;
|
|
22319
23045
|
}
|
|
22320
23046
|
const preset = getPresetById(profile.providerId);
|
|
22321
|
-
const baseUrl = profile.baseURL || preset?.baseURL || "Default";
|
|
23047
|
+
const baseUrl = profile.baseURL || preset?.baseURLChat || preset?.baseURL || "Default";
|
|
22322
23048
|
console.log();
|
|
22323
23049
|
console.log(import_picocolors9.default.bold("Current active profile:"));
|
|
22324
23050
|
console.log();
|
|
@@ -22466,7 +23192,7 @@ async function cmdRun2(args) {
|
|
|
22466
23192
|
}
|
|
22467
23193
|
}
|
|
22468
23194
|
const preset = getPresetById(profile.providerId);
|
|
22469
|
-
const baseURL = profile.baseURL || preset?.baseURL || "";
|
|
23195
|
+
const baseURL = profile.baseURL || preset?.baseURLChat || preset?.baseURL || "";
|
|
22470
23196
|
const env = {};
|
|
22471
23197
|
for (const [key, value] of Object.entries(process.env)) {
|
|
22472
23198
|
if (value !== undefined) {
|
|
@@ -22665,7 +23391,7 @@ async function cmdCreateInteractive3() {
|
|
|
22665
23391
|
options: presets.map((preset2) => ({
|
|
22666
23392
|
value: preset2.id,
|
|
22667
23393
|
label: preset2.displayName,
|
|
22668
|
-
hint: preset2.baseURL
|
|
23394
|
+
hint: preset2.baseURLChat || preset2.baseURL
|
|
22669
23395
|
}))
|
|
22670
23396
|
});
|
|
22671
23397
|
if (pD(providerId)) {
|
|
@@ -22688,7 +23414,7 @@ async function cmdCreateInteractive3() {
|
|
|
22688
23414
|
}
|
|
22689
23415
|
const customBaseURL = await he({
|
|
22690
23416
|
message: "Base URL (optional, leave empty for default)",
|
|
22691
|
-
placeholder: preset?.baseURL || "https://api.example.com",
|
|
23417
|
+
placeholder: preset?.baseURLChat || preset?.baseURL || "https://api.example.com",
|
|
22692
23418
|
validate: (value) => {
|
|
22693
23419
|
if (!value || value.trim() === "") {
|
|
22694
23420
|
return;
|
|
@@ -22769,7 +23495,7 @@ async function cmdCreateInteractive3() {
|
|
|
22769
23495
|
const spinner = Y2();
|
|
22770
23496
|
spinner.start("Creating profile...");
|
|
22771
23497
|
try {
|
|
22772
|
-
const finalBaseURL = customBaseURL || preset?.baseURL;
|
|
23498
|
+
const finalBaseURL = customBaseURL || preset?.baseURLChat || preset?.baseURL;
|
|
22773
23499
|
const finalModel = modelName;
|
|
22774
23500
|
const profile = {
|
|
22775
23501
|
name,
|
|
@@ -22829,7 +23555,7 @@ async function cmdCreateQuiet3(params) {
|
|
|
22829
23555
|
process.exit(1);
|
|
22830
23556
|
}
|
|
22831
23557
|
try {
|
|
22832
|
-
const finalBaseURL = params["base-url"] || preset.baseURL;
|
|
23558
|
+
const finalBaseURL = params["base-url"] || preset.baseURLChat || preset.baseURL;
|
|
22833
23559
|
const finalModel = params.model;
|
|
22834
23560
|
const profile = {
|
|
22835
23561
|
name: params.name,
|
|
@@ -22888,7 +23614,7 @@ async function cmdList3() {
|
|
|
22888
23614
|
const preset = getPresetById(profile.providerId);
|
|
22889
23615
|
const isCurrent = current?.name === profile.name;
|
|
22890
23616
|
const marker = isCurrent ? import_picocolors10.default.green(MARKERS.active) : import_picocolors10.default.dim(MARKERS.inactive);
|
|
22891
|
-
const baseUrl = profile.baseURL || preset?.baseURL || MISC_DEFAULTS.baseUrlFallback;
|
|
23617
|
+
const baseUrl = profile.baseURL || preset?.baseURLChat || preset?.baseURL || MISC_DEFAULTS.baseUrlFallback;
|
|
22892
23618
|
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)}`);
|
|
22893
23619
|
}
|
|
22894
23620
|
console.log();
|
|
@@ -22908,7 +23634,7 @@ async function cmdSwitch3(profileName, args = []) {
|
|
|
22908
23634
|
await setActiveProfileForCoder(CODER_NAME3, profileName);
|
|
22909
23635
|
const profile = await getActiveProfileForCoder(CODER_NAME3);
|
|
22910
23636
|
const preset = getPresetById(profile.providerId);
|
|
22911
|
-
const baseUrl = profile.baseURL || preset?.baseURL || "Default";
|
|
23637
|
+
const baseUrl = profile.baseURL || preset?.baseURLChat || preset?.baseURL || "Default";
|
|
22912
23638
|
console.log();
|
|
22913
23639
|
console.log(import_picocolors10.default.green("✓") + " Switched successfully!");
|
|
22914
23640
|
console.log();
|
|
@@ -22998,7 +23724,7 @@ async function cmdEdit3(profileName) {
|
|
|
22998
23724
|
options: presets.map((preset) => ({
|
|
22999
23725
|
value: preset.id,
|
|
23000
23726
|
label: preset.displayName,
|
|
23001
|
-
hint: preset.baseURL
|
|
23727
|
+
hint: preset.baseURLChat || preset.baseURL
|
|
23002
23728
|
})),
|
|
23003
23729
|
initialValue: profile.providerId
|
|
23004
23730
|
});
|
|
@@ -23203,7 +23929,7 @@ async function cmdCurrent3() {
|
|
|
23203
23929
|
return;
|
|
23204
23930
|
}
|
|
23205
23931
|
const preset = getPresetById(profile.providerId);
|
|
23206
|
-
const baseUrl = profile.baseURL || preset?.baseURL || "Default";
|
|
23932
|
+
const baseUrl = profile.baseURL || preset?.baseURLChat || preset?.baseURL || "Default";
|
|
23207
23933
|
console.log();
|
|
23208
23934
|
console.log(import_picocolors10.default.bold("Current active profile:"));
|
|
23209
23935
|
console.log();
|
|
@@ -23907,6 +24633,8 @@ async function listCoders(req, res) {
|
|
|
23907
24633
|
id: coderId,
|
|
23908
24634
|
displayName: coderConfig.displayName,
|
|
23909
24635
|
executable: coderConfig.executable,
|
|
24636
|
+
wireApi: coderConfig.wireApi,
|
|
24637
|
+
supportsAuthToken: coderConfig.supportsAuthToken,
|
|
23910
24638
|
activeProfile: activeProfile ? {
|
|
23911
24639
|
name: activeProfile.name,
|
|
23912
24640
|
providerId: activeProfile.providerId,
|
|
@@ -23971,6 +24699,22 @@ async function applyProfile(req, res, params) {
|
|
|
23971
24699
|
sendError(res, { code: "NO_ACTIVE_PROFILE", message: `No active profile for coder "${coder}"` }, 400);
|
|
23972
24700
|
return;
|
|
23973
24701
|
}
|
|
24702
|
+
const coderConfig = CODER_REGISTRY[coder];
|
|
24703
|
+
const { getPresetById: getPresetById2 } = await Promise.resolve().then(() => (init_presets(), exports_presets));
|
|
24704
|
+
const provider = getPresetById2(profile.providerId);
|
|
24705
|
+
if (provider) {
|
|
24706
|
+
const providerWireApi = provider.wire_api || "chat";
|
|
24707
|
+
const coderWireApi = coderConfig.wireApi;
|
|
24708
|
+
const isCompatible = coderWireApi === "both" || coderWireApi === "chat" && providerWireApi === "chat" || coderWireApi === "responses" && providerWireApi === "responses";
|
|
24709
|
+
if (!isCompatible) {
|
|
24710
|
+
sendJson(res, {
|
|
24711
|
+
success: false,
|
|
24712
|
+
message: `Provider "${provider.displayName}" uses ${providerWireApi} API which is not compatible with ${coderConfig.displayName}. This provider may not work correctly with this coder.`,
|
|
24713
|
+
warning: true
|
|
24714
|
+
});
|
|
24715
|
+
return;
|
|
24716
|
+
}
|
|
24717
|
+
}
|
|
23974
24718
|
try {
|
|
23975
24719
|
const adapter = getAdapter(coder);
|
|
23976
24720
|
await adapter.apply(profile);
|
|
@@ -24007,100 +24751,10 @@ async function verifyConfig(req, res, params) {
|
|
|
24007
24751
|
init_meta();
|
|
24008
24752
|
init_versions2();
|
|
24009
24753
|
init_paths();
|
|
24754
|
+
init_export();
|
|
24010
24755
|
import { existsSync as existsSync7, statSync } from "node:fs";
|
|
24011
24756
|
import { readFile as readFile7, writeFile as writeFile7, unlink } from "node:fs/promises";
|
|
24012
24757
|
import { join as join5 } from "node:path";
|
|
24013
|
-
|
|
24014
|
-
// src/config/export.ts
|
|
24015
|
-
init_types();
|
|
24016
|
-
init_manager();
|
|
24017
|
-
init_constants();
|
|
24018
|
-
import { existsSync as existsSync6 } from "node:fs";
|
|
24019
|
-
import { readFile as readFile6, writeFile as writeFile6 } from "node:fs/promises";
|
|
24020
|
-
function sanitizeApiKey(apiKey) {
|
|
24021
|
-
if (apiKey.length <= API_KEY_FORMAT.sanitizeLength) {
|
|
24022
|
-
return "***";
|
|
24023
|
-
}
|
|
24024
|
-
const start = apiKey.slice(0, API_KEY_FORMAT.prefixLength);
|
|
24025
|
-
const end = apiKey.slice(-API_KEY_FORMAT.suffixLength);
|
|
24026
|
-
return `${start}***${end}`;
|
|
24027
|
-
}
|
|
24028
|
-
async function exportConfig(filePath, options = {}) {
|
|
24029
|
-
const { sanitizeKeys = false, profileNames } = options;
|
|
24030
|
-
const config2 = await loadConfig();
|
|
24031
|
-
let profilesToExport;
|
|
24032
|
-
if (profileNames && profileNames.length > 0) {
|
|
24033
|
-
profilesToExport = profileNames.map((name) => config2.profiles[name]).filter(Boolean);
|
|
24034
|
-
if (profilesToExport.length === 0) {
|
|
24035
|
-
throw new Error("No profiles found to export");
|
|
24036
|
-
}
|
|
24037
|
-
} else {
|
|
24038
|
-
profilesToExport = Object.values(config2.profiles);
|
|
24039
|
-
}
|
|
24040
|
-
if (profilesToExport.length === 0) {
|
|
24041
|
-
throw new Error("No profiles available to export");
|
|
24042
|
-
}
|
|
24043
|
-
if (sanitizeKeys) {
|
|
24044
|
-
profilesToExport = profilesToExport.map((profile) => ({
|
|
24045
|
-
...profile,
|
|
24046
|
-
apiKey: sanitizeApiKey(profile.apiKey)
|
|
24047
|
-
}));
|
|
24048
|
-
}
|
|
24049
|
-
const exportData = {
|
|
24050
|
-
profiles: profilesToExport,
|
|
24051
|
-
exportedAt: new Date().toISOString(),
|
|
24052
|
-
version: EXPORT_VERSION,
|
|
24053
|
-
sanitized: sanitizeKeys
|
|
24054
|
-
};
|
|
24055
|
-
ExportConfigSchema.parse(exportData);
|
|
24056
|
-
const content = JSON.stringify(exportData, null, SERIALIZATION.jsonIndent);
|
|
24057
|
-
await writeFile6(filePath, content, "utf-8");
|
|
24058
|
-
}
|
|
24059
|
-
async function importConfig(filePath, options = {}) {
|
|
24060
|
-
const { overwrite = false, skipSanitized = true } = options;
|
|
24061
|
-
if (!existsSync6(filePath)) {
|
|
24062
|
-
throw new Error(`File does not exist: ${filePath}`);
|
|
24063
|
-
}
|
|
24064
|
-
const content = await readFile6(filePath, "utf-8");
|
|
24065
|
-
const data = JSON.parse(content);
|
|
24066
|
-
let importData;
|
|
24067
|
-
try {
|
|
24068
|
-
importData = ExportConfigSchema.parse(data);
|
|
24069
|
-
} catch (error46) {
|
|
24070
|
-
throw new Error(`Invalid import file format: ${error46}`);
|
|
24071
|
-
}
|
|
24072
|
-
if (importData.sanitized && skipSanitized) {
|
|
24073
|
-
throw new Error("Import file contains sanitized API Keys and cannot be imported. Please use the complete configuration file or set skipSanitized=false");
|
|
24074
|
-
}
|
|
24075
|
-
const config2 = await loadConfig();
|
|
24076
|
-
let imported = 0;
|
|
24077
|
-
let skipped = 0;
|
|
24078
|
-
const errors3 = [];
|
|
24079
|
-
for (const profile of importData.profiles) {
|
|
24080
|
-
try {
|
|
24081
|
-
const exists = profile.name in config2.profiles;
|
|
24082
|
-
if (exists && !overwrite) {
|
|
24083
|
-
skipped++;
|
|
24084
|
-
continue;
|
|
24085
|
-
}
|
|
24086
|
-
const now = new Date().toISOString();
|
|
24087
|
-
config2.profiles[profile.name] = {
|
|
24088
|
-
...profile,
|
|
24089
|
-
createdAt: exists ? config2.profiles[profile.name].createdAt : now,
|
|
24090
|
-
updatedAt: now
|
|
24091
|
-
};
|
|
24092
|
-
imported++;
|
|
24093
|
-
} catch (error46) {
|
|
24094
|
-
errors3.push(`Failed to import "${profile.name}": ${error46}`);
|
|
24095
|
-
}
|
|
24096
|
-
}
|
|
24097
|
-
if (imported > 0) {
|
|
24098
|
-
await saveConfig(config2);
|
|
24099
|
-
}
|
|
24100
|
-
return { imported, skipped, errors: errors3 };
|
|
24101
|
-
}
|
|
24102
|
-
|
|
24103
|
-
// src/server/api/config.ts
|
|
24104
24758
|
async function getVersion(req, res) {
|
|
24105
24759
|
sendJson(res, {
|
|
24106
24760
|
appVersion: APP_VERSION,
|
|
@@ -24148,12 +24802,23 @@ async function getConfigMeta(req, res) {
|
|
|
24148
24802
|
}
|
|
24149
24803
|
async function exportConfigFile(req, res) {
|
|
24150
24804
|
try {
|
|
24151
|
-
const
|
|
24152
|
-
const
|
|
24153
|
-
|
|
24154
|
-
|
|
24155
|
-
|
|
24156
|
-
|
|
24805
|
+
const url2 = new URL(req.url || "", `http://${req.headers.host || "localhost"}`);
|
|
24806
|
+
const sanitize = url2.searchParams.get("sanitize") === "true";
|
|
24807
|
+
const { exportConfig: exportConfig3 } = await Promise.resolve().then(() => (init_export(), exports_export));
|
|
24808
|
+
const tempDir = getConfigDir("swixter");
|
|
24809
|
+
const tempPath = join5(tempDir, `.export-${Date.now()}.json`);
|
|
24810
|
+
try {
|
|
24811
|
+
await exportConfig3(tempPath, { sanitizeKeys: sanitize });
|
|
24812
|
+
const content = await readFile7(tempPath, "utf-8");
|
|
24813
|
+
res.setHeader("Content-Type", "application/json");
|
|
24814
|
+
res.setHeader("Content-Disposition", 'attachment; filename="swixter-config.json"');
|
|
24815
|
+
res.statusCode = 200;
|
|
24816
|
+
res.end(content);
|
|
24817
|
+
} finally {
|
|
24818
|
+
try {
|
|
24819
|
+
await unlink(tempPath);
|
|
24820
|
+
} catch {}
|
|
24821
|
+
}
|
|
24157
24822
|
} catch (error46) {
|
|
24158
24823
|
sendError(res, { code: "EXPORT_FAILED", message: "Failed to export configuration" }, 500);
|
|
24159
24824
|
}
|
|
@@ -24180,6 +24845,15 @@ async function importConfigFile(req, res) {
|
|
|
24180
24845
|
sendError(res, { code: "IMPORT_FAILED", message: error46 instanceof Error ? error46.message : "Failed to import configuration" }, 500);
|
|
24181
24846
|
}
|
|
24182
24847
|
}
|
|
24848
|
+
async function resetConfig(req, res) {
|
|
24849
|
+
try {
|
|
24850
|
+
const { resetAllData: resetAllData2 } = await Promise.resolve().then(() => (init_manager(), exports_manager));
|
|
24851
|
+
await resetAllData2();
|
|
24852
|
+
sendJson(res, { success: true, message: "All data has been reset" });
|
|
24853
|
+
} catch (error46) {
|
|
24854
|
+
sendError(res, { code: "RESET_FAILED", message: error46 instanceof Error ? error46.message : "Failed to reset configuration" }, 500);
|
|
24855
|
+
}
|
|
24856
|
+
}
|
|
24183
24857
|
|
|
24184
24858
|
// src/server/index.ts
|
|
24185
24859
|
var __dirname2 = dirname7(fileURLToPath(import.meta.url));
|
|
@@ -24236,6 +24910,7 @@ async function startServer(portArg) {
|
|
|
24236
24910
|
router.get("/api/config", getConfigMeta);
|
|
24237
24911
|
router.get("/api/config/export", exportConfigFile);
|
|
24238
24912
|
router.post("/api/config/import", importConfigFile);
|
|
24913
|
+
router.post("/api/config/reset", resetConfig);
|
|
24239
24914
|
const uiDir = getUiDir();
|
|
24240
24915
|
const serveStatic = createStaticServe({ root: uiDir, index: "index.html", spa: true });
|
|
24241
24916
|
const server = createServer(async (req, res) => {
|
|
@@ -24314,6 +24989,9 @@ function getPortFromArgs(args) {
|
|
|
24314
24989
|
return;
|
|
24315
24990
|
}
|
|
24316
24991
|
|
|
24992
|
+
// src/cli/index.ts
|
|
24993
|
+
init_export();
|
|
24994
|
+
|
|
24317
24995
|
// src/cli/help.ts
|
|
24318
24996
|
var import_picocolors13 = __toESM(require_picocolors(), 1);
|
|
24319
24997
|
function showGlobalHelp() {
|