ccjk 2.0.20 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/README.md +601 -35
  2. package/README.zh-CN.md +651 -0
  3. package/dist/chunks/api.mjs +100 -0
  4. package/dist/chunks/auto-updater.mjs +252 -0
  5. package/dist/chunks/ccjk-config.mjs +261 -0
  6. package/dist/chunks/ccr.mjs +77 -0
  7. package/dist/chunks/ccu.mjs +36 -0
  8. package/dist/chunks/check-updates.mjs +93 -0
  9. package/dist/chunks/claude-code-config-manager.mjs +28 -21
  10. package/dist/chunks/claude-code-incremental-manager.mjs +26 -18
  11. package/dist/chunks/claude-config.mjs +228 -0
  12. package/dist/chunks/codex.mjs +2134 -0
  13. package/dist/chunks/commands.mjs +2 -15
  14. package/dist/chunks/commit.mjs +119 -0
  15. package/dist/chunks/config-consolidator.mjs +281 -0
  16. package/dist/chunks/config-switch.mjs +302 -0
  17. package/dist/chunks/constants.mjs +156 -0
  18. package/dist/chunks/doctor.mjs +708 -0
  19. package/dist/chunks/features.mjs +35 -640
  20. package/dist/chunks/features2.mjs +661 -0
  21. package/dist/chunks/fs-operations.mjs +180 -0
  22. package/dist/chunks/index.mjs +3082 -0
  23. package/dist/chunks/index2.mjs +145 -0
  24. package/dist/chunks/init.mjs +2468 -0
  25. package/dist/chunks/interview.mjs +2916 -0
  26. package/dist/chunks/json-config.mjs +59 -0
  27. package/dist/chunks/marketplace.mjs +258 -0
  28. package/dist/chunks/mcp-doctor.mjs +160 -0
  29. package/dist/chunks/mcp-market.mjs +475 -0
  30. package/dist/chunks/mcp-performance.mjs +110 -0
  31. package/dist/chunks/mcp-profile.mjs +220 -0
  32. package/dist/chunks/mcp-release.mjs +138 -0
  33. package/dist/chunks/menu.mjs +3599 -0
  34. package/dist/chunks/notification.mjs +2336 -0
  35. package/dist/chunks/onboarding.mjs +711 -0
  36. package/dist/chunks/package.mjs +4 -0
  37. package/dist/chunks/permission-manager.mjs +210 -0
  38. package/dist/chunks/platform.mjs +321 -0
  39. package/dist/chunks/prompts.mjs +228 -0
  40. package/dist/chunks/session.mjs +355 -0
  41. package/dist/chunks/shencha.mjs +320 -0
  42. package/dist/chunks/skills-sync.mjs +4 -13
  43. package/dist/chunks/team.mjs +51 -0
  44. package/dist/chunks/tools.mjs +169 -0
  45. package/dist/chunks/uninstall.mjs +784 -0
  46. package/dist/chunks/update.mjs +104 -0
  47. package/dist/chunks/upgrade-manager.mjs +197 -0
  48. package/dist/chunks/workflows.mjs +100 -0
  49. package/dist/cli.mjs +581 -15348
  50. package/dist/i18n/locales/zh-CN/cli.json +1 -1
  51. package/dist/i18n/locales/zh-CN/common.json +1 -1
  52. package/dist/index.mjs +43 -2062
  53. package/dist/shared/ccjk.-FoZ3zat.mjs +761 -0
  54. package/dist/shared/ccjk.B7169qud.mjs +25 -0
  55. package/dist/shared/ccjk.BhKlRJ0h.mjs +114 -0
  56. package/dist/shared/ccjk.Bi-m3LKY.mjs +357 -0
  57. package/dist/shared/ccjk.COdsoe-Y.mjs +64 -0
  58. package/dist/shared/ccjk.CUdzQluX.mjs +46 -0
  59. package/dist/shared/ccjk.Cy-RH2qV.mjs +506 -0
  60. package/dist/shared/ccjk.DGjQxTq_.mjs +34 -0
  61. package/dist/shared/ccjk.DJM5aVQJ.mjs +586 -0
  62. package/dist/shared/ccjk.DhBeLRzf.mjs +28 -0
  63. package/dist/shared/ccjk.DwDtZ5cK.mjs +266 -0
  64. package/dist/shared/ccjk.n_AtlHzB.mjs +186 -0
  65. package/dist/shared/ccjk.qYAnUMuy.mjs +749 -0
  66. package/package.json +29 -25
  67. package/dist/chunks/codex-config-switch.mjs +0 -429
  68. package/dist/chunks/codex-provider-manager.mjs +0 -234
  69. package/dist/chunks/codex-uninstaller.mjs +0 -406
  70. package/dist/chunks/plugin-recommendation.mjs +0 -575
  71. package/dist/chunks/simple-config.mjs +0 -10950
@@ -0,0 +1,784 @@
1
+ import ansis from 'ansis';
2
+ import inquirer from 'inquirer';
3
+ import { ZCF_CONFIG_FILE, DEFAULT_CODE_TOOL_TYPE, isCodeToolType } from './constants.mjs';
4
+ import { i18n, ensureI18nInitialized } from './index2.mjs';
5
+ import { readZcfConfig } from './ccjk-config.mjs';
6
+ import { r as resolveCodeType } from '../shared/ccjk.CUdzQluX.mjs';
7
+ import { h as handleExitPromptError, a as handleGeneralError } from '../shared/ccjk.B7169qud.mjs';
8
+ import { p as promptBoolean, a as addNumbersToChoices } from '../shared/ccjk.DhBeLRzf.mjs';
9
+ import { homedir } from 'node:os';
10
+ import { pathExists } from 'fs-extra';
11
+ import { join } from 'pathe';
12
+ import { exec } from 'tinyexec';
13
+ import { readJsonConfig, writeJsonConfig } from './json-config.mjs';
14
+ import { m as moveToTrash } from '../shared/ccjk.DGjQxTq_.mjs';
15
+ import 'node:fs';
16
+ import 'node:process';
17
+ import 'node:url';
18
+ import 'i18next';
19
+ import 'i18next-fs-backend';
20
+ import 'smol-toml';
21
+ import './fs-operations.mjs';
22
+ import 'node:crypto';
23
+ import 'node:fs/promises';
24
+ import 'dayjs';
25
+ import 'inquirer-toggle';
26
+ import 'trash';
27
+
28
+ class ZcfUninstaller {
29
+ _lang;
30
+ // Reserved for future i18n support
31
+ conflictResolution = /* @__PURE__ */ new Map();
32
+ constructor(lang = "en") {
33
+ this._lang = lang;
34
+ this.conflictResolution.set("claude-code", ["mcps"]);
35
+ void this._lang;
36
+ }
37
+ /**
38
+ * 1. Remove outputStyle field from settings.json and output-styles directory
39
+ */
40
+ async removeOutputStyles() {
41
+ const result = {
42
+ success: false,
43
+ removed: [],
44
+ removedConfigs: [],
45
+ errors: [],
46
+ warnings: []
47
+ };
48
+ try {
49
+ const settingsPath = join(homedir(), ".claude", "settings.json");
50
+ const outputStylesPath = join(homedir(), ".claude", "output-styles");
51
+ if (await pathExists(settingsPath)) {
52
+ const settings = readJsonConfig(settingsPath) || {};
53
+ if (settings.outputStyle) {
54
+ delete settings.outputStyle;
55
+ writeJsonConfig(settingsPath, settings);
56
+ result.removedConfigs.push("outputStyle field from settings.json");
57
+ }
58
+ } else {
59
+ result.warnings.push(i18n.t("uninstall:settingsJsonNotFound"));
60
+ }
61
+ if (await pathExists(outputStylesPath)) {
62
+ const trashResult = await moveToTrash(outputStylesPath);
63
+ if (!trashResult[0]?.success) {
64
+ result.warnings.push(trashResult[0]?.error || "Failed to move to trash");
65
+ }
66
+ result.removed.push("~/.claude/output-styles/");
67
+ } else {
68
+ result.warnings.push(i18n.t("uninstall:outputStylesDirectoryNotFound"));
69
+ }
70
+ result.success = true;
71
+ } catch (error) {
72
+ result.errors.push(`Failed to remove output styles: ${error.message}`);
73
+ }
74
+ return result;
75
+ }
76
+ /**
77
+ * 2. Remove custom commands directory (commands/ccjk/)
78
+ */
79
+ async removeCustomCommands() {
80
+ const result = {
81
+ success: false,
82
+ removed: [],
83
+ removedConfigs: [],
84
+ errors: [],
85
+ warnings: []
86
+ };
87
+ try {
88
+ const commandsPath = join(homedir(), ".claude", "commands", "ccjk");
89
+ if (await pathExists(commandsPath)) {
90
+ const trashResult = await moveToTrash(commandsPath);
91
+ if (!trashResult[0]?.success) {
92
+ result.warnings.push(trashResult[0]?.error || "Failed to move to trash");
93
+ }
94
+ result.removed.push("commands/ccjk/");
95
+ result.success = true;
96
+ } else {
97
+ result.warnings.push(i18n.t("uninstall:commandsNotFound"));
98
+ result.success = true;
99
+ }
100
+ } catch (error) {
101
+ result.errors.push(`Failed to remove custom commands: ${error.message}`);
102
+ }
103
+ return result;
104
+ }
105
+ /**
106
+ * 3. Remove custom agents directory (agents/ccjk/)
107
+ */
108
+ async removeCustomAgents() {
109
+ const result = {
110
+ success: false,
111
+ removed: [],
112
+ removedConfigs: [],
113
+ errors: [],
114
+ warnings: []
115
+ };
116
+ try {
117
+ const agentsPath = join(homedir(), ".claude", "agents", "ccjk");
118
+ if (await pathExists(agentsPath)) {
119
+ const trashResult = await moveToTrash(agentsPath);
120
+ if (!trashResult[0]?.success) {
121
+ result.warnings.push(trashResult[0]?.error || "Failed to move to trash");
122
+ }
123
+ result.removed.push("agents/ccjk/");
124
+ result.success = true;
125
+ } else {
126
+ result.warnings.push(i18n.t("uninstall:agentsNotFound"));
127
+ result.success = true;
128
+ }
129
+ } catch (error) {
130
+ result.errors.push(`Failed to remove custom agents: ${error.message}`);
131
+ }
132
+ return result;
133
+ }
134
+ /**
135
+ * 4. Remove global memory file (CLAUDE.md)
136
+ */
137
+ async removeClaudeMd() {
138
+ const result = {
139
+ success: false,
140
+ removed: [],
141
+ removedConfigs: [],
142
+ errors: [],
143
+ warnings: []
144
+ };
145
+ try {
146
+ const claudeMdPath = join(homedir(), ".claude", "CLAUDE.md");
147
+ if (await pathExists(claudeMdPath)) {
148
+ const trashResult = await moveToTrash(claudeMdPath);
149
+ if (!trashResult[0]?.success) {
150
+ result.warnings.push(trashResult[0]?.error || "Failed to move to trash");
151
+ }
152
+ result.removed.push("CLAUDE.md");
153
+ result.success = true;
154
+ } else {
155
+ result.warnings.push(i18n.t("uninstall:claudeMdNotFound"));
156
+ result.success = true;
157
+ }
158
+ } catch (error) {
159
+ result.errors.push(`Failed to remove CLAUDE.md: ${error.message}`);
160
+ }
161
+ return result;
162
+ }
163
+ /**
164
+ * 5. Remove permissions and environment variables
165
+ */
166
+ async removePermissionsAndEnvs() {
167
+ const result = {
168
+ success: false,
169
+ removed: [],
170
+ removedConfigs: [],
171
+ errors: [],
172
+ warnings: []
173
+ };
174
+ try {
175
+ const settingsPath = join(homedir(), ".claude", "settings.json");
176
+ if (await pathExists(settingsPath)) {
177
+ const settings = readJsonConfig(settingsPath) || {};
178
+ let modified = false;
179
+ if (settings.permissions) {
180
+ delete settings.permissions;
181
+ result.removedConfigs.push("permissions configuration");
182
+ modified = true;
183
+ }
184
+ if (settings.env) {
185
+ delete settings.env;
186
+ result.removedConfigs.push("environment variables");
187
+ modified = true;
188
+ }
189
+ if (modified) {
190
+ writeJsonConfig(settingsPath, settings);
191
+ }
192
+ result.success = true;
193
+ } else {
194
+ result.warnings.push(i18n.t("uninstall:settingsJsonNotFound"));
195
+ result.success = true;
196
+ }
197
+ } catch (error) {
198
+ result.errors.push(`Failed to remove permissions and envs: ${error.message}`);
199
+ }
200
+ return result;
201
+ }
202
+ /**
203
+ * 6. Remove MCP servers from .claude.json (mcpServers field only)
204
+ */
205
+ async removeMcps() {
206
+ const result = {
207
+ success: false,
208
+ removed: [],
209
+ removedConfigs: [],
210
+ errors: [],
211
+ warnings: []
212
+ };
213
+ try {
214
+ const claudeJsonPath = join(homedir(), ".claude.json");
215
+ if (await pathExists(claudeJsonPath)) {
216
+ const config = readJsonConfig(claudeJsonPath) || {};
217
+ if (config.mcpServers) {
218
+ delete config.mcpServers;
219
+ writeJsonConfig(claudeJsonPath, config);
220
+ result.removedConfigs.push("mcpServers from .claude.json");
221
+ }
222
+ result.success = true;
223
+ } else {
224
+ result.warnings.push(i18n.t("uninstall:claudeJsonNotFound"));
225
+ result.success = true;
226
+ }
227
+ } catch (error) {
228
+ result.errors.push(`Failed to remove MCP servers: ${error.message}`);
229
+ }
230
+ return result;
231
+ }
232
+ /**
233
+ * 7. Uninstall Claude Code Router and remove configuration
234
+ */
235
+ async uninstallCcr() {
236
+ const result = {
237
+ success: false,
238
+ removed: [],
239
+ removedConfigs: [],
240
+ errors: [],
241
+ warnings: []
242
+ };
243
+ try {
244
+ const ccrPath = join(homedir(), ".claude-code-router");
245
+ if (await pathExists(ccrPath)) {
246
+ const trashResult = await moveToTrash(ccrPath);
247
+ if (!trashResult[0]?.success) {
248
+ result.warnings.push(trashResult[0]?.error || "Failed to move to trash");
249
+ }
250
+ result.removed.push(".claude-code-router/");
251
+ }
252
+ try {
253
+ await exec("npm", ["uninstall", "-g", "@musistudio/claude-code-router"]);
254
+ result.removed.push("@musistudio/claude-code-router package");
255
+ result.success = true;
256
+ } catch (npmError) {
257
+ if (npmError.message.includes("not found") || npmError.message.includes("not installed")) {
258
+ result.warnings.push(i18n.t("uninstall:ccrPackageNotFound"));
259
+ result.success = true;
260
+ } else {
261
+ result.errors.push(`Failed to uninstall CCR package: ${npmError.message}`);
262
+ }
263
+ }
264
+ } catch (error) {
265
+ result.errors.push(`Failed to uninstall CCR: ${error.message}`);
266
+ }
267
+ return result;
268
+ }
269
+ /**
270
+ * 8. Uninstall CCometixLine
271
+ */
272
+ async uninstallCcline() {
273
+ const result = {
274
+ success: false,
275
+ removed: [],
276
+ removedConfigs: [],
277
+ errors: [],
278
+ warnings: []
279
+ };
280
+ try {
281
+ await exec("npm", ["uninstall", "-g", "@cometix/ccline"]);
282
+ result.removed.push("@cometix/ccline package");
283
+ result.success = true;
284
+ } catch (error) {
285
+ if (error.message.includes("not found") || error.message.includes("not installed")) {
286
+ result.warnings.push(i18n.t("uninstall:cclinePackageNotFound"));
287
+ result.success = true;
288
+ } else {
289
+ result.errors.push(`Failed to uninstall CCometixLine: ${error.message}`);
290
+ }
291
+ }
292
+ return result;
293
+ }
294
+ /**
295
+ * 9. Uninstall Claude Code and remove entire .claude.json
296
+ */
297
+ async uninstallClaudeCode() {
298
+ const result = {
299
+ success: false,
300
+ removed: [],
301
+ removedConfigs: [],
302
+ errors: [],
303
+ warnings: []
304
+ };
305
+ try {
306
+ const claudeJsonPath = join(homedir(), ".claude.json");
307
+ if (await pathExists(claudeJsonPath)) {
308
+ const trashResult = await moveToTrash(claudeJsonPath);
309
+ if (!trashResult[0]?.success) {
310
+ result.warnings.push(trashResult[0]?.error || "Failed to move to trash");
311
+ }
312
+ result.removed.push(".claude.json (includes MCP configuration)");
313
+ }
314
+ try {
315
+ const { uninstallCodeTool } = await import('./init.mjs').then(function (n) { return n.G; });
316
+ const success = await uninstallCodeTool("claude-code");
317
+ if (success) {
318
+ result.removed.push("@anthropic-ai/claude-code");
319
+ result.success = true;
320
+ } else {
321
+ result.errors.push(i18n.t("uninstall:uninstallFailed", { codeType: i18n.t("common:claudeCode"), message: "" }));
322
+ }
323
+ } catch (npmError) {
324
+ if (npmError.message.includes("not found") || npmError.message.includes("not installed")) {
325
+ result.warnings.push(i18n.t("uninstall:claudeCodePackageNotFound"));
326
+ result.success = true;
327
+ } else {
328
+ result.errors.push(i18n.t("uninstall:uninstallFailed", { codeType: i18n.t("common:claudeCode"), message: `: ${npmError.message}` }));
329
+ }
330
+ }
331
+ } catch (error) {
332
+ result.errors.push(i18n.t("uninstall:uninstallFailed", { codeType: i18n.t("common:claudeCode"), message: `: ${error.message}` }));
333
+ }
334
+ return result;
335
+ }
336
+ /**
337
+ * 10. Remove backup files
338
+ */
339
+ async removeBackups() {
340
+ const result = {
341
+ success: false,
342
+ removed: [],
343
+ removedConfigs: [],
344
+ errors: [],
345
+ warnings: []
346
+ };
347
+ try {
348
+ const backupPath = join(homedir(), ".claude", "backup");
349
+ if (await pathExists(backupPath)) {
350
+ const trashResult = await moveToTrash(backupPath);
351
+ if (!trashResult[0]?.success) {
352
+ result.warnings.push(trashResult[0]?.error || "Failed to move to trash");
353
+ }
354
+ result.removed.push("backup/");
355
+ result.success = true;
356
+ } else {
357
+ result.warnings.push(i18n.t("uninstall:backupsNotFound"));
358
+ result.success = true;
359
+ }
360
+ } catch (error) {
361
+ result.errors.push(`Failed to remove backups: ${error.message}`);
362
+ }
363
+ return result;
364
+ }
365
+ /**
366
+ * 11. Remove CCJK preference configuration
367
+ */
368
+ async removeZcfConfig() {
369
+ const result = {
370
+ success: false,
371
+ removed: [],
372
+ removedConfigs: [],
373
+ errors: [],
374
+ warnings: []
375
+ };
376
+ try {
377
+ const zcfConfigPath = ZCF_CONFIG_FILE;
378
+ const relativeName = zcfConfigPath.replace(homedir(), "~");
379
+ if (await pathExists(zcfConfigPath)) {
380
+ const trashResult = await moveToTrash(zcfConfigPath);
381
+ if (!trashResult[0]?.success) {
382
+ result.warnings.push(trashResult[0]?.error || "Failed to move to trash");
383
+ }
384
+ result.removed.push(relativeName);
385
+ result.success = true;
386
+ } else {
387
+ result.warnings.push(i18n.t("uninstall:ccjkConfigNotFound"));
388
+ result.success = true;
389
+ }
390
+ } catch (error) {
391
+ result.errors.push(`Failed to remove CCJK config: ${error.message}`);
392
+ }
393
+ return result;
394
+ }
395
+ /**
396
+ * Complete uninstall - remove all directories and packages
397
+ */
398
+ async completeUninstall() {
399
+ const result = {
400
+ success: true,
401
+ removed: [],
402
+ removedConfigs: [],
403
+ errors: [],
404
+ warnings: []
405
+ };
406
+ try {
407
+ const directoriesToRemove = [
408
+ { path: join(homedir(), ".claude"), name: "~/.claude/" },
409
+ { path: join(homedir(), ".claude.json"), name: "~/.claude.json" },
410
+ { path: join(homedir(), ".claude-code-router"), name: "~/.claude-code-router/" }
411
+ ];
412
+ for (const dir of directoriesToRemove) {
413
+ try {
414
+ if (await pathExists(dir.path)) {
415
+ const trashResult = await moveToTrash(dir.path);
416
+ if (!trashResult[0]?.success) {
417
+ result.warnings.push(`Failed to move ${dir.name} to trash: ${trashResult[0]?.error || "Unknown error"}`);
418
+ }
419
+ result.removed.push(dir.name);
420
+ }
421
+ } catch (error) {
422
+ result.warnings.push(`Failed to remove ${dir.name}: ${error.message}`);
423
+ }
424
+ }
425
+ const packagesToUninstall = [
426
+ "@musistudio/claude-code-router",
427
+ "@cometix/ccline",
428
+ "@anthropic-ai/claude-code"
429
+ ];
430
+ for (const pkg of packagesToUninstall) {
431
+ try {
432
+ await exec("npm", ["uninstall", "-g", pkg]);
433
+ result.removed.push(`${pkg} package`);
434
+ } catch (error) {
435
+ if (error.message.includes("not found") || error.message.includes("not installed")) {
436
+ if (pkg.includes("claude-code-router")) {
437
+ result.warnings.push(i18n.t("uninstall:ccrPackageNotFound"));
438
+ } else if (pkg.includes("ccline")) {
439
+ result.warnings.push(i18n.t("uninstall:cclinePackageNotFound"));
440
+ } else {
441
+ result.warnings.push(i18n.t("uninstall:claudeCodePackageNotFound"));
442
+ }
443
+ } else {
444
+ result.warnings.push(`Failed to uninstall ${pkg}: ${error.message}`);
445
+ }
446
+ }
447
+ }
448
+ } catch (error) {
449
+ result.errors.push(`Complete uninstall failed: ${error.message}`);
450
+ result.success = false;
451
+ }
452
+ return result;
453
+ }
454
+ /**
455
+ * Custom uninstall with conflict resolution
456
+ */
457
+ async customUninstall(selectedItems) {
458
+ const resolvedItems = this.resolveConflicts(selectedItems);
459
+ const results = [];
460
+ for (const item of resolvedItems) {
461
+ try {
462
+ const result = await this.executeUninstallItem(item);
463
+ results.push(result);
464
+ } catch (error) {
465
+ results.push({
466
+ success: false,
467
+ removed: [],
468
+ removedConfigs: [],
469
+ errors: [`Failed to execute ${item}: ${error.message}`],
470
+ warnings: []
471
+ });
472
+ }
473
+ }
474
+ return results;
475
+ }
476
+ /**
477
+ * Resolve conflicts between uninstall items
478
+ */
479
+ resolveConflicts(items) {
480
+ const resolved = [...items];
481
+ for (const [primary, conflicts] of this.conflictResolution) {
482
+ if (resolved.includes(primary)) {
483
+ conflicts.forEach((conflict) => {
484
+ const index = resolved.indexOf(conflict);
485
+ if (index > -1) {
486
+ resolved.splice(index, 1);
487
+ }
488
+ });
489
+ }
490
+ }
491
+ return resolved;
492
+ }
493
+ /**
494
+ * Execute uninstall for a specific item
495
+ */
496
+ async executeUninstallItem(item) {
497
+ switch (item) {
498
+ case "output-styles":
499
+ return await this.removeOutputStyles();
500
+ case "commands":
501
+ return await this.removeCustomCommands();
502
+ case "agents":
503
+ return await this.removeCustomAgents();
504
+ case "claude-md":
505
+ return await this.removeClaudeMd();
506
+ case "permissions-envs":
507
+ return await this.removePermissionsAndEnvs();
508
+ case "mcps":
509
+ return await this.removeMcps();
510
+ case "ccr":
511
+ return await this.uninstallCcr();
512
+ case "ccline":
513
+ return await this.uninstallCcline();
514
+ case "claude-code":
515
+ return await this.uninstallClaudeCode();
516
+ case "backups":
517
+ return await this.removeBackups();
518
+ case "ccjk-config":
519
+ return await this.removeZcfConfig();
520
+ default:
521
+ return {
522
+ success: false,
523
+ removed: [],
524
+ removedConfigs: [],
525
+ errors: [`Unknown uninstall item: ${item}`],
526
+ warnings: []
527
+ };
528
+ }
529
+ }
530
+ }
531
+
532
+ async function uninstall(options = {}) {
533
+ try {
534
+ ensureI18nInitialized();
535
+ let codeType;
536
+ if (options.codeType) {
537
+ try {
538
+ codeType = await resolveCodeType(options.codeType);
539
+ } catch (error) {
540
+ const errorMessage = error instanceof Error ? error.message : String(error);
541
+ console.error(ansis.red(`${i18n.t("errors:generalError")} ${errorMessage}`));
542
+ const config = readZcfConfig();
543
+ codeType = config?.codeToolType && isCodeToolType(config.codeToolType) ? config.codeToolType : DEFAULT_CODE_TOOL_TYPE;
544
+ }
545
+ } else {
546
+ const config = readZcfConfig();
547
+ codeType = config?.codeToolType && isCodeToolType(config.codeToolType) ? config.codeToolType : DEFAULT_CODE_TOOL_TYPE;
548
+ }
549
+ const uninstaller = new ZcfUninstaller(options.lang || "en");
550
+ if (codeType === "codex") {
551
+ const { runCodexUninstall } = await import('./codex.mjs').then(function (n) { return n.a2; });
552
+ await runCodexUninstall();
553
+ return;
554
+ }
555
+ if (options.mode && options.mode !== "interactive") {
556
+ if (options.mode === "complete") {
557
+ await executeCompleteUninstall(uninstaller);
558
+ return;
559
+ } else if (options.mode === "custom" && options.items) {
560
+ let items;
561
+ if (typeof options.items === "string") {
562
+ items = options.items.split(",").map((item) => item.trim());
563
+ } else {
564
+ items = options.items;
565
+ }
566
+ await executeCustomUninstall(uninstaller, items);
567
+ return;
568
+ }
569
+ }
570
+ await showInteractiveUninstall(uninstaller);
571
+ } catch (error) {
572
+ if (!handleExitPromptError(error)) {
573
+ handleGeneralError(error);
574
+ }
575
+ }
576
+ }
577
+ async function showInteractiveUninstall(uninstaller) {
578
+ console.log(ansis.cyan.bold(i18n.t("uninstall:title")));
579
+ console.log("");
580
+ const { mainChoice } = await inquirer.prompt({
581
+ type: "list",
582
+ name: "mainChoice",
583
+ message: i18n.t("uninstall:selectMainOption"),
584
+ choices: addNumbersToChoices([
585
+ {
586
+ name: `${i18n.t("uninstall:completeUninstall")} - ${ansis.gray(i18n.t("uninstall:completeUninstallDesc"))}`,
587
+ value: "complete",
588
+ short: i18n.t("uninstall:completeUninstall")
589
+ },
590
+ {
591
+ name: `${i18n.t("uninstall:customUninstall")} - ${ansis.gray(i18n.t("uninstall:customUninstallDesc"))}`,
592
+ value: "custom",
593
+ short: i18n.t("uninstall:customUninstall")
594
+ }
595
+ ])
596
+ });
597
+ if (!mainChoice) {
598
+ console.log(ansis.yellow(i18n.t("common:cancelled")));
599
+ return;
600
+ }
601
+ if (mainChoice === "complete") {
602
+ await executeCompleteUninstall(uninstaller);
603
+ } else {
604
+ await showCustomUninstallMenu(uninstaller);
605
+ }
606
+ }
607
+ async function showCustomUninstallMenu(uninstaller) {
608
+ console.log("");
609
+ console.log(ansis.cyan(i18n.t("uninstall:selectCustomItems")));
610
+ const { customItems } = await inquirer.prompt({
611
+ type: "checkbox",
612
+ name: "customItems",
613
+ message: `${i18n.t("uninstall:selectItemsToRemove")} ${i18n.t("common:multiSelectHint")}`,
614
+ choices: [
615
+ {
616
+ name: i18n.t("uninstall:outputStyles"),
617
+ value: "output-styles"
618
+ },
619
+ {
620
+ name: i18n.t("uninstall:commands"),
621
+ value: "commands"
622
+ },
623
+ {
624
+ name: i18n.t("uninstall:agents"),
625
+ value: "agents"
626
+ },
627
+ {
628
+ name: i18n.t("uninstall:claudeMd"),
629
+ value: "claude-md"
630
+ },
631
+ {
632
+ name: i18n.t("uninstall:permissionsEnvs"),
633
+ value: "permissions-envs"
634
+ },
635
+ {
636
+ name: i18n.t("uninstall:mcps"),
637
+ value: "mcps"
638
+ },
639
+ {
640
+ name: i18n.t("uninstall:ccr"),
641
+ value: "ccr"
642
+ },
643
+ {
644
+ name: i18n.t("uninstall:ccline"),
645
+ value: "ccline"
646
+ },
647
+ {
648
+ name: i18n.t("uninstall:claudeCode"),
649
+ value: "claude-code"
650
+ },
651
+ {
652
+ name: i18n.t("uninstall:backups"),
653
+ value: "backups"
654
+ },
655
+ {
656
+ name: i18n.t("uninstall:ccjkConfig"),
657
+ value: "ccjk-config"
658
+ }
659
+ ],
660
+ validate: (answers) => {
661
+ if (answers.length === 0) {
662
+ return i18n.t("uninstall:selectAtLeastOne");
663
+ }
664
+ return true;
665
+ }
666
+ });
667
+ if (!customItems || customItems.length === 0) {
668
+ console.log(ansis.yellow(i18n.t("common:cancelled")));
669
+ return;
670
+ }
671
+ await executeCustomUninstall(uninstaller, customItems);
672
+ }
673
+ async function executeCompleteUninstall(uninstaller) {
674
+ console.log("");
675
+ console.log(ansis.red.bold(i18n.t("uninstall:executingComplete")));
676
+ console.log(ansis.yellow(i18n.t("uninstall:completeWarning")));
677
+ const confirm = await promptBoolean({
678
+ message: i18n.t("uninstall:confirmComplete"),
679
+ defaultValue: false
680
+ });
681
+ if (!confirm) {
682
+ console.log(ansis.yellow(i18n.t("common:cancelled")));
683
+ return;
684
+ }
685
+ console.log("");
686
+ console.log(ansis.cyan(i18n.t("uninstall:processingComplete")));
687
+ const result = await uninstaller.completeUninstall();
688
+ displayUninstallResult("complete", [result]);
689
+ }
690
+ async function executeCustomUninstall(uninstaller, items) {
691
+ console.log("");
692
+ console.log(ansis.cyan(i18n.t("uninstall:executingCustom")));
693
+ console.log(ansis.gray(i18n.t("uninstall:selectedItems")));
694
+ items.forEach((item) => {
695
+ console.log(` \u2022 ${i18n.t(`uninstall:${item}`)}`);
696
+ });
697
+ const confirm = await promptBoolean({
698
+ message: i18n.t("uninstall:confirmCustom"),
699
+ defaultValue: false
700
+ });
701
+ if (!confirm) {
702
+ console.log(ansis.yellow(i18n.t("common:cancelled")));
703
+ return;
704
+ }
705
+ console.log("");
706
+ console.log(ansis.cyan(i18n.t("uninstall:processingCustom")));
707
+ const results = await uninstaller.customUninstall(items);
708
+ displayUninstallResult("custom", results);
709
+ }
710
+ function displayUninstallResult(mode, results) {
711
+ console.log("");
712
+ console.log(ansis.cyan("\u2500".repeat(50)));
713
+ let totalSuccess = 0;
714
+ let totalErrors = 0;
715
+ let totalWarnings = 0;
716
+ results.forEach((result) => {
717
+ if (result.success) {
718
+ totalSuccess++;
719
+ }
720
+ if (result.removed && result.removed.length > 0) {
721
+ console.log(ansis.green(`\u{1F5D1}\uFE0F ${i18n.t("uninstall:movedToTrash")}:`));
722
+ result.removed.forEach((item) => {
723
+ console.log(ansis.gray(` \u2022 ${item}`));
724
+ });
725
+ }
726
+ if (result.removedConfigs && result.removedConfigs.length > 0) {
727
+ console.log(ansis.green(`\u2714 ${i18n.t("uninstall:removedConfigs")}:`));
728
+ result.removedConfigs.forEach((item) => {
729
+ console.log(ansis.gray(` \u2022 ${item}`));
730
+ });
731
+ }
732
+ if (result.errors && result.errors.length > 0) {
733
+ totalErrors += result.errors.length;
734
+ console.log(ansis.red(`\u2716 ${i18n.t("uninstall:errors")}:`));
735
+ result.errors.forEach((error) => {
736
+ console.log(ansis.red(` \u2022 ${error}`));
737
+ });
738
+ }
739
+ if (result.warnings && result.warnings.length > 0) {
740
+ totalWarnings += result.warnings.length;
741
+ console.log(ansis.yellow(`\u26A0 ${i18n.t("uninstall:warnings")}:`));
742
+ result.warnings.forEach((warning) => {
743
+ console.log(ansis.yellow(` \u2022 ${warning}`));
744
+ });
745
+ }
746
+ });
747
+ const totalRemovedFiles = results.reduce((count, result) => count + (result.removed?.length || 0), 0);
748
+ const totalRemovedConfigs = results.reduce((count, result) => count + (result.removedConfigs?.length || 0), 0);
749
+ console.log("");
750
+ console.log(ansis.cyan("\u2500".repeat(50)));
751
+ if (mode === "complete") {
752
+ if (totalErrors === 0) {
753
+ console.log(ansis.green.bold(`\u2714 ${i18n.t("uninstall:completeSuccess")}`));
754
+ } else {
755
+ console.log(ansis.yellow.bold(`\u26A0 ${i18n.t("uninstall:completePartialSuccess")}`));
756
+ }
757
+ } else {
758
+ if (totalRemovedFiles > 0 && totalRemovedConfigs > 0) {
759
+ console.log(ansis.green.bold(`\u2714 ${i18n.t("uninstall:customSuccessBoth", {
760
+ fileCount: totalRemovedFiles,
761
+ configCount: totalRemovedConfigs
762
+ })}`));
763
+ } else if (totalRemovedFiles > 0) {
764
+ console.log(ansis.green.bold(`\u2714 ${i18n.t("uninstall:customSuccessFiles", {
765
+ count: totalRemovedFiles
766
+ })}`));
767
+ } else if (totalRemovedConfigs > 0) {
768
+ console.log(ansis.green.bold(`\u2714 ${i18n.t("uninstall:customSuccessConfigs", {
769
+ count: totalRemovedConfigs
770
+ })}`));
771
+ } else {
772
+ console.log(ansis.green.bold(`\u2714 ${i18n.t("uninstall:customSuccess", { count: totalSuccess })}`));
773
+ }
774
+ if (totalErrors > 0) {
775
+ console.log(ansis.red(`\u2716 ${i18n.t("uninstall:errorsCount", { count: totalErrors })}`));
776
+ }
777
+ if (totalWarnings > 0) {
778
+ console.log(ansis.yellow(`\u26A0 ${i18n.t("uninstall:warningsCount", { count: totalWarnings })}`));
779
+ }
780
+ }
781
+ console.log("");
782
+ }
783
+
784
+ export { uninstall };