zcf 2.12.11 → 2.12.13
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 +15 -3
- package/dist/chunks/simple-config.mjs +67 -2
- package/dist/cli.mjs +781 -25
- package/dist/i18n/locales/en/cli.json +3 -0
- package/dist/i18n/locales/en/installation.json +5 -1
- package/dist/i18n/locales/en/menu.json +2 -2
- package/dist/i18n/locales/en/uninstall.json +60 -0
- package/dist/i18n/locales/zh-CN/cli.json +3 -0
- package/dist/i18n/locales/zh-CN/installation.json +5 -1
- package/dist/i18n/locales/zh-CN/menu.json +2 -2
- package/dist/i18n/locales/zh-CN/uninstall.json +60 -0
- package/package.json +11 -8
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
[![JSDocs][jsdocs-src]][jsdocs-href]
|
|
9
9
|
[![Ask DeepWiki][deepwiki-src]][deepwiki-href]
|
|
10
10
|
|
|
11
|
-
[中文](README_zh-CN.md) | **English** | [Changelog](CHANGELOG.md)
|
|
11
|
+
[中文](README_zh-CN.md) | **English** | [日本語](README_ja-JP.md) | [Changelog](CHANGELOG.md)
|
|
12
12
|
|
|
13
13
|
> Zero-config, one-click setup for Claude Code with bilingual support, intelligent agent system and personalized AI assistant
|
|
14
14
|
|
|
@@ -288,7 +288,7 @@ After configuration:
|
|
|
288
288
|
|
|
289
289
|
- Auto-detects Claude Code installation status
|
|
290
290
|
- Uses npm for automatic installation (ensures compatibility)
|
|
291
|
-
- Cross-platform support (Windows/macOS/Linux/Termux)
|
|
291
|
+
- Cross-platform support (Windows/macOS/Linux/WSL/Termux)
|
|
292
292
|
- Automatic MCP service configuration
|
|
293
293
|
- Smart configuration merging and partial modification support (v2.0 new)
|
|
294
294
|
- Enhanced command detection mechanism (v2.1 new)
|
|
@@ -350,7 +350,7 @@ Select function:
|
|
|
350
350
|
|
|
351
351
|
------------ ZCF ------------
|
|
352
352
|
0. Select display language / 更改显示语言 - Change ZCF interface language
|
|
353
|
-
-.
|
|
353
|
+
-. Uninstall - Remove Claude Code configurations and tools from system
|
|
354
354
|
+. Check updates - Check and update Claude Code, CCR and CCometixLine versions
|
|
355
355
|
Q. Exit
|
|
356
356
|
|
|
@@ -473,6 +473,7 @@ Enter your choice: _
|
|
|
473
473
|
| `zcf update` | `zcf u` | Update workflow-related md files with backup |
|
|
474
474
|
| `zcf ccu` | - | Run Claude Code usage analysis tool - [ccusage](https://github.com/ryoppippi/ccusage) |
|
|
475
475
|
| `zcf ccr` | - | Open CCR (Claude Code Router) management menu |
|
|
476
|
+
| `zcf uninstall` | - | Interactive uninstall tool for Claude Code configurations and tools |
|
|
476
477
|
| `zcf check-updates` | - | Check and update Claude Code, CCR and CCometixLine versions |
|
|
477
478
|
|
|
478
479
|
#### Common Options
|
|
@@ -647,6 +648,17 @@ ZCF fully supports Windows platform:
|
|
|
647
648
|
|
|
648
649
|
If you encounter MCP connection issues on Windows, running `npx zcf` will automatically fix the configuration format.
|
|
649
650
|
|
|
651
|
+
#### WSL Support (v2.12.12+ new)
|
|
652
|
+
|
|
653
|
+
ZCF now provides comprehensive support for Windows Subsystem for Linux (WSL):
|
|
654
|
+
|
|
655
|
+
- **Smart Detection**: Multi-layered WSL environment detection using environment variables, system files, and mount points
|
|
656
|
+
- **Distribution Recognition**: Automatically identifies WSL distribution (Ubuntu, Debian, etc.) for optimized configuration
|
|
657
|
+
- **Seamless Installation**: Native Linux-style installation experience within WSL environment
|
|
658
|
+
- **Path Management**: Intelligent handling of WSL-specific configuration paths and file locations
|
|
659
|
+
|
|
660
|
+
If running in WSL, ZCF will automatically detect the environment and display appropriate installation messages.
|
|
661
|
+
|
|
650
662
|
#### Termux Support (v2.1 new)
|
|
651
663
|
|
|
652
664
|
ZCF now supports running in Android Termux environment:
|
|
@@ -15,7 +15,7 @@ import { rm, mkdir, copyFile as copyFile$1 } from 'node:fs/promises';
|
|
|
15
15
|
import i18next from 'i18next';
|
|
16
16
|
import Backend from 'i18next-fs-backend';
|
|
17
17
|
|
|
18
|
-
const version = "2.12.
|
|
18
|
+
const version = "2.12.13";
|
|
19
19
|
const homepage = "https://github.com/UfoMiao/zcf";
|
|
20
20
|
|
|
21
21
|
const i18n = i18next.createInstance();
|
|
@@ -32,6 +32,7 @@ const NAMESPACES = [
|
|
|
32
32
|
"mcp",
|
|
33
33
|
"menu",
|
|
34
34
|
"tools",
|
|
35
|
+
"uninstall",
|
|
35
36
|
"updater",
|
|
36
37
|
"workflow"
|
|
37
38
|
];
|
|
@@ -717,6 +718,57 @@ function getTermuxPrefix() {
|
|
|
717
718
|
function isWindows() {
|
|
718
719
|
return getPlatform() === "windows";
|
|
719
720
|
}
|
|
721
|
+
function isWSL() {
|
|
722
|
+
if (process.env.WSL_DISTRO_NAME) {
|
|
723
|
+
return true;
|
|
724
|
+
}
|
|
725
|
+
if (existsSync("/proc/version")) {
|
|
726
|
+
try {
|
|
727
|
+
const version = readFileSync("/proc/version", "utf8");
|
|
728
|
+
if (version.includes("Microsoft") || version.includes("WSL")) {
|
|
729
|
+
return true;
|
|
730
|
+
}
|
|
731
|
+
} catch {
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
if (existsSync("/mnt/c")) {
|
|
735
|
+
return true;
|
|
736
|
+
}
|
|
737
|
+
return false;
|
|
738
|
+
}
|
|
739
|
+
function getWSLDistro() {
|
|
740
|
+
if (process.env.WSL_DISTRO_NAME) {
|
|
741
|
+
return process.env.WSL_DISTRO_NAME;
|
|
742
|
+
}
|
|
743
|
+
if (existsSync("/etc/os-release")) {
|
|
744
|
+
try {
|
|
745
|
+
const osRelease = readFileSync("/etc/os-release", "utf8");
|
|
746
|
+
const nameMatch = osRelease.match(/^PRETTY_NAME="(.+)"$/m);
|
|
747
|
+
if (nameMatch) {
|
|
748
|
+
return nameMatch[1];
|
|
749
|
+
}
|
|
750
|
+
} catch {
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
return null;
|
|
754
|
+
}
|
|
755
|
+
function getWSLInfo() {
|
|
756
|
+
if (!isWSL()) {
|
|
757
|
+
return null;
|
|
758
|
+
}
|
|
759
|
+
let version = null;
|
|
760
|
+
if (existsSync("/proc/version")) {
|
|
761
|
+
try {
|
|
762
|
+
version = readFileSync("/proc/version", "utf8").trim();
|
|
763
|
+
} catch {
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
return {
|
|
767
|
+
isWSL: true,
|
|
768
|
+
distro: getWSLDistro(),
|
|
769
|
+
version
|
|
770
|
+
};
|
|
771
|
+
}
|
|
720
772
|
function getMcpCommand() {
|
|
721
773
|
if (isWindows()) {
|
|
722
774
|
return ["cmd", "/c", "npx"];
|
|
@@ -2513,6 +2565,15 @@ async function installClaudeCode() {
|
|
|
2513
2565
|
console.log(ansis.gray(`Node.js: ${termuxPrefix}/bin/node`));
|
|
2514
2566
|
console.log(ansis.gray(`npm: ${termuxPrefix}/bin/npm`));
|
|
2515
2567
|
}
|
|
2568
|
+
if (isWSL()) {
|
|
2569
|
+
const wslInfo = getWSLInfo();
|
|
2570
|
+
if (wslInfo?.distro) {
|
|
2571
|
+
console.log(ansis.yellow(`\u2139 ${i18n.t("installation:wslDetected", { distro: wslInfo.distro })}`));
|
|
2572
|
+
} else {
|
|
2573
|
+
console.log(ansis.yellow(`\u2139 ${i18n.t("installation:wslDetectedGeneric")}`));
|
|
2574
|
+
}
|
|
2575
|
+
console.log(ansis.gray(i18n.t("installation:wslPathInfo", { path: `${homedir()}/.claude/` })));
|
|
2576
|
+
}
|
|
2516
2577
|
console.log(i18n.t("installation:installing"));
|
|
2517
2578
|
try {
|
|
2518
2579
|
await exec("npm", ["install", "-g", "@anthropic-ai/claude-code"]);
|
|
@@ -2521,6 +2582,10 @@ async function installClaudeCode() {
|
|
|
2521
2582
|
console.log(ansis.gray(`
|
|
2522
2583
|
Claude Code installed to: ${getTermuxPrefix()}/bin/claude`));
|
|
2523
2584
|
}
|
|
2585
|
+
if (isWSL()) {
|
|
2586
|
+
console.log(ansis.gray(`
|
|
2587
|
+
${i18n.t("installation:wslInstallSuccess")}`));
|
|
2588
|
+
}
|
|
2524
2589
|
} catch (error) {
|
|
2525
2590
|
console.error(`\u2716 ${i18n.t("installation:installFailed")}`);
|
|
2526
2591
|
if (isTermux()) {
|
|
@@ -3548,4 +3613,4 @@ async function openSettingsJson() {
|
|
|
3548
3613
|
}
|
|
3549
3614
|
}
|
|
3550
3615
|
|
|
3551
|
-
export { addNumbersToChoices as $, AI_OUTPUT_LANGUAGES as A, copyConfigFiles as B, CLAUDE_DIR as C, configureApi as D, mergeConfigs as E, updateCustomModel as F, updateDefaultModel as G, mergeSettingsFile as H, getExistingModelConfig as I, getExistingApiConfig as J, applyAiLanguageDirective as K, LEGACY_ZCF_CONFIG_FILE as L, isClaudeCodeInstalled as M, installClaudeCode as N, isLocalClaudeCodeInstalled as O, getInstallationStatus as P, removeLocalClaudeCode as Q, ensureI18nInitialized as R, SETTINGS_FILE as S, i18n as T, readCcrConfig as U, isCcrInstalled as V, installCcr as W, configureCcrFeature as X, handleExitPromptError as Y, ZCF_CONFIG_FILE as Z, handleGeneralError as _, commandExists as a, updateZcfConfig as a0, changeLanguage as a1, readZcfConfig as a2, configureOutputStyle as a3, isWindows as a4, selectMcpServices as a5, getMcpServices as a6, formatApiKeyDisplay as a7, modifyApiConfigPartially as a8, setupCcrConfiguration as a9, validateApiKey as aa, COMETIX_COMMAND_NAME as ab, COMETIX_COMMANDS as ac, installCometixLine as ad, checkAndUpdateTools as ae,
|
|
3616
|
+
export { addNumbersToChoices as $, AI_OUTPUT_LANGUAGES as A, copyConfigFiles as B, CLAUDE_DIR as C, configureApi as D, mergeConfigs as E, updateCustomModel as F, updateDefaultModel as G, mergeSettingsFile as H, getExistingModelConfig as I, getExistingApiConfig as J, applyAiLanguageDirective as K, LEGACY_ZCF_CONFIG_FILE as L, isClaudeCodeInstalled as M, installClaudeCode as N, isLocalClaudeCodeInstalled as O, getInstallationStatus as P, removeLocalClaudeCode as Q, ensureI18nInitialized as R, SETTINGS_FILE as S, i18n as T, readCcrConfig as U, isCcrInstalled as V, installCcr as W, configureCcrFeature as X, handleExitPromptError as Y, ZCF_CONFIG_FILE as Z, handleGeneralError as _, commandExists as a, updateZcfConfig as a0, changeLanguage as a1, readZcfConfig as a2, configureOutputStyle as a3, isWindows as a4, selectMcpServices as a5, getMcpServices as a6, formatApiKeyDisplay as a7, modifyApiConfigPartially as a8, setupCcrConfiguration as a9, validateApiKey as aa, COMETIX_COMMAND_NAME as ab, COMETIX_COMMANDS as ac, installCometixLine as ad, checkAndUpdateTools as ae, readJsonConfig as af, writeJsonConfig as ag, displayBanner as ah, resolveAiOutputLanguage as ai, updatePromptOnly as aj, selectAndInstallWorkflows as ak, checkClaudeCodeVersionAndPrompt as al, version as am, displayBannerWithInfo as an, readZcfConfigAsync as ao, initI18n as ap, selectScriptLanguage as aq, prompts as ar, importRecommendedEnv as b, cleanupPermissions as c, importRecommendedPermissions as d, CLAUDE_MD_FILE as e, ClAUDE_CONFIG_FILE as f, getPlatform as g, SUPPORTED_LANGS as h, init as i, LANG_LABELS as j, getAiOutputLanguageLabel as k, getMcpConfigPath as l, mergeAndCleanPermissions as m, backupMcpConfig as n, openSettingsJson as o, mergeMcpServers as p, buildMcpServerConfig as q, readMcpConfig as r, fixWindowsMcpConfig as s, addCompletedOnboarding as t, ensureApiKeyApproved as u, removeApiKeyFromRejected as v, writeMcpConfig as w, manageApiKeyApproval as x, ensureClaudeDir as y, backupExistingConfig as z };
|
package/dist/cli.mjs
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import cac from 'cac';
|
|
3
3
|
import ansis from 'ansis';
|
|
4
|
-
import { R as ensureI18nInitialized, T as i18n, U as readCcrConfig, V as isCcrInstalled, W as installCcr, X as configureCcrFeature, Y as handleExitPromptError, _ as handleGeneralError,
|
|
5
|
-
import { existsSync
|
|
4
|
+
import { R as ensureI18nInitialized, T as i18n, U as readCcrConfig, V as isCcrInstalled, W as installCcr, X as configureCcrFeature, Y as handleExitPromptError, _ as handleGeneralError, h as SUPPORTED_LANGS, $ as addNumbersToChoices, j as LANG_LABELS, a0 as updateZcfConfig, a1 as changeLanguage, o as openSettingsJson, d as importRecommendedPermissions, b as importRecommendedEnv, a2 as readZcfConfig, K as applyAiLanguageDirective, a3 as configureOutputStyle, I as getExistingModelConfig, F as updateCustomModel, G as updateDefaultModel, a4 as isWindows, r as readMcpConfig, s as fixWindowsMcpConfig, w as writeMcpConfig, a5 as selectMcpServices, n as backupMcpConfig, a6 as getMcpServices, q as buildMcpServerConfig, p as mergeMcpServers, J as getExistingApiConfig, a7 as formatApiKeyDisplay, t as addCompletedOnboarding, a8 as modifyApiConfigPartially, a9 as setupCcrConfiguration, aa as validateApiKey, D as configureApi, ab as COMETIX_COMMAND_NAME, ac as COMETIX_COMMANDS, ad as installCometixLine, ae as checkAndUpdateTools, af as readJsonConfig, ag as writeJsonConfig, ah as displayBanner, ai as resolveAiOutputLanguage, aj as updatePromptOnly, ak as selectAndInstallWorkflows, al as checkClaudeCodeVersionAndPrompt, am as version, an as displayBannerWithInfo, i as init, ao as readZcfConfigAsync, ap as initI18n, aq as selectScriptLanguage } from './chunks/simple-config.mjs';
|
|
5
|
+
import { existsSync } from 'node:fs';
|
|
6
6
|
import { homedir } from 'node:os';
|
|
7
7
|
import inquirer from 'inquirer';
|
|
8
8
|
import { join } from 'pathe';
|
|
9
9
|
import { exec, spawn } from 'node:child_process';
|
|
10
10
|
import { promisify } from 'node:util';
|
|
11
11
|
import process from 'node:process';
|
|
12
|
-
import { x } from 'tinyexec';
|
|
12
|
+
import { x, exec as exec$1 } from 'tinyexec';
|
|
13
|
+
import { pathExists } from 'fs-extra';
|
|
14
|
+
import trash from 'trash';
|
|
13
15
|
import 'dayjs';
|
|
14
16
|
import 'node:url';
|
|
15
17
|
import 'ora';
|
|
@@ -555,7 +557,7 @@ ${ansis.blue(`\u2139 ${i18n.t("configuration:existingLanguageConfig") || "Existi
|
|
|
555
557
|
return;
|
|
556
558
|
}
|
|
557
559
|
}
|
|
558
|
-
const { selectAiOutputLanguage } = await import('./chunks/simple-config.mjs').then(function (n) { return n.
|
|
560
|
+
const { selectAiOutputLanguage } = await import('./chunks/simple-config.mjs').then(function (n) { return n.ar; });
|
|
559
561
|
const aiOutputLang = await selectAiOutputLanguage();
|
|
560
562
|
applyAiLanguageDirective(aiOutputLang);
|
|
561
563
|
updateZcfConfig({ aiOutputLang });
|
|
@@ -564,25 +566,6 @@ ${ansis.blue(`\u2139 ${i18n.t("configuration:existingLanguageConfig") || "Existi
|
|
|
564
566
|
await configureOutputStyle();
|
|
565
567
|
}
|
|
566
568
|
}
|
|
567
|
-
async function clearZcfCacheFeature() {
|
|
568
|
-
ensureI18nInitialized();
|
|
569
|
-
const { confirm } = await inquirer.prompt({
|
|
570
|
-
type: "confirm",
|
|
571
|
-
name: "confirm",
|
|
572
|
-
message: i18n.t("configuration:confirmClearCache") || "Clear all ZCF preferences cache?",
|
|
573
|
-
default: false
|
|
574
|
-
});
|
|
575
|
-
if (!confirm) {
|
|
576
|
-
await handleCancellation();
|
|
577
|
-
return;
|
|
578
|
-
}
|
|
579
|
-
if (existsSync(ZCF_CONFIG_FILE)) {
|
|
580
|
-
unlinkSync(ZCF_CONFIG_FILE);
|
|
581
|
-
console.log(ansis.green(`\u2714 ${i18n.t("configuration:cacheCleared") || "ZCF cache cleared"}`));
|
|
582
|
-
} else {
|
|
583
|
-
console.log(ansis.yellow("No cache found"));
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
569
|
async function changeScriptLanguageFeature(currentLang) {
|
|
587
570
|
ensureI18nInitialized();
|
|
588
571
|
const { lang } = await inquirer.prompt({
|
|
@@ -866,6 +849,772 @@ async function checkUpdates(options = {}) {
|
|
|
866
849
|
}
|
|
867
850
|
}
|
|
868
851
|
|
|
852
|
+
async function moveToTrash(paths) {
|
|
853
|
+
const pathArray = Array.isArray(paths) ? paths : [paths];
|
|
854
|
+
const results = [];
|
|
855
|
+
for (const path of pathArray) {
|
|
856
|
+
try {
|
|
857
|
+
const exists = await pathExists(path);
|
|
858
|
+
if (!exists) {
|
|
859
|
+
results.push({
|
|
860
|
+
success: false,
|
|
861
|
+
path,
|
|
862
|
+
error: "Path does not exist"
|
|
863
|
+
});
|
|
864
|
+
continue;
|
|
865
|
+
}
|
|
866
|
+
await trash(path);
|
|
867
|
+
results.push({
|
|
868
|
+
success: true,
|
|
869
|
+
path
|
|
870
|
+
});
|
|
871
|
+
} catch (error) {
|
|
872
|
+
results.push({
|
|
873
|
+
success: false,
|
|
874
|
+
path,
|
|
875
|
+
error: error.message || "Unknown error occurred"
|
|
876
|
+
});
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
return results;
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
class ZcfUninstaller {
|
|
883
|
+
_lang;
|
|
884
|
+
// Reserved for future i18n support
|
|
885
|
+
conflictResolution = /* @__PURE__ */ new Map();
|
|
886
|
+
constructor(lang = "en") {
|
|
887
|
+
this._lang = lang;
|
|
888
|
+
this.conflictResolution.set("claude-code", ["mcps"]);
|
|
889
|
+
void this._lang;
|
|
890
|
+
}
|
|
891
|
+
/**
|
|
892
|
+
* 1. Remove outputStyle field from settings.json and output-styles directory
|
|
893
|
+
*/
|
|
894
|
+
async removeOutputStyles() {
|
|
895
|
+
const result = {
|
|
896
|
+
success: false,
|
|
897
|
+
removed: [],
|
|
898
|
+
removedConfigs: [],
|
|
899
|
+
errors: [],
|
|
900
|
+
warnings: []
|
|
901
|
+
};
|
|
902
|
+
try {
|
|
903
|
+
const settingsPath = join(homedir(), ".claude", "settings.json");
|
|
904
|
+
const outputStylesPath = join(homedir(), ".claude", "output-styles");
|
|
905
|
+
if (await pathExists(settingsPath)) {
|
|
906
|
+
const settings = readJsonConfig(settingsPath) || {};
|
|
907
|
+
if (settings.outputStyle) {
|
|
908
|
+
delete settings.outputStyle;
|
|
909
|
+
writeJsonConfig(settingsPath, settings);
|
|
910
|
+
result.removedConfigs.push("outputStyle field from settings.json");
|
|
911
|
+
}
|
|
912
|
+
} else {
|
|
913
|
+
result.warnings.push(i18n.t("uninstall:settingsJsonNotFound"));
|
|
914
|
+
}
|
|
915
|
+
if (await pathExists(outputStylesPath)) {
|
|
916
|
+
const trashResult = await moveToTrash(outputStylesPath);
|
|
917
|
+
if (!trashResult[0]?.success) {
|
|
918
|
+
result.warnings.push(trashResult[0]?.error || "Failed to move to trash");
|
|
919
|
+
}
|
|
920
|
+
result.removed.push("~/.claude/output-styles/");
|
|
921
|
+
} else {
|
|
922
|
+
result.warnings.push(i18n.t("uninstall:outputStylesDirectoryNotFound"));
|
|
923
|
+
}
|
|
924
|
+
result.success = true;
|
|
925
|
+
} catch (error) {
|
|
926
|
+
result.errors.push(`Failed to remove output styles: ${error.message}`);
|
|
927
|
+
}
|
|
928
|
+
return result;
|
|
929
|
+
}
|
|
930
|
+
/**
|
|
931
|
+
* 2. Remove custom commands directory (commands/zcf/)
|
|
932
|
+
*/
|
|
933
|
+
async removeCustomCommands() {
|
|
934
|
+
const result = {
|
|
935
|
+
success: false,
|
|
936
|
+
removed: [],
|
|
937
|
+
removedConfigs: [],
|
|
938
|
+
errors: [],
|
|
939
|
+
warnings: []
|
|
940
|
+
};
|
|
941
|
+
try {
|
|
942
|
+
const commandsPath = join(homedir(), ".claude", "commands", "zcf");
|
|
943
|
+
if (await pathExists(commandsPath)) {
|
|
944
|
+
const trashResult = await moveToTrash(commandsPath);
|
|
945
|
+
if (!trashResult[0]?.success) {
|
|
946
|
+
result.warnings.push(trashResult[0]?.error || "Failed to move to trash");
|
|
947
|
+
}
|
|
948
|
+
result.removed.push("commands/zcf/");
|
|
949
|
+
result.success = true;
|
|
950
|
+
} else {
|
|
951
|
+
result.warnings.push(i18n.t("uninstall:commandsNotFound"));
|
|
952
|
+
result.success = true;
|
|
953
|
+
}
|
|
954
|
+
} catch (error) {
|
|
955
|
+
result.errors.push(`Failed to remove custom commands: ${error.message}`);
|
|
956
|
+
}
|
|
957
|
+
return result;
|
|
958
|
+
}
|
|
959
|
+
/**
|
|
960
|
+
* 3. Remove custom agents directory (agents/zcf/)
|
|
961
|
+
*/
|
|
962
|
+
async removeCustomAgents() {
|
|
963
|
+
const result = {
|
|
964
|
+
success: false,
|
|
965
|
+
removed: [],
|
|
966
|
+
removedConfigs: [],
|
|
967
|
+
errors: [],
|
|
968
|
+
warnings: []
|
|
969
|
+
};
|
|
970
|
+
try {
|
|
971
|
+
const agentsPath = join(homedir(), ".claude", "agents", "zcf");
|
|
972
|
+
if (await pathExists(agentsPath)) {
|
|
973
|
+
const trashResult = await moveToTrash(agentsPath);
|
|
974
|
+
if (!trashResult[0]?.success) {
|
|
975
|
+
result.warnings.push(trashResult[0]?.error || "Failed to move to trash");
|
|
976
|
+
}
|
|
977
|
+
result.removed.push("agents/zcf/");
|
|
978
|
+
result.success = true;
|
|
979
|
+
} else {
|
|
980
|
+
result.warnings.push(i18n.t("uninstall:agentsNotFound"));
|
|
981
|
+
result.success = true;
|
|
982
|
+
}
|
|
983
|
+
} catch (error) {
|
|
984
|
+
result.errors.push(`Failed to remove custom agents: ${error.message}`);
|
|
985
|
+
}
|
|
986
|
+
return result;
|
|
987
|
+
}
|
|
988
|
+
/**
|
|
989
|
+
* 4. Remove global memory file (CLAUDE.md)
|
|
990
|
+
*/
|
|
991
|
+
async removeClaudeMd() {
|
|
992
|
+
const result = {
|
|
993
|
+
success: false,
|
|
994
|
+
removed: [],
|
|
995
|
+
removedConfigs: [],
|
|
996
|
+
errors: [],
|
|
997
|
+
warnings: []
|
|
998
|
+
};
|
|
999
|
+
try {
|
|
1000
|
+
const claudeMdPath = join(homedir(), ".claude", "CLAUDE.md");
|
|
1001
|
+
if (await pathExists(claudeMdPath)) {
|
|
1002
|
+
const trashResult = await moveToTrash(claudeMdPath);
|
|
1003
|
+
if (!trashResult[0]?.success) {
|
|
1004
|
+
result.warnings.push(trashResult[0]?.error || "Failed to move to trash");
|
|
1005
|
+
}
|
|
1006
|
+
result.removed.push("CLAUDE.md");
|
|
1007
|
+
result.success = true;
|
|
1008
|
+
} else {
|
|
1009
|
+
result.warnings.push(i18n.t("uninstall:claudeMdNotFound"));
|
|
1010
|
+
result.success = true;
|
|
1011
|
+
}
|
|
1012
|
+
} catch (error) {
|
|
1013
|
+
result.errors.push(`Failed to remove CLAUDE.md: ${error.message}`);
|
|
1014
|
+
}
|
|
1015
|
+
return result;
|
|
1016
|
+
}
|
|
1017
|
+
/**
|
|
1018
|
+
* 5. Remove permissions and environment variables
|
|
1019
|
+
*/
|
|
1020
|
+
async removePermissionsAndEnvs() {
|
|
1021
|
+
const result = {
|
|
1022
|
+
success: false,
|
|
1023
|
+
removed: [],
|
|
1024
|
+
removedConfigs: [],
|
|
1025
|
+
errors: [],
|
|
1026
|
+
warnings: []
|
|
1027
|
+
};
|
|
1028
|
+
try {
|
|
1029
|
+
const settingsPath = join(homedir(), ".claude", "settings.json");
|
|
1030
|
+
if (await pathExists(settingsPath)) {
|
|
1031
|
+
const settings = readJsonConfig(settingsPath) || {};
|
|
1032
|
+
let modified = false;
|
|
1033
|
+
if (settings.permissions) {
|
|
1034
|
+
delete settings.permissions;
|
|
1035
|
+
result.removedConfigs.push("permissions configuration");
|
|
1036
|
+
modified = true;
|
|
1037
|
+
}
|
|
1038
|
+
if (settings.env) {
|
|
1039
|
+
delete settings.env;
|
|
1040
|
+
result.removedConfigs.push("environment variables");
|
|
1041
|
+
modified = true;
|
|
1042
|
+
}
|
|
1043
|
+
if (modified) {
|
|
1044
|
+
writeJsonConfig(settingsPath, settings);
|
|
1045
|
+
}
|
|
1046
|
+
result.success = true;
|
|
1047
|
+
} else {
|
|
1048
|
+
result.warnings.push(i18n.t("uninstall:settingsJsonNotFound"));
|
|
1049
|
+
result.success = true;
|
|
1050
|
+
}
|
|
1051
|
+
} catch (error) {
|
|
1052
|
+
result.errors.push(`Failed to remove permissions and envs: ${error.message}`);
|
|
1053
|
+
}
|
|
1054
|
+
return result;
|
|
1055
|
+
}
|
|
1056
|
+
/**
|
|
1057
|
+
* 6. Remove MCP servers from .claude.json (mcpServers field only)
|
|
1058
|
+
*/
|
|
1059
|
+
async removeMcps() {
|
|
1060
|
+
const result = {
|
|
1061
|
+
success: false,
|
|
1062
|
+
removed: [],
|
|
1063
|
+
removedConfigs: [],
|
|
1064
|
+
errors: [],
|
|
1065
|
+
warnings: []
|
|
1066
|
+
};
|
|
1067
|
+
try {
|
|
1068
|
+
const claudeJsonPath = join(homedir(), ".claude.json");
|
|
1069
|
+
if (await pathExists(claudeJsonPath)) {
|
|
1070
|
+
const config = readJsonConfig(claudeJsonPath) || {};
|
|
1071
|
+
if (config.mcpServers) {
|
|
1072
|
+
delete config.mcpServers;
|
|
1073
|
+
writeJsonConfig(claudeJsonPath, config);
|
|
1074
|
+
result.removedConfigs.push("mcpServers from .claude.json");
|
|
1075
|
+
}
|
|
1076
|
+
result.success = true;
|
|
1077
|
+
} else {
|
|
1078
|
+
result.warnings.push(i18n.t("uninstall:claudeJsonNotFound"));
|
|
1079
|
+
result.success = true;
|
|
1080
|
+
}
|
|
1081
|
+
} catch (error) {
|
|
1082
|
+
result.errors.push(`Failed to remove MCP servers: ${error.message}`);
|
|
1083
|
+
}
|
|
1084
|
+
return result;
|
|
1085
|
+
}
|
|
1086
|
+
/**
|
|
1087
|
+
* 7. Uninstall Claude Code Router and remove configuration
|
|
1088
|
+
*/
|
|
1089
|
+
async uninstallCcr() {
|
|
1090
|
+
const result = {
|
|
1091
|
+
success: false,
|
|
1092
|
+
removed: [],
|
|
1093
|
+
removedConfigs: [],
|
|
1094
|
+
errors: [],
|
|
1095
|
+
warnings: []
|
|
1096
|
+
};
|
|
1097
|
+
try {
|
|
1098
|
+
const ccrPath = join(homedir(), ".claude-code-router");
|
|
1099
|
+
if (await pathExists(ccrPath)) {
|
|
1100
|
+
const trashResult = await moveToTrash(ccrPath);
|
|
1101
|
+
if (!trashResult[0]?.success) {
|
|
1102
|
+
result.warnings.push(trashResult[0]?.error || "Failed to move to trash");
|
|
1103
|
+
}
|
|
1104
|
+
result.removed.push(".claude-code-router/");
|
|
1105
|
+
}
|
|
1106
|
+
try {
|
|
1107
|
+
await exec$1("npm", ["uninstall", "-g", "@musistudio/claude-code-router"]);
|
|
1108
|
+
result.removed.push("@musistudio/claude-code-router package");
|
|
1109
|
+
result.success = true;
|
|
1110
|
+
} catch (npmError) {
|
|
1111
|
+
if (npmError.message.includes("not found") || npmError.message.includes("not installed")) {
|
|
1112
|
+
result.warnings.push(i18n.t("uninstall:ccrPackageNotFound"));
|
|
1113
|
+
result.success = true;
|
|
1114
|
+
} else {
|
|
1115
|
+
result.errors.push(`Failed to uninstall CCR package: ${npmError.message}`);
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
} catch (error) {
|
|
1119
|
+
result.errors.push(`Failed to uninstall CCR: ${error.message}`);
|
|
1120
|
+
}
|
|
1121
|
+
return result;
|
|
1122
|
+
}
|
|
1123
|
+
/**
|
|
1124
|
+
* 8. Uninstall CCometixLine
|
|
1125
|
+
*/
|
|
1126
|
+
async uninstallCcline() {
|
|
1127
|
+
const result = {
|
|
1128
|
+
success: false,
|
|
1129
|
+
removed: [],
|
|
1130
|
+
removedConfigs: [],
|
|
1131
|
+
errors: [],
|
|
1132
|
+
warnings: []
|
|
1133
|
+
};
|
|
1134
|
+
try {
|
|
1135
|
+
await exec$1("npm", ["uninstall", "-g", "@cometix/ccline"]);
|
|
1136
|
+
result.removed.push("@cometix/ccline package");
|
|
1137
|
+
result.success = true;
|
|
1138
|
+
} catch (error) {
|
|
1139
|
+
if (error.message.includes("not found") || error.message.includes("not installed")) {
|
|
1140
|
+
result.warnings.push(i18n.t("uninstall:cclinePackageNotFound"));
|
|
1141
|
+
result.success = true;
|
|
1142
|
+
} else {
|
|
1143
|
+
result.errors.push(`Failed to uninstall CCometixLine: ${error.message}`);
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
return result;
|
|
1147
|
+
}
|
|
1148
|
+
/**
|
|
1149
|
+
* 9. Uninstall Claude Code and remove entire .claude.json
|
|
1150
|
+
*/
|
|
1151
|
+
async uninstallClaudeCode() {
|
|
1152
|
+
const result = {
|
|
1153
|
+
success: false,
|
|
1154
|
+
removed: [],
|
|
1155
|
+
removedConfigs: [],
|
|
1156
|
+
errors: [],
|
|
1157
|
+
warnings: []
|
|
1158
|
+
};
|
|
1159
|
+
try {
|
|
1160
|
+
const claudeJsonPath = join(homedir(), ".claude.json");
|
|
1161
|
+
if (await pathExists(claudeJsonPath)) {
|
|
1162
|
+
const trashResult = await moveToTrash(claudeJsonPath);
|
|
1163
|
+
if (!trashResult[0]?.success) {
|
|
1164
|
+
result.warnings.push(trashResult[0]?.error || "Failed to move to trash");
|
|
1165
|
+
}
|
|
1166
|
+
result.removed.push(".claude.json (includes MCP configuration)");
|
|
1167
|
+
}
|
|
1168
|
+
try {
|
|
1169
|
+
await exec$1("npm", ["uninstall", "-g", "@anthropic-ai/claude-code"]);
|
|
1170
|
+
result.removed.push("@anthropic-ai/claude-code package");
|
|
1171
|
+
result.success = true;
|
|
1172
|
+
} catch (npmError) {
|
|
1173
|
+
if (npmError.message.includes("not found") || npmError.message.includes("not installed")) {
|
|
1174
|
+
result.warnings.push(i18n.t("uninstall:claudeCodePackageNotFound"));
|
|
1175
|
+
result.success = true;
|
|
1176
|
+
} else {
|
|
1177
|
+
result.errors.push(`Failed to uninstall Claude Code package: ${npmError.message}`);
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
} catch (error) {
|
|
1181
|
+
result.errors.push(`Failed to uninstall Claude Code: ${error.message}`);
|
|
1182
|
+
}
|
|
1183
|
+
return result;
|
|
1184
|
+
}
|
|
1185
|
+
/**
|
|
1186
|
+
* 10. Remove backup files
|
|
1187
|
+
*/
|
|
1188
|
+
async removeBackups() {
|
|
1189
|
+
const result = {
|
|
1190
|
+
success: false,
|
|
1191
|
+
removed: [],
|
|
1192
|
+
removedConfigs: [],
|
|
1193
|
+
errors: [],
|
|
1194
|
+
warnings: []
|
|
1195
|
+
};
|
|
1196
|
+
try {
|
|
1197
|
+
const backupPath = join(homedir(), ".claude", "backup");
|
|
1198
|
+
if (await pathExists(backupPath)) {
|
|
1199
|
+
const trashResult = await moveToTrash(backupPath);
|
|
1200
|
+
if (!trashResult[0]?.success) {
|
|
1201
|
+
result.warnings.push(trashResult[0]?.error || "Failed to move to trash");
|
|
1202
|
+
}
|
|
1203
|
+
result.removed.push("backup/");
|
|
1204
|
+
result.success = true;
|
|
1205
|
+
} else {
|
|
1206
|
+
result.warnings.push(i18n.t("uninstall:backupsNotFound"));
|
|
1207
|
+
result.success = true;
|
|
1208
|
+
}
|
|
1209
|
+
} catch (error) {
|
|
1210
|
+
result.errors.push(`Failed to remove backups: ${error.message}`);
|
|
1211
|
+
}
|
|
1212
|
+
return result;
|
|
1213
|
+
}
|
|
1214
|
+
/**
|
|
1215
|
+
* 11. Remove ZCF preference configuration
|
|
1216
|
+
*/
|
|
1217
|
+
async removeZcfConfig() {
|
|
1218
|
+
const result = {
|
|
1219
|
+
success: false,
|
|
1220
|
+
removed: [],
|
|
1221
|
+
removedConfigs: [],
|
|
1222
|
+
errors: [],
|
|
1223
|
+
warnings: []
|
|
1224
|
+
};
|
|
1225
|
+
try {
|
|
1226
|
+
const zcfConfigPath = join(homedir(), ".zcf-config.json");
|
|
1227
|
+
if (await pathExists(zcfConfigPath)) {
|
|
1228
|
+
const trashResult = await moveToTrash(zcfConfigPath);
|
|
1229
|
+
if (!trashResult[0]?.success) {
|
|
1230
|
+
result.warnings.push(trashResult[0]?.error || "Failed to move to trash");
|
|
1231
|
+
}
|
|
1232
|
+
result.removed.push(".zcf-config.json");
|
|
1233
|
+
result.success = true;
|
|
1234
|
+
} else {
|
|
1235
|
+
result.warnings.push(i18n.t("uninstall:zcfConfigNotFound"));
|
|
1236
|
+
result.success = true;
|
|
1237
|
+
}
|
|
1238
|
+
} catch (error) {
|
|
1239
|
+
result.errors.push(`Failed to remove ZCF config: ${error.message}`);
|
|
1240
|
+
}
|
|
1241
|
+
return result;
|
|
1242
|
+
}
|
|
1243
|
+
/**
|
|
1244
|
+
* Complete uninstall - remove all directories and packages
|
|
1245
|
+
*/
|
|
1246
|
+
async completeUninstall() {
|
|
1247
|
+
const result = {
|
|
1248
|
+
success: true,
|
|
1249
|
+
removed: [],
|
|
1250
|
+
removedConfigs: [],
|
|
1251
|
+
errors: [],
|
|
1252
|
+
warnings: []
|
|
1253
|
+
};
|
|
1254
|
+
try {
|
|
1255
|
+
const directoriesToRemove = [
|
|
1256
|
+
{ path: join(homedir(), ".claude"), name: "~/.claude/" },
|
|
1257
|
+
{ path: join(homedir(), ".claude.json"), name: "~/.claude.json" },
|
|
1258
|
+
{ path: join(homedir(), ".claude-code-router"), name: "~/.claude-code-router/" }
|
|
1259
|
+
];
|
|
1260
|
+
for (const dir of directoriesToRemove) {
|
|
1261
|
+
try {
|
|
1262
|
+
if (await pathExists(dir.path)) {
|
|
1263
|
+
const trashResult = await moveToTrash(dir.path);
|
|
1264
|
+
if (!trashResult[0]?.success) {
|
|
1265
|
+
result.warnings.push(`Failed to move ${dir.name} to trash: ${trashResult[0]?.error || "Unknown error"}`);
|
|
1266
|
+
}
|
|
1267
|
+
result.removed.push(dir.name);
|
|
1268
|
+
}
|
|
1269
|
+
} catch (error) {
|
|
1270
|
+
result.warnings.push(`Failed to remove ${dir.name}: ${error.message}`);
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
const packagesToUninstall = [
|
|
1274
|
+
"@musistudio/claude-code-router",
|
|
1275
|
+
"@cometix/ccline",
|
|
1276
|
+
"@anthropic-ai/claude-code"
|
|
1277
|
+
];
|
|
1278
|
+
for (const pkg of packagesToUninstall) {
|
|
1279
|
+
try {
|
|
1280
|
+
await exec$1("npm", ["uninstall", "-g", pkg]);
|
|
1281
|
+
result.removed.push(`${pkg} package`);
|
|
1282
|
+
} catch (error) {
|
|
1283
|
+
if (error.message.includes("not found") || error.message.includes("not installed")) {
|
|
1284
|
+
if (pkg.includes("claude-code-router")) {
|
|
1285
|
+
result.warnings.push(i18n.t("uninstall:ccrPackageNotFound"));
|
|
1286
|
+
} else if (pkg.includes("ccline")) {
|
|
1287
|
+
result.warnings.push(i18n.t("uninstall:cclinePackageNotFound"));
|
|
1288
|
+
} else {
|
|
1289
|
+
result.warnings.push(i18n.t("uninstall:claudeCodePackageNotFound"));
|
|
1290
|
+
}
|
|
1291
|
+
} else {
|
|
1292
|
+
result.warnings.push(`Failed to uninstall ${pkg}: ${error.message}`);
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1296
|
+
} catch (error) {
|
|
1297
|
+
result.errors.push(`Complete uninstall failed: ${error.message}`);
|
|
1298
|
+
result.success = false;
|
|
1299
|
+
}
|
|
1300
|
+
return result;
|
|
1301
|
+
}
|
|
1302
|
+
/**
|
|
1303
|
+
* Custom uninstall with conflict resolution
|
|
1304
|
+
*/
|
|
1305
|
+
async customUninstall(selectedItems) {
|
|
1306
|
+
const resolvedItems = this.resolveConflicts(selectedItems);
|
|
1307
|
+
const results = [];
|
|
1308
|
+
for (const item of resolvedItems) {
|
|
1309
|
+
try {
|
|
1310
|
+
const result = await this.executeUninstallItem(item);
|
|
1311
|
+
results.push(result);
|
|
1312
|
+
} catch (error) {
|
|
1313
|
+
results.push({
|
|
1314
|
+
success: false,
|
|
1315
|
+
removed: [],
|
|
1316
|
+
removedConfigs: [],
|
|
1317
|
+
errors: [`Failed to execute ${item}: ${error.message}`],
|
|
1318
|
+
warnings: []
|
|
1319
|
+
});
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1322
|
+
return results;
|
|
1323
|
+
}
|
|
1324
|
+
/**
|
|
1325
|
+
* Resolve conflicts between uninstall items
|
|
1326
|
+
*/
|
|
1327
|
+
resolveConflicts(items) {
|
|
1328
|
+
const resolved = [...items];
|
|
1329
|
+
for (const [primary, conflicts] of this.conflictResolution) {
|
|
1330
|
+
if (resolved.includes(primary)) {
|
|
1331
|
+
conflicts.forEach((conflict) => {
|
|
1332
|
+
const index = resolved.indexOf(conflict);
|
|
1333
|
+
if (index > -1) {
|
|
1334
|
+
resolved.splice(index, 1);
|
|
1335
|
+
}
|
|
1336
|
+
});
|
|
1337
|
+
}
|
|
1338
|
+
}
|
|
1339
|
+
return resolved;
|
|
1340
|
+
}
|
|
1341
|
+
/**
|
|
1342
|
+
* Execute uninstall for a specific item
|
|
1343
|
+
*/
|
|
1344
|
+
async executeUninstallItem(item) {
|
|
1345
|
+
switch (item) {
|
|
1346
|
+
case "output-styles":
|
|
1347
|
+
return await this.removeOutputStyles();
|
|
1348
|
+
case "commands":
|
|
1349
|
+
return await this.removeCustomCommands();
|
|
1350
|
+
case "agents":
|
|
1351
|
+
return await this.removeCustomAgents();
|
|
1352
|
+
case "claude-md":
|
|
1353
|
+
return await this.removeClaudeMd();
|
|
1354
|
+
case "permissions-envs":
|
|
1355
|
+
return await this.removePermissionsAndEnvs();
|
|
1356
|
+
case "mcps":
|
|
1357
|
+
return await this.removeMcps();
|
|
1358
|
+
case "ccr":
|
|
1359
|
+
return await this.uninstallCcr();
|
|
1360
|
+
case "ccline":
|
|
1361
|
+
return await this.uninstallCcline();
|
|
1362
|
+
case "claude-code":
|
|
1363
|
+
return await this.uninstallClaudeCode();
|
|
1364
|
+
case "backups":
|
|
1365
|
+
return await this.removeBackups();
|
|
1366
|
+
case "zcf-config":
|
|
1367
|
+
return await this.removeZcfConfig();
|
|
1368
|
+
default:
|
|
1369
|
+
return {
|
|
1370
|
+
success: false,
|
|
1371
|
+
removed: [],
|
|
1372
|
+
removedConfigs: [],
|
|
1373
|
+
errors: [`Unknown uninstall item: ${item}`],
|
|
1374
|
+
warnings: []
|
|
1375
|
+
};
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1378
|
+
}
|
|
1379
|
+
|
|
1380
|
+
async function uninstall(options = {}) {
|
|
1381
|
+
try {
|
|
1382
|
+
ensureI18nInitialized();
|
|
1383
|
+
const uninstaller = new ZcfUninstaller(options.lang || "en");
|
|
1384
|
+
if (options.mode && options.mode !== "interactive") {
|
|
1385
|
+
if (options.mode === "complete") {
|
|
1386
|
+
await executeCompleteUninstall(uninstaller);
|
|
1387
|
+
return;
|
|
1388
|
+
} else if (options.mode === "custom" && options.items) {
|
|
1389
|
+
let items;
|
|
1390
|
+
if (typeof options.items === "string") {
|
|
1391
|
+
items = options.items.split(",").map((item) => item.trim());
|
|
1392
|
+
} else {
|
|
1393
|
+
items = options.items;
|
|
1394
|
+
}
|
|
1395
|
+
await executeCustomUninstall(uninstaller, items);
|
|
1396
|
+
return;
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
await showInteractiveUninstall(uninstaller);
|
|
1400
|
+
} catch (error) {
|
|
1401
|
+
if (!handleExitPromptError(error)) {
|
|
1402
|
+
handleGeneralError(error);
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
async function showInteractiveUninstall(uninstaller) {
|
|
1407
|
+
console.log(ansis.cyan.bold(i18n.t("uninstall:title")));
|
|
1408
|
+
console.log(ansis.yellow(i18n.t("uninstall:warning")));
|
|
1409
|
+
console.log("");
|
|
1410
|
+
const { mainChoice } = await inquirer.prompt({
|
|
1411
|
+
type: "list",
|
|
1412
|
+
name: "mainChoice",
|
|
1413
|
+
message: i18n.t("uninstall:selectMainOption"),
|
|
1414
|
+
choices: addNumbersToChoices([
|
|
1415
|
+
{
|
|
1416
|
+
name: `${i18n.t("uninstall:completeUninstall")} - ${ansis.gray(i18n.t("uninstall:completeUninstallDesc"))}`,
|
|
1417
|
+
value: "complete",
|
|
1418
|
+
short: i18n.t("uninstall:completeUninstall")
|
|
1419
|
+
},
|
|
1420
|
+
{
|
|
1421
|
+
name: `${i18n.t("uninstall:customUninstall")} - ${ansis.gray(i18n.t("uninstall:customUninstallDesc"))}`,
|
|
1422
|
+
value: "custom",
|
|
1423
|
+
short: i18n.t("uninstall:customUninstall")
|
|
1424
|
+
}
|
|
1425
|
+
])
|
|
1426
|
+
});
|
|
1427
|
+
if (!mainChoice) {
|
|
1428
|
+
console.log(ansis.yellow(i18n.t("common:cancelled")));
|
|
1429
|
+
return;
|
|
1430
|
+
}
|
|
1431
|
+
if (mainChoice === "complete") {
|
|
1432
|
+
await executeCompleteUninstall(uninstaller);
|
|
1433
|
+
} else {
|
|
1434
|
+
await showCustomUninstallMenu(uninstaller);
|
|
1435
|
+
}
|
|
1436
|
+
}
|
|
1437
|
+
async function showCustomUninstallMenu(uninstaller) {
|
|
1438
|
+
console.log("");
|
|
1439
|
+
console.log(ansis.cyan(i18n.t("uninstall:selectCustomItems")));
|
|
1440
|
+
const { customItems } = await inquirer.prompt({
|
|
1441
|
+
type: "checkbox",
|
|
1442
|
+
name: "customItems",
|
|
1443
|
+
message: `${i18n.t("uninstall:selectItemsToRemove")} ${i18n.t("common:multiSelectHint")}`,
|
|
1444
|
+
choices: [
|
|
1445
|
+
{
|
|
1446
|
+
name: i18n.t("uninstall:outputStyles"),
|
|
1447
|
+
value: "output-styles"
|
|
1448
|
+
},
|
|
1449
|
+
{
|
|
1450
|
+
name: i18n.t("uninstall:commands"),
|
|
1451
|
+
value: "commands"
|
|
1452
|
+
},
|
|
1453
|
+
{
|
|
1454
|
+
name: i18n.t("uninstall:agents"),
|
|
1455
|
+
value: "agents"
|
|
1456
|
+
},
|
|
1457
|
+
{
|
|
1458
|
+
name: i18n.t("uninstall:claudeMd"),
|
|
1459
|
+
value: "claude-md"
|
|
1460
|
+
},
|
|
1461
|
+
{
|
|
1462
|
+
name: i18n.t("uninstall:permissionsEnvs"),
|
|
1463
|
+
value: "permissions-envs"
|
|
1464
|
+
},
|
|
1465
|
+
{
|
|
1466
|
+
name: i18n.t("uninstall:mcps"),
|
|
1467
|
+
value: "mcps"
|
|
1468
|
+
},
|
|
1469
|
+
{
|
|
1470
|
+
name: i18n.t("uninstall:ccr"),
|
|
1471
|
+
value: "ccr"
|
|
1472
|
+
},
|
|
1473
|
+
{
|
|
1474
|
+
name: i18n.t("uninstall:ccline"),
|
|
1475
|
+
value: "ccline"
|
|
1476
|
+
},
|
|
1477
|
+
{
|
|
1478
|
+
name: i18n.t("uninstall:claudeCode"),
|
|
1479
|
+
value: "claude-code"
|
|
1480
|
+
},
|
|
1481
|
+
{
|
|
1482
|
+
name: i18n.t("uninstall:backups"),
|
|
1483
|
+
value: "backups"
|
|
1484
|
+
},
|
|
1485
|
+
{
|
|
1486
|
+
name: i18n.t("uninstall:zcfConfig"),
|
|
1487
|
+
value: "zcf-config"
|
|
1488
|
+
}
|
|
1489
|
+
],
|
|
1490
|
+
validate: (answers) => {
|
|
1491
|
+
if (answers.length === 0) {
|
|
1492
|
+
return i18n.t("uninstall:selectAtLeastOne");
|
|
1493
|
+
}
|
|
1494
|
+
return true;
|
|
1495
|
+
}
|
|
1496
|
+
});
|
|
1497
|
+
if (!customItems || customItems.length === 0) {
|
|
1498
|
+
console.log(ansis.yellow(i18n.t("common:cancelled")));
|
|
1499
|
+
return;
|
|
1500
|
+
}
|
|
1501
|
+
await executeCustomUninstall(uninstaller, customItems);
|
|
1502
|
+
}
|
|
1503
|
+
async function executeCompleteUninstall(uninstaller) {
|
|
1504
|
+
console.log("");
|
|
1505
|
+
console.log(ansis.red.bold(i18n.t("uninstall:executingComplete")));
|
|
1506
|
+
console.log(ansis.yellow(i18n.t("uninstall:completeWarning")));
|
|
1507
|
+
const { confirm } = await inquirer.prompt({
|
|
1508
|
+
type: "confirm",
|
|
1509
|
+
name: "confirm",
|
|
1510
|
+
message: i18n.t("uninstall:confirmComplete"),
|
|
1511
|
+
default: false
|
|
1512
|
+
});
|
|
1513
|
+
if (!confirm) {
|
|
1514
|
+
console.log(ansis.yellow(i18n.t("common:cancelled")));
|
|
1515
|
+
return;
|
|
1516
|
+
}
|
|
1517
|
+
console.log("");
|
|
1518
|
+
console.log(ansis.cyan(i18n.t("uninstall:processingComplete")));
|
|
1519
|
+
const result = await uninstaller.completeUninstall();
|
|
1520
|
+
displayUninstallResult("complete", [result]);
|
|
1521
|
+
}
|
|
1522
|
+
async function executeCustomUninstall(uninstaller, items) {
|
|
1523
|
+
console.log("");
|
|
1524
|
+
console.log(ansis.cyan(i18n.t("uninstall:executingCustom")));
|
|
1525
|
+
console.log(ansis.gray(i18n.t("uninstall:selectedItems")));
|
|
1526
|
+
items.forEach((item) => {
|
|
1527
|
+
console.log(` \u2022 ${i18n.t(`uninstall:${item}`)}`);
|
|
1528
|
+
});
|
|
1529
|
+
const { confirm } = await inquirer.prompt({
|
|
1530
|
+
type: "confirm",
|
|
1531
|
+
name: "confirm",
|
|
1532
|
+
message: i18n.t("uninstall:confirmCustom"),
|
|
1533
|
+
default: false
|
|
1534
|
+
});
|
|
1535
|
+
if (!confirm) {
|
|
1536
|
+
console.log(ansis.yellow(i18n.t("common:cancelled")));
|
|
1537
|
+
return;
|
|
1538
|
+
}
|
|
1539
|
+
console.log("");
|
|
1540
|
+
console.log(ansis.cyan(i18n.t("uninstall:processingCustom")));
|
|
1541
|
+
const results = await uninstaller.customUninstall(items);
|
|
1542
|
+
displayUninstallResult("custom", results);
|
|
1543
|
+
}
|
|
1544
|
+
function displayUninstallResult(mode, results) {
|
|
1545
|
+
console.log("");
|
|
1546
|
+
console.log(ansis.cyan("\u2500".repeat(50)));
|
|
1547
|
+
let totalSuccess = 0;
|
|
1548
|
+
let totalErrors = 0;
|
|
1549
|
+
let totalWarnings = 0;
|
|
1550
|
+
results.forEach((result) => {
|
|
1551
|
+
if (result.success) {
|
|
1552
|
+
totalSuccess++;
|
|
1553
|
+
}
|
|
1554
|
+
if (result.removed && result.removed.length > 0) {
|
|
1555
|
+
console.log(ansis.green(`\u{1F5D1}\uFE0F ${i18n.t("uninstall:movedToTrash")}:`));
|
|
1556
|
+
result.removed.forEach((item) => {
|
|
1557
|
+
console.log(ansis.gray(` \u2022 ${item}`));
|
|
1558
|
+
});
|
|
1559
|
+
}
|
|
1560
|
+
if (result.removedConfigs && result.removedConfigs.length > 0) {
|
|
1561
|
+
console.log(ansis.green(`\u2714 ${i18n.t("uninstall:removedConfigs")}:`));
|
|
1562
|
+
result.removedConfigs.forEach((item) => {
|
|
1563
|
+
console.log(ansis.gray(` \u2022 ${item}`));
|
|
1564
|
+
});
|
|
1565
|
+
}
|
|
1566
|
+
if (result.errors && result.errors.length > 0) {
|
|
1567
|
+
totalErrors += result.errors.length;
|
|
1568
|
+
console.log(ansis.red(`\u2716 ${i18n.t("uninstall:errors")}:`));
|
|
1569
|
+
result.errors.forEach((error) => {
|
|
1570
|
+
console.log(ansis.red(` \u2022 ${error}`));
|
|
1571
|
+
});
|
|
1572
|
+
}
|
|
1573
|
+
if (result.warnings && result.warnings.length > 0) {
|
|
1574
|
+
totalWarnings += result.warnings.length;
|
|
1575
|
+
console.log(ansis.yellow(`\u26A0 ${i18n.t("uninstall:warnings")}:`));
|
|
1576
|
+
result.warnings.forEach((warning) => {
|
|
1577
|
+
console.log(ansis.yellow(` \u2022 ${warning}`));
|
|
1578
|
+
});
|
|
1579
|
+
}
|
|
1580
|
+
});
|
|
1581
|
+
const totalRemovedFiles = results.reduce((count, result) => count + (result.removed?.length || 0), 0);
|
|
1582
|
+
const totalRemovedConfigs = results.reduce((count, result) => count + (result.removedConfigs?.length || 0), 0);
|
|
1583
|
+
console.log("");
|
|
1584
|
+
console.log(ansis.cyan("\u2500".repeat(50)));
|
|
1585
|
+
if (mode === "complete") {
|
|
1586
|
+
if (totalErrors === 0) {
|
|
1587
|
+
console.log(ansis.green.bold(`\u2714 ${i18n.t("uninstall:completeSuccess")}`));
|
|
1588
|
+
} else {
|
|
1589
|
+
console.log(ansis.yellow.bold(`\u26A0 ${i18n.t("uninstall:completePartialSuccess")}`));
|
|
1590
|
+
}
|
|
1591
|
+
} else {
|
|
1592
|
+
if (totalRemovedFiles > 0 && totalRemovedConfigs > 0) {
|
|
1593
|
+
console.log(ansis.green.bold(`\u2714 ${i18n.t("uninstall:customSuccessBoth", {
|
|
1594
|
+
fileCount: totalRemovedFiles,
|
|
1595
|
+
configCount: totalRemovedConfigs
|
|
1596
|
+
})}`));
|
|
1597
|
+
} else if (totalRemovedFiles > 0) {
|
|
1598
|
+
console.log(ansis.green.bold(`\u2714 ${i18n.t("uninstall:customSuccessFiles", {
|
|
1599
|
+
count: totalRemovedFiles
|
|
1600
|
+
})}`));
|
|
1601
|
+
} else if (totalRemovedConfigs > 0) {
|
|
1602
|
+
console.log(ansis.green.bold(`\u2714 ${i18n.t("uninstall:customSuccessConfigs", {
|
|
1603
|
+
count: totalRemovedConfigs
|
|
1604
|
+
})}`));
|
|
1605
|
+
} else {
|
|
1606
|
+
console.log(ansis.green.bold(`\u2714 ${i18n.t("uninstall:customSuccess", { count: totalSuccess })}`));
|
|
1607
|
+
}
|
|
1608
|
+
if (totalErrors > 0) {
|
|
1609
|
+
console.log(ansis.red(`\u2716 ${i18n.t("uninstall:errorsCount", { count: totalErrors })}`));
|
|
1610
|
+
}
|
|
1611
|
+
if (totalWarnings > 0) {
|
|
1612
|
+
console.log(ansis.yellow(`\u26A0 ${i18n.t("uninstall:warningsCount", { count: totalWarnings })}`));
|
|
1613
|
+
}
|
|
1614
|
+
}
|
|
1615
|
+
console.log("");
|
|
1616
|
+
}
|
|
1617
|
+
|
|
869
1618
|
async function update(options = {}) {
|
|
870
1619
|
try {
|
|
871
1620
|
if (!options.skipBanner) {
|
|
@@ -970,7 +1719,7 @@ async function showMainMenu() {
|
|
|
970
1719
|
)}`
|
|
971
1720
|
);
|
|
972
1721
|
console.log(
|
|
973
|
-
` ${ansis.cyan("-.")} ${i18n.t("menu:menuOptions.
|
|
1722
|
+
` ${ansis.cyan("-.")} ${i18n.t("menu:menuOptions.uninstall")} ${ansis.gray(`- ${i18n.t("menu:menuDescriptions.uninstall")}`)}`
|
|
974
1723
|
);
|
|
975
1724
|
console.log(
|
|
976
1725
|
` ${ansis.cyan("+.")} ${i18n.t("menu:menuOptions.checkUpdates")} ${ansis.gray(`- ${i18n.t("menu:menuDescriptions.checkUpdates")}`)}`
|
|
@@ -1031,7 +1780,7 @@ async function showMainMenu() {
|
|
|
1031
1780
|
break;
|
|
1032
1781
|
}
|
|
1033
1782
|
case "-":
|
|
1034
|
-
await
|
|
1783
|
+
await uninstall();
|
|
1035
1784
|
break;
|
|
1036
1785
|
case "+":
|
|
1037
1786
|
await checkUpdates();
|
|
@@ -1128,6 +1877,7 @@ function customizeHelp(sections) {
|
|
|
1128
1877
|
` ${ansis.cyan("zcf update")} | ${ansis.cyan("u")} ${i18n.t("cli:help.commandDescriptions.updateWorkflowFiles")}`,
|
|
1129
1878
|
` ${ansis.cyan("zcf ccr")} ${i18n.t("cli:help.commandDescriptions.configureCcrProxy")}`,
|
|
1130
1879
|
` ${ansis.cyan("zcf ccu")} [args] ${i18n.t("cli:help.commandDescriptions.claudeCodeUsageAnalysis")}`,
|
|
1880
|
+
` ${ansis.cyan("zcf uninstall")} ${i18n.t("cli:help.commandDescriptions.uninstallConfigurations")}`,
|
|
1131
1881
|
` ${ansis.cyan("zcf check-updates")} ${i18n.t("cli:help.commandDescriptions.checkUpdateVersions")}`,
|
|
1132
1882
|
"",
|
|
1133
1883
|
ansis.gray(` ${i18n.t("cli:help.shortcuts")}`),
|
|
@@ -1180,6 +1930,9 @@ function customizeHelp(sections) {
|
|
|
1180
1930
|
` ${ansis.cyan("npx zcf ccu")} ${ansis.gray(`# ${i18n.t("cli:help.defaults.dailyUsage")}`)}`,
|
|
1181
1931
|
` ${ansis.cyan("npx zcf ccu monthly --json")}`,
|
|
1182
1932
|
"",
|
|
1933
|
+
ansis.gray(` # ${i18n.t("cli:help.exampleDescriptions.uninstallConfigurations")}`),
|
|
1934
|
+
` ${ansis.cyan("npx zcf uninstall")} ${ansis.gray(`# ${i18n.t("cli:help.defaults.interactiveUninstall")}`)}`,
|
|
1935
|
+
"",
|
|
1183
1936
|
ansis.gray(` # ${i18n.t("cli:help.exampleDescriptions.checkAndUpdateTools")}`),
|
|
1184
1937
|
` ${ansis.cyan("npx zcf check-updates")} ${ansis.gray(`# ${i18n.t("cli:help.defaults.updateTools")}`)}`,
|
|
1185
1938
|
` ${ansis.cyan("npx zcf check")}`,
|
|
@@ -1215,6 +1968,9 @@ async function setupCommands(cli) {
|
|
|
1215
1968
|
cli.command("ccu [...args]", "Run Claude Code usage analysis tool").option("--lang, -l <lang>", "ZCF display language (zh-CN, en)").option("--all-lang, -g <lang>", "Set all language parameters to this value").allowUnknownOptions().action(await withLanguageResolution(async (args) => {
|
|
1216
1969
|
await executeCcusage(args);
|
|
1217
1970
|
}));
|
|
1971
|
+
cli.command("uninstall", "Remove ZCF configurations and tools").option("--lang, -l <lang>", "ZCF display language (zh-CN, en)").option("--all-lang, -g <lang>", "Set all language parameters to this value").option("--mode, -m <mode>", "Uninstall mode (complete/custom/interactive), default: interactive").option("--items, -i <items>", "Comma-separated items for custom uninstall mode").action(await withLanguageResolution(async (options) => {
|
|
1972
|
+
await uninstall(options);
|
|
1973
|
+
}));
|
|
1218
1974
|
cli.command("check-updates", "Check and update Claude Code and CCR to latest versions").alias("check").option("--lang, -l <lang>", "ZCF display language (zh-CN, en)").option("--all-lang, -g <lang>", "Set all language parameters to this value").action(await withLanguageResolution(async () => {
|
|
1219
1975
|
await checkUpdates();
|
|
1220
1976
|
}));
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
"help.commandDescriptions.updateWorkflowFiles": "Update workflow-related md files",
|
|
10
10
|
"help.commandDescriptions.configureCcrProxy": "Configure Claude Code Router for model proxy",
|
|
11
11
|
"help.commandDescriptions.claudeCodeUsageAnalysis": "Claude Code usage statistics analysis",
|
|
12
|
+
"help.commandDescriptions.uninstallConfigurations": "Remove Claude Code configurations and tools",
|
|
12
13
|
"help.commandDescriptions.checkUpdateVersions": "Check and update to latest versions",
|
|
13
14
|
"help.shortcutDescriptions.quickInit": "Quick init",
|
|
14
15
|
"help.shortcutDescriptions.quickUpdate": "Quick update",
|
|
@@ -35,11 +36,13 @@
|
|
|
35
36
|
"help.exampleDescriptions.updateWorkflowFilesOnly": "Update workflow-related md files only",
|
|
36
37
|
"help.exampleDescriptions.configureClaudeCodeRouter": "Configure Claude Code Router",
|
|
37
38
|
"help.exampleDescriptions.runClaudeCodeUsageAnalysis": "Run Claude Code usage analysis",
|
|
39
|
+
"help.exampleDescriptions.uninstallConfigurations": "Uninstall configurations and tools",
|
|
38
40
|
"help.exampleDescriptions.checkAndUpdateTools": "Check and update tools",
|
|
39
41
|
"help.exampleDescriptions.nonInteractiveModeCicd": "Non-interactive mode (CI/CD)",
|
|
40
42
|
"banner.subtitle": "One-click configuration tool for Claude Code",
|
|
41
43
|
"banner.updateSubtitle": "Update configuration for Claude Code",
|
|
42
44
|
"help.defaults.dailyUsage": "Daily usage (default)",
|
|
45
|
+
"help.defaults.interactiveUninstall": "Interactive uninstall menu",
|
|
43
46
|
"help.defaults.updateTools": "Update Claude Code, CCR and CCometixLine",
|
|
44
47
|
"help.defaults.prefix": "default:"
|
|
45
48
|
}
|
|
@@ -24,5 +24,9 @@
|
|
|
24
24
|
"onlyLocalInstallationDetected": "Only local installation detected",
|
|
25
25
|
"notInstalled": "not installed",
|
|
26
26
|
"installingGlobalClaudeCode": "Installing global Claude Code",
|
|
27
|
-
"globalInstallationCompleted": "Global installation completed"
|
|
27
|
+
"globalInstallationCompleted": "Global installation completed",
|
|
28
|
+
"wslDetected": "WSL environment detected ({distro})",
|
|
29
|
+
"wslDetectedGeneric": "WSL environment detected",
|
|
30
|
+
"wslPathInfo": "Configuration path: {path}",
|
|
31
|
+
"wslInstallSuccess": "Claude Code successfully installed in WSL environment"
|
|
28
32
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"menuDescriptions.ccusage": "Claude Code usage analysis",
|
|
4
4
|
"menuDescriptions.changeLanguage": "Change ZCF interface language",
|
|
5
5
|
"menuDescriptions.checkUpdates": "Check and update Claude Code, CCR and CCometixLine versions",
|
|
6
|
-
"menuDescriptions.
|
|
6
|
+
"menuDescriptions.uninstall": "Remove Claude Code configurations and tools from your system",
|
|
7
7
|
"menuDescriptions.cometixLine": "High-performance Claude Code statusline tool with Git integration and real-time usage tracking",
|
|
8
8
|
"menuDescriptions.configureAiMemory": "Configure AI output language and output styles",
|
|
9
9
|
"menuDescriptions.configureApiOrCcr": "Configure API URL, authentication or CCR proxy",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"menuOptions.ccusage": "ccusage",
|
|
17
17
|
"menuOptions.changeLanguage": "Select display language / 更改显示语言",
|
|
18
18
|
"menuOptions.checkUpdates": "Check updates",
|
|
19
|
-
"menuOptions.
|
|
19
|
+
"menuOptions.uninstall": "Uninstall & Remove Configurations",
|
|
20
20
|
"menuOptions.cometixLine": "CCometixLine",
|
|
21
21
|
"menuOptions.configureAiMemory": "Configure Claude global memory",
|
|
22
22
|
"menuOptions.configureApiOrCcr": "Configure API / CCR proxy",
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "ZCF Uninstaller",
|
|
3
|
+
"warning": "⚠️ This will permanently remove Claude Code configurations and tools from your system.",
|
|
4
|
+
"selectMainOption": "Select uninstall option:",
|
|
5
|
+
"completeUninstall": "Complete Uninstall",
|
|
6
|
+
"completeUninstallDesc": "Remove all Claude Code related configurations and tools",
|
|
7
|
+
"customUninstall": "Custom Uninstall",
|
|
8
|
+
"customUninstallDesc": "Select specific items to remove",
|
|
9
|
+
"selectCustomItems": "Select items to remove:",
|
|
10
|
+
"selectItemsToRemove": "Choose configurations and tools to remove:",
|
|
11
|
+
"selectAtLeastOne": "Please select at least one item to remove.",
|
|
12
|
+
"executingComplete": "🗑️ Executing Complete Uninstall",
|
|
13
|
+
"executingCustom": "🗑️ Executing Custom Uninstall",
|
|
14
|
+
"completeWarning": "⚠️ This will remove ALL Claude Code configurations, directories, and tools. This action cannot be undone!",
|
|
15
|
+
"confirmComplete": "Are you sure you want to completely uninstall Claude Code and all related tools?",
|
|
16
|
+
"confirmCustom": "Are you sure you want to remove the selected items?",
|
|
17
|
+
"processingComplete": "🔄 Processing complete uninstall...",
|
|
18
|
+
"processingCustom": "🔄 Processing custom uninstall...",
|
|
19
|
+
"selectedItems": "Selected items:",
|
|
20
|
+
"removed": "Moved to trash/recycle bin",
|
|
21
|
+
"movedToTrash": "Moved to trash/recycle bin",
|
|
22
|
+
"removedConfigs": "Configuration removed",
|
|
23
|
+
"errors": "Errors occurred",
|
|
24
|
+
"warnings": "Warnings",
|
|
25
|
+
"completeSuccess": "Complete uninstall completed successfully! All files moved to trash/recycle bin.",
|
|
26
|
+
"completePartialSuccess": "Complete uninstall completed with some warnings.",
|
|
27
|
+
"customSuccess": "Custom uninstall completed successfully! Processed {{count}} items.",
|
|
28
|
+
"customSuccessFiles": "Custom uninstall completed successfully! Moved {{count}} files/directories to trash/recycle bin.",
|
|
29
|
+
"customSuccessConfigs": "Custom uninstall completed successfully! Removed {{count}} configuration items.",
|
|
30
|
+
"customSuccessBoth": "Custom uninstall completed successfully! Moved {{fileCount}} files/directories to trash/recycle bin and removed {{configCount}} configuration items.",
|
|
31
|
+
"errorsCount": "{{count}} errors occurred during uninstall.",
|
|
32
|
+
"warningsCount": "{{count}} warnings occurred during uninstall.",
|
|
33
|
+
|
|
34
|
+
"outputStyles": "Output Styles - Remove output style configurations",
|
|
35
|
+
"commands": "Commands - Remove custom ZCF commands",
|
|
36
|
+
"agents": "Agents - Remove custom ZCF agents",
|
|
37
|
+
"claudeMd": "CLAUDE.md - Remove global memory file",
|
|
38
|
+
"permissionsEnvs": "Permissions & Envs - Remove permissions and environment variables",
|
|
39
|
+
"mcps": "MCPs - Remove MCP server configurations",
|
|
40
|
+
"ccr": "Claude Code Router - Uninstall CCR and remove configurations",
|
|
41
|
+
"ccline": "CCometixLine - Uninstall status line tool",
|
|
42
|
+
"claudeCode": "Claude Code - Uninstall Claude Code and configurations",
|
|
43
|
+
"backups": "Backups - Remove backup files",
|
|
44
|
+
"zcfConfig": "ZCF Config - Remove ZCF preference configurations",
|
|
45
|
+
|
|
46
|
+
"outputStyleNotFound": "Output style field not found in settings.json",
|
|
47
|
+
"settingsJsonNotFound": "settings.json not found",
|
|
48
|
+
"commandsNotFound": "Commands directory not found",
|
|
49
|
+
"agentsNotFound": "Agents directory not found",
|
|
50
|
+
"claudeMdNotFound": "CLAUDE.md file not found",
|
|
51
|
+
"noPermissionsOrEnvFound": "No permissions or environment variables found",
|
|
52
|
+
"mcpServersNotFound": "MCP servers configuration not found",
|
|
53
|
+
"claudeJsonNotFound": ".claude.json file not found",
|
|
54
|
+
"ccrPackageNotFound": "Claude Code Router package not found",
|
|
55
|
+
"cclinePackageNotFound": "CCometixLine package not found",
|
|
56
|
+
"claudeCodePackageNotFound": "Claude Code package not found",
|
|
57
|
+
"backupsNotFound": "Backup directory not found",
|
|
58
|
+
"zcfConfigNotFound": "ZCF configuration file not found",
|
|
59
|
+
"outputStylesDirectoryNotFound": "Output styles directory not found"
|
|
60
|
+
}
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
"help.commandDescriptions.updateWorkflowFiles": "仅更新工作流相关md",
|
|
10
10
|
"help.commandDescriptions.configureCcrProxy": "配置模型路由代理",
|
|
11
11
|
"help.commandDescriptions.claudeCodeUsageAnalysis": "Claude Code 用量统计分析",
|
|
12
|
+
"help.commandDescriptions.uninstallConfigurations": "删除 Claude Code 配置和工具",
|
|
12
13
|
"help.commandDescriptions.checkUpdateVersions": "检查并更新到最新版本",
|
|
13
14
|
"help.shortcutDescriptions.quickInit": "快速初始化",
|
|
14
15
|
"help.shortcutDescriptions.quickUpdate": "快速更新",
|
|
@@ -35,11 +36,13 @@
|
|
|
35
36
|
"help.exampleDescriptions.updateWorkflowFilesOnly": "仅更新工作流相关md文件",
|
|
36
37
|
"help.exampleDescriptions.configureClaudeCodeRouter": "配置 Claude Code Router",
|
|
37
38
|
"help.exampleDescriptions.runClaudeCodeUsageAnalysis": "运行 Claude Code 用量分析",
|
|
39
|
+
"help.exampleDescriptions.uninstallConfigurations": "卸载配置和工具",
|
|
38
40
|
"help.exampleDescriptions.checkAndUpdateTools": "检查并更新工具",
|
|
39
41
|
"help.exampleDescriptions.nonInteractiveModeCicd": "非交互模式(CI/CD)",
|
|
40
42
|
"banner.subtitle": "Claude Code 一键配置工具",
|
|
41
43
|
"banner.updateSubtitle": "更新 Claude Code 配置",
|
|
42
44
|
"help.defaults.dailyUsage": "每日用量(默认)",
|
|
45
|
+
"help.defaults.interactiveUninstall": "交互式卸载菜单",
|
|
43
46
|
"help.defaults.updateTools": "更新 Claude Code、CCR 和 CCometixLine",
|
|
44
47
|
"help.defaults.prefix": "默认:"
|
|
45
48
|
}
|
|
@@ -24,5 +24,9 @@
|
|
|
24
24
|
"onlyLocalInstallationDetected": "检测到仅有本地安装",
|
|
25
25
|
"notInstalled": "未安装",
|
|
26
26
|
"installingGlobalClaudeCode": "正在安装全局 Claude Code",
|
|
27
|
-
"globalInstallationCompleted": "全局安装完成"
|
|
27
|
+
"globalInstallationCompleted": "全局安装完成",
|
|
28
|
+
"wslDetected": "检测到 WSL 环境 ({distro})",
|
|
29
|
+
"wslDetectedGeneric": "检测到 WSL 环境",
|
|
30
|
+
"wslPathInfo": "配置文件位置:{path}",
|
|
31
|
+
"wslInstallSuccess": "Claude Code 已成功安装在 WSL 环境中"
|
|
28
32
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"menuDescriptions.ccusage": "Claude Code 用量分析",
|
|
4
4
|
"menuDescriptions.changeLanguage": "更改 ZCF 界面语言",
|
|
5
5
|
"menuDescriptions.checkUpdates": "检查并更新 Claude Code、CCR 和 CCometixLine 的版本",
|
|
6
|
-
"menuDescriptions.
|
|
6
|
+
"menuDescriptions.uninstall": "从系统中删除 Claude Code 配置和工具",
|
|
7
7
|
"menuDescriptions.cometixLine": "基于 Rust 的高性能 Claude Code 状态栏工具,集成 Git 信息和实时使用量跟踪",
|
|
8
8
|
"menuDescriptions.configureAiMemory": "配置 AI 输出语言和输出风格",
|
|
9
9
|
"menuDescriptions.configureApiOrCcr": "配置 API URL、认证信息或 CCR 代理",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"menuOptions.ccusage": "ccusage",
|
|
17
17
|
"menuOptions.changeLanguage": "更改显示语言 / Select display language",
|
|
18
18
|
"menuOptions.checkUpdates": "检查更新",
|
|
19
|
-
"menuOptions.
|
|
19
|
+
"menuOptions.uninstall": "卸载和删除配置",
|
|
20
20
|
"menuOptions.cometixLine": "CCometixLine",
|
|
21
21
|
"menuOptions.configureAiMemory": "配置 Claude 全局记忆",
|
|
22
22
|
"menuOptions.configureApiOrCcr": "配置 API 或 CCR 代理",
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "ZCF 卸载工具",
|
|
3
|
+
"warning": "⚠️ 这将永久删除您系统中的 Claude Code 配置和工具。",
|
|
4
|
+
"selectMainOption": "选择卸载选项:",
|
|
5
|
+
"completeUninstall": "完全卸载",
|
|
6
|
+
"completeUninstallDesc": "删除所有 Claude Code 相关配置和工具",
|
|
7
|
+
"customUninstall": "自定义卸载",
|
|
8
|
+
"customUninstallDesc": "选择特定项目进行删除",
|
|
9
|
+
"selectCustomItems": "选择要删除的项目:",
|
|
10
|
+
"selectItemsToRemove": "选择要删除的配置和工具:",
|
|
11
|
+
"selectAtLeastOne": "请至少选择一个要删除的项目。",
|
|
12
|
+
"executingComplete": "🗑️ 执行完全卸载",
|
|
13
|
+
"executingCustom": "🗑️ 执行自定义卸载",
|
|
14
|
+
"completeWarning": "⚠️ 这将删除所有 Claude Code 配置、目录和工具。此操作无法撤销!",
|
|
15
|
+
"confirmComplete": "您确定要完全卸载 Claude Code 和所有相关工具吗?",
|
|
16
|
+
"confirmCustom": "您确定要删除选定的项目吗?",
|
|
17
|
+
"processingComplete": "🔄 正在处理完全卸载...",
|
|
18
|
+
"processingCustom": "🔄 正在处理自定义卸载...",
|
|
19
|
+
"selectedItems": "选定项目:",
|
|
20
|
+
"removed": "已移至废纸篓/回收站",
|
|
21
|
+
"movedToTrash": "已移至废纸篓/回收站",
|
|
22
|
+
"removedConfigs": "已删除配置项",
|
|
23
|
+
"errors": "发生错误",
|
|
24
|
+
"warnings": "警告",
|
|
25
|
+
"completeSuccess": "完全卸载成功完成!所有文件已移至废纸篓/回收站。",
|
|
26
|
+
"completePartialSuccess": "完全卸载已完成,但有一些警告。",
|
|
27
|
+
"customSuccess": "自定义卸载成功完成!已处理 {{count}} 个项目。",
|
|
28
|
+
"customSuccessFiles": "自定义卸载成功完成!已将 {{count}} 个文件/目录移至废纸篓/回收站。",
|
|
29
|
+
"customSuccessConfigs": "自定义卸载成功完成!已删除 {{count}} 个配置项。",
|
|
30
|
+
"customSuccessBoth": "自定义卸载成功完成!已将 {{fileCount}} 个文件/目录移至废纸篓/回收站,已删除 {{configCount}} 个配置项。",
|
|
31
|
+
"errorsCount": "卸载过程中发生了 {{count}} 个错误。",
|
|
32
|
+
"warningsCount": "卸载过程中发生了 {{count}} 个警告。",
|
|
33
|
+
|
|
34
|
+
"outputStyles": "输出风格 - 删除输出风格配置",
|
|
35
|
+
"commands": "自定义指令 - 删除自定义 ZCF 指令",
|
|
36
|
+
"agents": "自定义代理 - 删除自定义 ZCF 代理",
|
|
37
|
+
"claudeMd": "CLAUDE.md - 删除全局记忆文件",
|
|
38
|
+
"permissionsEnvs": "权限和环境变量 - 删除权限配置和环境变量",
|
|
39
|
+
"mcps": "MCP 服务 - 删除 MCP 服务器配置",
|
|
40
|
+
"ccr": "Claude Code Router - 卸载 CCR 并删除配置",
|
|
41
|
+
"ccline": "CCometixLine - 卸载状态栏工具",
|
|
42
|
+
"claudeCode": "Claude Code - 卸载 Claude Code 和配置",
|
|
43
|
+
"backups": "备份文件 - 删除备份文件",
|
|
44
|
+
"zcfConfig": "ZCF 配置 - 删除 ZCF 偏好设置配置",
|
|
45
|
+
|
|
46
|
+
"outputStyleNotFound": "在 settings.json 中未找到输出风格字段",
|
|
47
|
+
"settingsJsonNotFound": "未找到 settings.json 文件",
|
|
48
|
+
"commandsNotFound": "未找到指令目录",
|
|
49
|
+
"agentsNotFound": "未找到代理目录",
|
|
50
|
+
"claudeMdNotFound": "未找到 CLAUDE.md 文件",
|
|
51
|
+
"noPermissionsOrEnvFound": "未找到权限或环境变量配置",
|
|
52
|
+
"mcpServersNotFound": "未找到 MCP 服务器配置",
|
|
53
|
+
"claudeJsonNotFound": "未找到 .claude.json 文件",
|
|
54
|
+
"ccrPackageNotFound": "未找到 Claude Code Router 包",
|
|
55
|
+
"cclinePackageNotFound": "未找到 CCometixLine 包",
|
|
56
|
+
"claudeCodePackageNotFound": "未找到 Claude Code 包",
|
|
57
|
+
"backupsNotFound": "未找到备份目录",
|
|
58
|
+
"zcfConfigNotFound": "未找到 ZCF 配置文件",
|
|
59
|
+
"outputStylesDirectoryNotFound": "未找到输出风格目录"
|
|
60
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zcf",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "2.12.
|
|
4
|
+
"version": "2.12.13",
|
|
5
5
|
"description": "Zero-Config Claude-Code Flow - One-click configuration tool for Claude Code",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Miao Da",
|
|
@@ -40,30 +40,33 @@
|
|
|
40
40
|
"templates"
|
|
41
41
|
],
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@types/semver": "^7.7.
|
|
43
|
+
"@types/semver": "^7.7.1",
|
|
44
44
|
"ansis": "^4.1.0",
|
|
45
45
|
"cac": "^6.7.14",
|
|
46
46
|
"dayjs": "^1.11.18",
|
|
47
47
|
"find-up-simple": "^1.0.1",
|
|
48
|
-
"
|
|
48
|
+
"fs-extra": "^11.3.1",
|
|
49
|
+
"i18next": "^25.5.2",
|
|
49
50
|
"i18next-fs-backend": "^2.6.0",
|
|
50
51
|
"inquirer": "^12.9.4",
|
|
51
52
|
"ora": "^8.2.0",
|
|
52
53
|
"pathe": "^2.0.3",
|
|
53
54
|
"semver": "^7.7.2",
|
|
54
|
-
"tinyexec": "^1.0.1"
|
|
55
|
+
"tinyexec": "^1.0.1",
|
|
56
|
+
"trash": "^10.0.0"
|
|
55
57
|
},
|
|
56
58
|
"devDependencies": {
|
|
57
|
-
"@antfu/eslint-config": "^5.
|
|
58
|
-
"@changesets/cli": "^2.29.
|
|
59
|
+
"@antfu/eslint-config": "^5.3.0",
|
|
60
|
+
"@changesets/cli": "^2.29.7",
|
|
59
61
|
"@commitlint/cli": "^19.8.1",
|
|
60
62
|
"@commitlint/config-conventional": "^19.8.1",
|
|
61
63
|
"@commitlint/types": "^19.8.1",
|
|
64
|
+
"@types/fs-extra": "^11.0.4",
|
|
62
65
|
"@types/inquirer": "^9.0.9",
|
|
63
|
-
"@types/node": "^22.18.
|
|
66
|
+
"@types/node": "^22.18.3",
|
|
64
67
|
"@vitest/coverage-v8": "^3.2.4",
|
|
65
68
|
"@vitest/ui": "^3.2.4",
|
|
66
|
-
"eslint": "^9.
|
|
69
|
+
"eslint": "^9.35.0",
|
|
67
70
|
"eslint-plugin-format": "^1.0.1",
|
|
68
71
|
"glob": "^11.0.3",
|
|
69
72
|
"husky": "^9.1.7",
|