zcf 3.3.1 → 3.3.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 +27 -3
- package/dist/chunks/api-providers.mjs +18 -5
- package/dist/chunks/claude-code-incremental-manager.mjs +9 -0
- package/dist/chunks/simple-config.mjs +107 -23
- package/dist/i18n/locales/en/codex.json +1 -0
- package/dist/i18n/locales/en/installation.json +1 -0
- package/dist/i18n/locales/zh-CN/codex.json +1 -0
- package/dist/i18n/locales/zh-CN/installation.json +1 -0
- package/dist/index.d.mts +0 -1
- package/dist/index.d.ts +0 -1
- package/package.json +9 -3
package/README.md
CHANGED
|
@@ -27,6 +27,22 @@
|
|
|
27
27
|
[](https://share.302.ai/gAT9VG)
|
|
28
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
29
|
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
[](https://z.ai/subscribe?ic=8JVLJQFSKB)
|
|
33
|
+
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.6 model across 10+ popular AI coding tools (Claude Code, Cline, Roo Code, etc.), offering developers top-tier, fast, and stable coding experiences.
|
|
35
|
+
Get 10% OFF GLM CODING PLAN:https://z.ai/subscribe?ic=8JVLJQFSKB
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
<table>
|
|
40
|
+
<tr>
|
|
41
|
+
<td width="180"><a href="https://www.packyapi.com/register?aff=zcf"><img src="./src/assets/packycode.png" alt="PackyCode" width="150"></a></td>
|
|
42
|
+
<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>
|
|
43
|
+
</tr>
|
|
44
|
+
</table>
|
|
45
|
+
|
|
30
46
|
## 🚀 Quick Start
|
|
31
47
|
|
|
32
48
|
### 🎯 Recommended: Use Interactive Menu (v2.0 New)
|
|
@@ -154,7 +170,8 @@ ZCF now supports API provider presets that automatically configure baseUrl and m
|
|
|
154
170
|
|
|
155
171
|
**Supported Providers:**
|
|
156
172
|
- `302ai` - [302.AI](https://share.302.ai/gAT9VG) API Service
|
|
157
|
-
- `
|
|
173
|
+
- `packycode` - [PackyCode](https://www.packyapi.com/register?aff=zcf) API Service
|
|
174
|
+
- `glm` - [GLM](https://z.ai/subscribe?ic=8JVLJQFSKB) API Service
|
|
158
175
|
- `minimax` - MiniMax API Service
|
|
159
176
|
- `kimi` - Kimi (Moonshot AI)
|
|
160
177
|
- `custom` - Custom API endpoint (requires manual URL configuration)
|
|
@@ -167,6 +184,9 @@ npx zcf i --skip-prompt --provider 302ai --api-key "sk-xxx"
|
|
|
167
184
|
# or shorthand
|
|
168
185
|
npx zcf i -s -p 302ai -k "sk-xxx"
|
|
169
186
|
|
|
187
|
+
# Using PackyCode provider
|
|
188
|
+
npx zcf i -s -p packycode -k "sk-xxx"
|
|
189
|
+
|
|
170
190
|
# Using GLM provider
|
|
171
191
|
npx zcf i -s -p glm -k "sk-xxx"
|
|
172
192
|
|
|
@@ -197,7 +217,7 @@ When using `--skip-prompt`, the following parameters are available:
|
|
|
197
217
|
| Parameter | Description | Values | Required | Default |
|
|
198
218
|
| ---------------------------- | -------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
|
|
199
219
|
| `--skip-prompt, -s` | Skip all interactive prompts | - | Yes (for non-interactive mode) | - |
|
|
200
|
-
| `--provider, -p` | API provider preset (v3.3.0+ New) | `302ai`, `glm`, `minimax`, `kimi`, `custom`
|
|
220
|
+
| `--provider, -p` | API provider preset (v3.3.0+ New) | `302ai`, `packycode`, `glm`, `minimax`, `kimi`, `custom` | No | - (Simplifies configuration by auto-filling baseUrl and models) |
|
|
201
221
|
| `--lang, -l` | ZCF display language (applies to all commands) | `zh-CN`, `en` | No | `en` or user's saved preference |
|
|
202
222
|
| `--config-lang, -c` | Configuration language (template files language) | `zh-CN`, `en` | No | `en` |
|
|
203
223
|
| `--ai-output-lang, -a` | AI output language | `zh-CN`, `en`, custom string | No | `en` |
|
|
@@ -289,7 +309,7 @@ ZCF now supports customizable AI output styles to personalize your Claude Code e
|
|
|
289
309
|
|
|
290
310
|
<p align="center">
|
|
291
311
|
<a href="https://github.com/Haleclipse">
|
|
292
|
-
<img src="./src/assets/Haleclipse.
|
|
312
|
+
<img src="./src/assets/Haleclipse.webp" alt="Halley-chan" width="200"/>
|
|
293
313
|
</a>
|
|
294
314
|
<div align="center">Tsundere <a href="https://github.com/Haleclipse">Halley-chan</a> Ojou-sama ( ̄▽ ̄)ゞ</div>
|
|
295
315
|
</p>
|
|
@@ -473,6 +493,7 @@ ZCF provides flexible API configuration options for both Claude Code and Codex:
|
|
|
473
493
|
|
|
474
494
|
Choose from popular API providers with pre-configured settings:
|
|
475
495
|
- **302.AI** - Pay-as-you-go AI service with comprehensive model support
|
|
496
|
+
- **PackyCode** - PackyCode API Service
|
|
476
497
|
- **GLM (智谱AI)** - Zhipu AI's GLM models
|
|
477
498
|
- **MiniMax** - MiniMax AI service
|
|
478
499
|
- **Kimi (Moonshot AI)** - Moonshot's Kimi models
|
|
@@ -930,6 +951,8 @@ If you find this project helpful, please consider sponsoring its development. Yo
|
|
|
930
951
|
|
|
931
952
|
A huge thank you to all our sponsors for their generous support!
|
|
932
953
|
- [302.AI](https://share.302.ai/gAT9VG) (first corporate sponsorship 🤠)
|
|
954
|
+
- [GLM](https://z.ai/subscribe?ic=8JVLJQFSKB) (first AI model sponsorship 🤖)
|
|
955
|
+
- [PackyCode](https://www.packyapi.com/register?aff=zcf) (first API proxy service sponsor 🧝🏻♀️)
|
|
933
956
|
- Tc (first sponsor)
|
|
934
957
|
- Argolinhas (first ko-fi sponsor ٩(•̤̀ᵕ•̤́๑))
|
|
935
958
|
- r\*r (first anonymous sponsor 🤣)
|
|
@@ -939,6 +962,7 @@ A huge thank you to all our sponsors for their generous support!
|
|
|
939
962
|
- [chamo101](https://github.com/chamo101) (first GitHub issue sponsor 🎉)
|
|
940
963
|
- 初屿贤 (first Codex user sponsor 🙅🏻♂️)
|
|
941
964
|
- Protein (first 1688 sponsor 😏)
|
|
965
|
+
- [musistudio](https://github.com/musistudio) (first open source project author sponsor, the author of [CCR](https://github.com/musistudio/claude-code-router) 🤩)
|
|
942
966
|
- [BeatSeat](https://github.com/BeatSeat) (community expert 😎, provided $1000 Claude credits)
|
|
943
967
|
- [wenwen](https://github.com/wenwen12345) (community expert 🤓, provided daily $100 Claude&GPT credits)
|
|
944
968
|
- 16°C coffee (My best friend 🤪, offered ChatGPT Pro $200 package)
|
|
@@ -13,6 +13,20 @@ const API_PROVIDER_PRESETS = [
|
|
|
13
13
|
},
|
|
14
14
|
description: "302.AI API Service"
|
|
15
15
|
},
|
|
16
|
+
{
|
|
17
|
+
id: "packycode",
|
|
18
|
+
name: "PackyCode",
|
|
19
|
+
supportedCodeTools: ["claude-code", "codex"],
|
|
20
|
+
claudeCode: {
|
|
21
|
+
baseUrl: "https://www.packyapi.com",
|
|
22
|
+
authType: "auth_token"
|
|
23
|
+
},
|
|
24
|
+
codex: {
|
|
25
|
+
baseUrl: "https://www.packyapi.com/v1",
|
|
26
|
+
wireApi: "responses"
|
|
27
|
+
},
|
|
28
|
+
description: "PackyCode API Service"
|
|
29
|
+
},
|
|
16
30
|
{
|
|
17
31
|
id: "glm",
|
|
18
32
|
name: "GLM",
|
|
@@ -49,14 +63,13 @@ const API_PROVIDER_PRESETS = [
|
|
|
49
63
|
name: "Kimi",
|
|
50
64
|
supportedCodeTools: ["claude-code", "codex"],
|
|
51
65
|
claudeCode: {
|
|
52
|
-
baseUrl: "https://api.
|
|
53
|
-
authType: "auth_token"
|
|
54
|
-
defaultModels: ["kimi-k2-0905-preview", "kimi-k2-turbo-preview"]
|
|
66
|
+
baseUrl: "https://api.kimi.com/coding/",
|
|
67
|
+
authType: "auth_token"
|
|
55
68
|
},
|
|
56
69
|
codex: {
|
|
57
|
-
baseUrl: "https://api.
|
|
70
|
+
baseUrl: "https://api.kimi.com/coding/v1",
|
|
58
71
|
wireApi: "chat",
|
|
59
|
-
defaultModel: "kimi-
|
|
72
|
+
defaultModel: "kimi-for-coding"
|
|
60
73
|
},
|
|
61
74
|
description: "Kimi (Moonshot AI)"
|
|
62
75
|
}
|
|
@@ -103,11 +103,13 @@ ${i18n.t("multi-config:addingNewProfile")}`));
|
|
|
103
103
|
}]);
|
|
104
104
|
let prefilledBaseUrl;
|
|
105
105
|
let prefilledAuthType;
|
|
106
|
+
let prefilledDefaultModels;
|
|
106
107
|
if (selectedProvider !== "custom") {
|
|
107
108
|
const provider = providers.find((p) => p.id === selectedProvider);
|
|
108
109
|
if (provider?.claudeCode) {
|
|
109
110
|
prefilledBaseUrl = provider.claudeCode.baseUrl;
|
|
110
111
|
prefilledAuthType = provider.claudeCode.authType;
|
|
112
|
+
prefilledDefaultModels = provider.claudeCode.defaultModels;
|
|
111
113
|
console.log(ansis.gray(i18n.t("api:providerSelected", { name: provider.name })));
|
|
112
114
|
}
|
|
113
115
|
}
|
|
@@ -208,6 +210,13 @@ ${i18n.t("multi-config:addingNewProfile")}`));
|
|
|
208
210
|
if (modelConfig.fastModel.trim()) {
|
|
209
211
|
profile.fastModel = modelConfig.fastModel.trim();
|
|
210
212
|
}
|
|
213
|
+
} else if (prefilledDefaultModels?.length) {
|
|
214
|
+
if (prefilledDefaultModels[0]?.trim()) {
|
|
215
|
+
profile.primaryModel = prefilledDefaultModels[0].trim();
|
|
216
|
+
}
|
|
217
|
+
if (prefilledDefaultModels[1]?.trim()) {
|
|
218
|
+
profile.fastModel = prefilledDefaultModels[1].trim();
|
|
219
|
+
}
|
|
211
220
|
}
|
|
212
221
|
const existingProfile = ClaudeCodeConfigManager.getProfileByName(profile.name);
|
|
213
222
|
if (existingProfile) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as nodeFs from 'node:fs';
|
|
2
|
+
import { existsSync, mkdirSync, copyFileSync, readFileSync, writeFileSync, rmSync, rmdirSync, readdirSync, statSync, unlinkSync, renameSync } from 'node:fs';
|
|
2
3
|
import process from 'node:process';
|
|
3
4
|
import ansis from 'ansis';
|
|
4
5
|
import inquirer from 'inquirer';
|
|
@@ -16,7 +17,7 @@ import { rm, mkdir, copyFile as copyFile$1 } from 'node:fs/promises';
|
|
|
16
17
|
import i18next from 'i18next';
|
|
17
18
|
import Backend from 'i18next-fs-backend';
|
|
18
19
|
|
|
19
|
-
const version = "3.3.
|
|
20
|
+
const version = "3.3.3";
|
|
20
21
|
const homepage = "https://github.com/UfoMiao/zcf";
|
|
21
22
|
|
|
22
23
|
const i18n = i18next.createInstance();
|
|
@@ -523,7 +524,7 @@ function getPlatform() {
|
|
|
523
524
|
return "linux";
|
|
524
525
|
}
|
|
525
526
|
function isTermux() {
|
|
526
|
-
return !!(process.env.PREFIX && process.env.PREFIX.includes("com.termux")) || !!process.env.TERMUX_VERSION || existsSync("/data/data/com.termux/files/usr");
|
|
527
|
+
return !!(process.env.PREFIX && process.env.PREFIX.includes("com.termux")) || !!process.env.TERMUX_VERSION || nodeFs.existsSync("/data/data/com.termux/files/usr");
|
|
527
528
|
}
|
|
528
529
|
function getTermuxPrefix() {
|
|
529
530
|
return process.env.PREFIX || "/data/data/com.termux/files/usr";
|
|
@@ -535,16 +536,16 @@ function isWSL() {
|
|
|
535
536
|
if (process.env.WSL_DISTRO_NAME) {
|
|
536
537
|
return true;
|
|
537
538
|
}
|
|
538
|
-
if (existsSync("/proc/version")) {
|
|
539
|
+
if (nodeFs.existsSync("/proc/version")) {
|
|
539
540
|
try {
|
|
540
|
-
const version = readFileSync("/proc/version", "utf8");
|
|
541
|
+
const version = nodeFs.readFileSync("/proc/version", "utf8");
|
|
541
542
|
if (version.includes("Microsoft") || version.includes("WSL")) {
|
|
542
543
|
return true;
|
|
543
544
|
}
|
|
544
545
|
} catch {
|
|
545
546
|
}
|
|
546
547
|
}
|
|
547
|
-
if (existsSync("/mnt/c")) {
|
|
548
|
+
if (nodeFs.existsSync("/mnt/c")) {
|
|
548
549
|
return true;
|
|
549
550
|
}
|
|
550
551
|
return false;
|
|
@@ -553,9 +554,9 @@ function getWSLDistro() {
|
|
|
553
554
|
if (process.env.WSL_DISTRO_NAME) {
|
|
554
555
|
return process.env.WSL_DISTRO_NAME;
|
|
555
556
|
}
|
|
556
|
-
if (existsSync("/etc/os-release")) {
|
|
557
|
+
if (nodeFs.existsSync("/etc/os-release")) {
|
|
557
558
|
try {
|
|
558
|
-
const osRelease = readFileSync("/etc/os-release", "utf8");
|
|
559
|
+
const osRelease = nodeFs.readFileSync("/etc/os-release", "utf8");
|
|
559
560
|
const nameMatch = osRelease.match(/^PRETTY_NAME="(.+)"$/m);
|
|
560
561
|
if (nameMatch) {
|
|
561
562
|
return nameMatch[1];
|
|
@@ -570,9 +571,9 @@ function getWSLInfo() {
|
|
|
570
571
|
return null;
|
|
571
572
|
}
|
|
572
573
|
let version = null;
|
|
573
|
-
if (existsSync("/proc/version")) {
|
|
574
|
+
if (nodeFs.existsSync("/proc/version")) {
|
|
574
575
|
try {
|
|
575
|
-
version = readFileSync("/proc/version", "utf8").trim();
|
|
576
|
+
version = nodeFs.readFileSync("/proc/version", "utf8").trim();
|
|
576
577
|
} catch {
|
|
577
578
|
}
|
|
578
579
|
}
|
|
@@ -599,6 +600,71 @@ function getSystemRoot() {
|
|
|
599
600
|
systemRoot = env.SystemRoot;
|
|
600
601
|
return systemRoot.replace(/\\+/g, "/").replace(/\/+/g, "/");
|
|
601
602
|
}
|
|
603
|
+
function shouldUseSudoForGlobalInstall() {
|
|
604
|
+
if (isTermux())
|
|
605
|
+
return false;
|
|
606
|
+
if (getPlatform() !== "linux")
|
|
607
|
+
return false;
|
|
608
|
+
const npmPrefix = getGlobalNpmPrefix();
|
|
609
|
+
if (npmPrefix) {
|
|
610
|
+
if (isPathInsideHome(npmPrefix) || canWriteToPath(npmPrefix))
|
|
611
|
+
return false;
|
|
612
|
+
}
|
|
613
|
+
const getuid = process.getuid;
|
|
614
|
+
if (typeof getuid !== "function")
|
|
615
|
+
return false;
|
|
616
|
+
try {
|
|
617
|
+
return getuid() !== 0;
|
|
618
|
+
} catch {
|
|
619
|
+
return false;
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
function wrapCommandWithSudo(command, args) {
|
|
623
|
+
if (shouldUseSudoForGlobalInstall()) {
|
|
624
|
+
return {
|
|
625
|
+
command: "sudo",
|
|
626
|
+
args: [command, ...args],
|
|
627
|
+
usedSudo: true
|
|
628
|
+
};
|
|
629
|
+
}
|
|
630
|
+
return {
|
|
631
|
+
command,
|
|
632
|
+
args,
|
|
633
|
+
usedSudo: false
|
|
634
|
+
};
|
|
635
|
+
}
|
|
636
|
+
const WRITE_CHECK_FLAG = 2;
|
|
637
|
+
function normalizePath(path) {
|
|
638
|
+
return path.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
639
|
+
}
|
|
640
|
+
function isPathInsideHome(path) {
|
|
641
|
+
const home = process.env.HOME;
|
|
642
|
+
if (!home)
|
|
643
|
+
return false;
|
|
644
|
+
const normalizedHome = normalizePath(home);
|
|
645
|
+
const normalizedPath = normalizePath(path);
|
|
646
|
+
return normalizedPath === normalizedHome || normalizedPath.startsWith(`${normalizedHome}/`);
|
|
647
|
+
}
|
|
648
|
+
function canWriteToPath(path) {
|
|
649
|
+
try {
|
|
650
|
+
nodeFs.accessSync(path, WRITE_CHECK_FLAG);
|
|
651
|
+
return true;
|
|
652
|
+
} catch {
|
|
653
|
+
return false;
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
function getGlobalNpmPrefix() {
|
|
657
|
+
const env = process.env;
|
|
658
|
+
const envPrefix = env.npm_config_prefix || env.NPM_CONFIG_PREFIX || env.PREFIX;
|
|
659
|
+
if (envPrefix)
|
|
660
|
+
return envPrefix;
|
|
661
|
+
const execPath = process.execPath;
|
|
662
|
+
if (execPath) {
|
|
663
|
+
const binDir = dirname(execPath);
|
|
664
|
+
return dirname(binDir);
|
|
665
|
+
}
|
|
666
|
+
return null;
|
|
667
|
+
}
|
|
602
668
|
async function commandExists(command) {
|
|
603
669
|
try {
|
|
604
670
|
const cmd = getPlatform() === "windows" ? "where" : "which";
|
|
@@ -616,7 +682,7 @@ async function commandExists(command) {
|
|
|
616
682
|
`/data/data/com.termux/files/usr/bin/${command}`
|
|
617
683
|
];
|
|
618
684
|
for (const path of possiblePaths) {
|
|
619
|
-
if (existsSync(path)) {
|
|
685
|
+
if (nodeFs.existsSync(path)) {
|
|
620
686
|
return true;
|
|
621
687
|
}
|
|
622
688
|
}
|
|
@@ -629,7 +695,7 @@ async function commandExists(command) {
|
|
|
629
695
|
`${process.env.HOME}/.local/bin/${command}`
|
|
630
696
|
];
|
|
631
697
|
for (const path of commonPaths) {
|
|
632
|
-
if (existsSync(path)) {
|
|
698
|
+
if (nodeFs.existsSync(path)) {
|
|
633
699
|
return true;
|
|
634
700
|
}
|
|
635
701
|
}
|
|
@@ -1360,11 +1426,6 @@ function switchToOfficialLogin$1() {
|
|
|
1360
1426
|
delete vscConfig.primaryApiKey;
|
|
1361
1427
|
writeJsonConfig(CLAUDE_VSC_CONFIG_FILE, vscConfig);
|
|
1362
1428
|
}
|
|
1363
|
-
const mcpConfig = readMcpConfig();
|
|
1364
|
-
if (mcpConfig) {
|
|
1365
|
-
delete mcpConfig.hasCompletedOnboarding;
|
|
1366
|
-
writeMcpConfig(mcpConfig);
|
|
1367
|
-
}
|
|
1368
1429
|
console.log(i18n.t("api:officialLoginConfigured"));
|
|
1369
1430
|
return true;
|
|
1370
1431
|
} catch (error) {
|
|
@@ -2224,7 +2285,12 @@ async function installCcr() {
|
|
|
2224
2285
|
}
|
|
2225
2286
|
console.log(ansis.cyan(`\u{1F4E6} ${i18n.t("ccr:installingCcr")}`));
|
|
2226
2287
|
try {
|
|
2227
|
-
|
|
2288
|
+
const installArgs = ["install", "-g", "@musistudio/claude-code-router", "--force"];
|
|
2289
|
+
const { command, args, usedSudo } = wrapCommandWithSudo("npm", installArgs);
|
|
2290
|
+
if (usedSudo) {
|
|
2291
|
+
console.log(ansis.yellow(`\u2139 ${i18n.t("installation:usingSudo")}`));
|
|
2292
|
+
}
|
|
2293
|
+
await execAsync$1([command, ...args].join(" "));
|
|
2228
2294
|
console.log(ansis.green(`\u2714 ${i18n.t("ccr:ccrInstallSuccess")}`));
|
|
2229
2295
|
} catch (error) {
|
|
2230
2296
|
if (error.message?.includes("EEXIST")) {
|
|
@@ -2943,7 +3009,10 @@ async function executeCodexInstallation(isUpdate) {
|
|
|
2943
3009
|
} else {
|
|
2944
3010
|
console.log(ansis.cyan(i18n.t("codex:installingCli")));
|
|
2945
3011
|
}
|
|
2946
|
-
const
|
|
3012
|
+
const { command, args, usedSudo } = wrapCommandWithSudo("npm", ["install", "-g", "@openai/codex"]);
|
|
3013
|
+
if (usedSudo)
|
|
3014
|
+
console.log(ansis.yellow(i18n.t("codex:usingSudo")));
|
|
3015
|
+
const result = await x(command, args);
|
|
2947
3016
|
if (result.exitCode !== 0) {
|
|
2948
3017
|
throw new Error(`Failed to ${action} codex CLI: exit code ${result.exitCode}`);
|
|
2949
3018
|
}
|
|
@@ -3975,7 +4044,10 @@ async function runCodexUpdate(force = false, skipPrompt = false) {
|
|
|
3975
4044
|
async function runCodexUninstall() {
|
|
3976
4045
|
ensureI18nInitialized();
|
|
3977
4046
|
const { CodexUninstaller } = await import('./codex-uninstaller.mjs');
|
|
3978
|
-
const
|
|
4047
|
+
const zcfConfig = readZcfConfig();
|
|
4048
|
+
const preferredLang = zcfConfig?.preferredLang;
|
|
4049
|
+
const uninstallLang = preferredLang && SUPPORTED_LANGS.includes(preferredLang) ? preferredLang : "en";
|
|
4050
|
+
const uninstaller = new CodexUninstaller(uninstallLang);
|
|
3979
4051
|
const { mode } = await inquirer.prompt([{
|
|
3980
4052
|
type: "list",
|
|
3981
4053
|
name: "mode",
|
|
@@ -4289,12 +4361,20 @@ async function isCometixLineInstalled() {
|
|
|
4289
4361
|
}
|
|
4290
4362
|
async function installCometixLine() {
|
|
4291
4363
|
ensureI18nInitialized();
|
|
4364
|
+
const runInstallCommand = async () => {
|
|
4365
|
+
const installArgs = ["install", "-g", COMETIX_PACKAGE_NAME];
|
|
4366
|
+
const { command, args, usedSudo } = wrapCommandWithSudo("npm", installArgs);
|
|
4367
|
+
if (usedSudo) {
|
|
4368
|
+
console.log(ansis.yellow(`\u2139 ${i18n.t("installation:usingSudo")}`));
|
|
4369
|
+
}
|
|
4370
|
+
await execAsync([command, ...args].join(" "));
|
|
4371
|
+
};
|
|
4292
4372
|
const isInstalled = await isCometixLineInstalled();
|
|
4293
4373
|
if (isInstalled) {
|
|
4294
4374
|
console.log(ansis.green(`\u2714 ${i18n.t("cometix:cometixAlreadyInstalled")}`));
|
|
4295
4375
|
try {
|
|
4296
4376
|
console.log(ansis.blue(`${i18n.t("cometix:installingOrUpdating")}`));
|
|
4297
|
-
await
|
|
4377
|
+
await runInstallCommand();
|
|
4298
4378
|
console.log(ansis.green(`\u2714 ${i18n.t("cometix:installUpdateSuccess")}`));
|
|
4299
4379
|
} catch (error) {
|
|
4300
4380
|
console.log(ansis.yellow(`\u26A0 ${i18n.t("cometix:installUpdateFailed")}: ${error}`));
|
|
@@ -4313,7 +4393,7 @@ async function installCometixLine() {
|
|
|
4313
4393
|
}
|
|
4314
4394
|
try {
|
|
4315
4395
|
console.log(ansis.blue(`${i18n.t("cometix:installingCometix")}`));
|
|
4316
|
-
await
|
|
4396
|
+
await runInstallCommand();
|
|
4317
4397
|
console.log(ansis.green(`\u2714 ${i18n.t("cometix:cometixInstallSuccess")}`));
|
|
4318
4398
|
try {
|
|
4319
4399
|
addCCometixLineConfig();
|
|
@@ -4794,7 +4874,11 @@ async function installClaudeCode() {
|
|
|
4794
4874
|
}
|
|
4795
4875
|
console.log(i18n.t("installation:installing"));
|
|
4796
4876
|
try {
|
|
4797
|
-
|
|
4877
|
+
const { command, args, usedSudo } = wrapCommandWithSudo("npm", ["install", "-g", "@anthropic-ai/claude-code"]);
|
|
4878
|
+
if (usedSudo) {
|
|
4879
|
+
console.log(ansis.yellow(`\u2139 ${i18n.t("installation:usingSudo")}`));
|
|
4880
|
+
}
|
|
4881
|
+
await exec(command, args);
|
|
4798
4882
|
console.log(`\u2714 ${i18n.t("installation:installSuccess")}`);
|
|
4799
4883
|
await setInstallMethod("npm");
|
|
4800
4884
|
if (isTermux()) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"installingCli": "🚀 Installing Codex CLI...",
|
|
3
3
|
"installSuccess": "✔ Codex CLI installed",
|
|
4
|
+
"usingSudo": "⚠️ Detected non-root Linux user. Using sudo for Codex CLI installation (password prompt may appear).",
|
|
4
5
|
"alreadyInstalled": "⚠️ Codex CLI already installed, skipping installation",
|
|
5
6
|
"updatingCli": "🔄 Updating Codex CLI...",
|
|
6
7
|
"updateSuccess": "✔ Codex CLI updated",
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
"installPrompt": "Claude Code not found. Install automatically?",
|
|
5
5
|
"installSuccess": "Claude Code installed successfully",
|
|
6
6
|
"installing": "Installing Claude Code...",
|
|
7
|
+
"usingSudo": "Detected non-root Linux user. Elevating with sudo for global installation (password prompt may appear).",
|
|
7
8
|
"termuxDetected": "Termux environment detected",
|
|
8
9
|
"termuxEnvironmentInfo": "Termux environment provides Node.js and npm through pkg manager",
|
|
9
10
|
"termuxInstallHint": "In Termux, please run first: pkg install nodejs or pkg install nodejs-lts",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"installingCli": "🚀 正在安装 Codex CLI...",
|
|
3
3
|
"installSuccess": "✔ Codex CLI 安装完成",
|
|
4
|
+
"usingSudo": "⚠️ 检测到 Linux 非 root 用户,正在使用 sudo 安装 Codex CLI(可能需要输入密码)。",
|
|
4
5
|
"alreadyInstalled": "⚠️ Codex CLI 已安装,跳过安装步骤",
|
|
5
6
|
"updatingCli": "🔄 正在更新 Codex CLI...",
|
|
6
7
|
"updateSuccess": "✔ Codex CLI 更新完成",
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
"installPrompt": "检测到 Claude Code 未安装,是否自动安装?",
|
|
5
5
|
"installSuccess": "Claude Code 安装成功",
|
|
6
6
|
"installing": "正在安装 Claude Code...",
|
|
7
|
+
"usingSudo": "检测到 Linux 非 root 用户,正在使用 sudo 提升权限进行全局安装(可能需要输入密码)。",
|
|
7
8
|
"termuxDetected": "检测到 Termux 环境",
|
|
8
9
|
"termuxEnvironmentInfo": "Termux 环境通过 pkg 管理器提供 Node.js 和 npm",
|
|
9
10
|
"termuxInstallHint": "在 Termux 中,请先运行: pkg install nodejs 或 pkg install nodejs-lts",
|
package/dist/index.d.mts
CHANGED
|
@@ -173,7 +173,6 @@ declare function applyAiLanguageDirective(aiOutputLang: AiOutputLanguage | strin
|
|
|
173
173
|
* Switch to official login mode - remove all third-party API configurations
|
|
174
174
|
* Removes: ANTHROPIC_BASE_URL, ANTHROPIC_AUTH_TOKEN, ANTHROPIC_API_KEY from settings.json
|
|
175
175
|
* Removes: primaryApiKey from ~/.claude/config.json
|
|
176
|
-
* Removes: hasCompletedOnboarding from ~/.claude.json
|
|
177
176
|
*/
|
|
178
177
|
declare function switchToOfficialLogin(): boolean;
|
|
179
178
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -173,7 +173,6 @@ declare function applyAiLanguageDirective(aiOutputLang: AiOutputLanguage | strin
|
|
|
173
173
|
* Switch to official login mode - remove all third-party API configurations
|
|
174
174
|
* Removes: ANTHROPIC_BASE_URL, ANTHROPIC_AUTH_TOKEN, ANTHROPIC_API_KEY from settings.json
|
|
175
175
|
* Removes: primaryApiKey from ~/.claude/config.json
|
|
176
|
-
* Removes: hasCompletedOnboarding from ~/.claude.json
|
|
177
176
|
*/
|
|
178
177
|
declare function switchToOfficialLogin(): boolean;
|
|
179
178
|
/**
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zcf",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "3.3.
|
|
5
|
-
"description": "Zero-Config Code Flow - One-click configuration tool for
|
|
4
|
+
"version": "3.3.3",
|
|
5
|
+
"description": "Zero-Config Code Flow - One-click configuration tool for Code Cli",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Miao Da",
|
|
8
8
|
"email": "ufo025174@gmail.com",
|
|
@@ -18,12 +18,15 @@
|
|
|
18
18
|
"keywords": [
|
|
19
19
|
"claude",
|
|
20
20
|
"claude-code",
|
|
21
|
+
"codex",
|
|
21
22
|
"config",
|
|
22
23
|
"cli",
|
|
23
24
|
"setup",
|
|
24
25
|
"zero-config",
|
|
25
26
|
"zcf",
|
|
26
27
|
"anthropic",
|
|
28
|
+
"openai",
|
|
29
|
+
"ChatGPT",
|
|
27
30
|
"ai",
|
|
28
31
|
"automation",
|
|
29
32
|
"mcp"
|
|
@@ -99,6 +102,9 @@
|
|
|
99
102
|
"update:deps": "pnpx taze major -r -w",
|
|
100
103
|
"release": "pnpm build && changeset publish",
|
|
101
104
|
"commitlint": "commitlint",
|
|
102
|
-
"commitlint:check": "commitlint --from HEAD~1 --to HEAD --verbose"
|
|
105
|
+
"commitlint:check": "commitlint --from HEAD~1 --to HEAD --verbose",
|
|
106
|
+
"docs:dev": "pnpm -F @zcf/docs dev",
|
|
107
|
+
"docs:build": "pnpm -F @zcf/docs build",
|
|
108
|
+
"docs:preview": "pnpm -F @zcf/docs preview"
|
|
103
109
|
}
|
|
104
110
|
}
|