zcf 3.6.0 → 3.6.2

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 CHANGED
@@ -24,24 +24,29 @@
24
24
 
25
25
  ## ♥️ Sponsor AI API
26
26
 
27
- [![Sponsor AI API](./src/assets/302.ai-en.jpg)](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.
29
-
30
- ---
31
-
32
27
  [![GLM](./src/assets/GLM-en.png)](https://z.ai/subscribe?ic=8JVLJQFSKB)
28
+
33
29
  This project is sponsored by Z.ai, supporting us with their GLM CODING PLAN.
34
- GLM CODING PLAN is a subscription service designed for AI coding, starting at just $3/month. It provides access to their flagship GLM-4.7 model across 10+ popular AI coding tools (Claude Code, Cline, Roo Code, etc.), offering developers top-tier, fast, and stable coding experiences.
30
+ GLM CODING PLAN is a subscription service designed for AI coding, starting at just $10/month. It provides access to their flagship GLM-4.7 & (GLM-5 Only Available for Pro Users)model across 10+ popular AI coding tools (Claude Code, Cline, Roo Code, etc.), offering developers top-tier, fast, and stable coding experiences.
35
31
  Get 10% OFF GLM CODING PLAN:https://z.ai/subscribe?ic=8JVLJQFSKB
36
32
 
37
33
  ---
38
34
 
35
+ [![Sponsor AI API](./src/assets/302.ai-en.jpg)](https://share.302.ai/gAT9VG)
36
+ [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.
37
+
38
+ ---
39
+
39
40
  <table>
40
41
  <tbody>
41
42
  <tr>
42
43
  <td width="180"><a href="https://www.packyapi.com/register?aff=zcf"><img src="./src/assets/packycode.png" alt="PackyCode" width="150"></a></td>
43
44
  <td>Thanks to PackyCode for sponsoring this project! PackyCode is a reliable and efficient API relay service provider, offering relay services for Claude Code, Codex, Gemini, and more. PackyCode provides special discounts for our software users: register using <a href="https://www.packyapi.com/register?aff=zcf">this link</a> and enter the "zcf" promo code during recharge to get 10% off.</td>
44
45
  </tr>
46
+ <tr>
47
+ <td width="180"><a href="https://www.aicodemirror.com/register?invitecode=ZCFZCF"><img src="./src/assets/AICodeMirror.jpg" alt="AICodeMirror" width="150"></a></td>
48
+ <td>Thanks to AICodeMirror for sponsoring this project! AICodeMirror provides official high-stability relay services for Claude Code/Codex/Gemini CLI, supporting enterprise-level high concurrency, fast invoicing, and 7x24 dedicated technical support. Official channels for Claude Code/Codex/Gemini at discounts as low as 38%/2%/10.9% off, with additional discounts on top-ups! AICodeMirror offers special benefits for ZCF users: users who register through <a href="https://www.aicodemirror.com/register?invitecode=ZCFZCF">this link</a> can enjoy 20% off on first top-up, and enterprise customers can get up to 25% off!</td>
49
+ </tr>
45
50
  <tbody>
46
51
  </table>
47
52
 
@@ -108,6 +113,7 @@ A huge thank you to all our sponsors for their generous support!
108
113
  - [302.AI](https://share.302.ai/gAT9VG) (first corporate sponsorship 🤠)
109
114
  - [GLM](https://z.ai/subscribe?ic=8JVLJQFSKB) (first AI model sponsorship 🤖)
110
115
  - [PackyCode](https://www.packyapi.com/register?aff=zcf) (first API proxy service sponsor 🧝🏻‍♀️)
116
+ - [AICodeMirror](https://www.aicodemirror.com/register?invitecode=ZCFZCF) (official high-stability relay service sponsor 🪞)
111
117
  - [UUCode](https://www.uucode.org/auth?ref=JQ2DJ1T8) (sponsored $100 proxy credits 💰)
112
118
 
113
119
  【Individual Sponsors】
@@ -28,49 +28,83 @@ const API_PROVIDER_PRESETS = [
28
28
  description: "PackyCode API Service"
29
29
  },
30
30
  {
31
- id: "glm",
32
- name: "GLM",
31
+ id: "aicodemirror",
32
+ name: "AICodeMirror",
33
33
  supportedCodeTools: ["claude-code", "codex"],
34
34
  claudeCode: {
35
- baseUrl: "https://open.bigmodel.cn/api/anthropic",
35
+ baseUrl: "https://api.aicodemirror.com/api/claudecode",
36
36
  authType: "auth_token"
37
37
  },
38
38
  codex: {
39
- baseUrl: "https://open.bigmodel.cn/api/coding/paas/v4",
40
- wireApi: "chat",
41
- defaultModel: "GLM-4.7"
39
+ baseUrl: "https://api.aicodemirror.com/api/codex/backend-api/codex",
40
+ wireApi: "responses"
41
+ },
42
+ description: "AICodeMirror Global High-Quality Line"
43
+ },
44
+ {
45
+ id: "aicodemirror-cn",
46
+ name: "AICodeMirror CN",
47
+ supportedCodeTools: ["claude-code", "codex"],
48
+ claudeCode: {
49
+ baseUrl: "https://api.claudecode.net.cn/api/claudecode",
50
+ authType: "auth_token"
51
+ },
52
+ codex: {
53
+ baseUrl: "https://api.claudecode.net.cn/api/codex/backend-api/codex",
54
+ wireApi: "responses"
55
+ },
56
+ description: "AICodeMirror China Optimized Line"
57
+ },
58
+ {
59
+ id: "glm-cn",
60
+ name: "GLM CN",
61
+ supportedCodeTools: ["claude-code"],
62
+ claudeCode: {
63
+ baseUrl: "https://open.bigmodel.cn/api/anthropic",
64
+ authType: "auth_token"
42
65
  },
43
66
  description: "GLM (\u667A\u8C31AI)"
44
67
  },
68
+ {
69
+ id: "z-ai",
70
+ name: "Z.ai",
71
+ supportedCodeTools: ["claude-code"],
72
+ claudeCode: {
73
+ baseUrl: "https://api.z.ai/api/anthropic",
74
+ authType: "auth_token"
75
+ },
76
+ description: "Z.ai API Service"
77
+ },
78
+ {
79
+ id: "bailian-coding",
80
+ name: "Bailian Coding",
81
+ supportedCodeTools: ["claude-code"],
82
+ claudeCode: {
83
+ baseUrl: "https://coding.dashscope.aliyuncs.com/apps/anthropic",
84
+ authType: "auth_token",
85
+ defaultModels: ["GLM-5"]
86
+ },
87
+ description: "Bailian Coding API Service"
88
+ },
45
89
  {
46
90
  id: "minimax",
47
91
  name: "MiniMax",
48
- supportedCodeTools: ["claude-code", "codex"],
92
+ supportedCodeTools: ["claude-code"],
49
93
  claudeCode: {
50
94
  baseUrl: "https://api.minimaxi.com/anthropic",
51
95
  authType: "auth_token",
52
96
  defaultModels: ["MiniMax-M2", "MiniMax-M2"]
53
97
  },
54
- codex: {
55
- baseUrl: "https://api.minimaxi.com/v1",
56
- wireApi: "chat",
57
- defaultModel: "MiniMax-M2"
58
- },
59
98
  description: "MiniMax API Service"
60
99
  },
61
100
  {
62
- id: "kimi",
63
- name: "Kimi",
64
- supportedCodeTools: ["claude-code", "codex"],
101
+ id: "kimi-coding",
102
+ name: "Kimi Coding",
103
+ supportedCodeTools: ["claude-code"],
65
104
  claudeCode: {
66
105
  baseUrl: "https://api.kimi.com/coding/",
67
106
  authType: "auth_token"
68
107
  },
69
- codex: {
70
- baseUrl: "https://api.kimi.com/coding/v1",
71
- wireApi: "chat",
72
- defaultModel: "kimi-for-coding"
73
- },
74
108
  description: "Kimi (Moonshot AI)"
75
109
  }
76
110
  ];
@@ -111,17 +111,6 @@ async function handleAddProvider() {
111
111
  when: () => selectedProvider === "custom",
112
112
  validate: (input) => !!input.trim() || i18n.t("codex:providerBaseUrlRequired")
113
113
  },
114
- {
115
- type: "list",
116
- name: "wireApi",
117
- message: i18n.t("codex:providerProtocolPrompt"),
118
- choices: [
119
- { name: i18n.t("codex:protocolResponses"), value: "responses" },
120
- { name: i18n.t("codex:protocolChat"), value: "chat" }
121
- ],
122
- default: prefilledWireApi || "responses",
123
- when: () => selectedProvider === "custom"
124
- },
125
114
  {
126
115
  type: "input",
127
116
  name: "apiKey",
@@ -149,7 +138,7 @@ async function handleAddProvider() {
149
138
  id: providerId,
150
139
  name: answers.providerName.trim(),
151
140
  baseUrl: selectedProvider === "custom" ? answers.baseUrl.trim() : prefilledBaseUrl,
152
- wireApi: selectedProvider === "custom" ? answers.wireApi : prefilledWireApi,
141
+ wireApi: prefilledWireApi || "responses",
153
142
  tempEnvKey: `${providerId.toUpperCase().replace(/-/g, "_")}_API_KEY`,
154
143
  requiresOpenaiAuth: true,
155
144
  model: prefilledModel || "gpt-5.2"
@@ -220,16 +209,6 @@ async function handleEditProvider(providers) {
220
209
  default: provider.baseUrl,
221
210
  validate: (input) => !!input.trim() || i18n.t("codex:providerBaseUrlRequired")
222
211
  },
223
- {
224
- type: "list",
225
- name: "wireApi",
226
- message: i18n.t("codex:providerProtocolPrompt"),
227
- choices: [
228
- { name: i18n.t("codex:protocolResponses"), value: "responses" },
229
- { name: i18n.t("codex:protocolChat"), value: "chat" }
230
- ],
231
- default: provider.wireApi
232
- },
233
212
  {
234
213
  type: "input",
235
214
  name: "apiKey",
@@ -251,7 +230,7 @@ async function handleEditProvider(providers) {
251
230
  const updates = {
252
231
  name: answers.providerName.trim(),
253
232
  baseUrl: answers.baseUrl.trim(),
254
- wireApi: answers.wireApi,
233
+ wireApi: "responses",
255
234
  apiKey: answers.apiKey.trim(),
256
235
  model: model.trim()
257
236
  };
@@ -312,16 +291,6 @@ ${i18n.t("codex:copyingProvider", { name: provider.name })}`));
312
291
  default: provider.baseUrl,
313
292
  validate: (input) => !!input.trim() || i18n.t("codex:providerBaseUrlRequired")
314
293
  },
315
- {
316
- type: "list",
317
- name: "wireApi",
318
- message: i18n.t("codex:providerProtocolPrompt"),
319
- choices: [
320
- { name: i18n.t("codex:protocolResponses"), value: "responses" },
321
- { name: i18n.t("codex:protocolChat"), value: "chat" }
322
- ],
323
- default: provider.wireApi
324
- },
325
294
  {
326
295
  type: "input",
327
296
  name: "apiKey",
@@ -345,7 +314,7 @@ ${i18n.t("codex:copyingProvider", { name: provider.name })}`));
345
314
  id: providerId,
346
315
  name: answers.providerName.trim(),
347
316
  baseUrl: answers.baseUrl.trim(),
348
- wireApi: answers.wireApi,
317
+ wireApi: "responses",
349
318
  tempEnvKey: `${providerId.toUpperCase().replace(/-/g, "_")}_API_KEY`,
350
319
  requiresOpenaiAuth: provider.requiresOpenaiAuth ?? true,
351
320
  model: model.trim()
@@ -1,5 +1,5 @@
1
1
  import * as nodeFs from 'node:fs';
2
- import { existsSync, mkdirSync, copyFileSync, readFileSync, writeFileSync, rmSync, rmdirSync, readdirSync, statSync, unlinkSync, renameSync } from 'node:fs';
2
+ import { existsSync, mkdirSync, copyFileSync, readFileSync, writeFileSync, lstatSync, statSync, rmSync, rmdirSync, readdirSync, unlinkSync, renameSync } from 'node:fs';
3
3
  import process from 'node:process';
4
4
  import ansis from 'ansis';
5
5
  import inquirer from 'inquirer';
@@ -18,7 +18,7 @@ import { rm, mkdir, copyFile as copyFile$1 } from 'node:fs/promises';
18
18
  import i18next from 'i18next';
19
19
  import Backend from 'i18next-fs-backend';
20
20
 
21
- const version = "3.6.0";
21
+ const version = "3.6.2";
22
22
  const homepage = "https://github.com/UfoMiao/zcf";
23
23
 
24
24
  const i18n = i18next.createInstance();
@@ -947,10 +947,35 @@ function copyDir(src, dest, options = {}) {
947
947
  for (const entry of entries) {
948
948
  const srcPath = `${src}/${entry}`;
949
949
  const destPath = `${dest}/${entry}`;
950
- const stats = getStats(srcPath);
950
+ let stats;
951
+ try {
952
+ stats = lstatSync(srcPath);
953
+ } catch (error) {
954
+ if (error.code === "ENOENT") {
955
+ continue;
956
+ }
957
+ throw error;
958
+ }
951
959
  if (filter && !filter(srcPath, stats)) {
952
960
  continue;
953
961
  }
962
+ if (stats.isSymbolicLink()) {
963
+ try {
964
+ existsSync(srcPath);
965
+ const targetStats = statSync(srcPath);
966
+ if (targetStats.isDirectory()) {
967
+ copyDir(srcPath, destPath, options);
968
+ } else {
969
+ if (!overwrite && exists(destPath)) {
970
+ continue;
971
+ }
972
+ copyFile(srcPath, destPath);
973
+ }
974
+ } catch {
975
+ continue;
976
+ }
977
+ continue;
978
+ }
954
979
  if (stats.isDirectory()) {
955
980
  copyDir(srcPath, destPath, options);
956
981
  } else {
@@ -3048,7 +3073,7 @@ function migrateFromJsonConfig(jsonConfig) {
3048
3073
  claudeCode: {
3049
3074
  enabled: jsonConfig.codeToolType === "claude-code",
3050
3075
  outputStyles: jsonConfig.outputStyles || defaultConfig.claudeCode.outputStyles,
3051
- defaultOutputStyle: jsonConfig.defaultOutputStyle || defaultConfig.claudeCode.defaultOutputStyle,
3076
+ defaultOutputStyle: jsonConfig.defaultOutputStyle ?? defaultConfig.claudeCode.defaultOutputStyle,
3052
3077
  installType: claudeCodeInstallType,
3053
3078
  currentProfile: jsonConfig.currentProfileId || defaultConfig.claudeCode.currentProfile,
3054
3079
  profiles: jsonConfig.claudeCode?.profiles || {}
@@ -3912,8 +3937,9 @@ function backupCodexFiles() {
3912
3937
  return cachedSkipPromptBackup;
3913
3938
  const timestamp = dayjs().format("YYYY-MM-DD_HH-mm-ss");
3914
3939
  const backupDir = createBackupDirectory(timestamp);
3940
+ const tmpDir = join(CODEX_DIR, "tmp");
3915
3941
  const filter = (path) => {
3916
- return !path.includes("/backup");
3942
+ return !path.includes("/backup") && !path.startsWith(tmpDir);
3917
3943
  };
3918
3944
  copyDir(CODEX_DIR, backupDir, { filter });
3919
3945
  if (process.env.ZCF_CODEX_SKIP_PROMPT_SINGLE_BACKUP === "true")
@@ -4733,18 +4759,6 @@ async function configureCodexApi(options) {
4733
4759
  when: () => selectedProvider2 === "custom",
4734
4760
  validate: (input) => !!input || i18n.t("codex:providerBaseUrlRequired")
4735
4761
  },
4736
- {
4737
- type: "list",
4738
- name: "wireApi",
4739
- message: i18n.t("codex:providerProtocolPrompt"),
4740
- choices: [
4741
- { name: i18n.t("codex:protocolResponses"), value: "responses" },
4742
- { name: i18n.t("codex:protocolChat"), value: "chat" }
4743
- ],
4744
- default: prefilledWireApi || ((answers2) => existingMap.get(sanitizeProviderName(answers2.providerName))?.wireApi || "responses"),
4745
- when: () => selectedProvider2 === "custom"
4746
- // Only ask if custom
4747
- },
4748
4762
  {
4749
4763
  type: "input",
4750
4764
  name: "apiKey",
@@ -4794,7 +4808,7 @@ async function configureCodexApi(options) {
4794
4808
  id: providerId,
4795
4809
  name: answers.providerName,
4796
4810
  baseUrl: selectedProvider2 === "custom" ? answers.baseUrl : prefilledBaseUrl,
4797
- wireApi: selectedProvider2 === "custom" ? answers.wireApi || "responses" : prefilledWireApi,
4811
+ wireApi: prefilledWireApi || "responses",
4798
4812
  tempEnvKey,
4799
4813
  requiresOpenaiAuth: true,
4800
4814
  model: customModel || prefilledModel || "gpt-5.2"
@@ -5377,6 +5391,11 @@ function setGlobalDefaultOutputStyle(styleId) {
5377
5391
  };
5378
5392
  writeJsonConfig(SETTINGS_FILE, updatedSettings);
5379
5393
  }
5394
+ function clearGlobalOutputStyle() {
5395
+ const existingSettings = readJsonConfig(SETTINGS_FILE) || {};
5396
+ const { outputStyle: _, ...rest } = existingSettings;
5397
+ writeJsonConfig(SETTINGS_FILE, rest);
5398
+ }
5380
5399
  function hasLegacyPersonalityFiles() {
5381
5400
  return LEGACY_FILES.some((filename) => exists(join(CLAUDE_DIR, filename)));
5382
5401
  }
@@ -5402,25 +5421,15 @@ async function configureOutputStyle(preselectedStyles, preselectedDefault) {
5402
5421
  description: i18n.t("configuration:outputStyles.engineer-professional.description")
5403
5422
  },
5404
5423
  {
5405
- id: "explanatory",
5406
- name: i18n.t("configuration:outputStyles.explanatory.name"),
5407
- description: i18n.t("configuration:outputStyles.explanatory.description")
5424
+ id: "nekomata-engineer",
5425
+ name: i18n.t("configuration:outputStyles.nekomata-engineer.name"),
5426
+ description: i18n.t("configuration:outputStyles.nekomata-engineer.description")
5408
5427
  },
5409
5428
  {
5410
5429
  id: "laowang-engineer",
5411
5430
  name: i18n.t("configuration:outputStyles.laowang-engineer.name"),
5412
5431
  description: i18n.t("configuration:outputStyles.laowang-engineer.description")
5413
5432
  },
5414
- {
5415
- id: "learning",
5416
- name: i18n.t("configuration:outputStyles.learning.name"),
5417
- description: i18n.t("configuration:outputStyles.learning.description")
5418
- },
5419
- {
5420
- id: "nekomata-engineer",
5421
- name: i18n.t("configuration:outputStyles.nekomata-engineer.name"),
5422
- description: i18n.t("configuration:outputStyles.nekomata-engineer.description")
5423
- },
5424
5433
  {
5425
5434
  id: "ojousama-engineer",
5426
5435
  name: i18n.t("configuration:outputStyles.ojousama-engineer.name"),
@@ -5435,6 +5444,16 @@ async function configureOutputStyle(preselectedStyles, preselectedDefault) {
5435
5444
  id: "rem-engineer",
5436
5445
  name: i18n.t("configuration:outputStyles.rem-engineer.name"),
5437
5446
  description: i18n.t("configuration:outputStyles.rem-engineer.description")
5447
+ },
5448
+ {
5449
+ id: "explanatory",
5450
+ name: i18n.t("configuration:outputStyles.explanatory.name"),
5451
+ description: i18n.t("configuration:outputStyles.explanatory.description")
5452
+ },
5453
+ {
5454
+ id: "learning",
5455
+ name: i18n.t("configuration:outputStyles.learning.name"),
5456
+ description: i18n.t("configuration:outputStyles.learning.description")
5438
5457
  }
5439
5458
  ];
5440
5459
  const availableStyles = getAvailableOutputStyles();
@@ -5470,14 +5489,59 @@ async function configureOutputStyle(preselectedStyles, preselectedDefault) {
5470
5489
  checked: true
5471
5490
  // Default select all custom styles
5472
5491
  };
5473
- })),
5474
- validate: async (input) => input.length > 0 || i18n.t("configuration:selectAtLeastOne")
5492
+ }))
5493
+ // Allow empty selection - user can choose to not install any custom styles
5475
5494
  });
5476
- if (!promptedStyles || promptedStyles.length === 0) {
5477
- console.log(ansis.yellow(i18n.t("common:cancelled")));
5495
+ selectedStyles = promptedStyles || [];
5496
+ if (selectedStyles.length === 0) {
5497
+ const builtinStyles = availableStyles.filter((style) => !style.isCustom);
5498
+ const noneOption = { name: i18n.t("configuration:noOutputStyle"), description: i18n.t("configuration:noOutputStyleDesc") };
5499
+ const { defaultStyle: promptedDefault2 } = await inquirer.prompt({
5500
+ type: "list",
5501
+ name: "defaultStyle",
5502
+ message: i18n.t("configuration:selectDefaultOutputStyle"),
5503
+ choices: addNumbersToChoices([
5504
+ // Show "none" option first
5505
+ {
5506
+ name: `${noneOption.name} - ${ansis.gray(noneOption.description)}`,
5507
+ value: "__none__",
5508
+ short: noneOption.name
5509
+ },
5510
+ // Then show built-in styles
5511
+ ...builtinStyles.map((style) => {
5512
+ const styleInfo = outputStyleList.find((s) => s.id === style.id);
5513
+ return {
5514
+ name: `${styleInfo?.name || style.id} - ${ansis.gray(styleInfo?.description || "")}`,
5515
+ value: style.id,
5516
+ short: styleInfo?.name || style.id
5517
+ };
5518
+ })
5519
+ ]),
5520
+ default: "__none__"
5521
+ });
5522
+ if (!promptedDefault2) {
5523
+ console.log(ansis.yellow(i18n.t("common:cancelled")));
5524
+ return;
5525
+ }
5526
+ if (promptedDefault2 === "__none__") {
5527
+ clearGlobalOutputStyle();
5528
+ updateZcfConfig({
5529
+ outputStyles: [],
5530
+ defaultOutputStyle: "none"
5531
+ });
5532
+ console.log(ansis.green(`\u2714 ${i18n.t("configuration:outputStyleCleared")}`));
5533
+ return;
5534
+ }
5535
+ defaultStyle = promptedDefault2;
5536
+ setGlobalDefaultOutputStyle(defaultStyle);
5537
+ updateZcfConfig({
5538
+ outputStyles: [],
5539
+ defaultOutputStyle: defaultStyle
5540
+ });
5541
+ console.log(ansis.green(`\u2714 ${i18n.t("configuration:outputStyleInstalled")}`));
5542
+ console.log(ansis.gray(` ${i18n.t("configuration:defaultStyle")}: ${defaultStyle}`));
5478
5543
  return;
5479
5544
  }
5480
- selectedStyles = promptedStyles;
5481
5545
  const { defaultStyle: promptedDefault } = await inquirer.prompt({
5482
5546
  type: "list",
5483
5547
  name: "defaultStyle",
@@ -5492,8 +5556,8 @@ async function configureOutputStyle(preselectedStyles, preselectedDefault) {
5492
5556
  short: styleInfo?.name || styleId
5493
5557
  };
5494
5558
  }),
5495
- // Then show all built-in styles (always available)
5496
- ...availableStyles.filter((style) => !style.isCustom).map((style) => {
5559
+ // Then show all built-in styles (always available), with default first
5560
+ ...availableStyles.filter((style) => !style.isCustom).sort((a, b) => a.id === "default" ? -1 : b.id === "default" ? 1 : 0).map((style) => {
5497
5561
  const styleInfo = outputStyleList.find((s) => s.id === style.id);
5498
5562
  return {
5499
5563
  name: `${styleInfo?.name || style.id} - ${ansis.gray(styleInfo?.description || "")}`,
@@ -20,7 +20,6 @@
20
20
  "providerBaseUrlRequired": "Base URL is required",
21
21
  "providerProtocolPrompt": "Select protocol to use",
22
22
  "protocolResponses": "Responses (Recommended, new-generation response API with state management)",
23
- "protocolChat": "Chat (Traditional chat completion API, requires message history)",
24
23
  "providerApiKeyPrompt": "API key value",
25
24
  "providerApiKeyRequired": "API key is required",
26
25
  "addProviderPrompt": "Add another provider?",
@@ -118,7 +117,7 @@
118
117
  "providerManager.providerIdRequired": "Provider ID is required",
119
118
  "providerManager.providerNameRequired": "Provider name is required",
120
119
  "providerManager.baseUrlRequired": "Base URL is required",
121
- "providerManager.wireApiInvalid": "Wire API must be either \"responses\" or \"chat\"",
120
+ "providerManager.wireApiInvalid": "Wire API must be \"responses\"",
122
121
  "providerManager.unknownError": "Unknown error",
123
122
  "envKeyMigrationComplete": "✔ env_key to temp_env_key migration completed"
124
123
  }
@@ -41,6 +41,9 @@
41
41
  "openingSettingsJson": "Opening settings.json...",
42
42
  "opusModelOption": "Opus - Only use opus, high token consumption, use with caution",
43
43
  "sonnet1mModelOption": "Sonnet 1M - 1M context version",
44
+ "noOutputStyle": "No output style",
45
+ "noOutputStyleDesc": "Do not set any output style, use Claude Code default behavior",
46
+ "outputStyleCleared": "Output style settings cleared",
44
47
  "outputStyleInstalled": "Output styles installed successfully",
45
48
  "outputStyles.default.description": "Claude completes coding tasks efficiently and provides concise responses (Claude Code built-in)",
46
49
  "outputStyles.default.name": "Default",
@@ -20,7 +20,6 @@
20
20
  "providerBaseUrlRequired": "必须填写基础 URL",
21
21
  "providerProtocolPrompt": "选择使用的协议",
22
22
  "protocolResponses": "Responses(推荐,新一代响应 API,支持状态管理)",
23
- "protocolChat": "Chat(传统聊天补全 API,需要消息历史记录)",
24
23
  "providerApiKeyPrompt": "API Key 内容",
25
24
  "providerApiKeyRequired": "必须填写 API Key",
26
25
  "addProviderPrompt": "是否继续添加其他提供商?",
@@ -118,7 +117,7 @@
118
117
  "providerManager.providerIdRequired": "提供商 ID 是必需的",
119
118
  "providerManager.providerNameRequired": "提供商名称是必需的",
120
119
  "providerManager.baseUrlRequired": "基础 URL 是必需的",
121
- "providerManager.wireApiInvalid": "Wire API 必须是 \"responses\" 或 \"chat\"",
120
+ "providerManager.wireApiInvalid": "Wire API 必须是 \"responses\"",
122
121
  "providerManager.unknownError": "未知错误",
123
122
  "envKeyMigrationComplete": "✔ 已完成 env_key 到 temp_env_key 的迁移"
124
123
  }
@@ -41,6 +41,9 @@
41
41
  "openingSettingsJson": "正在打开 settings.json...",
42
42
  "opusModelOption": "Opus - 只用opus,token消耗高,慎用",
43
43
  "sonnet1mModelOption": "Sonnet 1M - 1M上下文版本",
44
+ "noOutputStyle": "不使用输出风格",
45
+ "noOutputStyleDesc": "不设置任何输出风格,使用 Claude Code 原始行为",
46
+ "outputStyleCleared": "已清除输出风格设置",
44
47
  "outputStyleInstalled": "输出风格安装成功",
45
48
  "outputStyles.default.description": "完成编码任务时高效且提供简洁响应 (Claude Code自带)",
46
49
  "outputStyles.default.name": "默认风格",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "zcf",
3
3
  "type": "module",
4
- "version": "3.6.0",
4
+ "version": "3.6.2",
5
5
  "description": "Zero-Config Code Flow - One-click configuration tool for Code Cli",
6
6
  "author": {
7
7
  "name": "Miao Da",
@@ -10,16 +10,26 @@
10
10
  "permissions": {
11
11
  "allow": [
12
12
  "Bash",
13
- "BashOutput",
14
13
  "Edit",
15
14
  "Glob",
16
15
  "Grep",
17
16
  "KillShell",
17
+ "LS",
18
+ "LSP",
19
+ "MultiEdit",
18
20
  "NotebookEdit",
21
+ "NotebookRead",
19
22
  "Read",
20
- "SlashCommand",
23
+ "Skill",
21
24
  "Task",
25
+ "TaskCreate",
26
+ "TaskGet",
27
+ "TaskList",
28
+ "TaskOutput",
29
+ "TaskStop",
30
+ "TaskUpdate",
22
31
  "TodoWrite",
32
+ "ToolSearch",
23
33
  "WebFetch",
24
34
  "WebSearch",
25
35
  "Write",