zcf 3.2.3 → 3.3.1
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 +102 -14
- package/dist/chunks/api-providers.mjs +76 -0
- package/dist/chunks/claude-code-config-manager.mjs +21 -7
- package/dist/chunks/claude-code-incremental-manager.mjs +210 -14
- package/dist/chunks/codex-config-switch.mjs +197 -12
- package/dist/chunks/codex-provider-manager.mjs +20 -9
- package/dist/chunks/codex-uninstaller.mjs +19 -24
- package/dist/chunks/commands.mjs +1 -1
- package/dist/chunks/features.mjs +637 -0
- package/dist/chunks/simple-config.mjs +182 -29
- package/dist/cli.mjs +13 -613
- package/dist/i18n/locales/en/api.json +6 -1
- package/dist/i18n/locales/en/codex.json +7 -0
- package/dist/i18n/locales/en/errors.json +1 -0
- package/dist/i18n/locales/en/multi-config.json +8 -1
- package/dist/i18n/locales/zh-CN/api.json +6 -1
- package/dist/i18n/locales/zh-CN/codex.json +7 -0
- package/dist/i18n/locales/zh-CN/errors.json +1 -0
- package/dist/i18n/locales/zh-CN/multi-config.json +8 -1
- package/dist/index.d.mts +13 -1
- package/dist/index.d.ts +13 -1
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
- package/templates/CLAUDE.md +191 -0
- package/templates/claude-code/CLAUDE.md +1 -0
- package/templates/claude-code/en/output-styles/engineer-professional.md +2 -1
- package/templates/claude-code/en/output-styles/laowang-engineer.md +1 -0
- package/templates/claude-code/en/output-styles/nekomata-engineer.md +1 -0
- package/templates/claude-code/en/output-styles/ojousama-engineer.md +1 -0
- package/templates/claude-code/zh-CN/output-styles/engineer-professional.md +2 -1
- package/templates/claude-code/zh-CN/output-styles/laowang-engineer.md +1 -0
- package/templates/claude-code/zh-CN/output-styles/nekomata-engineer.md +1 -0
- package/templates/claude-code/zh-CN/output-styles/ojousama-engineer.md +1 -0
- package/templates/codex/en/system-prompt/engineer-professional.md +2 -1
- package/templates/codex/en/system-prompt/laowang-engineer.md +1 -0
- package/templates/codex/en/system-prompt/nekomata-engineer.md +1 -0
- package/templates/codex/en/system-prompt/ojousama-engineer.md +1 -0
- package/templates/codex/zh-CN/system-prompt/engineer-professional.md +2 -1
- package/templates/codex/zh-CN/system-prompt/laowang-engineer.md +1 -0
- package/templates/codex/zh-CN/system-prompt/nekomata-engineer.md +1 -0
- package/templates/codex/zh-CN/system-prompt/ojousama-engineer.md +1 -0
|
@@ -16,7 +16,7 @@ import { rm, mkdir, copyFile as copyFile$1 } from 'node:fs/promises';
|
|
|
16
16
|
import i18next from 'i18next';
|
|
17
17
|
import Backend from 'i18next-fs-backend';
|
|
18
18
|
|
|
19
|
-
const version = "3.
|
|
19
|
+
const version = "3.3.1";
|
|
20
20
|
const homepage = "https://github.com/UfoMiao/zcf";
|
|
21
21
|
|
|
22
22
|
const i18n = i18next.createInstance();
|
|
@@ -381,6 +381,11 @@ const SETTINGS_FILE = join(CLAUDE_DIR, "settings.json");
|
|
|
381
381
|
const CLAUDE_MD_FILE = join(CLAUDE_DIR, "CLAUDE.md");
|
|
382
382
|
const ClAUDE_CONFIG_FILE = join(homedir(), ".claude.json");
|
|
383
383
|
const CLAUDE_VSC_CONFIG_FILE = join(CLAUDE_DIR, "config.json");
|
|
384
|
+
const CODEX_DIR = join(homedir(), ".codex");
|
|
385
|
+
const CODEX_CONFIG_FILE = join(CODEX_DIR, "config.toml");
|
|
386
|
+
const CODEX_AUTH_FILE = join(CODEX_DIR, "auth.json");
|
|
387
|
+
const CODEX_AGENTS_FILE = join(CODEX_DIR, "AGENTS.md");
|
|
388
|
+
const CODEX_PROMPTS_DIR = join(CODEX_DIR, "prompts");
|
|
384
389
|
const ZCF_CONFIG_DIR = join(homedir(), ".ufomiao", "zcf");
|
|
385
390
|
const ZCF_CONFIG_FILE = join(ZCF_CONFIG_DIR, "config.toml");
|
|
386
391
|
const LEGACY_ZCF_CONFIG_FILES = [
|
|
@@ -442,6 +447,11 @@ const constants = {
|
|
|
442
447
|
CLAUDE_DIR: CLAUDE_DIR,
|
|
443
448
|
CLAUDE_MD_FILE: CLAUDE_MD_FILE,
|
|
444
449
|
CLAUDE_VSC_CONFIG_FILE: CLAUDE_VSC_CONFIG_FILE,
|
|
450
|
+
CODEX_AGENTS_FILE: CODEX_AGENTS_FILE,
|
|
451
|
+
CODEX_AUTH_FILE: CODEX_AUTH_FILE,
|
|
452
|
+
CODEX_CONFIG_FILE: CODEX_CONFIG_FILE,
|
|
453
|
+
CODEX_DIR: CODEX_DIR,
|
|
454
|
+
CODEX_PROMPTS_DIR: CODEX_PROMPTS_DIR,
|
|
445
455
|
CODE_TOOL_ALIASES: CODE_TOOL_ALIASES,
|
|
446
456
|
CODE_TOOL_BANNERS: CODE_TOOL_BANNERS,
|
|
447
457
|
CODE_TOOL_TYPES: CODE_TOOL_TYPES,
|
|
@@ -2915,11 +2925,6 @@ async function configureCodexMcp(options) {
|
|
|
2915
2925
|
console.log(ansis.green(i18n.t("codex:mcpConfigured")));
|
|
2916
2926
|
}
|
|
2917
2927
|
|
|
2918
|
-
const CODEX_DIR = join(homedir(), ".codex");
|
|
2919
|
-
const CODEX_CONFIG_FILE = join(CODEX_DIR, "config.toml");
|
|
2920
|
-
const CODEX_AUTH_FILE = join(CODEX_DIR, "auth.json");
|
|
2921
|
-
const CODEX_AGENTS_FILE = join(CODEX_DIR, "AGENTS.md");
|
|
2922
|
-
const CODEX_PROMPTS_DIR = join(CODEX_DIR, "prompts");
|
|
2923
2928
|
function getRootDir$1() {
|
|
2924
2929
|
const currentFilePath = fileURLToPath(import.meta.url);
|
|
2925
2930
|
let dir = dirname(currentFilePath);
|
|
@@ -3032,7 +3037,7 @@ function sanitizeProviderName(input) {
|
|
|
3032
3037
|
const cleaned = input.trim();
|
|
3033
3038
|
if (!cleaned)
|
|
3034
3039
|
return "";
|
|
3035
|
-
return cleaned.replace(/[
|
|
3040
|
+
return cleaned.toLowerCase().replace(/\./g, "-").replace(/\s+/g, "-").replace(/[^a-z0-9\-]/g, "");
|
|
3036
3041
|
}
|
|
3037
3042
|
function parseCodexConfig(content) {
|
|
3038
3043
|
if (!content.trim()) {
|
|
@@ -3061,7 +3066,9 @@ function parseCodexConfig(content) {
|
|
|
3061
3066
|
baseUrl: provider.base_url || "",
|
|
3062
3067
|
wireApi: provider.wire_api || "responses",
|
|
3063
3068
|
envKey: provider.env_key || "OPENAI_API_KEY",
|
|
3064
|
-
requiresOpenaiAuth: provider.requires_openai_auth !== false
|
|
3069
|
+
requiresOpenaiAuth: provider.requires_openai_auth !== false,
|
|
3070
|
+
model: provider.model || void 0
|
|
3071
|
+
// Parse model field from provider
|
|
3065
3072
|
});
|
|
3066
3073
|
}
|
|
3067
3074
|
}
|
|
@@ -3211,7 +3218,7 @@ function renderCodexConfig(data) {
|
|
|
3211
3218
|
return false;
|
|
3212
3219
|
if (/^#?\s*model_provider\s*=/.test(l))
|
|
3213
3220
|
return false;
|
|
3214
|
-
if (/^\s*model\s*=/.test(l))
|
|
3221
|
+
if (/^\s*model\s*=/.test(l) && !l.includes("["))
|
|
3215
3222
|
return false;
|
|
3216
3223
|
return true;
|
|
3217
3224
|
});
|
|
@@ -3231,6 +3238,9 @@ function renderCodexConfig(data) {
|
|
|
3231
3238
|
lines.push(`wire_api = "${provider.wireApi}"`);
|
|
3232
3239
|
lines.push(`env_key = "${provider.envKey}"`);
|
|
3233
3240
|
lines.push(`requires_openai_auth = ${provider.requiresOpenaiAuth}`);
|
|
3241
|
+
if (provider.model) {
|
|
3242
|
+
lines.push(`model = "${provider.model}"`);
|
|
3243
|
+
}
|
|
3234
3244
|
}
|
|
3235
3245
|
}
|
|
3236
3246
|
if (data.mcpServices.length > 0) {
|
|
@@ -3710,12 +3720,36 @@ async function configureCodexApi(options) {
|
|
|
3710
3720
|
const existingValues = existingMap.size ? Array.from(existingMap.values()) : [];
|
|
3711
3721
|
const firstExisting = existingValues.length === 1 ? existingValues[0] : void 0;
|
|
3712
3722
|
while (addMore) {
|
|
3723
|
+
const { getApiProviders } = await import('./api-providers.mjs');
|
|
3724
|
+
const apiProviders = getApiProviders("codex");
|
|
3725
|
+
const providerChoices = [
|
|
3726
|
+
{ name: i18n.t("api:customProvider"), value: "custom" },
|
|
3727
|
+
...apiProviders.map((p) => ({ name: p.name, value: p.id }))
|
|
3728
|
+
];
|
|
3729
|
+
const { selectedProvider: selectedProvider2 } = await inquirer.prompt([{
|
|
3730
|
+
type: "list",
|
|
3731
|
+
name: "selectedProvider",
|
|
3732
|
+
message: i18n.t("api:selectApiProvider"),
|
|
3733
|
+
choices: addNumbersToChoices(providerChoices)
|
|
3734
|
+
}]);
|
|
3735
|
+
let prefilledBaseUrl;
|
|
3736
|
+
let prefilledWireApi;
|
|
3737
|
+
let prefilledModel;
|
|
3738
|
+
if (selectedProvider2 !== "custom") {
|
|
3739
|
+
const provider = apiProviders.find((p) => p.id === selectedProvider2);
|
|
3740
|
+
if (provider?.codex) {
|
|
3741
|
+
prefilledBaseUrl = provider.codex.baseUrl;
|
|
3742
|
+
prefilledWireApi = provider.codex.wireApi;
|
|
3743
|
+
prefilledModel = provider.codex.defaultModel;
|
|
3744
|
+
console.log(ansis.gray(i18n.t("api:providerSelected", { name: provider.name })));
|
|
3745
|
+
}
|
|
3746
|
+
}
|
|
3713
3747
|
const answers = await inquirer.prompt([
|
|
3714
3748
|
{
|
|
3715
3749
|
type: "input",
|
|
3716
3750
|
name: "providerName",
|
|
3717
3751
|
message: i18n.t("codex:providerNamePrompt"),
|
|
3718
|
-
default: firstExisting?.name,
|
|
3752
|
+
default: selectedProvider2 !== "custom" ? apiProviders.find((p) => p.id === selectedProvider2)?.name : firstExisting?.name,
|
|
3719
3753
|
validate: (input) => {
|
|
3720
3754
|
const sanitized = sanitizeProviderName(input);
|
|
3721
3755
|
if (!sanitized)
|
|
@@ -3729,7 +3763,8 @@ async function configureCodexApi(options) {
|
|
|
3729
3763
|
type: "input",
|
|
3730
3764
|
name: "baseUrl",
|
|
3731
3765
|
message: i18n.t("codex:providerBaseUrlPrompt"),
|
|
3732
|
-
default: (answers2) => existingMap.get(answers2.providerId)?.baseUrl || "https://api.openai.com/v1",
|
|
3766
|
+
default: prefilledBaseUrl || ((answers2) => existingMap.get(answers2.providerId)?.baseUrl || "https://api.openai.com/v1"),
|
|
3767
|
+
when: () => selectedProvider2 === "custom",
|
|
3733
3768
|
validate: (input) => !!input || i18n.t("codex:providerBaseUrlRequired")
|
|
3734
3769
|
},
|
|
3735
3770
|
{
|
|
@@ -3740,15 +3775,29 @@ async function configureCodexApi(options) {
|
|
|
3740
3775
|
{ name: i18n.t("codex:protocolResponses"), value: "responses" },
|
|
3741
3776
|
{ name: i18n.t("codex:protocolChat"), value: "chat" }
|
|
3742
3777
|
],
|
|
3743
|
-
default: (answers2) => existingMap.get(sanitizeProviderName(answers2.providerName))?.wireApi || "responses"
|
|
3778
|
+
default: prefilledWireApi || ((answers2) => existingMap.get(sanitizeProviderName(answers2.providerName))?.wireApi || "responses"),
|
|
3779
|
+
when: () => selectedProvider2 === "custom"
|
|
3780
|
+
// Only ask if custom
|
|
3744
3781
|
},
|
|
3745
3782
|
{
|
|
3746
3783
|
type: "input",
|
|
3747
3784
|
name: "apiKey",
|
|
3748
|
-
message: i18n.t("codex:providerApiKeyPrompt"),
|
|
3785
|
+
message: selectedProvider2 !== "custom" ? i18n.t("api:enterProviderApiKey", { provider: apiProviders.find((p) => p.id === selectedProvider2)?.name || selectedProvider2 }) : i18n.t("codex:providerApiKeyPrompt"),
|
|
3749
3786
|
validate: (input) => !!input || i18n.t("codex:providerApiKeyRequired")
|
|
3750
3787
|
}
|
|
3751
3788
|
]);
|
|
3789
|
+
let customModel;
|
|
3790
|
+
if (selectedProvider2 === "custom") {
|
|
3791
|
+
const { model } = await inquirer.prompt([{
|
|
3792
|
+
type: "input",
|
|
3793
|
+
name: "model",
|
|
3794
|
+
message: `${i18n.t("configuration:enterCustomModel")}${i18n.t("common:emptyToSkip")}`,
|
|
3795
|
+
default: "gpt-5-codex"
|
|
3796
|
+
}]);
|
|
3797
|
+
if (model.trim()) {
|
|
3798
|
+
customModel = model.trim();
|
|
3799
|
+
}
|
|
3800
|
+
}
|
|
3752
3801
|
const providerId = sanitizeProviderName(answers.providerName);
|
|
3753
3802
|
const envKey = `${providerId.toUpperCase().replace(/-/g, "_")}_API_KEY`;
|
|
3754
3803
|
const existingProvider = existingMap.get(providerId);
|
|
@@ -3780,10 +3829,12 @@ async function configureCodexApi(options) {
|
|
|
3780
3829
|
const newProvider = {
|
|
3781
3830
|
id: providerId,
|
|
3782
3831
|
name: answers.providerName,
|
|
3783
|
-
baseUrl: answers.baseUrl,
|
|
3784
|
-
wireApi: answers.wireApi || "responses",
|
|
3832
|
+
baseUrl: selectedProvider2 === "custom" ? answers.baseUrl : prefilledBaseUrl,
|
|
3833
|
+
wireApi: selectedProvider2 === "custom" ? answers.wireApi || "responses" : prefilledWireApi,
|
|
3785
3834
|
envKey,
|
|
3786
|
-
requiresOpenaiAuth: true
|
|
3835
|
+
requiresOpenaiAuth: true,
|
|
3836
|
+
model: customModel || prefilledModel || "gpt-5-codex"
|
|
3837
|
+
// Use custom model, provider's default model, or fallback
|
|
3787
3838
|
};
|
|
3788
3839
|
providers.push(newProvider);
|
|
3789
3840
|
currentSessionProviders.set(providerId, newProvider);
|
|
@@ -4078,8 +4129,18 @@ async function switchToProvider(providerId) {
|
|
|
4078
4129
|
console.log(ansis.gray(getBackupMessage(backupPath)));
|
|
4079
4130
|
}
|
|
4080
4131
|
try {
|
|
4132
|
+
let targetModel = existingConfig.model;
|
|
4133
|
+
if (provider.model) {
|
|
4134
|
+
targetModel = provider.model;
|
|
4135
|
+
} else {
|
|
4136
|
+
const currentModel = existingConfig.model;
|
|
4137
|
+
if (currentModel !== "gpt-5" && currentModel !== "gpt-5-codex") {
|
|
4138
|
+
targetModel = "gpt-5-codex";
|
|
4139
|
+
}
|
|
4140
|
+
}
|
|
4081
4141
|
const updatedConfig = {
|
|
4082
4142
|
...existingConfig,
|
|
4143
|
+
model: targetModel,
|
|
4083
4144
|
modelProvider: providerId,
|
|
4084
4145
|
modelProviderCommented: false
|
|
4085
4146
|
// Ensure it's not commented
|
|
@@ -4712,6 +4773,7 @@ async function installClaudeCode() {
|
|
|
4712
4773
|
if (installed) {
|
|
4713
4774
|
console.log(ansis.green(`\u2714 ${i18n.t("installation:alreadyInstalled")}`));
|
|
4714
4775
|
await updateClaudeCode();
|
|
4776
|
+
await setInstallMethod("npm");
|
|
4715
4777
|
return;
|
|
4716
4778
|
}
|
|
4717
4779
|
if (isTermux()) {
|
|
@@ -4734,6 +4796,7 @@ async function installClaudeCode() {
|
|
|
4734
4796
|
try {
|
|
4735
4797
|
await exec("npm", ["install", "-g", "@anthropic-ai/claude-code"]);
|
|
4736
4798
|
console.log(`\u2714 ${i18n.t("installation:installSuccess")}`);
|
|
4799
|
+
await setInstallMethod("npm");
|
|
4737
4800
|
if (isTermux()) {
|
|
4738
4801
|
console.log(ansis.gray(`
|
|
4739
4802
|
Claude Code installed to: ${getTermuxPrefix()}/bin/claude`));
|
|
@@ -4783,6 +4846,19 @@ async function removeLocalClaudeCode() {
|
|
|
4783
4846
|
throw new Error(`${i18n.t("installation:failedToRemoveLocalInstallation")}: ${error}`);
|
|
4784
4847
|
}
|
|
4785
4848
|
}
|
|
4849
|
+
async function setInstallMethod(method = "npm") {
|
|
4850
|
+
try {
|
|
4851
|
+
const { readMcpConfig, writeMcpConfig } = await Promise.resolve().then(function () { return claudeConfig; });
|
|
4852
|
+
let config = readMcpConfig();
|
|
4853
|
+
if (!config) {
|
|
4854
|
+
config = { mcpServers: {} };
|
|
4855
|
+
}
|
|
4856
|
+
config.installMethod = method;
|
|
4857
|
+
writeMcpConfig(config);
|
|
4858
|
+
} catch (error) {
|
|
4859
|
+
console.error("Failed to set installMethod in ~/.claude.json:", error);
|
|
4860
|
+
}
|
|
4861
|
+
}
|
|
4786
4862
|
|
|
4787
4863
|
const installer = {
|
|
4788
4864
|
__proto__: null,
|
|
@@ -4790,7 +4866,8 @@ const installer = {
|
|
|
4790
4866
|
installClaudeCode: installClaudeCode,
|
|
4791
4867
|
isClaudeCodeInstalled: isClaudeCodeInstalled,
|
|
4792
4868
|
isLocalClaudeCodeInstalled: isLocalClaudeCodeInstalled,
|
|
4793
|
-
removeLocalClaudeCode: removeLocalClaudeCode
|
|
4869
|
+
removeLocalClaudeCode: removeLocalClaudeCode,
|
|
4870
|
+
setInstallMethod: setInstallMethod
|
|
4794
4871
|
};
|
|
4795
4872
|
|
|
4796
4873
|
async function chooseInstallationMethod() {
|
|
@@ -5055,7 +5132,7 @@ async function cleanupOldVersionFiles() {
|
|
|
5055
5132
|
}
|
|
5056
5133
|
}
|
|
5057
5134
|
|
|
5058
|
-
function validateSkipPromptOptions(options) {
|
|
5135
|
+
async function validateSkipPromptOptions(options) {
|
|
5059
5136
|
if (options.allLang) {
|
|
5060
5137
|
if (options.allLang === "zh-CN" || options.allLang === "en") {
|
|
5061
5138
|
options.configLang = options.allLang;
|
|
@@ -5065,6 +5142,22 @@ function validateSkipPromptOptions(options) {
|
|
|
5065
5142
|
options.aiOutputLang = options.allLang;
|
|
5066
5143
|
}
|
|
5067
5144
|
}
|
|
5145
|
+
if (options.provider) {
|
|
5146
|
+
const { getValidProviderIds, getProviderPreset } = await import('./api-providers.mjs');
|
|
5147
|
+
const validProviders = [...getValidProviderIds(), "custom"];
|
|
5148
|
+
if (!validProviders.includes(options.provider)) {
|
|
5149
|
+
throw new Error(
|
|
5150
|
+
i18n.t("errors:invalidProvider", {
|
|
5151
|
+
provider: options.provider,
|
|
5152
|
+
validProviders: validProviders.join(", ")
|
|
5153
|
+
})
|
|
5154
|
+
);
|
|
5155
|
+
}
|
|
5156
|
+
if (!options.apiType) {
|
|
5157
|
+
const preset = options.provider !== "custom" ? getProviderPreset(options.provider) : null;
|
|
5158
|
+
options.apiType = preset?.claudeCode?.authType || "api_key";
|
|
5159
|
+
}
|
|
5160
|
+
}
|
|
5068
5161
|
if (!options.configAction) {
|
|
5069
5162
|
options.configAction = "backup";
|
|
5070
5163
|
}
|
|
@@ -5177,7 +5270,7 @@ function validateSkipPromptOptions(options) {
|
|
|
5177
5270
|
}
|
|
5178
5271
|
async function init(options = {}) {
|
|
5179
5272
|
if (options.skipPrompt) {
|
|
5180
|
-
validateSkipPromptOptions(options);
|
|
5273
|
+
await validateSkipPromptOptions(options);
|
|
5181
5274
|
}
|
|
5182
5275
|
try {
|
|
5183
5276
|
const zcfConfig = readZcfConfig();
|
|
@@ -5421,6 +5514,18 @@ async function init(options = {}) {
|
|
|
5421
5514
|
if (options.apiConfigs || options.apiConfigsFile) {
|
|
5422
5515
|
await handleMultiConfigurations(options, codeToolType);
|
|
5423
5516
|
apiConfig = null;
|
|
5517
|
+
} else if (options.provider && options.apiKey) {
|
|
5518
|
+
const { getProviderPreset } = await import('./api-providers.mjs');
|
|
5519
|
+
const preset = options.provider !== "custom" ? getProviderPreset(options.provider) : null;
|
|
5520
|
+
apiConfig = {
|
|
5521
|
+
authType: preset?.claudeCode?.authType || "api_key",
|
|
5522
|
+
key: options.apiKey,
|
|
5523
|
+
url: preset?.claudeCode?.baseUrl || options.apiUrl || API_DEFAULT_URL
|
|
5524
|
+
};
|
|
5525
|
+
if (preset?.claudeCode?.defaultModels && preset.claudeCode.defaultModels.length >= 2) {
|
|
5526
|
+
options.apiModel = options.apiModel || preset.claudeCode.defaultModels[0];
|
|
5527
|
+
options.apiFastModel = options.apiFastModel || preset.claudeCode.defaultModels[1];
|
|
5528
|
+
}
|
|
5424
5529
|
} else if (options.apiType === "auth_token" && options.apiKey) {
|
|
5425
5530
|
apiConfig = {
|
|
5426
5531
|
authType: "auth_token",
|
|
@@ -5708,7 +5813,7 @@ async function handleMultiConfigurations(options, codeToolType) {
|
|
|
5708
5813
|
throw new Error(i18n.t("multi-config:fileReadFailed", { error: error instanceof Error ? error.message : String(error) }));
|
|
5709
5814
|
}
|
|
5710
5815
|
}
|
|
5711
|
-
validateApiConfigs(configs);
|
|
5816
|
+
await validateApiConfigs(configs);
|
|
5712
5817
|
if (codeToolType === "claude-code") {
|
|
5713
5818
|
await handleClaudeCodeConfigs(configs);
|
|
5714
5819
|
} else if (codeToolType === "codex") {
|
|
@@ -5720,12 +5825,29 @@ async function handleMultiConfigurations(options, codeToolType) {
|
|
|
5720
5825
|
throw error;
|
|
5721
5826
|
}
|
|
5722
5827
|
}
|
|
5723
|
-
function validateApiConfigs(configs) {
|
|
5828
|
+
async function validateApiConfigs(configs) {
|
|
5724
5829
|
if (!Array.isArray(configs)) {
|
|
5725
5830
|
throw new TypeError(i18n.t("multi-config:mustBeArray"));
|
|
5726
5831
|
}
|
|
5832
|
+
const { getValidProviderIds } = await import('./api-providers.mjs');
|
|
5833
|
+
const validProviders = [...getValidProviderIds(), "custom"];
|
|
5727
5834
|
const names = /* @__PURE__ */ new Set();
|
|
5728
5835
|
for (const config of configs) {
|
|
5836
|
+
if (config.provider && !config.type) {
|
|
5837
|
+
config.type = "api_key";
|
|
5838
|
+
}
|
|
5839
|
+
if (config.provider && !config.name) {
|
|
5840
|
+
config.name = config.provider.toUpperCase();
|
|
5841
|
+
}
|
|
5842
|
+
if (!config.provider && !config.type) {
|
|
5843
|
+
throw new Error(i18n.t("multi-config:providerOrTypeRequired"));
|
|
5844
|
+
}
|
|
5845
|
+
if (config.provider && !validProviders.includes(config.provider)) {
|
|
5846
|
+
throw new Error(i18n.t("errors:invalidProvider", {
|
|
5847
|
+
provider: config.provider,
|
|
5848
|
+
validProviders: validProviders.join(", ")
|
|
5849
|
+
}));
|
|
5850
|
+
}
|
|
5729
5851
|
if (!config.name || typeof config.name !== "string" || config.name.trim() === "") {
|
|
5730
5852
|
throw new Error(i18n.t("multi-config:mustHaveValidName"));
|
|
5731
5853
|
}
|
|
@@ -5776,7 +5898,7 @@ async function handleCodexConfigs(configs) {
|
|
|
5776
5898
|
const { addProviderToExisting } = await import('./codex-provider-manager.mjs');
|
|
5777
5899
|
for (const config of configs) {
|
|
5778
5900
|
try {
|
|
5779
|
-
const provider = convertToCodexProvider(config);
|
|
5901
|
+
const provider = await convertToCodexProvider(config);
|
|
5780
5902
|
const result = await addProviderToExisting(provider, config.key || "");
|
|
5781
5903
|
if (!result.success) {
|
|
5782
5904
|
throw new Error(i18n.t("multi-config:providerAddFailed", { name: config.name, error: result.error }));
|
|
@@ -5799,23 +5921,54 @@ async function handleCodexConfigs(configs) {
|
|
|
5799
5921
|
}
|
|
5800
5922
|
async function convertToClaudeCodeProfile(config) {
|
|
5801
5923
|
const { ClaudeCodeConfigManager } = await import('./claude-code-config-manager.mjs');
|
|
5924
|
+
let baseUrl = config.url;
|
|
5925
|
+
let primaryModel = config.primaryModel;
|
|
5926
|
+
let fastModel = config.fastModel;
|
|
5927
|
+
let authType = config.type || "api_key";
|
|
5928
|
+
if (config.provider && config.provider !== "custom") {
|
|
5929
|
+
const { getProviderPreset } = await import('./api-providers.mjs');
|
|
5930
|
+
const preset = getProviderPreset(config.provider);
|
|
5931
|
+
if (preset?.claudeCode) {
|
|
5932
|
+
baseUrl = baseUrl || preset.claudeCode.baseUrl;
|
|
5933
|
+
authType = preset.claudeCode.authType;
|
|
5934
|
+
if (preset.claudeCode.defaultModels && preset.claudeCode.defaultModels.length >= 2) {
|
|
5935
|
+
primaryModel = primaryModel || preset.claudeCode.defaultModels[0];
|
|
5936
|
+
fastModel = fastModel || preset.claudeCode.defaultModels[1];
|
|
5937
|
+
}
|
|
5938
|
+
}
|
|
5939
|
+
}
|
|
5802
5940
|
const profile = {
|
|
5803
5941
|
name: config.name,
|
|
5804
|
-
authType
|
|
5942
|
+
authType,
|
|
5805
5943
|
apiKey: config.key,
|
|
5806
|
-
baseUrl
|
|
5944
|
+
baseUrl,
|
|
5945
|
+
primaryModel,
|
|
5946
|
+
fastModel,
|
|
5807
5947
|
id: ClaudeCodeConfigManager.generateProfileId(config.name)
|
|
5808
5948
|
};
|
|
5809
5949
|
return profile;
|
|
5810
5950
|
}
|
|
5811
|
-
function convertToCodexProvider(config) {
|
|
5951
|
+
async function convertToCodexProvider(config) {
|
|
5952
|
+
let baseUrl = config.url || API_DEFAULT_URL;
|
|
5953
|
+
let model = config.primaryModel || "gpt-5-codex";
|
|
5954
|
+
let wireApi = "chat";
|
|
5955
|
+
if (config.provider && config.provider !== "custom") {
|
|
5956
|
+
const { getProviderPreset } = await import('./api-providers.mjs');
|
|
5957
|
+
const preset = getProviderPreset(config.provider);
|
|
5958
|
+
if (preset?.codex) {
|
|
5959
|
+
baseUrl = config.url || preset.codex.baseUrl;
|
|
5960
|
+
model = config.primaryModel || preset.codex.defaultModel || model;
|
|
5961
|
+
wireApi = preset.codex.wireApi;
|
|
5962
|
+
}
|
|
5963
|
+
}
|
|
5812
5964
|
return {
|
|
5813
5965
|
id: config.name.toLowerCase().replace(/[^a-z0-9]/g, "-"),
|
|
5814
5966
|
name: config.name,
|
|
5815
|
-
baseUrl
|
|
5816
|
-
wireApi
|
|
5967
|
+
baseUrl,
|
|
5968
|
+
wireApi,
|
|
5817
5969
|
envKey: API_ENV_KEY,
|
|
5818
|
-
requiresOpenaiAuth: false
|
|
5970
|
+
requiresOpenaiAuth: false,
|
|
5971
|
+
model
|
|
5819
5972
|
};
|
|
5820
5973
|
}
|
|
5821
5974
|
|
|
@@ -5897,4 +6050,4 @@ async function openSettingsJson() {
|
|
|
5897
6050
|
}
|
|
5898
6051
|
}
|
|
5899
6052
|
|
|
5900
|
-
export {
|
|
6053
|
+
export { getExistingModelConfig as $, API_DEFAULT_URL as A, getAiOutputLanguageLabel as B, CLAUDE_DIR as C, DEFAULT_CODE_TOOL_TYPE as D, getMcpConfigPath as E, readMcpConfig as F, writeMcpConfig as G, backupMcpConfig as H, mergeMcpServers as I, buildMcpServerConfig as J, fixWindowsMcpConfig as K, LEGACY_ZCF_CONFIG_FILES as L, addCompletedOnboarding as M, ensureApiKeyApproved as N, removeApiKeyFromRejected as O, manageApiKeyApproval as P, setPrimaryApiKey as Q, ensureClaudeDir as R, SETTINGS_FILE as S, backupExistingConfig as T, copyConfigFiles as U, configureApi as V, mergeConfigs as W, updateCustomModel as X, updateDefaultModel as Y, ZCF_CONFIG_DIR as Z, mergeSettingsFile as _, commandExists as a, switchToOfficialLogin as a$, getExistingApiConfig as a0, applyAiLanguageDirective as a1, switchToOfficialLogin$1 as a2, promptApiConfigurationAction as a3, isClaudeCodeInstalled as a4, installClaudeCode as a5, isLocalClaudeCodeInstalled as a6, getInstallationStatus as a7, removeLocalClaudeCode as a8, setInstallMethod as a9, modifyApiConfigPartially as aA, formatApiKeyDisplay as aB, readCcrConfig as aC, configureCcrFeature as aD, handleExitPromptError as aE, handleGeneralError as aF, COMETIX_COMMAND_NAME as aG, COMETIX_COMMANDS as aH, installCometixLine as aI, checkAndUpdateTools as aJ, runCodexUpdate as aK, resolveCodeType as aL, writeJsonConfig as aM, displayBanner as aN, version as aO, resolveAiOutputLanguage as aP, updatePromptOnly as aQ, selectAndInstallWorkflows as aR, checkClaudeCodeVersionAndPrompt as aS, displayBannerWithInfo as aT, runCodexUninstall as aU, configureCodexMcp as aV, configureCodexApi as aW, runCodexWorkflowImportWithLanguageSelection as aX, runCodexFullInit as aY, switchCodexProvider as aZ, listCodexProviders as a_, ensureI18nInitialized as aa, i18n as ab, addNumbersToChoices as ac, validateApiKey as ad, ensureDir as ae, readDefaultTomlConfig as af, createDefaultTomlConfig as ag, exists as ah, readJsonConfig as ai, writeTomlConfig as aj, copyFile as ak, detectConfigManagementMode as al, readCodexConfig as am, backupCodexComplete as an, writeCodexConfig as ao, writeAuthFile as ap, updateZcfConfig as aq, changeLanguage as ar, readZcfConfig as as, configureOutputStyle as at, isWindows as au, selectMcpServices as av, getMcpServices as aw, isCcrInstalled as ax, installCcr as ay, setupCcrConfiguration as az, importRecommendedEnv as b, switchToProvider as b0, readZcfConfigAsync as b1, initI18n as b2, selectScriptLanguage as b3, index as b4, fsOperations as b5, jsonConfig as b6, claudeConfig as b7, config$1 as b8, config as b9, prompts as ba, codex as bb, cleanupPermissions as c, importRecommendedPermissions as d, CLAUDE_MD_FILE as e, ClAUDE_CONFIG_FILE as f, getPlatform as g, CLAUDE_VSC_CONFIG_FILE as h, init as i, CODEX_DIR as j, CODEX_CONFIG_FILE as k, CODEX_AUTH_FILE as l, mergeAndCleanPermissions as m, CODEX_AGENTS_FILE as n, openSettingsJson as o, CODEX_PROMPTS_DIR as p, ZCF_CONFIG_FILE as q, CODE_TOOL_TYPES as r, CODE_TOOL_BANNERS as s, CODE_TOOL_ALIASES as t, isCodeToolType as u, API_ENV_KEY as v, resolveCodeToolType as w, SUPPORTED_LANGS as x, LANG_LABELS as y, AI_OUTPUT_LANGUAGES as z };
|