zcf 3.2.2 → 3.2.3
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 +48 -10
- package/dist/chunks/claude-code-incremental-manager.mjs +4 -4
- package/dist/chunks/codex-config-switch.mjs +4 -4
- package/dist/chunks/simple-config.mjs +22 -18
- package/dist/cli.mjs +18 -5
- package/dist/i18n/locales/en/common.json +0 -1
- package/dist/i18n/locales/en/errors.json +1 -1
- package/dist/i18n/locales/zh-CN/common.json +0 -1
- package/dist/i18n/locales/zh-CN/errors.json +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
# ZCF - Zero-Config Code Flow
|
|
2
|
-
|
|
3
1
|
[![npm version][npm-version-src]][npm-version-href]
|
|
4
2
|
[![npm downloads][npm-downloads-src]][npm-downloads-href]
|
|
5
3
|
[![License][license-src]][license-href]
|
|
@@ -8,13 +6,26 @@
|
|
|
8
6
|
[![JSDocs][jsdocs-src]][jsdocs-href]
|
|
9
7
|
[![Ask DeepWiki][deepwiki-src]][deepwiki-href]
|
|
10
8
|
|
|
11
|
-
|
|
9
|
+
<div align="center">
|
|
10
|
+
<img src="./src/assets/banner.webp" alt="Banner"/>
|
|
11
|
+
|
|
12
|
+
<h1>
|
|
13
|
+
ZCF - Zero-Config Code Flow
|
|
14
|
+
</h1>
|
|
15
|
+
|
|
16
|
+
<p align="center">
|
|
17
|
+
<b>English</b> | <a href="README_zh-CN.md">中文</a> | <a href="README_ja-JP.md">日本語</a> | <a href="CHANGELOG.md">Changelog</a>
|
|
12
18
|
|
|
13
19
|
**✨ Quick Links**: [Codex Support](#-codex-support-v300-new) | [BMad Workflow](#-bmad-workflow-v27-new-feature) | [Spec Workflow](#-spec-workflow-v2124-new-feature) | [Open Web Search](#-open-web-search-v2129-new-feature) | [CCR Router](#-ccr-claude-code-router-support-v28-enhanced) | [CCometixLine](#-ccometixline-support-status-bar-tool-v299-new) | [Output Styles](#-ai-output-styles-v212-new-feature) | [Multi-Configuration Management](#-multi-configuration-management-v320-new)
|
|
14
20
|
|
|
15
21
|
> Zero-config, one-click setup for Claude Code & Codex with bilingual support, intelligent agent system and personalized AI assistant
|
|
22
|
+
</p>
|
|
23
|
+
</div>
|
|
16
24
|
|
|
17
|
-
|
|
25
|
+
## ♥️ Sponsor AI API
|
|
26
|
+
|
|
27
|
+
[](https://share.302.ai/gAT9VG)
|
|
28
|
+
[302.AI](https://share.302.ai/gAT9VG) is a pay-as-you-go enterprise AI resource hub that offers the latest and most comprehensive AI models and APIs on the market, along with a variety of ready-to-use online AI applications.
|
|
18
29
|
|
|
19
30
|
## 🚀 Quick Start
|
|
20
31
|
|
|
@@ -211,6 +222,13 @@ ZCF allows seamless switching between Claude Code and Codex while preserving you
|
|
|
211
222
|
|
|
212
223
|
ZCF now supports customizable AI output styles to personalize your Claude Code experience:
|
|
213
224
|
|
|
225
|
+
<p align="center">
|
|
226
|
+
<a href="https://github.com/Haleclipse">
|
|
227
|
+
<img src="./src/assets/Haleclipse.gif" alt="Halley-chan" width="200"/>
|
|
228
|
+
</a>
|
|
229
|
+
<div align="center">Tsundere <a href="https://github.com/Haleclipse">Halley-chan</a> Ojou-sama ( ̄▽ ̄)ゞ</div>
|
|
230
|
+
</p>
|
|
231
|
+
|
|
214
232
|
**Available Output Styles:**
|
|
215
233
|
|
|
216
234
|
- `engineer-professional`: Professional software engineer following SOLID, KISS, DRY, YAGNI principles
|
|
@@ -823,15 +841,26 @@ If you find this project helpful, please consider sponsoring its development. Yo
|
|
|
823
841
|
### Our Sponsors
|
|
824
842
|
|
|
825
843
|
A huge thank you to all our sponsors for their generous support!
|
|
826
|
-
|
|
844
|
+
- [302.AI](https://share.302.ai/gAT9VG) (first corporate sponsorship 🤠)
|
|
827
845
|
- Tc (first sponsor)
|
|
828
846
|
- Argolinhas (first ko-fi sponsor ٩(•̤̀ᵕ•̤́๑))
|
|
829
|
-
- r\*r (first anonymous sponsor🤣)
|
|
830
|
-
- \*\*康 (first KFC sponsor🍗)
|
|
831
|
-
- \*东 (first coffee sponsor☕️)
|
|
832
|
-
- 炼\*3 (first Termux user sponsor📱)
|
|
847
|
+
- r\*r (first anonymous sponsor 🤣)
|
|
848
|
+
- \*\*康 (first KFC sponsor 🍗)
|
|
849
|
+
- \*东 (first coffee sponsor ☕️)
|
|
850
|
+
- 炼\*3 (first Termux user sponsor 📱)
|
|
833
851
|
- [chamo101](https://github.com/chamo101) (first GitHub issue sponsor 🎉)
|
|
834
|
-
-
|
|
852
|
+
- 初屿贤 (first Codex user sponsor 🙅🏻♂️)
|
|
853
|
+
- Protein (first 1688 sponsor 😏)
|
|
854
|
+
- [BeatSeat](https://github.com/BeatSeat) (community expert 😎, provided $1000 Claude credits)
|
|
855
|
+
- [wenwen](https://github.com/wenwen12345) (community expert 🤓, provided daily $100 Claude&GPT credits)
|
|
856
|
+
- 16°C coffee (My best friend 🤪, offered ChatGPT Pro $200 package)
|
|
857
|
+
|
|
858
|
+
### Promotion Thanks
|
|
859
|
+
|
|
860
|
+
Thanks to the following authors for promoting this project:
|
|
861
|
+
|
|
862
|
+
- 逛逛 GitHub, article: https://mp.weixin.qq.com/s/phqwSRb16MKCHHVozTFeiQ
|
|
863
|
+
- Geek, tweet: https://x.com/geekbb/status/1955174718618866076
|
|
835
864
|
|
|
836
865
|
## 📄 License
|
|
837
866
|
|
|
@@ -839,6 +868,15 @@ A huge thank you to all our sponsors for their generous support!
|
|
|
839
868
|
|
|
840
869
|
---
|
|
841
870
|
|
|
871
|
+
## 🚀 Contributors
|
|
872
|
+
|
|
873
|
+
<a href="https://github.com/UfoMiao/zcf/graphs/contributors">
|
|
874
|
+
<img src="https://contrib.rocks/image?repo=UfoMiao/zcf" />
|
|
875
|
+
</a>
|
|
876
|
+
<br /><br />
|
|
877
|
+
|
|
878
|
+
## ⭐️ Star History
|
|
879
|
+
|
|
842
880
|
If this project helps you, please give me a ⭐️ Star!
|
|
843
881
|
|
|
844
882
|
[](https://star-history.com/#UfoMiao/zcf&Date)
|
|
@@ -131,9 +131,9 @@ ${i18n.t("multi-config:addingNewProfile")}`));
|
|
|
131
131
|
}
|
|
132
132
|
},
|
|
133
133
|
{
|
|
134
|
-
type: "
|
|
134
|
+
type: "input",
|
|
135
135
|
name: "apiKey",
|
|
136
|
-
message: i18n.t("multi-config:apiKeyPrompt")
|
|
136
|
+
message: i18n.t("multi-config:apiKeyPrompt"),
|
|
137
137
|
when: (answers2) => answers2.authType !== "ccr_proxy",
|
|
138
138
|
validate: (input) => {
|
|
139
139
|
const trimmed = input.trim();
|
|
@@ -288,9 +288,9 @@ ${i18n.t("multi-config:editingProfile", { name: selectedProfile.name })}`));
|
|
|
288
288
|
}
|
|
289
289
|
},
|
|
290
290
|
{
|
|
291
|
-
type: "
|
|
291
|
+
type: "input",
|
|
292
292
|
name: "apiKey",
|
|
293
|
-
message: i18n.t("multi-config:apiKeyPrompt")
|
|
293
|
+
message: i18n.t("multi-config:apiKeyPrompt"),
|
|
294
294
|
default: selectedProfile.apiKey,
|
|
295
295
|
when: () => selectedProfile.authType !== "ccr_proxy",
|
|
296
296
|
validate: (input) => {
|
|
@@ -91,9 +91,9 @@ async function handleAddProvider() {
|
|
|
91
91
|
default: "responses"
|
|
92
92
|
},
|
|
93
93
|
{
|
|
94
|
-
type: "
|
|
94
|
+
type: "input",
|
|
95
95
|
name: "apiKey",
|
|
96
|
-
message: i18n.t("codex:providerApiKeyPrompt")
|
|
96
|
+
message: i18n.t("codex:providerApiKeyPrompt"),
|
|
97
97
|
validate: (input) => !!input.trim() || i18n.t("codex:providerApiKeyRequired")
|
|
98
98
|
}
|
|
99
99
|
]);
|
|
@@ -169,9 +169,9 @@ async function handleEditProvider(providers) {
|
|
|
169
169
|
default: provider.wireApi
|
|
170
170
|
},
|
|
171
171
|
{
|
|
172
|
-
type: "
|
|
172
|
+
type: "input",
|
|
173
173
|
name: "apiKey",
|
|
174
|
-
message: i18n.t("codex:providerApiKeyPrompt")
|
|
174
|
+
message: i18n.t("codex:providerApiKeyPrompt"),
|
|
175
175
|
validate: (input) => !!input.trim() || i18n.t("codex:providerApiKeyRequired")
|
|
176
176
|
}
|
|
177
177
|
]);
|
|
@@ -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.2.
|
|
19
|
+
const version = "3.2.3";
|
|
20
20
|
const homepage = "https://github.com/UfoMiao/zcf";
|
|
21
21
|
|
|
22
22
|
const i18n = i18next.createInstance();
|
|
@@ -1666,9 +1666,9 @@ async function configureCcrWithPreset(preset) {
|
|
|
1666
1666
|
if (preset.requiresApiKey) {
|
|
1667
1667
|
try {
|
|
1668
1668
|
const { apiKey } = await inquirer.prompt({
|
|
1669
|
-
type: "
|
|
1669
|
+
type: "input",
|
|
1670
1670
|
name: "apiKey",
|
|
1671
|
-
message: i18n.t("ccr:enterApiKeyForProvider").replace("{provider}", preset.name)
|
|
1671
|
+
message: i18n.t("ccr:enterApiKeyForProvider").replace("{provider}", preset.name),
|
|
1672
1672
|
validate: async (value) => !!value || i18n.t("api:keyRequired")
|
|
1673
1673
|
});
|
|
1674
1674
|
provider.api_key = apiKey;
|
|
@@ -2867,9 +2867,9 @@ async function configureCodexMcp(options) {
|
|
|
2867
2867
|
if (configInfo.requiresApiKey && configInfo.apiKeyEnvVar) {
|
|
2868
2868
|
const promptMessage = serviceMeta?.apiKeyPrompt || i18n.t("mcp:apiKeyPrompt");
|
|
2869
2869
|
const { apiKey } = await inquirer.prompt([{
|
|
2870
|
-
type: "
|
|
2870
|
+
type: "input",
|
|
2871
2871
|
name: "apiKey",
|
|
2872
|
-
message: promptMessage
|
|
2872
|
+
message: promptMessage,
|
|
2873
2873
|
validate: (input) => !!input || i18n.t("api:keyRequired")
|
|
2874
2874
|
}]);
|
|
2875
2875
|
if (!apiKey)
|
|
@@ -3743,9 +3743,9 @@ async function configureCodexApi(options) {
|
|
|
3743
3743
|
default: (answers2) => existingMap.get(sanitizeProviderName(answers2.providerName))?.wireApi || "responses"
|
|
3744
3744
|
},
|
|
3745
3745
|
{
|
|
3746
|
-
type: "
|
|
3746
|
+
type: "input",
|
|
3747
3747
|
name: "apiKey",
|
|
3748
|
-
message: i18n.t("codex:providerApiKeyPrompt")
|
|
3748
|
+
message: i18n.t("codex:providerApiKeyPrompt"),
|
|
3749
3749
|
validate: (input) => !!input || i18n.t("codex:providerApiKeyRequired")
|
|
3750
3750
|
}
|
|
3751
3751
|
]);
|
|
@@ -4147,12 +4147,16 @@ async function resolveCodeType(codeTypeParam) {
|
|
|
4147
4147
|
const validAbbreviations = Object.keys(CODE_TYPE_ABBREVIATIONS);
|
|
4148
4148
|
const validFullTypes = Object.values(CODE_TYPE_ABBREVIATIONS);
|
|
4149
4149
|
const validOptions = [...validAbbreviations, ...validFullTypes].join(", ");
|
|
4150
|
+
let defaultValue = DEFAULT_CODE_TOOL_TYPE;
|
|
4151
|
+
try {
|
|
4152
|
+
const config = await readZcfConfigAsync();
|
|
4153
|
+
if (config?.codeToolType && isValidCodeType(config.codeToolType)) {
|
|
4154
|
+
defaultValue = config.codeToolType;
|
|
4155
|
+
}
|
|
4156
|
+
} catch {
|
|
4157
|
+
}
|
|
4150
4158
|
throw new Error(
|
|
4151
|
-
i18n.t(
|
|
4152
|
-
"errors:invalidCodeType",
|
|
4153
|
-
`Invalid code type: "${codeTypeParam}". Valid options are: ${validOptions}.`,
|
|
4154
|
-
{ value: codeTypeParam, validOptions }
|
|
4155
|
-
)
|
|
4159
|
+
i18n.t("errors:invalidCodeType", { value: codeTypeParam, validOptions, defaultValue })
|
|
4156
4160
|
);
|
|
4157
4161
|
}
|
|
4158
4162
|
try {
|
|
@@ -4544,9 +4548,9 @@ async function configureApiCompletely(preselectedAuthType) {
|
|
|
4544
4548
|
console.log(ansis.yellow(i18n.t("common:cancelled")));
|
|
4545
4549
|
return null;
|
|
4546
4550
|
}
|
|
4547
|
-
const keyMessage = authType === "auth_token" ? i18n.t("api:enterAuthToken")
|
|
4551
|
+
const keyMessage = authType === "auth_token" ? i18n.t("api:enterAuthToken") : i18n.t("api:enterApiKey");
|
|
4548
4552
|
const { key } = await inquirer.prompt({
|
|
4549
|
-
type: "
|
|
4553
|
+
type: "input",
|
|
4550
4554
|
name: "key",
|
|
4551
4555
|
message: keyMessage,
|
|
4552
4556
|
validate: async (value) => {
|
|
@@ -4617,9 +4621,9 @@ async function modifyApiConfigPartially(existingConfig) {
|
|
|
4617
4621
|
}
|
|
4618
4622
|
} else if (item === "key") {
|
|
4619
4623
|
const authType = currentConfig.authType || "auth_token";
|
|
4620
|
-
const keyMessage = authType === "auth_token" ? i18n.t("api:enterNewApiKey").replace("{key}", currentConfig.key ? formatApiKeyDisplay(currentConfig.key) : i18n.t("common:none"))
|
|
4624
|
+
const keyMessage = authType === "auth_token" ? i18n.t("api:enterNewApiKey").replace("{key}", currentConfig.key ? formatApiKeyDisplay(currentConfig.key) : i18n.t("common:none")) : i18n.t("api:enterNewApiKey").replace("{key}", currentConfig.key ? formatApiKeyDisplay(currentConfig.key) : i18n.t("common:none"));
|
|
4621
4625
|
const { key } = await inquirer.prompt({
|
|
4622
|
-
type: "
|
|
4626
|
+
type: "input",
|
|
4623
4627
|
name: "key",
|
|
4624
4628
|
message: keyMessage,
|
|
4625
4629
|
validate: async (value) => {
|
|
@@ -5613,9 +5617,9 @@ async function init(options = {}) {
|
|
|
5613
5617
|
continue;
|
|
5614
5618
|
} else {
|
|
5615
5619
|
const response = await inquirer.prompt({
|
|
5616
|
-
type: "
|
|
5620
|
+
type: "input",
|
|
5617
5621
|
name: "apiKey",
|
|
5618
|
-
message: service.apiKeyPrompt
|
|
5622
|
+
message: service.apiKeyPrompt,
|
|
5619
5623
|
validate: (value) => !!value || i18n.t("api:keyRequired")
|
|
5620
5624
|
});
|
|
5621
5625
|
if (!response.apiKey) {
|
package/dist/cli.mjs
CHANGED
|
@@ -328,9 +328,9 @@ async function configureMcpFeature() {
|
|
|
328
328
|
let config = service.config;
|
|
329
329
|
if (service.requiresApiKey) {
|
|
330
330
|
const { apiKey } = await inquirer.prompt({
|
|
331
|
-
type: "
|
|
331
|
+
type: "input",
|
|
332
332
|
name: "apiKey",
|
|
333
|
-
message: service.apiKeyPrompt
|
|
333
|
+
message: service.apiKeyPrompt,
|
|
334
334
|
validate: async (value) => !!value || i18n.t("api:keyRequired")
|
|
335
335
|
});
|
|
336
336
|
if (apiKey) {
|
|
@@ -2113,8 +2113,21 @@ async function showCodexMenu() {
|
|
|
2113
2113
|
}
|
|
2114
2114
|
return void 0;
|
|
2115
2115
|
}
|
|
2116
|
-
async function showMainMenu() {
|
|
2116
|
+
async function showMainMenu(options = {}) {
|
|
2117
2117
|
try {
|
|
2118
|
+
if (options.codeType) {
|
|
2119
|
+
try {
|
|
2120
|
+
const resolvedType = await resolveCodeType$1(options.codeType);
|
|
2121
|
+
const currentType = getCurrentCodeTool();
|
|
2122
|
+
if (resolvedType !== currentType) {
|
|
2123
|
+
updateZcfConfig({ codeToolType: resolvedType });
|
|
2124
|
+
console.log(ansis.green(`\u2714 ${i18n.t("menu:codeToolSwitched", { tool: getCodeToolLabel(resolvedType) })}`));
|
|
2125
|
+
}
|
|
2126
|
+
} catch (err) {
|
|
2127
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
2128
|
+
console.error(ansis.yellow(errorMessage));
|
|
2129
|
+
}
|
|
2130
|
+
}
|
|
2118
2131
|
let exitMenu = false;
|
|
2119
2132
|
while (!exitMenu) {
|
|
2120
2133
|
const codeTool = getCurrentCodeTool();
|
|
@@ -2546,8 +2559,8 @@ async function setupCommands(cli) {
|
|
|
2546
2559
|
await initI18n(defaultLang);
|
|
2547
2560
|
} catch {
|
|
2548
2561
|
}
|
|
2549
|
-
cli.command("", "Show interactive menu (default)").option("--lang, -l <lang>", "ZCF display language (zh-CN, en)").option("--all-lang, -g <lang>", "Set all language parameters to this value").option("--config-lang, -c <lang>", "Configuration language (zh-CN, en)").option("--force, -f", "Force overwrite existing configuration").option("--code-type, -T <codeType>", "Select code tool type (claude-code, codex, cc, cx)").action(await withLanguageResolution(async () => {
|
|
2550
|
-
await showMainMenu();
|
|
2562
|
+
cli.command("", "Show interactive menu (default)").option("--lang, -l <lang>", "ZCF display language (zh-CN, en)").option("--all-lang, -g <lang>", "Set all language parameters to this value").option("--config-lang, -c <lang>", "Configuration language (zh-CN, en)").option("--force, -f", "Force overwrite existing configuration").option("--code-type, -T <codeType>", "Select code tool type (claude-code, codex, cc, cx)").action(await withLanguageResolution(async (options) => {
|
|
2563
|
+
await showMainMenu({ codeType: options.codeType });
|
|
2551
2564
|
}));
|
|
2552
2565
|
cli.command("init", "Initialize Claude Code configuration").alias("i").option("--lang, -l <lang>", "ZCF display language (zh-CN, en)").option("--config-lang, -c <lang>", "Configuration language (zh-CN, en)").option("--ai-output-lang, -a <lang>", "AI output language").option("--force, -f", "Force overwrite existing configuration").option("--skip-prompt, -s", "Skip all interactive prompts (non-interactive mode)").option("--config-action, -r <action>", `Config handling (new/backup/merge/docs-only/skip), ${i18n.t("cli:help.defaults.prefix")} backup`).option("--api-type, -t <type>", "API type (auth_token/api_key/ccr_proxy/skip)").option("--api-key, -k <key>", "API key (used for both API key and auth token types)").option("--api-url, -u <url>", "Custom API URL").option("--api-model, -M <model>", "Primary API model (e.g., claude-sonnet-4-5)").option("--api-fast-model, -F <model>", "Fast API model (e.g., claude-haiku-4-5)").option("--mcp-services, -m <services>", `Comma-separated MCP services to install (context7,mcp-deepwiki,Playwright,exa), "skip" to skip all, "all" for all non-key services, ${i18n.t("cli:help.defaults.prefix")} all`).option("--workflows, -w <workflows>", `Comma-separated workflows to install (sixStepsWorkflow,featPlanUx,gitWorkflow,bmadWorkflow), "skip" to skip all, "all" for all workflows, ${i18n.t("cli:help.defaults.prefix")} all`).option("--output-styles, -o <styles>", `Comma-separated output styles (engineer-professional,nekomata-engineer,laowang-engineer,default,explanatory,learning), "skip" to skip all, "all" for all custom styles, ${i18n.t("cli:help.defaults.prefix")} all`).option("--default-output-style, -d <style>", `Default output style, ${i18n.t("cli:help.defaults.prefix")} engineer-professional`).option("--all-lang, -g <lang>", "Set all language parameters to this value").option("--code-type, -T <codeType>", "Select code tool type (claude-code, codex, cc, cx)").option("--install-cometix-line, -x <value>", `Install CCometixLine statusline tool (true/false), ${i18n.t("cli:help.defaults.prefix")} true`).option("--api-configs <configs>", "API configurations as JSON string for multiple profiles").option("--api-configs-file <file>", "Path to JSON file containing API configurations").action(await withLanguageResolution(async (options) => {
|
|
2553
2566
|
await init(options);
|
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
"goodbye": "👋 Thanks for using ZCF! Goodbye!",
|
|
12
12
|
"returnToMenu": "Return to main menu?",
|
|
13
13
|
"back": "Back",
|
|
14
|
-
"inputHidden": " (input will be hidden)",
|
|
15
14
|
"operationFailed": "Operation failed",
|
|
16
15
|
"backupCreated": "📁 Configuration backup created: {{path}}",
|
|
17
16
|
"current": "current"
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"invalidAuthTokenConfig": "Invalid ANTHROPIC_AUTH_TOKEN: expected string",
|
|
20
20
|
"invalidPermissionsConfig": "Invalid permissions configuration: expected object",
|
|
21
21
|
"invalidPermissionsAllow": "Invalid permissions.allow: expected array",
|
|
22
|
-
"invalidCodeType": "Invalid code type: \"{value}\". Valid options are: {validOptions}",
|
|
22
|
+
"invalidCodeType": "Invalid code type: \"{value}\". Valid options are: {validOptions}. Using default: {defaultValue}.",
|
|
23
23
|
"generalError": "Error",
|
|
24
24
|
"stackTrace": "Stack"
|
|
25
25
|
}
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"invalidAuthTokenConfig": "无效的 ANTHROPIC_AUTH_TOKEN:期望字符串类型",
|
|
20
20
|
"invalidPermissionsConfig": "无效的权限配置:期望对象类型",
|
|
21
21
|
"invalidPermissionsAllow": "无效的 permissions.allow:期望数组类型",
|
|
22
|
-
"invalidCodeType": "无效的代码类型:\"{value}\"。可用的类型:{validOptions}",
|
|
22
|
+
"invalidCodeType": "无效的代码类型:\"{value}\"。可用的类型:{validOptions}。使用默认值:{defaultValue}。",
|
|
23
23
|
"generalError": "错误",
|
|
24
24
|
"stackTrace": "堆栈跟踪"
|
|
25
25
|
}
|