ccman 3.0.31 → 3.0.32

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 (2) hide show
  1. package/dist/index.js +2022 -124
  2. package/package.json +5 -2
package/dist/index.js CHANGED
@@ -9,8 +9,1923 @@ var __export = (target, all) => {
9
9
  __defProp(target, name, { get: all[name], enumerable: true });
10
10
  };
11
11
 
12
+ // ../core/package.json
13
+ var package_default;
14
+ var init_package = __esm({
15
+ "../core/package.json"() {
16
+ package_default = {
17
+ name: "@ccman/core",
18
+ version: "3.0.32",
19
+ type: "module",
20
+ description: "Core business logic for ccman",
21
+ main: "./dist/index.js",
22
+ types: "./dist/index.d.ts",
23
+ files: [
24
+ "dist",
25
+ "templates"
26
+ ],
27
+ scripts: {
28
+ build: "tsc",
29
+ test: "vitest run",
30
+ "test:watch": "vitest",
31
+ clean: "rm -rf dist"
32
+ },
33
+ keywords: [
34
+ "codex",
35
+ "claude",
36
+ "claude-code",
37
+ "ai",
38
+ "api",
39
+ "config",
40
+ "manager"
41
+ ],
42
+ author: "2ue",
43
+ license: "MIT",
44
+ repository: {
45
+ type: "git",
46
+ url: "https://github.com/2ue/ccm.git",
47
+ directory: "packages/core"
48
+ },
49
+ homepage: "https://github.com/2ue/ccm#readme",
50
+ bugs: {
51
+ url: "https://github.com/2ue/ccm/issues"
52
+ },
53
+ dependencies: {
54
+ "@iarna/toml": "^2.2.5",
55
+ "proper-lockfile": "^4.1.2",
56
+ webdav: "^5.8.0"
57
+ },
58
+ devDependencies: {
59
+ vitest: "^1.0.0"
60
+ },
61
+ engines: {
62
+ node: ">=18.0.0"
63
+ }
64
+ };
65
+ }
66
+ });
67
+
68
+ // ../core/dist/paths.js
69
+ import * as os from "os";
70
+ import * as path from "path";
71
+ function getCcmanDir() {
72
+ return ccmanDir;
73
+ }
74
+ function getCodexDir() {
75
+ return codexDir;
76
+ }
77
+ function getClaudeDir() {
78
+ return claudeDir;
79
+ }
80
+ function getConfigPath() {
81
+ return path.join(ccmanDir, "config.json");
82
+ }
83
+ function getCodexConfigPath() {
84
+ return path.join(codexDir, "config.toml");
85
+ }
86
+ function getCodexAuthPath() {
87
+ return path.join(codexDir, "auth.json");
88
+ }
89
+ function getClaudeConfigPath() {
90
+ return path.join(claudeDir, "settings.json");
91
+ }
92
+ function getClaudeJsonPath() {
93
+ return path.join(rootDir, ".claude.json");
94
+ }
95
+ var isDev, isTest, rootDir, ccmanDir, codexDir, claudeDir;
96
+ var init_paths = __esm({
97
+ "../core/dist/paths.js"() {
98
+ "use strict";
99
+ isDev = process.env.NODE_ENV === "development";
100
+ isTest = process.env.NODE_ENV === "test";
101
+ if (isTest) {
102
+ rootDir = path.join(os.tmpdir(), `ccman-test-${process.pid}`);
103
+ } else if (isDev) {
104
+ rootDir = path.join(os.tmpdir(), "ccman-dev");
105
+ } else {
106
+ rootDir = os.homedir();
107
+ }
108
+ ccmanDir = path.join(rootDir, ".ccman");
109
+ codexDir = path.join(rootDir, ".codex");
110
+ claudeDir = path.join(rootDir, ".claude");
111
+ }
112
+ });
113
+
114
+ // ../core/dist/utils/file.js
115
+ import * as fs from "fs";
116
+ import * as path2 from "path";
117
+ function ensureDir(dir) {
118
+ fs.mkdirSync(dir, { recursive: true });
119
+ }
120
+ function readJSON(filePath) {
121
+ const content = fs.readFileSync(filePath, "utf-8");
122
+ return JSON.parse(content);
123
+ }
124
+ function writeJSON(filePath, data) {
125
+ const dir = path2.dirname(filePath);
126
+ ensureDir(dir);
127
+ const tmpPath = `${filePath}.tmp`;
128
+ fs.writeFileSync(tmpPath, JSON.stringify(data, null, 2), { mode: 384 });
129
+ fs.renameSync(tmpPath, filePath);
130
+ }
131
+ function fileExists(filePath) {
132
+ try {
133
+ fs.accessSync(filePath, fs.constants.F_OK);
134
+ return true;
135
+ } catch {
136
+ return false;
137
+ }
138
+ }
139
+ var init_file = __esm({
140
+ "../core/dist/utils/file.js"() {
141
+ "use strict";
142
+ }
143
+ });
144
+
145
+ // ../core/dist/utils/template.js
146
+ function replaceVariables(template, variables) {
147
+ const jsonStr = JSON.stringify(template);
148
+ let result = jsonStr;
149
+ for (const [key, value] of Object.entries(variables)) {
150
+ const escapedValue = value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
151
+ result = result.replace(new RegExp(`{{${key}}}`, "g"), escapedValue);
152
+ }
153
+ return JSON.parse(result);
154
+ }
155
+ function deepMerge(target, source) {
156
+ const result = { ...target };
157
+ for (const key in source) {
158
+ const sourceValue = source[key];
159
+ const targetValue = result[key];
160
+ if (sourceValue && typeof sourceValue === "object" && !Array.isArray(sourceValue) && targetValue && typeof targetValue === "object" && !Array.isArray(targetValue)) {
161
+ result[key] = deepMerge(targetValue, sourceValue);
162
+ } else {
163
+ result[key] = sourceValue;
164
+ }
165
+ }
166
+ return result;
167
+ }
168
+ var init_template = __esm({
169
+ "../core/dist/utils/template.js"() {
170
+ "use strict";
171
+ }
172
+ });
173
+
174
+ // ../core/dist/writers/codex.js
175
+ import * as fs2 from "fs";
176
+ import * as path3 from "path";
177
+ import { fileURLToPath } from "url";
178
+ import { parse as parseToml, stringify as stringifyToml } from "@iarna/toml";
179
+ function loadCodexTemplateConfig() {
180
+ try {
181
+ const templatePath = path3.resolve(__dirname, "../../templates/codex/config.toml");
182
+ if (fs2.existsSync(templatePath)) {
183
+ const content = fs2.readFileSync(templatePath, "utf-8");
184
+ return parseToml(content);
185
+ }
186
+ } catch {
187
+ }
188
+ return CODEX_DEFAULT_CONFIG;
189
+ }
190
+ function writeCodexConfig(provider) {
191
+ ensureDir(getCodexDir());
192
+ const configPath = getCodexConfigPath();
193
+ let userConfig = {};
194
+ if (fileExists(configPath)) {
195
+ const content = fs2.readFileSync(configPath, "utf-8");
196
+ userConfig = parseToml(content);
197
+ }
198
+ const templateConfig = loadCodexTemplateConfig();
199
+ const mergedConfig = deepMerge(templateConfig, userConfig);
200
+ mergedConfig.model_provider = provider.name;
201
+ mergedConfig.model = provider.model || mergedConfig.model || "gpt-5-codex";
202
+ mergedConfig.model_providers = mergedConfig.model_providers || {};
203
+ mergedConfig.model_providers[provider.name] = {
204
+ name: provider.name,
205
+ base_url: provider.baseUrl,
206
+ wire_api: "responses",
207
+ requires_openai_auth: true
208
+ };
209
+ fs2.writeFileSync(configPath, stringifyToml(mergedConfig), { mode: 384 });
210
+ const authPath = getCodexAuthPath();
211
+ let auth;
212
+ if (fileExists(authPath)) {
213
+ const content = fs2.readFileSync(authPath, "utf-8");
214
+ auth = JSON.parse(content);
215
+ } else {
216
+ auth = { OPENAI_API_KEY: "" };
217
+ }
218
+ auth.OPENAI_API_KEY = provider.apiKey;
219
+ fs2.writeFileSync(authPath, JSON.stringify(auth, null, 2), { mode: 384 });
220
+ }
221
+ var __filename, __dirname, CODEX_DEFAULT_CONFIG;
222
+ var init_codex = __esm({
223
+ "../core/dist/writers/codex.js"() {
224
+ "use strict";
225
+ init_paths();
226
+ init_file();
227
+ init_template();
228
+ __filename = fileURLToPath(import.meta.url);
229
+ __dirname = path3.dirname(__filename);
230
+ CODEX_DEFAULT_CONFIG = {
231
+ model: "gpt-5.1",
232
+ model_reasoning_effort: "high",
233
+ disable_response_storage: true,
234
+ sandbox_mode: "workspace-write",
235
+ windows_wsl_setup_acknowledged: true,
236
+ approval_policy: "never",
237
+ profile: "auto-max",
238
+ file_opener: "vscode",
239
+ history: {
240
+ persistence: "save-all"
241
+ },
242
+ tui: {
243
+ notifications: true
244
+ },
245
+ shell_environment_policy: {
246
+ inherit: "all",
247
+ ignore_default_excludes: false
248
+ },
249
+ features: {
250
+ plan_tool: true,
251
+ apply_patch_freeform: true,
252
+ view_image_tool: true,
253
+ web_search_request: true,
254
+ unified_exec: false,
255
+ streamable_shell: false,
256
+ rmcp_client: true
257
+ },
258
+ sandbox_workspace_write: {
259
+ network_access: true
260
+ },
261
+ profiles: {
262
+ "auto-max": {
263
+ approval_policy: "never",
264
+ sandbox_mode: "workspace-write"
265
+ },
266
+ "review": {
267
+ approval_policy: "on-request",
268
+ sandbox_mode: "workspace-write"
269
+ }
270
+ },
271
+ notice: {
272
+ hide_gpt5_1_migration_prompt: true
273
+ }
274
+ };
275
+ }
276
+ });
277
+
278
+ // ../core/dist/writers/claude.js
279
+ import * as fs3 from "fs";
280
+ import * as path4 from "path";
281
+ import { fileURLToPath as fileURLToPath2 } from "url";
282
+ function loadClaudeTemplateConfig() {
283
+ try {
284
+ const templatePath = path4.resolve(__dirname2, "../../templates/claude/settings.json");
285
+ if (fs3.existsSync(templatePath)) {
286
+ const content = fs3.readFileSync(templatePath, "utf-8");
287
+ return JSON.parse(content);
288
+ }
289
+ } catch {
290
+ }
291
+ return CLAUDE_CONFIG_TEMPLATE;
292
+ }
293
+ function writeClaudeConfig(provider) {
294
+ ensureDir(getClaudeDir());
295
+ const configPath = getClaudeConfigPath();
296
+ let userConfig = {};
297
+ if (fileExists(configPath)) {
298
+ const content = fs3.readFileSync(configPath, "utf-8");
299
+ userConfig = JSON.parse(content);
300
+ }
301
+ const defaultTemplate = loadClaudeTemplateConfig();
302
+ const defaultConfig = replaceVariables(defaultTemplate, {
303
+ apiKey: provider.apiKey,
304
+ baseUrl: provider.baseUrl
305
+ });
306
+ const mergedConfig = deepMerge(defaultConfig, userConfig);
307
+ mergedConfig.env = mergedConfig.env || {};
308
+ mergedConfig.env.ANTHROPIC_AUTH_TOKEN = provider.apiKey;
309
+ mergedConfig.env.ANTHROPIC_BASE_URL = provider.baseUrl;
310
+ fs3.writeFileSync(configPath, JSON.stringify(mergedConfig, null, 2), { mode: 384 });
311
+ }
312
+ var __filename2, __dirname2, CLAUDE_CONFIG_TEMPLATE;
313
+ var init_claude = __esm({
314
+ "../core/dist/writers/claude.js"() {
315
+ "use strict";
316
+ init_paths();
317
+ init_file();
318
+ init_template();
319
+ __filename2 = fileURLToPath2(import.meta.url);
320
+ __dirname2 = path4.dirname(__filename2);
321
+ CLAUDE_CONFIG_TEMPLATE = {
322
+ env: {
323
+ ANTHROPIC_AUTH_TOKEN: "{{apiKey}}",
324
+ ANTHROPIC_BASE_URL: "{{baseUrl}}",
325
+ CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: 1,
326
+ CLAUDE_CODE_MAX_OUTPUT_TOKENS: 32e3
327
+ },
328
+ permissions: {
329
+ allow: [],
330
+ deny: []
331
+ }
332
+ };
333
+ }
334
+ });
335
+
336
+ // ../core/dist/writers/mcp.js
337
+ import * as fs4 from "fs";
338
+ import * as path5 from "path";
339
+ function getMCPConfigPath() {
340
+ return path5.join(getCcmanDir(), "mcp.json");
341
+ }
342
+ function migrateMCPConfig(config) {
343
+ if (Array.isArray(config.managedServerNames)) {
344
+ config.managedServerNames = {
345
+ claude: config.managedServerNames,
346
+ codex: [],
347
+ cursor: [],
348
+ windsurf: []
349
+ };
350
+ } else if (!config.managedServerNames) {
351
+ config.managedServerNames = {
352
+ claude: [],
353
+ codex: [],
354
+ cursor: [],
355
+ windsurf: []
356
+ };
357
+ }
358
+ if (config.servers) {
359
+ for (const server of config.servers) {
360
+ if (!server.enabledApps) {
361
+ server.enabledApps = ["claude"];
362
+ }
363
+ }
364
+ } else {
365
+ config.servers = [];
366
+ }
367
+ return config;
368
+ }
369
+ function loadMCPConfig() {
370
+ const configPath = getMCPConfigPath();
371
+ if (!fileExists(configPath)) {
372
+ return {
373
+ servers: [],
374
+ managedServerNames: {
375
+ claude: [],
376
+ codex: [],
377
+ cursor: [],
378
+ windsurf: []
379
+ }
380
+ };
381
+ }
382
+ const config = readJSON(configPath);
383
+ return migrateMCPConfig(config);
384
+ }
385
+ function saveMCPConfig(config) {
386
+ const configPath = getMCPConfigPath();
387
+ writeJSON(configPath, config);
388
+ }
389
+ function providerToMCPServer(provider) {
390
+ let env;
391
+ let description;
392
+ if (provider.model) {
393
+ try {
394
+ const modelData = JSON.parse(provider.model);
395
+ env = modelData.env;
396
+ description = modelData.description;
397
+ } catch (error) {
398
+ env = JSON.parse(provider.model);
399
+ }
400
+ }
401
+ return {
402
+ id: provider.id,
403
+ name: provider.name,
404
+ command: provider.baseUrl,
405
+ args: provider.apiKey.split(" ").filter((arg) => arg.length > 0),
406
+ env,
407
+ description,
408
+ createdAt: provider.createdAt,
409
+ lastModified: provider.lastModified,
410
+ enabledApps: ["claude"]
411
+ // 新创建的 MCP 默认启用 Claude
412
+ };
413
+ }
414
+ function mcpServerToProvider(server) {
415
+ let model;
416
+ if (server.env || server.description) {
417
+ model = JSON.stringify({
418
+ env: server.env,
419
+ description: server.description
420
+ });
421
+ }
422
+ return {
423
+ id: server.id,
424
+ name: server.name,
425
+ baseUrl: server.command,
426
+ apiKey: server.args.join(" "),
427
+ model,
428
+ createdAt: server.createdAt,
429
+ lastModified: server.lastModified
430
+ };
431
+ }
432
+ function writeMCPConfigForApp(app, _provider) {
433
+ const mcpConfig = loadMCPConfig();
434
+ const enabledServers = mcpConfig.servers.filter((server) => server.enabledApps.includes(app));
435
+ let configPath;
436
+ let configDir;
437
+ switch (app) {
438
+ case "claude":
439
+ configPath = getClaudeConfigPath();
440
+ configDir = getClaudeDir();
441
+ break;
442
+ case "codex":
443
+ return;
444
+ case "cursor":
445
+ return;
446
+ case "windsurf":
447
+ return;
448
+ }
449
+ ensureDir(configDir);
450
+ let appConfig = {};
451
+ if (fileExists(configPath)) {
452
+ try {
453
+ const content = fs4.readFileSync(configPath, "utf-8");
454
+ appConfig = JSON.parse(content);
455
+ } catch (error) {
456
+ throw new Error(`\u65E0\u6CD5\u8BFB\u53D6 ${app} \u914D\u7F6E\u6587\u4EF6: ${error.message}`);
457
+ }
458
+ }
459
+ const existingMCPs = appConfig.mcpServers || {};
460
+ const userMCPs = {};
461
+ const managedNames = mcpConfig.managedServerNames[app] || [];
462
+ for (const [name, config] of Object.entries(existingMCPs)) {
463
+ if (!managedNames.includes(name)) {
464
+ userMCPs[name] = config;
465
+ }
466
+ }
467
+ const ccmanMCPs = {};
468
+ for (const server of enabledServers) {
469
+ ccmanMCPs[server.name] = {
470
+ command: server.command,
471
+ args: server.args,
472
+ env: server.env
473
+ };
474
+ }
475
+ appConfig.mcpServers = {
476
+ ...ccmanMCPs,
477
+ // ccman 管理的
478
+ ...userMCPs
479
+ // 用户手动配置的(优先级更高)
480
+ };
481
+ const tempPath = `${configPath}.tmp`;
482
+ fs4.writeFileSync(tempPath, JSON.stringify(appConfig, null, 2), {
483
+ mode: 384
484
+ });
485
+ fs4.renameSync(tempPath, configPath);
486
+ }
487
+ function writeMCPConfig(_provider) {
488
+ writeMCPConfigForApp("claude", _provider);
489
+ }
490
+ var init_mcp = __esm({
491
+ "../core/dist/writers/mcp.js"() {
492
+ "use strict";
493
+ init_paths();
494
+ init_file();
495
+ }
496
+ });
497
+
498
+ // ../core/dist/presets/codex.js
499
+ var CODEX_PRESETS;
500
+ var init_codex2 = __esm({
501
+ "../core/dist/presets/codex.js"() {
502
+ "use strict";
503
+ CODEX_PRESETS = [
504
+ {
505
+ name: "88Code",
506
+ baseUrl: "https://www.88code.org/openai/v1",
507
+ description: "88Code API \u670D\u52A1"
508
+ }
509
+ ];
510
+ }
511
+ });
512
+
513
+ // ../core/dist/presets/claude.js
514
+ var CC_PRESETS;
515
+ var init_claude2 = __esm({
516
+ "../core/dist/presets/claude.js"() {
517
+ "use strict";
518
+ CC_PRESETS = [
519
+ {
520
+ name: "Anthropic Official",
521
+ baseUrl: "https://api.anthropic.com",
522
+ description: "Anthropic \u5B98\u65B9 API"
523
+ },
524
+ {
525
+ name: "AnyRouter",
526
+ baseUrl: "https://anyrouter.top",
527
+ description: "AnyRouter API \u670D\u52A1"
528
+ },
529
+ {
530
+ name: "PackyCode",
531
+ baseUrl: "https://api.packycode.com",
532
+ description: "PackyCode API \u670D\u52A1"
533
+ },
534
+ {
535
+ name: "88Code",
536
+ baseUrl: "https://www.88code.org/api",
537
+ description: "88Code API \u670D\u52A1"
538
+ },
539
+ {
540
+ name: "KKYYXX",
541
+ baseUrl: "https://api.kkyyxx.xyz",
542
+ description: "KKYYXX API \u670D\u52A1"
543
+ },
544
+ {
545
+ name: "BigModel",
546
+ baseUrl: "https://open.bigmodel.cn/api/anthropic",
547
+ description: "\u667A\u8C31 BigModel API"
548
+ },
549
+ {
550
+ name: "ModelScope",
551
+ baseUrl: "https://api-inference.modelscope.cn/v1/chat/completions",
552
+ description: "\u963F\u91CC\u4E91 ModelScope API"
553
+ }
554
+ ];
555
+ }
556
+ });
557
+
558
+ // ../core/dist/presets/mcp.js
559
+ var MCP_PRESETS_DETAIL, MCP_PRESETS;
560
+ var init_mcp2 = __esm({
561
+ "../core/dist/presets/mcp.js"() {
562
+ "use strict";
563
+ MCP_PRESETS_DETAIL = [
564
+ {
565
+ name: "filesystem",
566
+ command: "npx",
567
+ args: ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/files"],
568
+ description: "\u6587\u4EF6\u7CFB\u7EDF\u8BBF\u95EE",
569
+ argsPlaceholder: "\u9700\u8981\u4FEE\u6539\u7B2C3\u4E2A\u53C2\u6570\u4E3A\u5141\u8BB8\u8BBF\u95EE\u7684\u76EE\u5F55\u8DEF\u5F84"
570
+ },
571
+ {
572
+ name: "github",
573
+ command: "npx",
574
+ args: ["-y", "@modelcontextprotocol/server-github"],
575
+ description: "GitHub \u96C6\u6210",
576
+ envRequired: ["GITHUB_PERSONAL_ACCESS_TOKEN"]
577
+ },
578
+ {
579
+ name: "postgres",
580
+ command: "npx",
581
+ args: ["-y", "@modelcontextprotocol/server-postgres", "postgresql://localhost/mydb"],
582
+ description: "PostgreSQL \u6570\u636E\u5E93",
583
+ argsPlaceholder: "\u9700\u8981\u4FEE\u6539\u7B2C3\u4E2A\u53C2\u6570\u4E3A\u6570\u636E\u5E93\u8FDE\u63A5\u5B57\u7B26\u4E32"
584
+ },
585
+ {
586
+ name: "brave-search",
587
+ command: "npx",
588
+ args: ["-y", "@modelcontextprotocol/server-brave-search"],
589
+ description: "Brave \u641C\u7D22",
590
+ envRequired: ["BRAVE_API_KEY"]
591
+ },
592
+ {
593
+ name: "google-maps",
594
+ command: "npx",
595
+ args: ["-y", "@modelcontextprotocol/server-google-maps"],
596
+ description: "Google Maps",
597
+ envRequired: ["GOOGLE_MAPS_API_KEY"]
598
+ },
599
+ {
600
+ name: "puppeteer",
601
+ command: "npx",
602
+ args: ["-y", "@modelcontextprotocol/server-puppeteer"],
603
+ description: "\u6D4F\u89C8\u5668\u81EA\u52A8\u5316"
604
+ },
605
+ {
606
+ name: "sqlite",
607
+ command: "npx",
608
+ args: ["-y", "@modelcontextprotocol/server-sqlite", "/path/to/database.db"],
609
+ description: "SQLite \u6570\u636E\u5E93",
610
+ argsPlaceholder: "\u9700\u8981\u4FEE\u6539\u7B2C3\u4E2A\u53C2\u6570\u4E3A\u6570\u636E\u5E93\u6587\u4EF6\u8DEF\u5F84"
611
+ },
612
+ {
613
+ name: "sequential-thinking",
614
+ command: "npx",
615
+ args: ["-y", "@modelcontextprotocol/server-sequential-thinking"],
616
+ description: "\u5E8F\u5217\u601D\u8003\u589E\u5F3A"
617
+ }
618
+ ];
619
+ MCP_PRESETS = MCP_PRESETS_DETAIL.map((preset) => ({
620
+ name: preset.name,
621
+ baseUrl: preset.command,
622
+ // 字段映射:command → baseUrl
623
+ description: preset.description
624
+ }));
625
+ }
626
+ });
627
+
628
+ // ../core/dist/tool-manager.types.js
629
+ var ProviderNotFoundError, ProviderNameConflictError, PresetNameConflictError;
630
+ var init_tool_manager_types = __esm({
631
+ "../core/dist/tool-manager.types.js"() {
632
+ "use strict";
633
+ ProviderNotFoundError = class extends Error {
634
+ constructor(id) {
635
+ super(`\u670D\u52A1\u5546\u4E0D\u5B58\u5728: ${id}`);
636
+ this.name = "ProviderNotFoundError";
637
+ }
638
+ };
639
+ ProviderNameConflictError = class extends Error {
640
+ constructor(name) {
641
+ super(`\u670D\u52A1\u5546\u540D\u79F0\u5DF2\u5B58\u5728: ${name}`);
642
+ this.name = "ProviderNameConflictError";
643
+ }
644
+ };
645
+ PresetNameConflictError = class extends Error {
646
+ constructor(name) {
647
+ super(`\u9884\u7F6E\u540D\u79F0\u5DF2\u5B58\u5728: ${name}`);
648
+ this.name = "PresetNameConflictError";
649
+ }
650
+ };
651
+ }
652
+ });
653
+
654
+ // ../core/dist/tool-manager.js
655
+ import * as path6 from "path";
656
+ function createToolManager(tool) {
657
+ const toolConfig = TOOL_CONFIGS[tool];
658
+ const configPath = toolConfig.configPath;
659
+ function generateId() {
660
+ const timestamp = Date.now();
661
+ const random = Math.random().toString(36).substring(2, 8);
662
+ return `${tool}-${timestamp}-${random}`;
663
+ }
664
+ function loadConfig2() {
665
+ if (toolConfig.customLoader) {
666
+ return toolConfig.customLoader();
667
+ }
668
+ if (!fileExists(configPath)) {
669
+ ensureDir(getCcmanDir());
670
+ const initialConfig = {
671
+ providers: [],
672
+ presets: []
673
+ };
674
+ writeJSON(configPath, initialConfig);
675
+ return initialConfig;
676
+ }
677
+ return readJSON(configPath);
678
+ }
679
+ function saveConfig2(config) {
680
+ if (toolConfig.customSaver) {
681
+ toolConfig.customSaver(config);
682
+ return;
683
+ }
684
+ writeJSON(configPath, config);
685
+ }
686
+ return {
687
+ add(input) {
688
+ const config = loadConfig2();
689
+ const nameExists = config.providers.some((p) => p.name === input.name);
690
+ if (nameExists) {
691
+ throw new ProviderNameConflictError(input.name);
692
+ }
693
+ const timestamp = Date.now();
694
+ const provider = {
695
+ id: generateId(),
696
+ name: input.name,
697
+ desc: input.desc,
698
+ baseUrl: input.baseUrl,
699
+ apiKey: input.apiKey,
700
+ model: input.model,
701
+ createdAt: timestamp,
702
+ lastModified: timestamp
703
+ };
704
+ config.providers.push(provider);
705
+ saveConfig2(config);
706
+ if (toolConfig.autoSync) {
707
+ toolConfig.writer(provider);
708
+ }
709
+ return provider;
710
+ },
711
+ list() {
712
+ const config = loadConfig2();
713
+ return config.providers;
714
+ },
715
+ get(id) {
716
+ const config = loadConfig2();
717
+ const provider = config.providers.find((p) => p.id === id);
718
+ if (!provider) {
719
+ throw new ProviderNotFoundError(id);
720
+ }
721
+ return provider;
722
+ },
723
+ findByName(name) {
724
+ const config = loadConfig2();
725
+ const lowerName = name.toLowerCase();
726
+ return config.providers.find((p) => p.name.toLowerCase() === lowerName);
727
+ },
728
+ switch(id) {
729
+ const config = loadConfig2();
730
+ const provider = config.providers.find((p) => p.id === id);
731
+ if (!provider) {
732
+ throw new ProviderNotFoundError(id);
733
+ }
734
+ config.currentProviderId = id;
735
+ provider.lastUsedAt = Date.now();
736
+ saveConfig2(config);
737
+ toolConfig.writer(provider);
738
+ },
739
+ getCurrent() {
740
+ const config = loadConfig2();
741
+ if (!config.currentProviderId) {
742
+ return null;
743
+ }
744
+ const provider = config.providers.find((p) => p.id === config.currentProviderId);
745
+ return provider || null;
746
+ },
747
+ // 注:edit 方法的"复杂度"来自必要的业务逻辑(检查存在性、名称冲突、更新 4 个可选字段、同步配置)
748
+ // 每个 if 都不可避免,没有特殊情况或嵌套逻辑,因此禁用 complexity 检查
749
+ // eslint-disable-next-line complexity
750
+ edit(id, updates) {
751
+ const config = loadConfig2();
752
+ const provider = config.providers.find((p) => p.id === id);
753
+ if (!provider) {
754
+ throw new ProviderNotFoundError(id);
755
+ }
756
+ if (updates.name !== void 0 && updates.name !== provider.name) {
757
+ const nameConflict = config.providers.some((p) => p.id !== id && p.name === updates.name);
758
+ if (nameConflict) {
759
+ throw new ProviderNameConflictError(updates.name);
760
+ }
761
+ }
762
+ if (updates.name !== void 0)
763
+ provider.name = updates.name;
764
+ if (updates.desc !== void 0)
765
+ provider.desc = updates.desc;
766
+ if (updates.baseUrl !== void 0)
767
+ provider.baseUrl = updates.baseUrl;
768
+ if (updates.apiKey !== void 0)
769
+ provider.apiKey = updates.apiKey;
770
+ if (updates.model !== void 0)
771
+ provider.model = updates.model;
772
+ provider.lastModified = Date.now();
773
+ saveConfig2(config);
774
+ if (config.currentProviderId === id) {
775
+ toolConfig.writer(provider);
776
+ }
777
+ if (toolConfig.autoSync) {
778
+ toolConfig.writer(provider);
779
+ }
780
+ return provider;
781
+ },
782
+ remove(id) {
783
+ const config = loadConfig2();
784
+ const index = config.providers.findIndex((p) => p.id === id);
785
+ if (index === -1) {
786
+ throw new ProviderNotFoundError(id);
787
+ }
788
+ if (config.currentProviderId === id) {
789
+ config.currentProviderId = void 0;
790
+ }
791
+ config.providers.splice(index, 1);
792
+ saveConfig2(config);
793
+ if (toolConfig.autoSync) {
794
+ toolConfig.writer({});
795
+ }
796
+ },
797
+ clone(sourceId, newName) {
798
+ const source = this.get(sourceId);
799
+ const config = loadConfig2();
800
+ const nameExists = config.providers.some((p) => p.name === newName);
801
+ if (nameExists) {
802
+ throw new ProviderNameConflictError(newName);
803
+ }
804
+ const timestamp = Date.now();
805
+ const newProvider = {
806
+ ...source,
807
+ id: generateId(),
808
+ name: newName,
809
+ desc: void 0,
810
+ createdAt: timestamp,
811
+ lastModified: timestamp,
812
+ lastUsedAt: void 0
813
+ };
814
+ config.providers.push(newProvider);
815
+ saveConfig2(config);
816
+ return newProvider;
817
+ },
818
+ addPreset(input) {
819
+ const config = loadConfig2();
820
+ if (!config.presets) {
821
+ config.presets = [];
822
+ }
823
+ const allPresets = [...toolConfig.builtinPresets, ...config.presets];
824
+ const nameExists = allPresets.some((p) => p.name === input.name);
825
+ if (nameExists) {
826
+ throw new PresetNameConflictError(input.name);
827
+ }
828
+ const preset = {
829
+ name: input.name,
830
+ baseUrl: input.baseUrl,
831
+ description: input.description
832
+ };
833
+ config.presets.push(preset);
834
+ saveConfig2(config);
835
+ return {
836
+ ...preset,
837
+ isBuiltIn: false
838
+ };
839
+ },
840
+ listPresets() {
841
+ const config = loadConfig2();
842
+ const userPresets = config.presets || [];
843
+ const builtinWithFlag = toolConfig.builtinPresets.map((p) => ({
844
+ ...p,
845
+ isBuiltIn: true
846
+ }));
847
+ const userWithFlag = userPresets.map((p) => ({
848
+ ...p,
849
+ isBuiltIn: false
850
+ }));
851
+ return [...builtinWithFlag, ...userWithFlag];
852
+ },
853
+ editPreset(name, updates) {
854
+ const config = loadConfig2();
855
+ if (!config.presets) {
856
+ config.presets = [];
857
+ }
858
+ const preset = config.presets.find((p) => p.name === name);
859
+ if (!preset) {
860
+ throw new Error(`\u9884\u7F6E\u4E0D\u5B58\u5728: ${name}`);
861
+ }
862
+ if (updates.name !== void 0 && updates.name !== preset.name) {
863
+ const allPresets = [...toolConfig.builtinPresets, ...config.presets];
864
+ const nameConflict = allPresets.some((p) => p.name !== name && p.name === updates.name);
865
+ if (nameConflict) {
866
+ throw new PresetNameConflictError(updates.name);
867
+ }
868
+ }
869
+ if (updates.name !== void 0)
870
+ preset.name = updates.name;
871
+ if (updates.baseUrl !== void 0)
872
+ preset.baseUrl = updates.baseUrl;
873
+ if (updates.description !== void 0)
874
+ preset.description = updates.description;
875
+ saveConfig2(config);
876
+ return {
877
+ ...preset,
878
+ isBuiltIn: false
879
+ };
880
+ },
881
+ removePreset(name) {
882
+ const config = loadConfig2();
883
+ if (!config.presets) {
884
+ return;
885
+ }
886
+ const index = config.presets.findIndex((p) => p.name === name);
887
+ if (index === -1) {
888
+ throw new Error(`Preset not found: ${name}`);
889
+ }
890
+ config.presets.splice(index, 1);
891
+ saveConfig2(config);
892
+ }
893
+ };
894
+ }
895
+ function createCodexManager() {
896
+ return createToolManager("codex");
897
+ }
898
+ function createClaudeManager() {
899
+ return createToolManager("claude");
900
+ }
901
+ function createMCPManager() {
902
+ return createToolManager("mcp");
903
+ }
904
+ var TOOL_CONFIGS;
905
+ var init_tool_manager = __esm({
906
+ "../core/dist/tool-manager.js"() {
907
+ "use strict";
908
+ init_paths();
909
+ init_file();
910
+ init_codex();
911
+ init_claude();
912
+ init_mcp();
913
+ init_codex2();
914
+ init_claude2();
915
+ init_mcp2();
916
+ init_tool_manager_types();
917
+ TOOL_CONFIGS = {
918
+ codex: {
919
+ configPath: path6.join(getCcmanDir(), "codex.json"),
920
+ builtinPresets: CODEX_PRESETS,
921
+ writer: writeCodexConfig
922
+ },
923
+ claude: {
924
+ configPath: path6.join(getCcmanDir(), "claude.json"),
925
+ builtinPresets: CC_PRESETS,
926
+ writer: writeClaudeConfig
927
+ },
928
+ mcp: {
929
+ configPath: path6.join(getCcmanDir(), "mcp.json"),
930
+ builtinPresets: MCP_PRESETS,
931
+ writer: writeMCPConfig,
932
+ autoSync: true,
933
+ // MCP 需要在每个操作后自动同步到 ~/.claude.json
934
+ // MCP 使用特殊的配置格式(MCPConfig),需要自定义 loader/saver
935
+ customLoader: () => {
936
+ const mcpConfig = loadMCPConfig();
937
+ return {
938
+ providers: mcpConfig.servers.map(mcpServerToProvider),
939
+ presets: []
940
+ };
941
+ },
942
+ customSaver: (config) => {
943
+ const mcpConfig = loadMCPConfig();
944
+ mcpConfig.servers = config.providers.map((provider) => {
945
+ const existingServer = mcpConfig.servers.find((s) => s.id === provider.id);
946
+ const mcpServer = providerToMCPServer(provider);
947
+ if (existingServer) {
948
+ mcpServer.enabledApps = existingServer.enabledApps;
949
+ }
950
+ return mcpServer;
951
+ });
952
+ for (const app of ["claude", "codex", "cursor", "windsurf"]) {
953
+ mcpConfig.managedServerNames[app] = mcpConfig.servers.filter((s) => s.enabledApps.includes(app)).map((s) => s.name);
954
+ }
955
+ saveMCPConfig(mcpConfig);
956
+ }
957
+ }
958
+ };
959
+ }
960
+ });
961
+
962
+ // ../core/dist/migrate.js
963
+ var init_migrate = __esm({
964
+ "../core/dist/migrate.js"() {
965
+ "use strict";
966
+ init_paths();
967
+ }
968
+ });
969
+
970
+ // ../core/dist/config.js
971
+ import * as fs5 from "fs";
972
+ function ensureConfigDir() {
973
+ const dir = getCcmanDir();
974
+ if (!fs5.existsSync(dir)) {
975
+ fs5.mkdirSync(dir, { recursive: true, mode: 448 });
976
+ }
977
+ }
978
+ function loadConfig() {
979
+ const configPath = getConfigPath();
980
+ if (!fs5.existsSync(configPath)) {
981
+ return {};
982
+ }
983
+ try {
984
+ const content = fs5.readFileSync(configPath, "utf-8");
985
+ return JSON.parse(content);
986
+ } catch (error) {
987
+ throw new Error(`Failed to load config: ${error.message}`);
988
+ }
989
+ }
990
+ function saveConfig(config) {
991
+ ensureConfigDir();
992
+ const configPath = getConfigPath();
993
+ try {
994
+ const tempPath = `${configPath}.tmp`;
995
+ fs5.writeFileSync(tempPath, JSON.stringify(config, null, 2), {
996
+ mode: 384
997
+ });
998
+ fs5.renameSync(tempPath, configPath);
999
+ } catch (error) {
1000
+ throw new Error(`Failed to save config: ${error.message}`);
1001
+ }
1002
+ }
1003
+ function getSyncConfig() {
1004
+ const config = loadConfig();
1005
+ return config.sync || null;
1006
+ }
1007
+ function saveSyncConfig(syncConfig) {
1008
+ const config = loadConfig();
1009
+ config.sync = syncConfig;
1010
+ saveConfig(config);
1011
+ }
1012
+ function updateLastSyncTime() {
1013
+ const config = loadConfig();
1014
+ if (config.sync) {
1015
+ config.sync.lastSync = Date.now();
1016
+ saveConfig(config);
1017
+ }
1018
+ }
1019
+ var init_config = __esm({
1020
+ "../core/dist/config.js"() {
1021
+ "use strict";
1022
+ init_paths();
1023
+ }
1024
+ });
1025
+
1026
+ // ../core/dist/sync/webdav-client.js
1027
+ import { createClient } from "webdav";
1028
+ function normalizePath(dir) {
1029
+ if (!dir || dir === "/") {
1030
+ return "/";
1031
+ }
1032
+ const normalized = dir.trim().replace(/^\/+/, "").replace(/\/+$/, "");
1033
+ return `/${normalized}`;
1034
+ }
1035
+ function joinPath(baseDir, filename) {
1036
+ const normalizedBase = normalizePath(baseDir);
1037
+ const normalizedFile = filename.replace(/^\/+/, "");
1038
+ if (normalizedBase === "/") {
1039
+ return `/${normalizedFile}`;
1040
+ }
1041
+ return `${normalizedBase}/${normalizedFile}`;
1042
+ }
1043
+ function createWebDAVClient(config) {
1044
+ const client = createClient(config.webdavUrl, {
1045
+ username: config.username,
1046
+ password: config.password,
1047
+ authType: config.authType || "password",
1048
+ // 默认使用 Basic Auth
1049
+ maxBodyLength: 100 * 1024 * 1024,
1050
+ // 100MB
1051
+ maxContentLength: 100 * 1024 * 1024
1052
+ // 100MB
1053
+ });
1054
+ return client;
1055
+ }
1056
+ async function testWebDAVConnection(config) {
1057
+ const remoteDir = normalizePath(config.remoteDir || "/");
1058
+ try {
1059
+ const client = createWebDAVClient(config);
1060
+ await client.getDirectoryContents(remoteDir);
1061
+ return true;
1062
+ } catch (error) {
1063
+ return false;
1064
+ }
1065
+ }
1066
+ async function ensureDirectory(config, dirPath) {
1067
+ const client = createWebDAVClient(config);
1068
+ const normalizedPath = normalizePath(dirPath);
1069
+ if (normalizedPath === "/") {
1070
+ return true;
1071
+ }
1072
+ try {
1073
+ const exists = await client.exists(normalizedPath);
1074
+ if (exists) {
1075
+ return true;
1076
+ }
1077
+ const parentPath = normalizedPath.substring(0, normalizedPath.lastIndexOf("/"));
1078
+ if (parentPath && parentPath !== "/") {
1079
+ await ensureDirectory(config, parentPath);
1080
+ }
1081
+ await client.createDirectory(normalizedPath);
1082
+ return true;
1083
+ } catch (error) {
1084
+ console.warn(`\u521B\u5EFA\u76EE\u5F55 ${normalizedPath} \u5931\u8D25\uFF0C\u5C06\u5C1D\u8BD5\u76F4\u63A5\u4E0A\u4F20\u6587\u4EF6:`, error.message);
1085
+ return false;
1086
+ }
1087
+ }
1088
+ function isPathNotFoundError(error) {
1089
+ const msg = error.message.toLowerCase();
1090
+ return msg.includes("404") || msg.includes("409") || msg.includes("not found") || msg.includes("conflict");
1091
+ }
1092
+ async function uploadToWebDAV(config, filename, data) {
1093
+ const client = createWebDAVClient(config);
1094
+ const remoteDir = normalizePath(config.remoteDir || "/");
1095
+ const fullPath = joinPath(remoteDir, filename);
1096
+ try {
1097
+ await client.putFileContents(fullPath, data, { overwrite: true });
1098
+ } catch (firstError) {
1099
+ if (isPathNotFoundError(firstError)) {
1100
+ const dirPath = fullPath.substring(0, fullPath.lastIndexOf("/"));
1101
+ if (dirPath && dirPath !== "/") {
1102
+ await ensureDirectory(config, dirPath);
1103
+ await client.putFileContents(fullPath, data, { overwrite: true });
1104
+ } else {
1105
+ throw firstError;
1106
+ }
1107
+ } else {
1108
+ throw firstError;
1109
+ }
1110
+ }
1111
+ try {
1112
+ const exists = await client.exists(fullPath);
1113
+ if (!exists) {
1114
+ throw new Error(`\u6587\u4EF6\u4E0A\u4F20\u540E\u672A\u5728\u670D\u52A1\u5668\u4E0A\u627E\u5230: ${fullPath}`);
1115
+ }
1116
+ } catch (verifyError) {
1117
+ const errorMsg = verifyError.message;
1118
+ if (errorMsg.includes("multistatus") || errorMsg.includes("Invalid response")) {
1119
+ throw new Error(`WebDAV \u914D\u7F6E\u9519\u8BEF\uFF0C\u8BF7\u68C0\u67E5\uFF1A
1120
+ 1. URL \u662F\u5426\u4E3A WebDAV \u7AEF\u70B9\uFF08\u4E0D\u662F\u7F51\u9875\u5730\u5740\uFF09
1121
+ 2. \u7528\u6237\u540D\u548C\u5BC6\u7801\u662F\u5426\u6B63\u786E
1122
+ 3. \u8BA4\u8BC1\u7C7B\u578B\u662F\u5426\u5339\u914D
1123
+
1124
+ \u8BE6\u7EC6\uFF1A${errorMsg}`);
1125
+ }
1126
+ throw verifyError;
1127
+ }
1128
+ }
1129
+ async function downloadFromWebDAV(config, filename) {
1130
+ const client = createWebDAVClient(config);
1131
+ const remoteDir = normalizePath(config.remoteDir || "/");
1132
+ const fullPath = joinPath(remoteDir, filename);
1133
+ try {
1134
+ const contents = await client.getFileContents(fullPath, { format: "text" });
1135
+ return contents;
1136
+ } catch (error) {
1137
+ throw new Error(`\u4E0B\u8F7D\u5931\u8D25: ${error.message}`);
1138
+ }
1139
+ }
1140
+ async function existsOnWebDAV(config, filename) {
1141
+ const client = createWebDAVClient(config);
1142
+ const remoteDir = normalizePath(config.remoteDir || "/");
1143
+ const fullPath = joinPath(remoteDir, filename);
1144
+ try {
1145
+ return await client.exists(fullPath);
1146
+ } catch (error) {
1147
+ return false;
1148
+ }
1149
+ }
1150
+ var init_webdav_client = __esm({
1151
+ "../core/dist/sync/webdav-client.js"() {
1152
+ "use strict";
1153
+ }
1154
+ });
1155
+
1156
+ // ../core/dist/sync/crypto.js
1157
+ import * as crypto from "crypto";
1158
+ function deriveKey(password, salt) {
1159
+ return crypto.pbkdf2Sync(password, salt, PBKDF2_ITERATIONS, KEY_LENGTH, "sha256");
1160
+ }
1161
+ function encryptApiKey(apiKey, password) {
1162
+ if (typeof apiKey !== "string") {
1163
+ throw new Error("API Key \u7F3A\u5931\u6216\u7C7B\u578B\u9519\u8BEF\uFF0C\u65E0\u6CD5\u52A0\u5BC6");
1164
+ }
1165
+ if (!password) {
1166
+ throw new Error("\u540C\u6B65\u5BC6\u7801\u4E0D\u80FD\u4E3A\u7A7A");
1167
+ }
1168
+ const salt = crypto.randomBytes(SALT_LENGTH);
1169
+ const iv = crypto.randomBytes(IV_LENGTH);
1170
+ const key = deriveKey(password, salt);
1171
+ const cipher = crypto.createCipheriv(ALGORITHM, key, iv);
1172
+ let encrypted = cipher.update(apiKey, "utf8");
1173
+ encrypted = Buffer.concat([encrypted, cipher.final()]);
1174
+ const tag = cipher.getAuthTag();
1175
+ const result = Buffer.concat([salt, iv, tag, encrypted]);
1176
+ return result.toString("base64");
1177
+ }
1178
+ function decryptApiKey(encryptedApiKey, password) {
1179
+ try {
1180
+ const data = Buffer.from(encryptedApiKey, "base64");
1181
+ const salt = data.subarray(0, SALT_LENGTH);
1182
+ const iv = data.subarray(SALT_LENGTH, SALT_LENGTH + IV_LENGTH);
1183
+ const tag = data.subarray(SALT_LENGTH + IV_LENGTH, SALT_LENGTH + IV_LENGTH + TAG_LENGTH);
1184
+ const encrypted = data.subarray(SALT_LENGTH + IV_LENGTH + TAG_LENGTH);
1185
+ const key = deriveKey(password, salt);
1186
+ const decipher = crypto.createDecipheriv(ALGORITHM, key, iv);
1187
+ decipher.setAuthTag(tag);
1188
+ let decrypted = decipher.update(encrypted);
1189
+ decrypted = Buffer.concat([decrypted, decipher.final()]);
1190
+ return decrypted.toString("utf8");
1191
+ } catch (error) {
1192
+ throw new Error("\u89E3\u5BC6\u5931\u8D25\uFF1A\u5BC6\u7801\u9519\u8BEF\u6216\u6570\u636E\u635F\u574F");
1193
+ }
1194
+ }
1195
+ function encryptProviders(providers, password) {
1196
+ return providers.map((provider) => {
1197
+ if (typeof provider.apiKey !== "string" || provider.apiKey.length === 0) {
1198
+ throw new Error(`\u670D\u52A1\u5546 "${provider.name}" \u7684 API Key \u4E3A\u7A7A\u6216\u7F3A\u5931\uFF0C\u8BF7\u5148\u5728 ccman \u4E2D\u8865\u5168\u540E\u518D\u8FDB\u884C\u540C\u6B65`);
1199
+ }
1200
+ return {
1201
+ ...provider,
1202
+ apiKey: encryptApiKey(provider.apiKey, password)
1203
+ };
1204
+ });
1205
+ }
1206
+ function decryptProviders(encryptedProviders, password) {
1207
+ return encryptedProviders.map((provider) => ({
1208
+ ...provider,
1209
+ apiKey: decryptApiKey(provider.apiKey, password)
1210
+ }));
1211
+ }
1212
+ var ALGORITHM, KEY_LENGTH, IV_LENGTH, SALT_LENGTH, TAG_LENGTH, PBKDF2_ITERATIONS;
1213
+ var init_crypto = __esm({
1214
+ "../core/dist/sync/crypto.js"() {
1215
+ "use strict";
1216
+ ALGORITHM = "aes-256-gcm";
1217
+ KEY_LENGTH = 32;
1218
+ IV_LENGTH = 16;
1219
+ SALT_LENGTH = 32;
1220
+ TAG_LENGTH = 16;
1221
+ PBKDF2_ITERATIONS = 1e5;
1222
+ }
1223
+ });
1224
+
1225
+ // ../core/dist/sync/merge-advanced.js
1226
+ function isSameConfig(a, b) {
1227
+ return a.baseUrl === b.baseUrl && a.apiKey === b.apiKey;
1228
+ }
1229
+ function isProviderEqual(a, b) {
1230
+ return a.id === b.id && a.name === b.name && a.baseUrl === b.baseUrl && a.apiKey === b.apiKey;
1231
+ }
1232
+ function resolveNameConflict(existingProviders, newProvider) {
1233
+ const existingNames = new Set(existingProviders.map((p) => p.name));
1234
+ if (!existingNames.has(newProvider.name)) {
1235
+ return newProvider;
1236
+ }
1237
+ let suffix = 2;
1238
+ let newName = `${newProvider.name}_${suffix}`;
1239
+ while (existingNames.has(newName)) {
1240
+ suffix++;
1241
+ newName = `${newProvider.name}_${suffix}`;
1242
+ }
1243
+ console.log(`name \u51B2\u7A81\uFF1A\u5C06 "${newProvider.name}" \u91CD\u547D\u540D\u4E3A "${newName}"`);
1244
+ return {
1245
+ ...newProvider,
1246
+ name: newName
1247
+ };
1248
+ }
1249
+ function mergeProviders(local, remote) {
1250
+ const mergedMap = /* @__PURE__ */ new Map();
1251
+ let hasChanges = false;
1252
+ for (const localProvider of local) {
1253
+ mergedMap.set(localProvider.id, localProvider);
1254
+ }
1255
+ for (const remoteProvider of remote) {
1256
+ const existingLocal = Array.from(mergedMap.values()).find((p) => isSameConfig(p, remoteProvider));
1257
+ if (existingLocal) {
1258
+ mergedMap.delete(existingLocal.id);
1259
+ mergedMap.set(remoteProvider.id, remoteProvider);
1260
+ if (!isProviderEqual(existingLocal, remoteProvider)) {
1261
+ hasChanges = true;
1262
+ console.log(`\u76F8\u540C\u914D\u7F6E (${remoteProvider.baseUrl})\uFF0C\u4F7F\u7528\u4E91\u7AEF\u6570\u636E`);
1263
+ }
1264
+ } else {
1265
+ const existingProviders = Array.from(mergedMap.values());
1266
+ const resolvedProvider = resolveNameConflict(existingProviders, remoteProvider);
1267
+ mergedMap.set(resolvedProvider.id, resolvedProvider);
1268
+ hasChanges = true;
1269
+ console.log(`\u65B0 provider ${resolvedProvider.name}\uFF0C\u6DFB\u52A0\u5230\u5408\u5E76\u5217\u8868`);
1270
+ }
1271
+ }
1272
+ const merged = Array.from(mergedMap.values());
1273
+ return {
1274
+ merged,
1275
+ hasChanges
1276
+ };
1277
+ }
1278
+ function resolvePresetNameConflict(existingPresets, newPreset) {
1279
+ const existingNames = new Set(existingPresets.map((p) => p.name));
1280
+ if (!existingNames.has(newPreset.name)) {
1281
+ return newPreset;
1282
+ }
1283
+ let suffix = 2;
1284
+ let newName = `${newPreset.name}_${suffix}`;
1285
+ while (existingNames.has(newName)) {
1286
+ suffix++;
1287
+ newName = `${newPreset.name}_${suffix}`;
1288
+ }
1289
+ console.log(`preset name \u51B2\u7A81\uFF1A\u5C06 "${newPreset.name}" \u91CD\u547D\u540D\u4E3A "${newName}"`);
1290
+ return {
1291
+ ...newPreset,
1292
+ name: newName
1293
+ };
1294
+ }
1295
+ function mergePresets(local, remote) {
1296
+ const localPresets = local || [];
1297
+ const remotePresets = remote || [];
1298
+ const mergedMap = /* @__PURE__ */ new Map();
1299
+ for (const preset of localPresets) {
1300
+ mergedMap.set(preset.baseUrl, preset);
1301
+ }
1302
+ for (const remotePreset of remotePresets) {
1303
+ const existingLocal = mergedMap.get(remotePreset.baseUrl);
1304
+ if (existingLocal) {
1305
+ mergedMap.set(remotePreset.baseUrl, remotePreset);
1306
+ console.log(`preset ${remotePreset.name} (${remotePreset.baseUrl})\uFF0C\u4F7F\u7528\u4E91\u7AEF\u6570\u636E`);
1307
+ } else {
1308
+ const existingPresets = Array.from(mergedMap.values());
1309
+ const resolvedPreset = resolvePresetNameConflict(existingPresets, remotePreset);
1310
+ mergedMap.set(resolvedPreset.baseUrl, resolvedPreset);
1311
+ }
1312
+ }
1313
+ return Array.from(mergedMap.values());
1314
+ }
1315
+ var init_merge_advanced = __esm({
1316
+ "../core/dist/sync/merge-advanced.js"() {
1317
+ "use strict";
1318
+ }
1319
+ });
1320
+
1321
+ // ../core/dist/sync/merge.js
1322
+ import fs6 from "fs";
1323
+ import path7 from "path";
1324
+ function backupConfig(configPath, keepCount = 3) {
1325
+ if (!fs6.existsSync(configPath)) {
1326
+ throw new Error(`\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728: ${configPath}`);
1327
+ }
1328
+ const timestamp = Date.now();
1329
+ const backupPath = `${configPath}.backup.${timestamp}`;
1330
+ fs6.copyFileSync(configPath, backupPath);
1331
+ cleanupOldBackups(configPath, keepCount);
1332
+ return backupPath;
1333
+ }
1334
+ function cleanupOldBackups(configPath, keepCount) {
1335
+ const dir = path7.dirname(configPath);
1336
+ const basename = path7.basename(configPath);
1337
+ const backupPrefix = `${basename}.backup.`;
1338
+ try {
1339
+ const files = fs6.readdirSync(dir);
1340
+ const backups = files.filter((f) => f.startsWith(backupPrefix)).map((f) => {
1341
+ const timestampStr = f.substring(backupPrefix.length);
1342
+ const timestamp = parseInt(timestampStr, 10);
1343
+ if (isNaN(timestamp)) {
1344
+ return null;
1345
+ }
1346
+ return {
1347
+ name: f,
1348
+ path: path7.join(dir, f),
1349
+ timestamp
1350
+ };
1351
+ }).filter((backup) => backup !== null).sort((a, b) => b.timestamp - a.timestamp);
1352
+ const toDelete = backups.slice(keepCount);
1353
+ for (const backup of toDelete) {
1354
+ try {
1355
+ fs6.unlinkSync(backup.path);
1356
+ } catch (error) {
1357
+ console.warn(`\u65E0\u6CD5\u5220\u9664\u65E7\u5907\u4EFD\u6587\u4EF6 ${backup.name}: ${error.message}`);
1358
+ }
1359
+ }
1360
+ } catch (error) {
1361
+ console.warn(`\u6E05\u7406\u65E7\u5907\u4EFD\u65F6\u51FA\u9519: ${error.message}`);
1362
+ }
1363
+ }
1364
+ var init_merge = __esm({
1365
+ "../core/dist/sync/merge.js"() {
1366
+ "use strict";
1367
+ }
1368
+ });
1369
+
1370
+ // ../core/dist/sync/sync-v2.js
1371
+ import fs7 from "fs";
1372
+ import path8 from "path";
1373
+ async function uploadToCloud(config, password) {
1374
+ const ccmanDir2 = getCcmanDir();
1375
+ const codexConfigPath = path8.join(ccmanDir2, "codex.json");
1376
+ const claudeConfigPath = path8.join(ccmanDir2, "claude.json");
1377
+ const codexConfig = readJSON(codexConfigPath);
1378
+ const claudeConfig = readJSON(claudeConfigPath);
1379
+ const encryptedCodexProviders = encryptProviders(codexConfig.providers, password);
1380
+ const encryptedClaudeProviders = encryptProviders(claudeConfig.providers, password);
1381
+ const encryptedCodexConfig = {
1382
+ ...codexConfig,
1383
+ // 保留所有字段
1384
+ providers: encryptedCodexProviders
1385
+ // 只替换 providers(加密后的)
1386
+ };
1387
+ const encryptedClaudeConfig = {
1388
+ ...claudeConfig,
1389
+ // 保留所有字段
1390
+ providers: encryptedClaudeProviders
1391
+ // 只替换 providers(加密后的)
1392
+ };
1393
+ const codexJson = JSON.stringify(encryptedCodexConfig, null, 2);
1394
+ const claudeJson = JSON.stringify(encryptedClaudeConfig, null, 2);
1395
+ await uploadToWebDAV(config, CODEX_REMOTE_PATH, codexJson);
1396
+ await uploadToWebDAV(config, CLAUDE_REMOTE_PATH, claudeJson);
1397
+ updateLastSyncTime();
1398
+ console.log("\u2705 \u914D\u7F6E\u5DF2\u4E0A\u4F20\u5230\u4E91\u7AEF");
1399
+ }
1400
+ async function downloadFromCloud(config, password) {
1401
+ const codexExists = await existsOnWebDAV(config, CODEX_REMOTE_PATH);
1402
+ const claudeExists = await existsOnWebDAV(config, CLAUDE_REMOTE_PATH);
1403
+ if (!codexExists && !claudeExists) {
1404
+ throw new Error("\u8FDC\u7A0B\u914D\u7F6E\u4E0D\u5B58\u5728\uFF0C\u8BF7\u5148\u4E0A\u4F20\u914D\u7F6E");
1405
+ }
1406
+ const codexJson = codexExists ? await downloadFromWebDAV(config, CODEX_REMOTE_PATH) : null;
1407
+ const claudeJson = claudeExists ? await downloadFromWebDAV(config, CLAUDE_REMOTE_PATH) : null;
1408
+ const remoteCodexConfig = codexJson ? JSON.parse(codexJson) : null;
1409
+ const remoteClaudeConfig = claudeJson ? JSON.parse(claudeJson) : null;
1410
+ let decryptedCodexProviders = null;
1411
+ let decryptedClaudeProviders = null;
1412
+ try {
1413
+ if (remoteCodexConfig) {
1414
+ decryptedCodexProviders = decryptProviders(remoteCodexConfig.providers, password);
1415
+ }
1416
+ if (remoteClaudeConfig) {
1417
+ decryptedClaudeProviders = decryptProviders(remoteClaudeConfig.providers, password);
1418
+ }
1419
+ } catch (error) {
1420
+ throw new Error("\u89E3\u5BC6\u5931\u8D25\uFF1A\u5BC6\u7801\u9519\u8BEF\u6216\u6570\u636E\u635F\u574F");
1421
+ }
1422
+ const backupPaths = [];
1423
+ const ccmanDir2 = getCcmanDir();
1424
+ const codexConfigPath = path8.join(ccmanDir2, "codex.json");
1425
+ const claudeConfigPath = path8.join(ccmanDir2, "claude.json");
1426
+ try {
1427
+ if (fs7.existsSync(codexConfigPath)) {
1428
+ backupPaths.push(backupConfig(codexConfigPath));
1429
+ }
1430
+ if (fs7.existsSync(claudeConfigPath)) {
1431
+ backupPaths.push(backupConfig(claudeConfigPath));
1432
+ }
1433
+ } catch (error) {
1434
+ throw new Error(`\u5907\u4EFD\u5931\u8D25: ${error.message}`);
1435
+ }
1436
+ try {
1437
+ if (remoteCodexConfig && decryptedCodexProviders) {
1438
+ const newCodexConfig = {
1439
+ ...remoteCodexConfig,
1440
+ // 使用云端配置的所有字段
1441
+ providers: decryptedCodexProviders
1442
+ // 只替换 providers(解密后的)
1443
+ };
1444
+ writeJSON(codexConfigPath, newCodexConfig);
1445
+ applyCurrentProvider("codex", newCodexConfig);
1446
+ }
1447
+ if (remoteClaudeConfig && decryptedClaudeProviders) {
1448
+ const newClaudeConfig = {
1449
+ ...remoteClaudeConfig,
1450
+ // 使用云端配置的所有字段
1451
+ providers: decryptedClaudeProviders
1452
+ // 只替换 providers(解密后的)
1453
+ };
1454
+ writeJSON(claudeConfigPath, newClaudeConfig);
1455
+ applyCurrentProvider("claude", newClaudeConfig);
1456
+ }
1457
+ updateLastSyncTime();
1458
+ console.log("\u2705 \u914D\u7F6E\u5DF2\u4ECE\u4E91\u7AEF\u4E0B\u8F7D\u5E76\u5E94\u7528");
1459
+ return backupPaths;
1460
+ } catch (error) {
1461
+ for (const backupPath of backupPaths) {
1462
+ const originalPath = backupPath.replace(/\.backup\.\d+$/, "");
1463
+ if (fs7.existsSync(backupPath)) {
1464
+ fs7.copyFileSync(backupPath, originalPath);
1465
+ }
1466
+ }
1467
+ throw new Error(`\u8986\u76D6\u914D\u7F6E\u5931\u8D25\uFF0C\u5DF2\u6062\u590D\u5907\u4EFD: ${error.message}`);
1468
+ }
1469
+ }
1470
+ async function mergeSync(config, password) {
1471
+ const codexExists = await existsOnWebDAV(config, CODEX_REMOTE_PATH);
1472
+ const claudeExists = await existsOnWebDAV(config, CLAUDE_REMOTE_PATH);
1473
+ if (!codexExists && !claudeExists) {
1474
+ console.log("\u8FDC\u7A0B\u914D\u7F6E\u4E0D\u5B58\u5728\uFF0C\u6267\u884C\u4E0A\u4F20\u64CD\u4F5C");
1475
+ await uploadToCloud(config, password);
1476
+ return {
1477
+ hasChanges: true,
1478
+ backupPaths: []
1479
+ };
1480
+ }
1481
+ const codexJson = codexExists ? await downloadFromWebDAV(config, CODEX_REMOTE_PATH) : null;
1482
+ const claudeJson = claudeExists ? await downloadFromWebDAV(config, CLAUDE_REMOTE_PATH) : null;
1483
+ const remoteCodexConfig = codexJson ? JSON.parse(codexJson) : null;
1484
+ const remoteClaudeConfig = claudeJson ? JSON.parse(claudeJson) : null;
1485
+ let remoteCodexProviders = [];
1486
+ let remoteClaudeProviders = [];
1487
+ try {
1488
+ if (remoteCodexConfig) {
1489
+ remoteCodexProviders = decryptProviders(remoteCodexConfig.providers, password);
1490
+ }
1491
+ if (remoteClaudeConfig) {
1492
+ remoteClaudeProviders = decryptProviders(remoteClaudeConfig.providers, password);
1493
+ }
1494
+ } catch (error) {
1495
+ throw new Error("\u89E3\u5BC6\u5931\u8D25\uFF1A\u5BC6\u7801\u9519\u8BEF\u6216\u6570\u636E\u635F\u574F");
1496
+ }
1497
+ const ccmanDir2 = getCcmanDir();
1498
+ const codexConfigPath = path8.join(ccmanDir2, "codex.json");
1499
+ const claudeConfigPath = path8.join(ccmanDir2, "claude.json");
1500
+ const localCodexConfig = readJSON(codexConfigPath);
1501
+ const localClaudeConfig = readJSON(claudeConfigPath);
1502
+ const codexMergeResult = mergeProviders(localCodexConfig.providers, remoteCodexProviders);
1503
+ const claudeMergeResult = mergeProviders(localClaudeConfig.providers, remoteClaudeProviders);
1504
+ const hasChanges = codexMergeResult.hasChanges || claudeMergeResult.hasChanges;
1505
+ if (!hasChanges) {
1506
+ console.log("\u2139\uFE0F \u914D\u7F6E\u5DF2\u540C\u6B65\uFF0C\u65E0\u9700\u64CD\u4F5C");
1507
+ return {
1508
+ hasChanges: false,
1509
+ backupPaths: []
1510
+ };
1511
+ }
1512
+ const backupPaths = [];
1513
+ try {
1514
+ if (fs7.existsSync(codexConfigPath)) {
1515
+ backupPaths.push(backupConfig(codexConfigPath));
1516
+ }
1517
+ if (fs7.existsSync(claudeConfigPath)) {
1518
+ backupPaths.push(backupConfig(claudeConfigPath));
1519
+ }
1520
+ } catch (error) {
1521
+ throw new Error(`\u5907\u4EFD\u5931\u8D25: ${error.message}`);
1522
+ }
1523
+ const mergedCodexPresets = mergePresets(localCodexConfig.presets, remoteCodexConfig?.presets);
1524
+ const mergedClaudePresets = mergePresets(localClaudeConfig.presets, remoteClaudeConfig?.presets);
1525
+ try {
1526
+ const mergedCodexConfig = {
1527
+ ...localCodexConfig,
1528
+ // 保留本地配置的所有字段
1529
+ providers: codexMergeResult.merged,
1530
+ // 替换为合并后的 providers
1531
+ presets: mergedCodexPresets
1532
+ // 替换为合并后的 presets
1533
+ };
1534
+ const mergedClaudeConfig = {
1535
+ ...localClaudeConfig,
1536
+ // 保留本地配置的所有字段
1537
+ providers: claudeMergeResult.merged,
1538
+ // 替换为合并后的 providers
1539
+ presets: mergedClaudePresets
1540
+ // 替换为合并后的 presets
1541
+ };
1542
+ writeJSON(codexConfigPath, mergedCodexConfig);
1543
+ writeJSON(claudeConfigPath, mergedClaudeConfig);
1544
+ applyCurrentProvider("codex", mergedCodexConfig);
1545
+ applyCurrentProvider("claude", mergedClaudeConfig);
1546
+ const encryptedCodexProviders = encryptProviders(codexMergeResult.merged, password);
1547
+ const encryptedClaudeProviders = encryptProviders(claudeMergeResult.merged, password);
1548
+ const encryptedCodexConfig = {
1549
+ ...mergedCodexConfig,
1550
+ // 保留合并后配置的所有字段
1551
+ providers: encryptedCodexProviders
1552
+ // 只替换 providers(加密后的)
1553
+ };
1554
+ const encryptedClaudeConfig = {
1555
+ ...mergedClaudeConfig,
1556
+ // 保留合并后配置的所有字段
1557
+ providers: encryptedClaudeProviders
1558
+ // 只替换 providers(加密后的)
1559
+ };
1560
+ const codexJson2 = JSON.stringify(encryptedCodexConfig, null, 2);
1561
+ const claudeJson2 = JSON.stringify(encryptedClaudeConfig, null, 2);
1562
+ await uploadToWebDAV(config, CODEX_REMOTE_PATH, codexJson2);
1563
+ await uploadToWebDAV(config, CLAUDE_REMOTE_PATH, claudeJson2);
1564
+ updateLastSyncTime();
1565
+ console.log("\u2705 \u914D\u7F6E\u5DF2\u5408\u5E76\u5E76\u540C\u6B65\u5230\u4E91\u7AEF");
1566
+ return {
1567
+ hasChanges: true,
1568
+ backupPaths
1569
+ };
1570
+ } catch (error) {
1571
+ for (const backupPath of backupPaths) {
1572
+ const originalPath = backupPath.replace(/\.backup\.\d+$/, "");
1573
+ if (fs7.existsSync(backupPath)) {
1574
+ fs7.copyFileSync(backupPath, originalPath);
1575
+ }
1576
+ }
1577
+ throw new Error(`\u5408\u5E76\u914D\u7F6E\u5931\u8D25\uFF0C\u5DF2\u6062\u590D\u5907\u4EFD: ${error.message}`);
1578
+ }
1579
+ }
1580
+ function applyCurrentProvider(tool, config) {
1581
+ if (!config.currentProviderId) {
1582
+ return;
1583
+ }
1584
+ const provider = config.providers.find((p) => p.id === config.currentProviderId);
1585
+ if (!provider) {
1586
+ return;
1587
+ }
1588
+ if (tool === "codex") {
1589
+ writeCodexConfig(provider);
1590
+ } else {
1591
+ writeClaudeConfig(provider);
1592
+ }
1593
+ }
1594
+ var CODEX_REMOTE_PATH, CLAUDE_REMOTE_PATH;
1595
+ var init_sync_v2 = __esm({
1596
+ "../core/dist/sync/sync-v2.js"() {
1597
+ "use strict";
1598
+ init_config();
1599
+ init_webdav_client();
1600
+ init_crypto();
1601
+ init_merge_advanced();
1602
+ init_merge();
1603
+ init_paths();
1604
+ init_file();
1605
+ init_codex();
1606
+ init_claude();
1607
+ CODEX_REMOTE_PATH = ".ccman/codex.json";
1608
+ CLAUDE_REMOTE_PATH = ".ccman/claude.json";
1609
+ }
1610
+ });
1611
+
1612
+ // ../core/dist/export.js
1613
+ import * as fs8 from "fs";
1614
+ import * as path9 from "path";
1615
+ function validateExport() {
1616
+ const ccmanDir2 = getCcmanDir();
1617
+ const codexPath = path9.join(ccmanDir2, CODEX_CONFIG_FILE);
1618
+ const claudePath = path9.join(ccmanDir2, CLAUDE_CONFIG_FILE);
1619
+ const missingFiles = [];
1620
+ if (!fileExists(codexPath)) {
1621
+ missingFiles.push(CODEX_CONFIG_FILE);
1622
+ }
1623
+ if (!fileExists(claudePath)) {
1624
+ missingFiles.push(CLAUDE_CONFIG_FILE);
1625
+ }
1626
+ if (missingFiles.length > 0) {
1627
+ return {
1628
+ valid: false,
1629
+ message: `\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728: ${missingFiles.join(", ")}`,
1630
+ missingFiles
1631
+ };
1632
+ }
1633
+ return { valid: true };
1634
+ }
1635
+ function validateImportDir(sourceDir) {
1636
+ if (!fileExists(sourceDir)) {
1637
+ return {
1638
+ valid: false,
1639
+ message: `\u76EE\u5F55\u4E0D\u5B58\u5728: ${sourceDir}`,
1640
+ foundFiles: []
1641
+ };
1642
+ }
1643
+ const stats = fs8.statSync(sourceDir);
1644
+ if (!stats.isDirectory()) {
1645
+ return {
1646
+ valid: false,
1647
+ message: `\u4E0D\u662F\u6709\u6548\u7684\u76EE\u5F55: ${sourceDir}`,
1648
+ foundFiles: []
1649
+ };
1650
+ }
1651
+ const codexPath = path9.join(sourceDir, CODEX_CONFIG_FILE);
1652
+ const claudePath = path9.join(sourceDir, CLAUDE_CONFIG_FILE);
1653
+ const foundFiles = [];
1654
+ if (fileExists(codexPath)) {
1655
+ foundFiles.push(CODEX_CONFIG_FILE);
1656
+ }
1657
+ if (fileExists(claudePath)) {
1658
+ foundFiles.push(CLAUDE_CONFIG_FILE);
1659
+ }
1660
+ if (foundFiles.length === 0) {
1661
+ return {
1662
+ valid: false,
1663
+ message: `\u672A\u627E\u5230\u914D\u7F6E\u6587\u4EF6 (${CODEX_CONFIG_FILE} \u6216 ${CLAUDE_CONFIG_FILE})`,
1664
+ foundFiles: []
1665
+ };
1666
+ }
1667
+ return {
1668
+ valid: true,
1669
+ foundFiles
1670
+ };
1671
+ }
1672
+ function exportConfig(targetDir) {
1673
+ const validation = validateExport();
1674
+ if (!validation.valid) {
1675
+ throw new Error(validation.message);
1676
+ }
1677
+ ensureDir(targetDir);
1678
+ const ccmanDir2 = getCcmanDir();
1679
+ const exportedFiles = [];
1680
+ const codexSrc = path9.join(ccmanDir2, CODEX_CONFIG_FILE);
1681
+ const codexDst = path9.join(targetDir, CODEX_CONFIG_FILE);
1682
+ if (fileExists(codexSrc)) {
1683
+ fs8.copyFileSync(codexSrc, codexDst);
1684
+ exportedFiles.push(CODEX_CONFIG_FILE);
1685
+ }
1686
+ const claudeSrc = path9.join(ccmanDir2, CLAUDE_CONFIG_FILE);
1687
+ const claudeDst = path9.join(targetDir, CLAUDE_CONFIG_FILE);
1688
+ if (fileExists(claudeSrc)) {
1689
+ fs8.copyFileSync(claudeSrc, claudeDst);
1690
+ exportedFiles.push(CLAUDE_CONFIG_FILE);
1691
+ }
1692
+ return {
1693
+ success: true,
1694
+ targetDir,
1695
+ exportedFiles
1696
+ };
1697
+ }
1698
+ function importConfig(sourceDir) {
1699
+ const validation = validateImportDir(sourceDir);
1700
+ if (!validation.valid) {
1701
+ throw new Error(validation.message);
1702
+ }
1703
+ const ccmanDir2 = getCcmanDir();
1704
+ const backupPaths = [];
1705
+ const importedFiles = [];
1706
+ ensureDir(ccmanDir2);
1707
+ try {
1708
+ if (validation.foundFiles.includes(CODEX_CONFIG_FILE)) {
1709
+ const codexDst = path9.join(ccmanDir2, CODEX_CONFIG_FILE);
1710
+ if (fileExists(codexDst)) {
1711
+ const backupPath = backupConfig(codexDst);
1712
+ backupPaths.push(backupPath);
1713
+ }
1714
+ const codexSrc = path9.join(sourceDir, CODEX_CONFIG_FILE);
1715
+ fs8.copyFileSync(codexSrc, codexDst);
1716
+ importedFiles.push(CODEX_CONFIG_FILE);
1717
+ }
1718
+ if (validation.foundFiles.includes(CLAUDE_CONFIG_FILE)) {
1719
+ const claudeDst = path9.join(ccmanDir2, CLAUDE_CONFIG_FILE);
1720
+ if (fileExists(claudeDst)) {
1721
+ const backupPath = backupConfig(claudeDst);
1722
+ backupPaths.push(backupPath);
1723
+ }
1724
+ const claudeSrc = path9.join(sourceDir, CLAUDE_CONFIG_FILE);
1725
+ fs8.copyFileSync(claudeSrc, claudeDst);
1726
+ importedFiles.push(CLAUDE_CONFIG_FILE);
1727
+ }
1728
+ return {
1729
+ success: true,
1730
+ backupPaths,
1731
+ importedFiles
1732
+ };
1733
+ } catch (error) {
1734
+ for (const backupPath of backupPaths) {
1735
+ const originalPath = backupPath.replace(/\.backup\.\d+$/, "");
1736
+ if (fileExists(backupPath)) {
1737
+ fs8.copyFileSync(backupPath, originalPath);
1738
+ }
1739
+ }
1740
+ throw new Error(`\u5BFC\u5165\u5931\u8D25\uFF0C\u5DF2\u6062\u590D\u5907\u4EFD: ${error.message}`);
1741
+ }
1742
+ }
1743
+ var CODEX_CONFIG_FILE, CLAUDE_CONFIG_FILE;
1744
+ var init_export = __esm({
1745
+ "../core/dist/export.js"() {
1746
+ "use strict";
1747
+ init_paths();
1748
+ init_file();
1749
+ init_merge();
1750
+ CODEX_CONFIG_FILE = "codex.json";
1751
+ CLAUDE_CONFIG_FILE = "claude.json";
1752
+ }
1753
+ });
1754
+
1755
+ // ../core/dist/claude-clean.js
1756
+ import * as fs9 from "fs";
1757
+ function formatBytes(bytes) {
1758
+ if (bytes < 1024)
1759
+ return `${bytes} B`;
1760
+ if (bytes < 1024 * 1024)
1761
+ return `${(bytes / 1024).toFixed(1)} KB`;
1762
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
1763
+ }
1764
+ function getFileSize(filePath) {
1765
+ try {
1766
+ const stats = fs9.statSync(filePath);
1767
+ return stats.size;
1768
+ } catch {
1769
+ return 0;
1770
+ }
1771
+ }
1772
+ function backupFile(filePath) {
1773
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/:/g, "-").split(".")[0];
1774
+ const backupPath = `${filePath}.backup-${timestamp}`;
1775
+ fs9.copyFileSync(filePath, backupPath);
1776
+ return backupPath;
1777
+ }
1778
+ function saveJsonAtomic(filePath, data) {
1779
+ const tempPath = `${filePath}.tmp`;
1780
+ const content = JSON.stringify(data, null, 2);
1781
+ fs9.writeFileSync(tempPath, content, { mode: 384 });
1782
+ fs9.renameSync(tempPath, filePath);
1783
+ }
1784
+ function analyzeClaudeJson() {
1785
+ const filePath = getClaudeJsonPath();
1786
+ if (!fs9.existsSync(filePath)) {
1787
+ throw new Error("~/.claude.json \u6587\u4EF6\u4E0D\u5B58\u5728");
1788
+ }
1789
+ const fileSize = getFileSize(filePath);
1790
+ const content = fs9.readFileSync(filePath, "utf-8");
1791
+ const config = JSON.parse(content);
1792
+ const projects = config.projects || {};
1793
+ const projectHistory = [];
1794
+ let totalHistoryCount = 0;
1795
+ for (const [projectPath, projectData] of Object.entries(projects)) {
1796
+ const historyCount = projectData.history?.length || 0;
1797
+ totalHistoryCount += historyCount;
1798
+ projectHistory.push({
1799
+ path: projectPath,
1800
+ count: historyCount
1801
+ });
1802
+ }
1803
+ projectHistory.sort((a, b) => b.count - a.count);
1804
+ const cacheSize = config.cachedChangelog?.length || 0;
1805
+ const historySize = fileSize - cacheSize - 2e4;
1806
+ const avgHistorySize = totalHistoryCount > 0 ? historySize / totalHistoryCount : 0;
1807
+ const estimatedSavings = {
1808
+ conservative: Math.floor(avgHistorySize * Math.max(0, totalHistoryCount - projectHistory.length * 10)) + cacheSize,
1809
+ moderate: Math.floor(avgHistorySize * Math.max(0, totalHistoryCount - projectHistory.length * 5)) + cacheSize,
1810
+ aggressive: Math.floor(historySize) + cacheSize
1811
+ };
1812
+ return {
1813
+ fileSize,
1814
+ fileSizeFormatted: formatBytes(fileSize),
1815
+ projectCount: projectHistory.length,
1816
+ totalHistoryCount,
1817
+ projectHistory,
1818
+ cacheSize,
1819
+ estimatedSavings
1820
+ };
1821
+ }
1822
+ function cleanClaudeJson(options = {}) {
1823
+ const filePath = getClaudeJsonPath();
1824
+ if (!fs9.existsSync(filePath)) {
1825
+ throw new Error("~/.claude.json \u6587\u4EF6\u4E0D\u5B58\u5728");
1826
+ }
1827
+ const backupPath = backupFile(filePath);
1828
+ const sizeBefore = getFileSize(filePath);
1829
+ const content = fs9.readFileSync(filePath, "utf-8");
1830
+ const config = JSON.parse(content);
1831
+ const cleanedItems = applyCleanOptions(config, options);
1832
+ saveJsonAtomic(filePath, config);
1833
+ const sizeAfter = getFileSize(filePath);
1834
+ return {
1835
+ sizeBefore,
1836
+ sizeAfter,
1837
+ saved: sizeBefore - sizeAfter,
1838
+ cleanedItems,
1839
+ backupPath
1840
+ };
1841
+ }
1842
+ function applyCleanOptions(config, options) {
1843
+ let projectHistoryCount = 0;
1844
+ if (options.cleanProjectHistory && config.projects) {
1845
+ const keepCount = options.keepRecentCount ?? 10;
1846
+ const targetProjects = options.projectPaths || [];
1847
+ for (const [projectPath, projectData] of Object.entries(config.projects)) {
1848
+ if (targetProjects.length > 0 && !targetProjects.includes(projectPath)) {
1849
+ continue;
1850
+ }
1851
+ if (projectData.history && Array.isArray(projectData.history)) {
1852
+ const originalCount = projectData.history.length;
1853
+ projectData.history = projectData.history.slice(-keepCount);
1854
+ projectHistoryCount += originalCount - projectData.history.length;
1855
+ }
1856
+ }
1857
+ }
1858
+ if (options.cleanCache) {
1859
+ delete config.cachedChangelog;
1860
+ config.changelogLastFetched = 0;
1861
+ }
1862
+ if (options.cleanStats) {
1863
+ config.numStartups = 0;
1864
+ config.promptQueueUseCount = 0;
1865
+ config.tipsHistory = {};
1866
+ }
1867
+ return {
1868
+ projectHistory: projectHistoryCount,
1869
+ cache: options.cleanCache || false,
1870
+ stats: options.cleanStats || false
1871
+ };
1872
+ }
1873
+ var CleanPresets;
1874
+ var init_claude_clean = __esm({
1875
+ "../core/dist/claude-clean.js"() {
1876
+ "use strict";
1877
+ init_paths();
1878
+ CleanPresets = {
1879
+ /** 保守清理:保留最近10条记录,清理缓存 */
1880
+ conservative: () => ({
1881
+ cleanProjectHistory: true,
1882
+ keepRecentCount: 10,
1883
+ cleanCache: true,
1884
+ cleanStats: false
1885
+ }),
1886
+ /** 中等清理:保留最近5条记录,清理缓存和统计 */
1887
+ moderate: () => ({
1888
+ cleanProjectHistory: true,
1889
+ keepRecentCount: 5,
1890
+ cleanCache: true,
1891
+ cleanStats: true
1892
+ }),
1893
+ /** 激进清理:清空历史记录,清理缓存和统计 */
1894
+ aggressive: () => ({
1895
+ cleanProjectHistory: true,
1896
+ keepRecentCount: 0,
1897
+ cleanCache: true,
1898
+ cleanStats: true
1899
+ })
1900
+ };
1901
+ }
1902
+ });
1903
+
1904
+ // ../core/dist/index.js
1905
+ var VERSION;
1906
+ var init_dist = __esm({
1907
+ "../core/dist/index.js"() {
1908
+ "use strict";
1909
+ init_package();
1910
+ init_tool_manager();
1911
+ init_codex2();
1912
+ init_claude2();
1913
+ init_mcp2();
1914
+ init_mcp();
1915
+ init_migrate();
1916
+ init_paths();
1917
+ init_config();
1918
+ init_webdav_client();
1919
+ init_sync_v2();
1920
+ init_crypto();
1921
+ init_merge_advanced();
1922
+ init_export();
1923
+ init_claude_clean();
1924
+ VERSION = package_default.version;
1925
+ }
1926
+ });
1927
+
12
1928
  // src/utils/sync-config.ts
13
- import { getSyncConfig, saveSyncConfig as coreSaveSyncConfig, getConfigPath } from "@ccman/core";
14
1929
  function loadSyncConfig() {
15
1930
  try {
16
1931
  const config = getSyncConfig();
@@ -22,13 +1937,13 @@ function loadSyncConfig() {
22
1937
  throw new Error(`\u8BFB\u53D6\u540C\u6B65\u914D\u7F6E\u5931\u8D25: ${error.message}`);
23
1938
  }
24
1939
  }
25
- function saveSyncConfig(config) {
1940
+ function saveSyncConfig2(config) {
26
1941
  try {
27
1942
  const configToSave = { ...config };
28
1943
  if (!configToSave.rememberSyncPassword) {
29
1944
  delete configToSave.syncPassword;
30
1945
  }
31
- coreSaveSyncConfig(configToSave);
1946
+ saveSyncConfig(configToSave);
32
1947
  } catch (error) {
33
1948
  throw new Error(`\u4FDD\u5B58\u540C\u6B65\u914D\u7F6E\u5931\u8D25: ${error.message}`);
34
1949
  }
@@ -39,6 +1954,7 @@ function getSyncConfigPath() {
39
1954
  var init_sync_config = __esm({
40
1955
  "src/utils/sync-config.ts"() {
41
1956
  "use strict";
1957
+ init_dist();
42
1958
  }
43
1959
  });
44
1960
 
@@ -49,7 +1965,6 @@ __export(config_exports, {
49
1965
  });
50
1966
  import chalk3 from "chalk";
51
1967
  import inquirer from "inquirer";
52
- import { testWebDAVConnection } from "@ccman/core";
53
1968
  function configCommand(program2) {
54
1969
  program2.command("config").description("\u914D\u7F6E WebDAV \u8FDE\u63A5").action(async () => {
55
1970
  try {
@@ -201,7 +2116,7 @@ function configCommand(program2) {
201
2116
  console.log();
202
2117
  return;
203
2118
  }
204
- saveSyncConfig(newConfig);
2119
+ saveSyncConfig2(newConfig);
205
2120
  console.log();
206
2121
  console.log(chalk3.green("\u2705 \u914D\u7F6E\u4FDD\u5B58\u6210\u529F"));
207
2122
  console.log();
@@ -243,10 +2158,11 @@ function configCommand(program2) {
243
2158
  }
244
2159
  });
245
2160
  }
246
- var init_config = __esm({
2161
+ var init_config2 = __esm({
247
2162
  "src/commands/sync/config.ts"() {
248
2163
  "use strict";
249
2164
  init_sync_config();
2165
+ init_dist();
250
2166
  }
251
2167
  });
252
2168
 
@@ -271,7 +2187,7 @@ async function ensureConfigExists() {
271
2187
  if (!shouldConfig) {
272
2188
  return null;
273
2189
  }
274
- const { configCommand: configCommand2 } = await Promise.resolve().then(() => (init_config(), config_exports));
2190
+ const { configCommand: configCommand2 } = await Promise.resolve().then(() => (init_config2(), config_exports));
275
2191
  const cmd = new Command();
276
2192
  configCommand2(cmd);
277
2193
  await cmd.parseAsync(["node", "ccman", "config"]);
@@ -290,7 +2206,6 @@ __export(test_exports, {
290
2206
  testCommand: () => testCommand
291
2207
  });
292
2208
  import chalk5 from "chalk";
293
- import { testWebDAVConnection as testWebDAVConnection2 } from "@ccman/core";
294
2209
  function testCommand(program2) {
295
2210
  program2.command("test").description("\u6D4B\u8BD5 WebDAV \u8FDE\u63A5").action(async () => {
296
2211
  try {
@@ -300,7 +2215,7 @@ function testCommand(program2) {
300
2215
  return;
301
2216
  }
302
2217
  console.log(chalk5.bold("\n\u{1F50D} \u6D4B\u8BD5 WebDAV \u8FDE\u63A5...\n"));
303
- const success = await testWebDAVConnection2(config);
2218
+ const success = await testWebDAVConnection(config);
304
2219
  if (success) {
305
2220
  console.log(chalk5.green("\u2705 \u8FDE\u63A5\u6210\u529F"));
306
2221
  console.log();
@@ -328,6 +2243,7 @@ function testCommand(program2) {
328
2243
  var init_test = __esm({
329
2244
  "src/commands/sync/test.ts"() {
330
2245
  "use strict";
2246
+ init_dist();
331
2247
  init_helpers();
332
2248
  }
333
2249
  });
@@ -339,7 +2255,6 @@ __export(upload_exports, {
339
2255
  });
340
2256
  import chalk6 from "chalk";
341
2257
  import inquirer3 from "inquirer";
342
- import { uploadToCloud, createCodexManager, createClaudeManager } from "@ccman/core";
343
2258
  function uploadCommand(program2) {
344
2259
  program2.command("upload").description("\u4E0A\u4F20\u672C\u5730\u914D\u7F6E\u5230\u4E91\u7AEF").action(async () => {
345
2260
  try {
@@ -406,6 +2321,7 @@ function uploadCommand(program2) {
406
2321
  var init_upload = __esm({
407
2322
  "src/commands/sync/upload.ts"() {
408
2323
  "use strict";
2324
+ init_dist();
409
2325
  init_helpers();
410
2326
  }
411
2327
  });
@@ -417,7 +2333,6 @@ __export(download_exports, {
417
2333
  });
418
2334
  import chalk7 from "chalk";
419
2335
  import inquirer4 from "inquirer";
420
- import { downloadFromCloud } from "@ccman/core";
421
2336
  function downloadCommand(program2) {
422
2337
  program2.command("download").description("\u4ECE\u4E91\u7AEF\u4E0B\u8F7D\u914D\u7F6E\u5230\u672C\u5730").action(async () => {
423
2338
  try {
@@ -464,8 +2379,8 @@ function downloadCommand(program2) {
464
2379
  console.log();
465
2380
  if (backupPaths.length > 0) {
466
2381
  console.log(chalk7.gray("\u672C\u5730\u5907\u4EFD:"));
467
- backupPaths.forEach((path3) => {
468
- console.log(chalk7.gray(` ${path3}`));
2382
+ backupPaths.forEach((path12) => {
2383
+ console.log(chalk7.gray(` ${path12}`));
469
2384
  });
470
2385
  console.log();
471
2386
  }
@@ -480,6 +2395,7 @@ function downloadCommand(program2) {
480
2395
  var init_download = __esm({
481
2396
  "src/commands/sync/download.ts"() {
482
2397
  "use strict";
2398
+ init_dist();
483
2399
  init_helpers();
484
2400
  }
485
2401
  });
@@ -491,7 +2407,6 @@ __export(merge_exports, {
491
2407
  });
492
2408
  import chalk8 from "chalk";
493
2409
  import inquirer5 from "inquirer";
494
- import { mergeSync } from "@ccman/core";
495
2410
  function mergeCommand(program2) {
496
2411
  program2.command("merge").description("\u667A\u80FD\u5408\u5E76\u672C\u5730\u548C\u4E91\u7AEF\u914D\u7F6E").action(async () => {
497
2412
  try {
@@ -526,8 +2441,8 @@ function mergeCommand(program2) {
526
2441
  console.log();
527
2442
  if (result.backupPaths.length > 0) {
528
2443
  console.log(chalk8.gray("\u5907\u4EFD:"));
529
- result.backupPaths.forEach((path3) => {
530
- console.log(chalk8.gray(` ${path3}`));
2444
+ result.backupPaths.forEach((path12) => {
2445
+ console.log(chalk8.gray(` ${path12}`));
531
2446
  });
532
2447
  console.log();
533
2448
  }
@@ -543,9 +2458,10 @@ function mergeCommand(program2) {
543
2458
  }
544
2459
  });
545
2460
  }
546
- var init_merge = __esm({
2461
+ var init_merge2 = __esm({
547
2462
  "src/commands/sync/merge.ts"() {
548
2463
  "use strict";
2464
+ init_dist();
549
2465
  init_helpers();
550
2466
  }
551
2467
  });
@@ -556,7 +2472,6 @@ __export(status_exports, {
556
2472
  statusCommand: () => statusCommand
557
2473
  });
558
2474
  import chalk9 from "chalk";
559
- import { createCodexManager as createCodexManager2, createClaudeManager as createClaudeManager2 } from "@ccman/core";
560
2475
  function statusCommand(program2) {
561
2476
  program2.command("status").description("\u67E5\u770B\u540C\u6B65\u72B6\u6001").action(async () => {
562
2477
  try {
@@ -575,8 +2490,8 @@ function statusCommand(program2) {
575
2490
  console.log(` \u8BA4\u8BC1: ${chalk9.gray(config.authType === "password" ? "Basic Auth" : "Digest Auth")}`);
576
2491
  console.log(` \u540C\u6B65\u5BC6\u7801: ${config.syncPassword ? chalk9.green("\u2713 \u5DF2\u4FDD\u5B58") : chalk9.yellow("\u2717 \u672A\u4FDD\u5B58")}`);
577
2492
  console.log();
578
- const codexManager = createCodexManager2();
579
- const claudeManager = createClaudeManager2();
2493
+ const codexManager = createCodexManager();
2494
+ const claudeManager = createClaudeManager();
580
2495
  const codexProviders = codexManager.list();
581
2496
  const claudeProviders = claudeManager.list();
582
2497
  console.log(chalk9.bold("\u672C\u5730\u914D\u7F6E:"));
@@ -602,6 +2517,7 @@ function statusCommand(program2) {
602
2517
  var init_status = __esm({
603
2518
  "src/commands/sync/status.ts"() {
604
2519
  "use strict";
2520
+ init_dist();
605
2521
  init_sync_config();
606
2522
  }
607
2523
  });
@@ -648,7 +2564,7 @@ async function startSyncMenu() {
648
2564
  try {
649
2565
  switch (action) {
650
2566
  case "config": {
651
- const { configCommand: configCommand2 } = await Promise.resolve().then(() => (init_config(), config_exports));
2567
+ const { configCommand: configCommand2 } = await Promise.resolve().then(() => (init_config2(), config_exports));
652
2568
  const cmd = new Command2();
653
2569
  configCommand2(cmd);
654
2570
  await cmd.parseAsync(["node", "ccman", "config"]);
@@ -676,7 +2592,7 @@ async function startSyncMenu() {
676
2592
  break;
677
2593
  }
678
2594
  case "merge": {
679
- const { mergeCommand: mergeCommand2 } = await Promise.resolve().then(() => (init_merge(), merge_exports));
2595
+ const { mergeCommand: mergeCommand2 } = await Promise.resolve().then(() => (init_merge2(), merge_exports));
680
2596
  const cmd = new Command2();
681
2597
  mergeCommand2(cmd);
682
2598
  await cmd.parseAsync(["node", "ccman", "merge"]);
@@ -707,11 +2623,11 @@ async function startSyncMenu() {
707
2623
  var init_sync = __esm({
708
2624
  "src/commands/sync/index.ts"() {
709
2625
  "use strict";
710
- init_config();
2626
+ init_config2();
711
2627
  init_test();
712
2628
  init_upload();
713
2629
  init_download();
714
- init_merge();
2630
+ init_merge2();
715
2631
  init_status();
716
2632
  }
717
2633
  });
@@ -721,8 +2637,8 @@ import { Command as Command3 } from "commander";
721
2637
  import chalk33 from "chalk";
722
2638
 
723
2639
  // src/utils/logo.ts
2640
+ init_dist();
724
2641
  import chalk from "chalk";
725
- import { VERSION } from "@ccman/core";
726
2642
  function printLogo() {
727
2643
  console.log(
728
2644
  chalk.bold(
@@ -742,19 +2658,14 @@ function printLogo() {
742
2658
  }
743
2659
 
744
2660
  // src/commands/codex/add.ts
2661
+ init_dist();
745
2662
  import chalk12 from "chalk";
746
2663
  import inquirer8 from "inquirer";
747
- import {
748
- createCodexManager as createCodexManager4,
749
- CODEX_PRESETS,
750
- getCodexConfigPath,
751
- getCodexAuthPath
752
- } from "@ccman/core";
753
2664
 
754
2665
  // src/interactive.ts
2666
+ init_dist();
755
2667
  import inquirer7 from "inquirer";
756
2668
  import chalk11 from "chalk";
757
- import { createCodexManager as createCodexManager3, createClaudeManager as createClaudeManager3 } from "@ccman/core";
758
2669
 
759
2670
  // src/utils/format.ts
760
2671
  import chalk2 from "chalk";
@@ -938,7 +2849,7 @@ async function showPresetsMenu() {
938
2849
  console.log(chalk11.yellow("\n\u26A0\uFE0F \u9884\u7F6E\u670D\u52A1\u5546\u7BA1\u7406\u529F\u80FD\u5373\u5C06\u63A8\u51FA\n"));
939
2850
  }
940
2851
  async function handleAdd(tool) {
941
- const manager = tool === "codex" ? createCodexManager3() : createClaudeManager3();
2852
+ const manager = tool === "codex" ? createCodexManager() : createClaudeManager();
942
2853
  const toolName = tool === "claude" ? "Claude" : "Codex";
943
2854
  const presets = manager.listPresets();
944
2855
  console.log(chalk11.bold(`
@@ -1044,7 +2955,7 @@ async function handleAdd(tool) {
1044
2955
  }
1045
2956
  }
1046
2957
  async function handleSwitch(tool) {
1047
- const manager = tool === "codex" ? createCodexManager3() : createClaudeManager3();
2958
+ const manager = tool === "codex" ? createCodexManager() : createClaudeManager();
1048
2959
  const providers = manager.list();
1049
2960
  const current = manager.getCurrent();
1050
2961
  if (providers.length === 0) {
@@ -1069,7 +2980,7 @@ async function handleSwitch(tool) {
1069
2980
  `));
1070
2981
  }
1071
2982
  async function handleList(tool) {
1072
- const manager = tool === "codex" ? createCodexManager3() : createClaudeManager3();
2983
+ const manager = tool === "codex" ? createCodexManager() : createClaudeManager();
1073
2984
  const providers = manager.list();
1074
2985
  const current = manager.getCurrent();
1075
2986
  const toolName = tool === "claude" ? "Claude" : "Codex";
@@ -1084,7 +2995,7 @@ async function handleList(tool) {
1084
2995
  console.log(formatProviderTable(providers, current?.id));
1085
2996
  }
1086
2997
  async function handleCurrent(tool) {
1087
- const manager = tool === "codex" ? createCodexManager3() : createClaudeManager3();
2998
+ const manager = tool === "codex" ? createCodexManager() : createClaudeManager();
1088
2999
  const current = manager.getCurrent();
1089
3000
  const toolName = tool === "claude" ? "Claude" : "Codex";
1090
3001
  if (!current) {
@@ -1105,7 +3016,7 @@ async function handleCurrent(tool) {
1105
3016
  console.log();
1106
3017
  }
1107
3018
  async function handleEdit(tool) {
1108
- const manager = tool === "codex" ? createCodexManager3() : createClaudeManager3();
3019
+ const manager = tool === "codex" ? createCodexManager() : createClaudeManager();
1109
3020
  const providers = manager.list();
1110
3021
  if (providers.length === 0) {
1111
3022
  console.log(chalk11.yellow("\n\u26A0\uFE0F \u6682\u65E0\u670D\u52A1\u5546\n"));
@@ -1166,7 +3077,7 @@ async function handleEdit(tool) {
1166
3077
  console.log(chalk11.green("\n\u2705 \u7F16\u8F91\u6210\u529F\n"));
1167
3078
  }
1168
3079
  async function handleClone(tool) {
1169
- const manager = tool === "codex" ? createCodexManager3() : createClaudeManager3();
3080
+ const manager = tool === "codex" ? createCodexManager() : createClaudeManager();
1170
3081
  const providers = manager.list();
1171
3082
  if (providers.length === 0) {
1172
3083
  console.log(chalk11.yellow("\n\u26A0\uFE0F \u6682\u65E0\u670D\u52A1\u5546\n"));
@@ -1213,7 +3124,7 @@ async function handleClone(tool) {
1213
3124
  console.log();
1214
3125
  }
1215
3126
  async function handleRemove(tool) {
1216
- const manager = tool === "codex" ? createCodexManager3() : createClaudeManager3();
3127
+ const manager = tool === "codex" ? createCodexManager() : createClaudeManager();
1217
3128
  const providers = manager.list();
1218
3129
  if (providers.length === 0) {
1219
3130
  console.log(chalk11.yellow("\n\u26A0\uFE0F \u6682\u65E0\u670D\u52A1\u5546\n"));
@@ -1253,7 +3164,7 @@ async function handleRemove(tool) {
1253
3164
  function addCommand(program2) {
1254
3165
  program2.command("add").description("\u6DFB\u52A0\u65B0\u7684 Codex \u670D\u52A1\u5546(\u4EA4\u4E92\u5F0F)").action(async () => {
1255
3166
  try {
1256
- const manager = createCodexManager4();
3167
+ const manager = createCodexManager();
1257
3168
  console.log(chalk12.bold("\n\u{1F4DD} \u6DFB\u52A0 Codex \u670D\u52A1\u5546\n"));
1258
3169
  const { usePreset } = await inquirer8.prompt([
1259
3170
  {
@@ -1370,12 +3281,12 @@ function addCommand(program2) {
1370
3281
  }
1371
3282
 
1372
3283
  // src/commands/codex/list.ts
3284
+ init_dist();
1373
3285
  import chalk13 from "chalk";
1374
- import { createCodexManager as createCodexManager5 } from "@ccman/core";
1375
3286
  function listCommand(program2) {
1376
3287
  program2.command("list").alias("ls").description("\u5217\u51FA\u6240\u6709 Codex \u670D\u52A1\u5546").action(async () => {
1377
3288
  try {
1378
- const manager = createCodexManager5();
3289
+ const manager = createCodexManager();
1379
3290
  const providers = manager.list();
1380
3291
  const current = manager.getCurrent();
1381
3292
  if (providers.length === 0) {
@@ -1396,18 +3307,13 @@ function listCommand(program2) {
1396
3307
  }
1397
3308
 
1398
3309
  // src/commands/codex/use.ts
3310
+ init_dist();
1399
3311
  import chalk14 from "chalk";
1400
3312
  import inquirer9 from "inquirer";
1401
- import {
1402
- createCodexManager as createCodexManager6,
1403
- ProviderNotFoundError,
1404
- getCodexConfigPath as getCodexConfigPath2,
1405
- getCodexAuthPath as getCodexAuthPath2
1406
- } from "@ccman/core";
1407
3313
  function useCommand(program2) {
1408
3314
  program2.command("use [name]").description("\u5207\u6362 Codex \u670D\u52A1\u5546").action(async (name) => {
1409
3315
  try {
1410
- const manager = createCodexManager6();
3316
+ const manager = createCodexManager();
1411
3317
  const providers = manager.list();
1412
3318
  if (providers.length === 0) {
1413
3319
  console.log(chalk14.yellow("\n\u26A0\uFE0F \u6682\u65E0 Codex \u670D\u52A1\u5546\n"));
@@ -1444,8 +3350,8 @@ function useCommand(program2) {
1444
3350
  console.log(` ${chalk14.gray(`URL: ${provider.baseUrl}`)}`);
1445
3351
  console.log();
1446
3352
  console.log(chalk14.gray("\u914D\u7F6E\u5DF2\u66F4\u65B0:"));
1447
- console.log(chalk14.gray(` - ${getCodexConfigPath2()}`));
1448
- console.log(chalk14.gray(` - ${getCodexAuthPath2()}`));
3353
+ console.log(chalk14.gray(` - ${getCodexConfigPath()}`));
3354
+ console.log(chalk14.gray(` - ${getCodexAuthPath()}`));
1449
3355
  console.log();
1450
3356
  } catch (error) {
1451
3357
  if (error instanceof ProviderNotFoundError) {
@@ -1464,12 +3370,12 @@ function useCommand(program2) {
1464
3370
  }
1465
3371
 
1466
3372
  // src/commands/codex/current.ts
3373
+ init_dist();
1467
3374
  import chalk15 from "chalk";
1468
- import { createCodexManager as createCodexManager7 } from "@ccman/core";
1469
3375
  function currentCommand(program2) {
1470
3376
  program2.command("current").description("\u663E\u793A\u5F53\u524D\u4F7F\u7528\u7684 Codex \u670D\u52A1\u5546").action(async () => {
1471
3377
  try {
1472
- const manager = createCodexManager7();
3378
+ const manager = createCodexManager();
1473
3379
  const current = manager.getCurrent();
1474
3380
  if (!current) {
1475
3381
  console.log(chalk15.yellow("\n\u26A0\uFE0F \u672A\u9009\u62E9\u4EFB\u4F55 Codex \u670D\u52A1\u5546\n"));
@@ -1495,13 +3401,13 @@ function currentCommand(program2) {
1495
3401
  }
1496
3402
 
1497
3403
  // src/commands/codex/remove.ts
3404
+ init_dist();
1498
3405
  import chalk16 from "chalk";
1499
3406
  import inquirer10 from "inquirer";
1500
- import { createCodexManager as createCodexManager8, ProviderNotFoundError as ProviderNotFoundError2 } from "@ccman/core";
1501
3407
  function removeCommand(program2) {
1502
3408
  program2.command("remove [name]").alias("rm").description("\u5220\u9664 Codex \u670D\u52A1\u5546").action(async (name) => {
1503
3409
  try {
1504
- const manager = createCodexManager8();
3410
+ const manager = createCodexManager();
1505
3411
  const providers = manager.list();
1506
3412
  if (providers.length === 0) {
1507
3413
  console.log(chalk16.yellow("\n\u26A0\uFE0F \u6682\u65E0 Codex \u670D\u52A1\u5546\n"));
@@ -1512,7 +3418,7 @@ function removeCommand(program2) {
1512
3418
  if (name) {
1513
3419
  const provider = manager.findByName(name);
1514
3420
  if (!provider) {
1515
- throw new ProviderNotFoundError2(name);
3421
+ throw new ProviderNotFoundError(name);
1516
3422
  }
1517
3423
  targetId = provider.id;
1518
3424
  targetName = provider.name;
@@ -1549,7 +3455,7 @@ function removeCommand(program2) {
1549
3455
  console.log(chalk16.green(`\u2705 \u5DF2\u5220\u9664: ${targetName}`));
1550
3456
  console.log();
1551
3457
  } catch (error) {
1552
- if (error instanceof ProviderNotFoundError2) {
3458
+ if (error instanceof ProviderNotFoundError) {
1553
3459
  console.error(chalk16.red(`
1554
3460
  \u274C \u670D\u52A1\u5546\u4E0D\u5B58\u5728
1555
3461
  `));
@@ -1565,13 +3471,13 @@ function removeCommand(program2) {
1565
3471
  }
1566
3472
 
1567
3473
  // src/commands/codex/edit.ts
3474
+ init_dist();
1568
3475
  import chalk17 from "chalk";
1569
3476
  import inquirer11 from "inquirer";
1570
- import { createCodexManager as createCodexManager9, ProviderNotFoundError as ProviderNotFoundError3 } from "@ccman/core";
1571
3477
  function editCommand(program2) {
1572
3478
  program2.command("edit [name]").description("\u7F16\u8F91 Codex \u670D\u52A1\u5546").action(async (name) => {
1573
3479
  try {
1574
- const manager = createCodexManager9();
3480
+ const manager = createCodexManager();
1575
3481
  const providers = manager.list();
1576
3482
  if (providers.length === 0) {
1577
3483
  console.log(chalk17.yellow("\n\u26A0\uFE0F \u6682\u65E0 Codex \u670D\u52A1\u5546\n"));
@@ -1581,7 +3487,7 @@ function editCommand(program2) {
1581
3487
  if (name) {
1582
3488
  const provider2 = manager.findByName(name);
1583
3489
  if (!provider2) {
1584
- throw new ProviderNotFoundError3(name);
3490
+ throw new ProviderNotFoundError(name);
1585
3491
  }
1586
3492
  targetId = provider2.id;
1587
3493
  } else {
@@ -1653,13 +3559,13 @@ function editCommand(program2) {
1653
3559
  }
1654
3560
 
1655
3561
  // src/commands/codex/clone.ts
3562
+ init_dist();
1656
3563
  import chalk18 from "chalk";
1657
3564
  import inquirer12 from "inquirer";
1658
- import { createCodexManager as createCodexManager10, ProviderNotFoundError as ProviderNotFoundError4 } from "@ccman/core";
1659
3565
  function cloneCommand(program2) {
1660
3566
  program2.command("clone [source-name] [new-name]").description("\u514B\u9686 Codex \u670D\u52A1\u5546").action(async (sourceName, newName) => {
1661
3567
  try {
1662
- const manager = createCodexManager10();
3568
+ const manager = createCodexManager();
1663
3569
  const providers = manager.list();
1664
3570
  if (providers.length === 0) {
1665
3571
  console.log(chalk18.yellow("\n\u26A0\uFE0F \u6682\u65E0 Codex \u670D\u52A1\u5546\n"));
@@ -1669,7 +3575,7 @@ function cloneCommand(program2) {
1669
3575
  if (sourceName) {
1670
3576
  const provider = manager.findByName(sourceName);
1671
3577
  if (!provider) {
1672
- throw new ProviderNotFoundError4(sourceName);
3578
+ throw new ProviderNotFoundError(sourceName);
1673
3579
  }
1674
3580
  sourceId = provider.id;
1675
3581
  } else {
@@ -1731,17 +3637,13 @@ function createCodexCommands(program2) {
1731
3637
  }
1732
3638
 
1733
3639
  // src/commands/claude/add.ts
3640
+ init_dist();
1734
3641
  import chalk19 from "chalk";
1735
3642
  import inquirer13 from "inquirer";
1736
- import {
1737
- createClaudeManager as createClaudeManager4,
1738
- CC_PRESETS,
1739
- getClaudeConfigPath
1740
- } from "@ccman/core";
1741
3643
  function addCommand2(program2) {
1742
3644
  program2.command("add").description("\u6DFB\u52A0\u65B0\u7684 Claude Code \u670D\u52A1\u5546(\u4EA4\u4E92\u5F0F)").action(async () => {
1743
3645
  try {
1744
- const manager = createClaudeManager4();
3646
+ const manager = createClaudeManager();
1745
3647
  console.log(chalk19.bold("\n\u{1F4DD} \u6DFB\u52A0 Claude Code \u670D\u52A1\u5546\n"));
1746
3648
  const { usePreset } = await inquirer13.prompt([
1747
3649
  {
@@ -1857,12 +3759,12 @@ function addCommand2(program2) {
1857
3759
  }
1858
3760
 
1859
3761
  // src/commands/claude/list.ts
3762
+ init_dist();
1860
3763
  import chalk20 from "chalk";
1861
- import { createClaudeManager as createClaudeManager5 } from "@ccman/core";
1862
3764
  function listCommand2(program2) {
1863
3765
  program2.command("list").alias("ls").description("\u5217\u51FA\u6240\u6709 Claude Code \u670D\u52A1\u5546").action(async () => {
1864
3766
  try {
1865
- const manager = createClaudeManager5();
3767
+ const manager = createClaudeManager();
1866
3768
  const providers = manager.list();
1867
3769
  const current = manager.getCurrent();
1868
3770
  if (providers.length === 0) {
@@ -1883,17 +3785,13 @@ function listCommand2(program2) {
1883
3785
  }
1884
3786
 
1885
3787
  // src/commands/claude/use.ts
3788
+ init_dist();
1886
3789
  import chalk21 from "chalk";
1887
3790
  import inquirer14 from "inquirer";
1888
- import {
1889
- createClaudeManager as createClaudeManager6,
1890
- ProviderNotFoundError as ProviderNotFoundError5,
1891
- getClaudeConfigPath as getClaudeConfigPath2
1892
- } from "@ccman/core";
1893
3791
  function useCommand2(program2) {
1894
3792
  program2.command("use [name]").description("\u5207\u6362 Claude Code \u670D\u52A1\u5546").action(async (name) => {
1895
3793
  try {
1896
- const manager = createClaudeManager6();
3794
+ const manager = createClaudeManager();
1897
3795
  const providers = manager.list();
1898
3796
  if (providers.length === 0) {
1899
3797
  console.log(chalk21.yellow("\n\u26A0\uFE0F \u6682\u65E0 Claude Code \u670D\u52A1\u5546\n"));
@@ -1904,7 +3802,7 @@ function useCommand2(program2) {
1904
3802
  if (name) {
1905
3803
  const provider2 = manager.findByName(name);
1906
3804
  if (!provider2) {
1907
- throw new ProviderNotFoundError5(name);
3805
+ throw new ProviderNotFoundError(name);
1908
3806
  }
1909
3807
  targetId = provider2.id;
1910
3808
  } else {
@@ -1930,10 +3828,10 @@ function useCommand2(program2) {
1930
3828
  console.log(` ${chalk21.gray(`URL: ${provider.baseUrl}`)}`);
1931
3829
  console.log();
1932
3830
  console.log(chalk21.gray("\u914D\u7F6E\u5DF2\u66F4\u65B0:"));
1933
- console.log(chalk21.gray(` - ${getClaudeConfigPath2()}`));
3831
+ console.log(chalk21.gray(` - ${getClaudeConfigPath()}`));
1934
3832
  console.log();
1935
3833
  } catch (error) {
1936
- if (error instanceof ProviderNotFoundError5) {
3834
+ if (error instanceof ProviderNotFoundError) {
1937
3835
  console.error(chalk21.red(`
1938
3836
  \u274C \u670D\u52A1\u5546\u4E0D\u5B58\u5728: ${error.message}
1939
3837
  `));
@@ -1949,12 +3847,12 @@ function useCommand2(program2) {
1949
3847
  }
1950
3848
 
1951
3849
  // src/commands/claude/current.ts
3850
+ init_dist();
1952
3851
  import chalk22 from "chalk";
1953
- import { createClaudeManager as createClaudeManager7 } from "@ccman/core";
1954
3852
  function currentCommand2(program2) {
1955
3853
  program2.command("current").description("\u663E\u793A\u5F53\u524D\u4F7F\u7528\u7684 Claude Code \u670D\u52A1\u5546").action(async () => {
1956
3854
  try {
1957
- const manager = createClaudeManager7();
3855
+ const manager = createClaudeManager();
1958
3856
  const current = manager.getCurrent();
1959
3857
  if (!current) {
1960
3858
  console.log(chalk22.yellow("\n\u26A0\uFE0F \u672A\u9009\u62E9\u4EFB\u4F55 Claude Code \u670D\u52A1\u5546\n"));
@@ -1980,13 +3878,13 @@ function currentCommand2(program2) {
1980
3878
  }
1981
3879
 
1982
3880
  // src/commands/claude/remove.ts
3881
+ init_dist();
1983
3882
  import chalk23 from "chalk";
1984
3883
  import inquirer15 from "inquirer";
1985
- import { createClaudeManager as createClaudeManager8, ProviderNotFoundError as ProviderNotFoundError6 } from "@ccman/core";
1986
3884
  function removeCommand2(program2) {
1987
3885
  program2.command("remove [name]").alias("rm").description("\u5220\u9664 Claude Code \u670D\u52A1\u5546").action(async (name) => {
1988
3886
  try {
1989
- const manager = createClaudeManager8();
3887
+ const manager = createClaudeManager();
1990
3888
  const providers = manager.list();
1991
3889
  if (providers.length === 0) {
1992
3890
  console.log(chalk23.yellow("\n\u26A0\uFE0F \u6682\u65E0 Claude Code \u670D\u52A1\u5546\n"));
@@ -1997,7 +3895,7 @@ function removeCommand2(program2) {
1997
3895
  if (name) {
1998
3896
  const provider = manager.findByName(name);
1999
3897
  if (!provider) {
2000
- throw new ProviderNotFoundError6(name);
3898
+ throw new ProviderNotFoundError(name);
2001
3899
  }
2002
3900
  targetId = provider.id;
2003
3901
  targetName = provider.name;
@@ -2034,7 +3932,7 @@ function removeCommand2(program2) {
2034
3932
  console.log(chalk23.green(`\u2705 \u5DF2\u5220\u9664: ${targetName}`));
2035
3933
  console.log();
2036
3934
  } catch (error) {
2037
- if (error instanceof ProviderNotFoundError6) {
3935
+ if (error instanceof ProviderNotFoundError) {
2038
3936
  console.error(chalk23.red(`
2039
3937
  \u274C \u670D\u52A1\u5546\u4E0D\u5B58\u5728
2040
3938
  `));
@@ -2050,13 +3948,13 @@ function removeCommand2(program2) {
2050
3948
  }
2051
3949
 
2052
3950
  // src/commands/claude/edit.ts
3951
+ init_dist();
2053
3952
  import chalk24 from "chalk";
2054
3953
  import inquirer16 from "inquirer";
2055
- import { createClaudeManager as createClaudeManager9, ProviderNotFoundError as ProviderNotFoundError7 } from "@ccman/core";
2056
3954
  function editCommand2(program2) {
2057
3955
  program2.command("edit [name]").description("\u7F16\u8F91 Claude Code \u670D\u52A1\u5546").action(async (name) => {
2058
3956
  try {
2059
- const manager = createClaudeManager9();
3957
+ const manager = createClaudeManager();
2060
3958
  const providers = manager.list();
2061
3959
  if (providers.length === 0) {
2062
3960
  console.log(chalk24.yellow("\n\u26A0\uFE0F \u6682\u65E0 Claude Code \u670D\u52A1\u5546\n"));
@@ -2066,7 +3964,7 @@ function editCommand2(program2) {
2066
3964
  if (name) {
2067
3965
  const provider2 = manager.findByName(name);
2068
3966
  if (!provider2) {
2069
- throw new ProviderNotFoundError7(name);
3967
+ throw new ProviderNotFoundError(name);
2070
3968
  }
2071
3969
  targetId = provider2.id;
2072
3970
  } else {
@@ -2138,13 +4036,13 @@ function editCommand2(program2) {
2138
4036
  }
2139
4037
 
2140
4038
  // src/commands/claude/clone.ts
4039
+ init_dist();
2141
4040
  import chalk25 from "chalk";
2142
4041
  import inquirer17 from "inquirer";
2143
- import { createClaudeManager as createClaudeManager10, ProviderNotFoundError as ProviderNotFoundError8 } from "@ccman/core";
2144
4042
  function cloneCommand2(program2) {
2145
4043
  program2.command("clone [source-name] [new-name]").description("\u514B\u9686 Claude Code \u670D\u52A1\u5546").action(async (sourceName, newName) => {
2146
4044
  try {
2147
- const manager = createClaudeManager10();
4045
+ const manager = createClaudeManager();
2148
4046
  const providers = manager.list();
2149
4047
  if (providers.length === 0) {
2150
4048
  console.log(chalk25.yellow("\n\u26A0\uFE0F \u6682\u65E0 Claude Code \u670D\u52A1\u5546\n"));
@@ -2154,7 +4052,7 @@ function cloneCommand2(program2) {
2154
4052
  if (sourceName) {
2155
4053
  const provider = manager.findByName(sourceName);
2156
4054
  if (!provider) {
2157
- throw new ProviderNotFoundError8(sourceName);
4055
+ throw new ProviderNotFoundError(sourceName);
2158
4056
  }
2159
4057
  sourceId = provider.id;
2160
4058
  } else {
@@ -2205,10 +4103,10 @@ function cloneCommand2(program2) {
2205
4103
  }
2206
4104
 
2207
4105
  // src/commands/clean.ts
4106
+ init_dist();
2208
4107
  import chalk26 from "chalk";
2209
4108
  import inquirer18 from "inquirer";
2210
- import { analyzeClaudeJson, cleanClaudeJson, CleanPresets } from "@ccman/core";
2211
- function formatBytes(bytes) {
4109
+ function formatBytes2(bytes) {
2212
4110
  if (bytes < 1024) return `${bytes} B`;
2213
4111
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
2214
4112
  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
@@ -2231,9 +4129,9 @@ function displayAnalysis() {
2231
4129
  }
2232
4130
  console.log();
2233
4131
  console.log(chalk26.cyan("\u9884\u8BA1\u53EF\u8282\u7701\u7A7A\u95F4:"));
2234
- console.log(` ${chalk26.green("\u4FDD\u5B88\u6E05\u7406")} (\u4FDD\u755910\u6761): ${chalk26.bold(formatBytes(analysis.estimatedSavings.conservative))}`);
2235
- console.log(` ${chalk26.yellow("\u4E2D\u7B49\u6E05\u7406")} (\u4FDD\u75595\u6761): ${chalk26.bold(formatBytes(analysis.estimatedSavings.moderate))}`);
2236
- console.log(` ${chalk26.red("\u6FC0\u8FDB\u6E05\u7406")} (\u6E05\u7A7A\u5386\u53F2): ${chalk26.bold(formatBytes(analysis.estimatedSavings.aggressive))}`);
4132
+ console.log(` ${chalk26.green("\u4FDD\u5B88\u6E05\u7406")} (\u4FDD\u755910\u6761): ${chalk26.bold(formatBytes2(analysis.estimatedSavings.conservative))}`);
4133
+ console.log(` ${chalk26.yellow("\u4E2D\u7B49\u6E05\u7406")} (\u4FDD\u75595\u6761): ${chalk26.bold(formatBytes2(analysis.estimatedSavings.moderate))}`);
4134
+ console.log(` ${chalk26.red("\u6FC0\u8FDB\u6E05\u7406")} (\u6E05\u7A7A\u5386\u53F2): ${chalk26.bold(formatBytes2(analysis.estimatedSavings.aggressive))}`);
2237
4135
  console.log();
2238
4136
  console.log(chalk26.blue(`\u{1F4A1} \u6267\u884C\u6E05\u7406: ccman cc clean
2239
4137
  `));
@@ -2278,9 +4176,9 @@ function cleanCommand(program2) {
2278
4176
  console.log(chalk26.cyan("\n\u6B63\u5728\u6E05\u7406...\n"));
2279
4177
  const result = cleanClaudeJson(cleanOptions);
2280
4178
  console.log(chalk26.green("\u2705 \u6E05\u7406\u5B8C\u6210\n"));
2281
- console.log(`\u6E05\u7406\u524D: ${chalk26.bold(formatBytes(result.sizeBefore))}`);
2282
- console.log(`\u6E05\u7406\u540E: ${chalk26.bold(formatBytes(result.sizeAfter))}`);
2283
- console.log(`\u8282\u7701\u7A7A\u95F4: ${chalk26.green.bold(formatBytes(result.saved))} (${(result.saved / result.sizeBefore * 100).toFixed(1)}%)`);
4179
+ console.log(`\u6E05\u7406\u524D: ${chalk26.bold(formatBytes2(result.sizeBefore))}`);
4180
+ console.log(`\u6E05\u7406\u540E: ${chalk26.bold(formatBytes2(result.sizeAfter))}`);
4181
+ console.log(`\u8282\u7701\u7A7A\u95F4: ${chalk26.green.bold(formatBytes2(result.saved))} (${(result.saved / result.sizeBefore * 100).toFixed(1)}%)`);
2284
4182
  console.log();
2285
4183
  if (result.cleanedItems.projectHistory > 0) {
2286
4184
  console.log(`\u6E05\u7406\u5386\u53F2\u8BB0\u5F55: ${chalk26.bold(result.cleanedItems.projectHistory)} \u6761`);
@@ -2346,15 +4244,15 @@ async function promptForOptions(analysis) {
2346
4244
  message: "\u9009\u62E9\u6E05\u7406\u65B9\u6848:",
2347
4245
  choices: [
2348
4246
  {
2349
- name: `${chalk26.green("\u4FDD\u5B88\u6E05\u7406")} - \u4FDD\u7559\u6700\u8FD110\u6761\u8BB0\u5F55\uFF0C\u6E05\u7406\u7F13\u5B58 (\u8282\u7701\u7EA6 ${formatBytes(analysis.estimatedSavings.conservative)})`,
4247
+ name: `${chalk26.green("\u4FDD\u5B88\u6E05\u7406")} - \u4FDD\u7559\u6700\u8FD110\u6761\u8BB0\u5F55\uFF0C\u6E05\u7406\u7F13\u5B58 (\u8282\u7701\u7EA6 ${formatBytes2(analysis.estimatedSavings.conservative)})`,
2350
4248
  value: "conservative"
2351
4249
  },
2352
4250
  {
2353
- name: `${chalk26.yellow("\u4E2D\u7B49\u6E05\u7406")} - \u4FDD\u7559\u6700\u8FD15\u6761\u8BB0\u5F55\uFF0C\u6E05\u7406\u7F13\u5B58\u548C\u7EDF\u8BA1 (\u8282\u7701\u7EA6 ${formatBytes(analysis.estimatedSavings.moderate)})`,
4251
+ name: `${chalk26.yellow("\u4E2D\u7B49\u6E05\u7406")} - \u4FDD\u7559\u6700\u8FD15\u6761\u8BB0\u5F55\uFF0C\u6E05\u7406\u7F13\u5B58\u548C\u7EDF\u8BA1 (\u8282\u7701\u7EA6 ${formatBytes2(analysis.estimatedSavings.moderate)})`,
2354
4252
  value: "moderate"
2355
4253
  },
2356
4254
  {
2357
- name: `${chalk26.red("\u6FC0\u8FDB\u6E05\u7406")} - \u6E05\u7A7A\u5386\u53F2\u8BB0\u5F55\uFF0C\u6E05\u7406\u7F13\u5B58\u548C\u7EDF\u8BA1 (\u8282\u7701\u7EA6 ${formatBytes(analysis.estimatedSavings.aggressive)})`,
4255
+ name: `${chalk26.red("\u6FC0\u8FDB\u6E05\u7406")} - \u6E05\u7A7A\u5386\u53F2\u8BB0\u5F55\uFF0C\u6E05\u7406\u7F13\u5B58\u548C\u7EDF\u8BA1 (\u8282\u7701\u7EA6 ${formatBytes2(analysis.estimatedSavings.aggressive)})`,
2358
4256
  value: "aggressive"
2359
4257
  },
2360
4258
  {
@@ -2422,9 +4320,9 @@ function createClaudeCommands(program2) {
2422
4320
  }
2423
4321
 
2424
4322
  // src/commands/mcp/add.ts
4323
+ init_dist();
2425
4324
  import chalk27 from "chalk";
2426
4325
  import inquirer19 from "inquirer";
2427
- import { createMCPManager, MCP_PRESETS_DETAIL, getClaudeConfigPath as getClaudeConfigPath3 } from "@ccman/core";
2428
4326
  function addCommand3(program2) {
2429
4327
  program2.command("add").description("\u6DFB\u52A0\u65B0\u7684 MCP \u670D\u52A1\u5668(\u4EA4\u4E92\u5F0F)").action(async () => {
2430
4328
  try {
@@ -2571,7 +4469,7 @@ function addCommand3(program2) {
2571
4469
  console.log(chalk27.green("\u2705 \u914D\u7F6E\u5DF2\u81EA\u52A8\u540C\u6B65\u5230 ~/.claude.json"));
2572
4470
  console.log();
2573
4471
  console.log(chalk27.gray("\u914D\u7F6E\u6587\u4EF6:"));
2574
- console.log(chalk27.gray(` - ${getClaudeConfigPath3()}`));
4472
+ console.log(chalk27.gray(` - ${getClaudeConfigPath()}`));
2575
4473
  console.log();
2576
4474
  } catch (error) {
2577
4475
  console.error(chalk27.red(`
@@ -2583,12 +4481,12 @@ function addCommand3(program2) {
2583
4481
  }
2584
4482
 
2585
4483
  // src/commands/mcp/list.ts
4484
+ init_dist();
2586
4485
  import chalk28 from "chalk";
2587
- import { createMCPManager as createMCPManager2 } from "@ccman/core";
2588
4486
  function listCommand3(program2) {
2589
4487
  program2.command("list").alias("ls").description("\u5217\u51FA\u6240\u6709 MCP \u670D\u52A1\u5668").action(async () => {
2590
4488
  try {
2591
- const manager = createMCPManager2();
4489
+ const manager = createMCPManager();
2592
4490
  const providers = manager.list();
2593
4491
  if (providers.length === 0) {
2594
4492
  console.log(chalk28.yellow("\n\u26A0\uFE0F \u6682\u65E0 MCP \u670D\u52A1\u5668\n"));
@@ -2629,13 +4527,13 @@ function listCommand3(program2) {
2629
4527
  }
2630
4528
 
2631
4529
  // src/commands/mcp/remove.ts
4530
+ init_dist();
2632
4531
  import chalk29 from "chalk";
2633
4532
  import inquirer20 from "inquirer";
2634
- import { createMCPManager as createMCPManager3, ProviderNotFoundError as ProviderNotFoundError9, getClaudeConfigPath as getClaudeConfigPath4 } from "@ccman/core";
2635
4533
  function removeCommand3(program2) {
2636
4534
  program2.command("remove [name]").alias("rm").description("\u5220\u9664 MCP \u670D\u52A1\u5668").action(async (name) => {
2637
4535
  try {
2638
- const manager = createMCPManager3();
4536
+ const manager = createMCPManager();
2639
4537
  const providers = manager.list();
2640
4538
  if (providers.length === 0) {
2641
4539
  console.log(chalk29.yellow("\n\u26A0\uFE0F \u6682\u65E0 MCP \u670D\u52A1\u5668\n"));
@@ -2646,7 +4544,7 @@ function removeCommand3(program2) {
2646
4544
  if (name) {
2647
4545
  const provider = manager.findByName(name);
2648
4546
  if (!provider) {
2649
- throw new ProviderNotFoundError9(name);
4547
+ throw new ProviderNotFoundError(name);
2650
4548
  }
2651
4549
  targetId = provider.id;
2652
4550
  targetName = provider.name;
@@ -2685,10 +4583,10 @@ function removeCommand3(program2) {
2685
4583
  console.log(chalk29.green("\u2705 \u914D\u7F6E\u5DF2\u81EA\u52A8\u540C\u6B65\u5230 ~/.claude.json"));
2686
4584
  console.log();
2687
4585
  console.log(chalk29.gray("\u914D\u7F6E\u6587\u4EF6:"));
2688
- console.log(chalk29.gray(` - ${getClaudeConfigPath4()}`));
4586
+ console.log(chalk29.gray(` - ${getClaudeConfigPath()}`));
2689
4587
  console.log();
2690
4588
  } catch (error) {
2691
- if (error instanceof ProviderNotFoundError9) {
4589
+ if (error instanceof ProviderNotFoundError) {
2692
4590
  console.error(chalk29.red(`
2693
4591
  \u274C MCP \u670D\u52A1\u5668\u4E0D\u5B58\u5728
2694
4592
  `));
@@ -2704,13 +4602,13 @@ function removeCommand3(program2) {
2704
4602
  }
2705
4603
 
2706
4604
  // src/commands/mcp/edit.ts
4605
+ init_dist();
2707
4606
  import chalk30 from "chalk";
2708
4607
  import inquirer21 from "inquirer";
2709
- import { createMCPManager as createMCPManager4, ProviderNotFoundError as ProviderNotFoundError10, getClaudeConfigPath as getClaudeConfigPath5 } from "@ccman/core";
2710
4608
  function editCommand3(program2) {
2711
4609
  program2.command("edit [name]").description("\u7F16\u8F91 MCP \u670D\u52A1\u5668").action(async (name) => {
2712
4610
  try {
2713
- const manager = createMCPManager4();
4611
+ const manager = createMCPManager();
2714
4612
  const providers = manager.list();
2715
4613
  if (providers.length === 0) {
2716
4614
  console.log(chalk30.yellow("\n\u26A0\uFE0F \u6682\u65E0 MCP \u670D\u52A1\u5668\n"));
@@ -2720,7 +4618,7 @@ function editCommand3(program2) {
2720
4618
  if (name) {
2721
4619
  const provider2 = manager.findByName(name);
2722
4620
  if (!provider2) {
2723
- throw new ProviderNotFoundError10(name);
4621
+ throw new ProviderNotFoundError(name);
2724
4622
  }
2725
4623
  targetId = provider2.id;
2726
4624
  } else {
@@ -2803,7 +4701,7 @@ function editCommand3(program2) {
2803
4701
  console.log(chalk30.green("\u2705 \u914D\u7F6E\u5DF2\u81EA\u52A8\u540C\u6B65\u5230 ~/.claude.json"));
2804
4702
  console.log();
2805
4703
  console.log(chalk30.gray("\u914D\u7F6E\u6587\u4EF6:"));
2806
- console.log(chalk30.gray(` - ${getClaudeConfigPath5()}`));
4704
+ console.log(chalk30.gray(` - ${getClaudeConfigPath()}`));
2807
4705
  console.log();
2808
4706
  } catch (error) {
2809
4707
  console.error(chalk30.red(`
@@ -2826,9 +4724,9 @@ function createMCPCommands(program2) {
2826
4724
  init_sync();
2827
4725
 
2828
4726
  // src/commands/export.ts
4727
+ init_dist();
2829
4728
  import chalk31 from "chalk";
2830
- import path from "path";
2831
- import { exportConfig, validateExport } from "@ccman/core";
4729
+ import path10 from "path";
2832
4730
  function exportCommand(program2) {
2833
4731
  program2.command("export <\u76EE\u6807\u76EE\u5F55>").description("\u5BFC\u51FA\u914D\u7F6E\u5230\u672C\u5730\u76EE\u5F55\uFF08\u5305\u542B API Key\uFF09").action(async (targetDir) => {
2834
4732
  try {
@@ -2839,7 +4737,7 @@ function exportCommand(program2) {
2839
4737
  `));
2840
4738
  process.exit(1);
2841
4739
  }
2842
- const resolvedPath = targetDir.startsWith("~") ? path.join(process.env.HOME || "", targetDir.slice(1)) : path.resolve(targetDir);
4740
+ const resolvedPath = targetDir.startsWith("~") ? path10.join(process.env.HOME || "", targetDir.slice(1)) : path10.resolve(targetDir);
2843
4741
  console.log("\u5BFC\u51FA\u6587\u4EF6:");
2844
4742
  console.log(` ${chalk31.cyan("codex.json")} - Codex \u914D\u7F6E`);
2845
4743
  console.log(` ${chalk31.cyan("claude.json")} - Claude \u914D\u7F6E`);
@@ -2868,14 +4766,14 @@ function exportCommand(program2) {
2868
4766
  }
2869
4767
 
2870
4768
  // src/commands/import.ts
4769
+ init_dist();
2871
4770
  import chalk32 from "chalk";
2872
4771
  import inquirer22 from "inquirer";
2873
- import path2 from "path";
2874
- import { importConfig, validateImportDir } from "@ccman/core";
4772
+ import path11 from "path";
2875
4773
  function importCommand(program2) {
2876
4774
  program2.command("import <\u6E90\u76EE\u5F55>").description("\u4ECE\u672C\u5730\u76EE\u5F55\u5BFC\u5165\u914D\u7F6E\uFF08\u4F1A\u8986\u76D6\u5F53\u524D\u914D\u7F6E\uFF09").action(async (sourceDir) => {
2877
4775
  try {
2878
- const resolvedPath = sourceDir.startsWith("~") ? path2.join(process.env.HOME || "", sourceDir.slice(1)) : path2.resolve(sourceDir);
4776
+ const resolvedPath = sourceDir.startsWith("~") ? path11.join(process.env.HOME || "", sourceDir.slice(1)) : path11.resolve(sourceDir);
2879
4777
  console.log(chalk32.bold("\n\u{1F4E5} \u5BFC\u5165\u914D\u7F6E\n"));
2880
4778
  const validation = validateImportDir(resolvedPath);
2881
4779
  if (!validation.valid) {
@@ -2950,7 +4848,7 @@ function importCommand(program2) {
2950
4848
  }
2951
4849
 
2952
4850
  // src/index.ts
2953
- import { getCcmanDir, getCodexDir, getClaudeDir, VERSION as VERSION2 } from "@ccman/core";
4851
+ init_dist();
2954
4852
  if (process.env.NODE_ENV === "development") {
2955
4853
  console.log(chalk33.gray("\n[\u5F00\u53D1\u6A21\u5F0F] \u914D\u7F6E\u76EE\u5F55:"));
2956
4854
  console.log(chalk33.gray(` ccman: ${getCcmanDir()}`));
@@ -2959,7 +4857,7 @@ if (process.env.NODE_ENV === "development") {
2959
4857
  console.log();
2960
4858
  }
2961
4859
  var program = new Command3();
2962
- program.name("ccman").description("Codex/Claude Code API \u670D\u52A1\u5546\u914D\u7F6E\u7BA1\u7406\u5DE5\u5177").version(VERSION2).showHelpAfterError(false).exitOverride((err) => {
4860
+ program.name("ccman").description("Codex/Claude Code API \u670D\u52A1\u5546\u914D\u7F6E\u7BA1\u7406\u5DE5\u5177").version(VERSION).showHelpAfterError(false).exitOverride((err) => {
2963
4861
  if (err.code === "commander.helpDisplayed" || err.code === "commander.version") {
2964
4862
  process.exit(0);
2965
4863
  }