ccman 3.0.31 → 3.0.33

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 +2034 -124
  2. package/package.json +5 -2
package/dist/index.js CHANGED
@@ -9,8 +9,1935 @@ 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.33",
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
+ return {
1788
+ fileSize: 0,
1789
+ fileSizeFormatted: "0 B",
1790
+ projectCount: 0,
1791
+ totalHistoryCount: 0,
1792
+ projectHistory: [],
1793
+ cacheSize: 0,
1794
+ estimatedSavings: {
1795
+ conservative: 0,
1796
+ moderate: 0,
1797
+ aggressive: 0
1798
+ }
1799
+ };
1800
+ }
1801
+ const fileSize = getFileSize(filePath);
1802
+ const content = fs9.readFileSync(filePath, "utf-8");
1803
+ const config = JSON.parse(content);
1804
+ const projects = config.projects || {};
1805
+ const projectHistory = [];
1806
+ let totalHistoryCount = 0;
1807
+ for (const [projectPath, projectData] of Object.entries(projects)) {
1808
+ const historyCount = projectData.history?.length || 0;
1809
+ totalHistoryCount += historyCount;
1810
+ projectHistory.push({
1811
+ path: projectPath,
1812
+ count: historyCount
1813
+ });
1814
+ }
1815
+ projectHistory.sort((a, b) => b.count - a.count);
1816
+ const cacheSize = config.cachedChangelog?.length || 0;
1817
+ const historySize = fileSize - cacheSize - 2e4;
1818
+ const avgHistorySize = totalHistoryCount > 0 ? historySize / totalHistoryCount : 0;
1819
+ const estimatedSavings = {
1820
+ conservative: Math.floor(avgHistorySize * Math.max(0, totalHistoryCount - projectHistory.length * 10)) + cacheSize,
1821
+ moderate: Math.floor(avgHistorySize * Math.max(0, totalHistoryCount - projectHistory.length * 5)) + cacheSize,
1822
+ aggressive: Math.floor(historySize) + cacheSize
1823
+ };
1824
+ return {
1825
+ fileSize,
1826
+ fileSizeFormatted: formatBytes(fileSize),
1827
+ projectCount: projectHistory.length,
1828
+ totalHistoryCount,
1829
+ projectHistory,
1830
+ cacheSize,
1831
+ estimatedSavings
1832
+ };
1833
+ }
1834
+ function cleanClaudeJson(options = {}) {
1835
+ const filePath = getClaudeJsonPath();
1836
+ if (!fs9.existsSync(filePath)) {
1837
+ throw new Error(`${filePath} \u6587\u4EF6\u4E0D\u5B58\u5728`);
1838
+ }
1839
+ const backupPath = backupFile(filePath);
1840
+ const sizeBefore = getFileSize(filePath);
1841
+ const content = fs9.readFileSync(filePath, "utf-8");
1842
+ const config = JSON.parse(content);
1843
+ const cleanedItems = applyCleanOptions(config, options);
1844
+ saveJsonAtomic(filePath, config);
1845
+ const sizeAfter = getFileSize(filePath);
1846
+ return {
1847
+ sizeBefore,
1848
+ sizeAfter,
1849
+ saved: sizeBefore - sizeAfter,
1850
+ cleanedItems,
1851
+ backupPath
1852
+ };
1853
+ }
1854
+ function applyCleanOptions(config, options) {
1855
+ let projectHistoryCount = 0;
1856
+ if (options.cleanProjectHistory && config.projects) {
1857
+ const keepCount = options.keepRecentCount ?? 10;
1858
+ const targetProjects = options.projectPaths || [];
1859
+ for (const [projectPath, projectData] of Object.entries(config.projects)) {
1860
+ if (targetProjects.length > 0 && !targetProjects.includes(projectPath)) {
1861
+ continue;
1862
+ }
1863
+ if (projectData.history && Array.isArray(projectData.history)) {
1864
+ const originalCount = projectData.history.length;
1865
+ projectData.history = projectData.history.slice(-keepCount);
1866
+ projectHistoryCount += originalCount - projectData.history.length;
1867
+ }
1868
+ }
1869
+ }
1870
+ if (options.cleanCache) {
1871
+ delete config.cachedChangelog;
1872
+ config.changelogLastFetched = 0;
1873
+ }
1874
+ if (options.cleanStats) {
1875
+ config.numStartups = 0;
1876
+ config.promptQueueUseCount = 0;
1877
+ config.tipsHistory = {};
1878
+ }
1879
+ return {
1880
+ projectHistory: projectHistoryCount,
1881
+ cache: options.cleanCache || false,
1882
+ stats: options.cleanStats || false
1883
+ };
1884
+ }
1885
+ var CleanPresets;
1886
+ var init_claude_clean = __esm({
1887
+ "../core/dist/claude-clean.js"() {
1888
+ "use strict";
1889
+ init_paths();
1890
+ CleanPresets = {
1891
+ /** 保守清理:保留最近10条记录,清理缓存 */
1892
+ conservative: () => ({
1893
+ cleanProjectHistory: true,
1894
+ keepRecentCount: 10,
1895
+ cleanCache: true,
1896
+ cleanStats: false
1897
+ }),
1898
+ /** 中等清理:保留最近5条记录,清理缓存和统计 */
1899
+ moderate: () => ({
1900
+ cleanProjectHistory: true,
1901
+ keepRecentCount: 5,
1902
+ cleanCache: true,
1903
+ cleanStats: true
1904
+ }),
1905
+ /** 激进清理:清空历史记录,清理缓存和统计 */
1906
+ aggressive: () => ({
1907
+ cleanProjectHistory: true,
1908
+ keepRecentCount: 0,
1909
+ cleanCache: true,
1910
+ cleanStats: true
1911
+ })
1912
+ };
1913
+ }
1914
+ });
1915
+
1916
+ // ../core/dist/index.js
1917
+ var VERSION;
1918
+ var init_dist = __esm({
1919
+ "../core/dist/index.js"() {
1920
+ "use strict";
1921
+ init_package();
1922
+ init_tool_manager();
1923
+ init_codex2();
1924
+ init_claude2();
1925
+ init_mcp2();
1926
+ init_mcp();
1927
+ init_migrate();
1928
+ init_paths();
1929
+ init_config();
1930
+ init_webdav_client();
1931
+ init_sync_v2();
1932
+ init_crypto();
1933
+ init_merge_advanced();
1934
+ init_export();
1935
+ init_claude_clean();
1936
+ VERSION = package_default.version;
1937
+ }
1938
+ });
1939
+
12
1940
  // src/utils/sync-config.ts
13
- import { getSyncConfig, saveSyncConfig as coreSaveSyncConfig, getConfigPath } from "@ccman/core";
14
1941
  function loadSyncConfig() {
15
1942
  try {
16
1943
  const config = getSyncConfig();
@@ -22,13 +1949,13 @@ function loadSyncConfig() {
22
1949
  throw new Error(`\u8BFB\u53D6\u540C\u6B65\u914D\u7F6E\u5931\u8D25: ${error.message}`);
23
1950
  }
24
1951
  }
25
- function saveSyncConfig(config) {
1952
+ function saveSyncConfig2(config) {
26
1953
  try {
27
1954
  const configToSave = { ...config };
28
1955
  if (!configToSave.rememberSyncPassword) {
29
1956
  delete configToSave.syncPassword;
30
1957
  }
31
- coreSaveSyncConfig(configToSave);
1958
+ saveSyncConfig(configToSave);
32
1959
  } catch (error) {
33
1960
  throw new Error(`\u4FDD\u5B58\u540C\u6B65\u914D\u7F6E\u5931\u8D25: ${error.message}`);
34
1961
  }
@@ -39,6 +1966,7 @@ function getSyncConfigPath() {
39
1966
  var init_sync_config = __esm({
40
1967
  "src/utils/sync-config.ts"() {
41
1968
  "use strict";
1969
+ init_dist();
42
1970
  }
43
1971
  });
44
1972
 
@@ -49,7 +1977,6 @@ __export(config_exports, {
49
1977
  });
50
1978
  import chalk3 from "chalk";
51
1979
  import inquirer from "inquirer";
52
- import { testWebDAVConnection } from "@ccman/core";
53
1980
  function configCommand(program2) {
54
1981
  program2.command("config").description("\u914D\u7F6E WebDAV \u8FDE\u63A5").action(async () => {
55
1982
  try {
@@ -201,7 +2128,7 @@ function configCommand(program2) {
201
2128
  console.log();
202
2129
  return;
203
2130
  }
204
- saveSyncConfig(newConfig);
2131
+ saveSyncConfig2(newConfig);
205
2132
  console.log();
206
2133
  console.log(chalk3.green("\u2705 \u914D\u7F6E\u4FDD\u5B58\u6210\u529F"));
207
2134
  console.log();
@@ -243,10 +2170,11 @@ function configCommand(program2) {
243
2170
  }
244
2171
  });
245
2172
  }
246
- var init_config = __esm({
2173
+ var init_config2 = __esm({
247
2174
  "src/commands/sync/config.ts"() {
248
2175
  "use strict";
249
2176
  init_sync_config();
2177
+ init_dist();
250
2178
  }
251
2179
  });
252
2180
 
@@ -271,7 +2199,7 @@ async function ensureConfigExists() {
271
2199
  if (!shouldConfig) {
272
2200
  return null;
273
2201
  }
274
- const { configCommand: configCommand2 } = await Promise.resolve().then(() => (init_config(), config_exports));
2202
+ const { configCommand: configCommand2 } = await Promise.resolve().then(() => (init_config2(), config_exports));
275
2203
  const cmd = new Command();
276
2204
  configCommand2(cmd);
277
2205
  await cmd.parseAsync(["node", "ccman", "config"]);
@@ -290,7 +2218,6 @@ __export(test_exports, {
290
2218
  testCommand: () => testCommand
291
2219
  });
292
2220
  import chalk5 from "chalk";
293
- import { testWebDAVConnection as testWebDAVConnection2 } from "@ccman/core";
294
2221
  function testCommand(program2) {
295
2222
  program2.command("test").description("\u6D4B\u8BD5 WebDAV \u8FDE\u63A5").action(async () => {
296
2223
  try {
@@ -300,7 +2227,7 @@ function testCommand(program2) {
300
2227
  return;
301
2228
  }
302
2229
  console.log(chalk5.bold("\n\u{1F50D} \u6D4B\u8BD5 WebDAV \u8FDE\u63A5...\n"));
303
- const success = await testWebDAVConnection2(config);
2230
+ const success = await testWebDAVConnection(config);
304
2231
  if (success) {
305
2232
  console.log(chalk5.green("\u2705 \u8FDE\u63A5\u6210\u529F"));
306
2233
  console.log();
@@ -328,6 +2255,7 @@ function testCommand(program2) {
328
2255
  var init_test = __esm({
329
2256
  "src/commands/sync/test.ts"() {
330
2257
  "use strict";
2258
+ init_dist();
331
2259
  init_helpers();
332
2260
  }
333
2261
  });
@@ -339,7 +2267,6 @@ __export(upload_exports, {
339
2267
  });
340
2268
  import chalk6 from "chalk";
341
2269
  import inquirer3 from "inquirer";
342
- import { uploadToCloud, createCodexManager, createClaudeManager } from "@ccman/core";
343
2270
  function uploadCommand(program2) {
344
2271
  program2.command("upload").description("\u4E0A\u4F20\u672C\u5730\u914D\u7F6E\u5230\u4E91\u7AEF").action(async () => {
345
2272
  try {
@@ -406,6 +2333,7 @@ function uploadCommand(program2) {
406
2333
  var init_upload = __esm({
407
2334
  "src/commands/sync/upload.ts"() {
408
2335
  "use strict";
2336
+ init_dist();
409
2337
  init_helpers();
410
2338
  }
411
2339
  });
@@ -417,7 +2345,6 @@ __export(download_exports, {
417
2345
  });
418
2346
  import chalk7 from "chalk";
419
2347
  import inquirer4 from "inquirer";
420
- import { downloadFromCloud } from "@ccman/core";
421
2348
  function downloadCommand(program2) {
422
2349
  program2.command("download").description("\u4ECE\u4E91\u7AEF\u4E0B\u8F7D\u914D\u7F6E\u5230\u672C\u5730").action(async () => {
423
2350
  try {
@@ -464,8 +2391,8 @@ function downloadCommand(program2) {
464
2391
  console.log();
465
2392
  if (backupPaths.length > 0) {
466
2393
  console.log(chalk7.gray("\u672C\u5730\u5907\u4EFD:"));
467
- backupPaths.forEach((path3) => {
468
- console.log(chalk7.gray(` ${path3}`));
2394
+ backupPaths.forEach((path12) => {
2395
+ console.log(chalk7.gray(` ${path12}`));
469
2396
  });
470
2397
  console.log();
471
2398
  }
@@ -480,6 +2407,7 @@ function downloadCommand(program2) {
480
2407
  var init_download = __esm({
481
2408
  "src/commands/sync/download.ts"() {
482
2409
  "use strict";
2410
+ init_dist();
483
2411
  init_helpers();
484
2412
  }
485
2413
  });
@@ -491,7 +2419,6 @@ __export(merge_exports, {
491
2419
  });
492
2420
  import chalk8 from "chalk";
493
2421
  import inquirer5 from "inquirer";
494
- import { mergeSync } from "@ccman/core";
495
2422
  function mergeCommand(program2) {
496
2423
  program2.command("merge").description("\u667A\u80FD\u5408\u5E76\u672C\u5730\u548C\u4E91\u7AEF\u914D\u7F6E").action(async () => {
497
2424
  try {
@@ -526,8 +2453,8 @@ function mergeCommand(program2) {
526
2453
  console.log();
527
2454
  if (result.backupPaths.length > 0) {
528
2455
  console.log(chalk8.gray("\u5907\u4EFD:"));
529
- result.backupPaths.forEach((path3) => {
530
- console.log(chalk8.gray(` ${path3}`));
2456
+ result.backupPaths.forEach((path12) => {
2457
+ console.log(chalk8.gray(` ${path12}`));
531
2458
  });
532
2459
  console.log();
533
2460
  }
@@ -543,9 +2470,10 @@ function mergeCommand(program2) {
543
2470
  }
544
2471
  });
545
2472
  }
546
- var init_merge = __esm({
2473
+ var init_merge2 = __esm({
547
2474
  "src/commands/sync/merge.ts"() {
548
2475
  "use strict";
2476
+ init_dist();
549
2477
  init_helpers();
550
2478
  }
551
2479
  });
@@ -556,7 +2484,6 @@ __export(status_exports, {
556
2484
  statusCommand: () => statusCommand
557
2485
  });
558
2486
  import chalk9 from "chalk";
559
- import { createCodexManager as createCodexManager2, createClaudeManager as createClaudeManager2 } from "@ccman/core";
560
2487
  function statusCommand(program2) {
561
2488
  program2.command("status").description("\u67E5\u770B\u540C\u6B65\u72B6\u6001").action(async () => {
562
2489
  try {
@@ -575,8 +2502,8 @@ function statusCommand(program2) {
575
2502
  console.log(` \u8BA4\u8BC1: ${chalk9.gray(config.authType === "password" ? "Basic Auth" : "Digest Auth")}`);
576
2503
  console.log(` \u540C\u6B65\u5BC6\u7801: ${config.syncPassword ? chalk9.green("\u2713 \u5DF2\u4FDD\u5B58") : chalk9.yellow("\u2717 \u672A\u4FDD\u5B58")}`);
577
2504
  console.log();
578
- const codexManager = createCodexManager2();
579
- const claudeManager = createClaudeManager2();
2505
+ const codexManager = createCodexManager();
2506
+ const claudeManager = createClaudeManager();
580
2507
  const codexProviders = codexManager.list();
581
2508
  const claudeProviders = claudeManager.list();
582
2509
  console.log(chalk9.bold("\u672C\u5730\u914D\u7F6E:"));
@@ -602,6 +2529,7 @@ function statusCommand(program2) {
602
2529
  var init_status = __esm({
603
2530
  "src/commands/sync/status.ts"() {
604
2531
  "use strict";
2532
+ init_dist();
605
2533
  init_sync_config();
606
2534
  }
607
2535
  });
@@ -648,7 +2576,7 @@ async function startSyncMenu() {
648
2576
  try {
649
2577
  switch (action) {
650
2578
  case "config": {
651
- const { configCommand: configCommand2 } = await Promise.resolve().then(() => (init_config(), config_exports));
2579
+ const { configCommand: configCommand2 } = await Promise.resolve().then(() => (init_config2(), config_exports));
652
2580
  const cmd = new Command2();
653
2581
  configCommand2(cmd);
654
2582
  await cmd.parseAsync(["node", "ccman", "config"]);
@@ -676,7 +2604,7 @@ async function startSyncMenu() {
676
2604
  break;
677
2605
  }
678
2606
  case "merge": {
679
- const { mergeCommand: mergeCommand2 } = await Promise.resolve().then(() => (init_merge(), merge_exports));
2607
+ const { mergeCommand: mergeCommand2 } = await Promise.resolve().then(() => (init_merge2(), merge_exports));
680
2608
  const cmd = new Command2();
681
2609
  mergeCommand2(cmd);
682
2610
  await cmd.parseAsync(["node", "ccman", "merge"]);
@@ -707,11 +2635,11 @@ async function startSyncMenu() {
707
2635
  var init_sync = __esm({
708
2636
  "src/commands/sync/index.ts"() {
709
2637
  "use strict";
710
- init_config();
2638
+ init_config2();
711
2639
  init_test();
712
2640
  init_upload();
713
2641
  init_download();
714
- init_merge();
2642
+ init_merge2();
715
2643
  init_status();
716
2644
  }
717
2645
  });
@@ -721,8 +2649,8 @@ import { Command as Command3 } from "commander";
721
2649
  import chalk33 from "chalk";
722
2650
 
723
2651
  // src/utils/logo.ts
2652
+ init_dist();
724
2653
  import chalk from "chalk";
725
- import { VERSION } from "@ccman/core";
726
2654
  function printLogo() {
727
2655
  console.log(
728
2656
  chalk.bold(
@@ -742,19 +2670,14 @@ function printLogo() {
742
2670
  }
743
2671
 
744
2672
  // src/commands/codex/add.ts
2673
+ init_dist();
745
2674
  import chalk12 from "chalk";
746
2675
  import inquirer8 from "inquirer";
747
- import {
748
- createCodexManager as createCodexManager4,
749
- CODEX_PRESETS,
750
- getCodexConfigPath,
751
- getCodexAuthPath
752
- } from "@ccman/core";
753
2676
 
754
2677
  // src/interactive.ts
2678
+ init_dist();
755
2679
  import inquirer7 from "inquirer";
756
2680
  import chalk11 from "chalk";
757
- import { createCodexManager as createCodexManager3, createClaudeManager as createClaudeManager3 } from "@ccman/core";
758
2681
 
759
2682
  // src/utils/format.ts
760
2683
  import chalk2 from "chalk";
@@ -938,7 +2861,7 @@ async function showPresetsMenu() {
938
2861
  console.log(chalk11.yellow("\n\u26A0\uFE0F \u9884\u7F6E\u670D\u52A1\u5546\u7BA1\u7406\u529F\u80FD\u5373\u5C06\u63A8\u51FA\n"));
939
2862
  }
940
2863
  async function handleAdd(tool) {
941
- const manager = tool === "codex" ? createCodexManager3() : createClaudeManager3();
2864
+ const manager = tool === "codex" ? createCodexManager() : createClaudeManager();
942
2865
  const toolName = tool === "claude" ? "Claude" : "Codex";
943
2866
  const presets = manager.listPresets();
944
2867
  console.log(chalk11.bold(`
@@ -1044,7 +2967,7 @@ async function handleAdd(tool) {
1044
2967
  }
1045
2968
  }
1046
2969
  async function handleSwitch(tool) {
1047
- const manager = tool === "codex" ? createCodexManager3() : createClaudeManager3();
2970
+ const manager = tool === "codex" ? createCodexManager() : createClaudeManager();
1048
2971
  const providers = manager.list();
1049
2972
  const current = manager.getCurrent();
1050
2973
  if (providers.length === 0) {
@@ -1069,7 +2992,7 @@ async function handleSwitch(tool) {
1069
2992
  `));
1070
2993
  }
1071
2994
  async function handleList(tool) {
1072
- const manager = tool === "codex" ? createCodexManager3() : createClaudeManager3();
2995
+ const manager = tool === "codex" ? createCodexManager() : createClaudeManager();
1073
2996
  const providers = manager.list();
1074
2997
  const current = manager.getCurrent();
1075
2998
  const toolName = tool === "claude" ? "Claude" : "Codex";
@@ -1084,7 +3007,7 @@ async function handleList(tool) {
1084
3007
  console.log(formatProviderTable(providers, current?.id));
1085
3008
  }
1086
3009
  async function handleCurrent(tool) {
1087
- const manager = tool === "codex" ? createCodexManager3() : createClaudeManager3();
3010
+ const manager = tool === "codex" ? createCodexManager() : createClaudeManager();
1088
3011
  const current = manager.getCurrent();
1089
3012
  const toolName = tool === "claude" ? "Claude" : "Codex";
1090
3013
  if (!current) {
@@ -1105,7 +3028,7 @@ async function handleCurrent(tool) {
1105
3028
  console.log();
1106
3029
  }
1107
3030
  async function handleEdit(tool) {
1108
- const manager = tool === "codex" ? createCodexManager3() : createClaudeManager3();
3031
+ const manager = tool === "codex" ? createCodexManager() : createClaudeManager();
1109
3032
  const providers = manager.list();
1110
3033
  if (providers.length === 0) {
1111
3034
  console.log(chalk11.yellow("\n\u26A0\uFE0F \u6682\u65E0\u670D\u52A1\u5546\n"));
@@ -1166,7 +3089,7 @@ async function handleEdit(tool) {
1166
3089
  console.log(chalk11.green("\n\u2705 \u7F16\u8F91\u6210\u529F\n"));
1167
3090
  }
1168
3091
  async function handleClone(tool) {
1169
- const manager = tool === "codex" ? createCodexManager3() : createClaudeManager3();
3092
+ const manager = tool === "codex" ? createCodexManager() : createClaudeManager();
1170
3093
  const providers = manager.list();
1171
3094
  if (providers.length === 0) {
1172
3095
  console.log(chalk11.yellow("\n\u26A0\uFE0F \u6682\u65E0\u670D\u52A1\u5546\n"));
@@ -1213,7 +3136,7 @@ async function handleClone(tool) {
1213
3136
  console.log();
1214
3137
  }
1215
3138
  async function handleRemove(tool) {
1216
- const manager = tool === "codex" ? createCodexManager3() : createClaudeManager3();
3139
+ const manager = tool === "codex" ? createCodexManager() : createClaudeManager();
1217
3140
  const providers = manager.list();
1218
3141
  if (providers.length === 0) {
1219
3142
  console.log(chalk11.yellow("\n\u26A0\uFE0F \u6682\u65E0\u670D\u52A1\u5546\n"));
@@ -1253,7 +3176,7 @@ async function handleRemove(tool) {
1253
3176
  function addCommand(program2) {
1254
3177
  program2.command("add").description("\u6DFB\u52A0\u65B0\u7684 Codex \u670D\u52A1\u5546(\u4EA4\u4E92\u5F0F)").action(async () => {
1255
3178
  try {
1256
- const manager = createCodexManager4();
3179
+ const manager = createCodexManager();
1257
3180
  console.log(chalk12.bold("\n\u{1F4DD} \u6DFB\u52A0 Codex \u670D\u52A1\u5546\n"));
1258
3181
  const { usePreset } = await inquirer8.prompt([
1259
3182
  {
@@ -1370,12 +3293,12 @@ function addCommand(program2) {
1370
3293
  }
1371
3294
 
1372
3295
  // src/commands/codex/list.ts
3296
+ init_dist();
1373
3297
  import chalk13 from "chalk";
1374
- import { createCodexManager as createCodexManager5 } from "@ccman/core";
1375
3298
  function listCommand(program2) {
1376
3299
  program2.command("list").alias("ls").description("\u5217\u51FA\u6240\u6709 Codex \u670D\u52A1\u5546").action(async () => {
1377
3300
  try {
1378
- const manager = createCodexManager5();
3301
+ const manager = createCodexManager();
1379
3302
  const providers = manager.list();
1380
3303
  const current = manager.getCurrent();
1381
3304
  if (providers.length === 0) {
@@ -1396,18 +3319,13 @@ function listCommand(program2) {
1396
3319
  }
1397
3320
 
1398
3321
  // src/commands/codex/use.ts
3322
+ init_dist();
1399
3323
  import chalk14 from "chalk";
1400
3324
  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
3325
  function useCommand(program2) {
1408
3326
  program2.command("use [name]").description("\u5207\u6362 Codex \u670D\u52A1\u5546").action(async (name) => {
1409
3327
  try {
1410
- const manager = createCodexManager6();
3328
+ const manager = createCodexManager();
1411
3329
  const providers = manager.list();
1412
3330
  if (providers.length === 0) {
1413
3331
  console.log(chalk14.yellow("\n\u26A0\uFE0F \u6682\u65E0 Codex \u670D\u52A1\u5546\n"));
@@ -1444,8 +3362,8 @@ function useCommand(program2) {
1444
3362
  console.log(` ${chalk14.gray(`URL: ${provider.baseUrl}`)}`);
1445
3363
  console.log();
1446
3364
  console.log(chalk14.gray("\u914D\u7F6E\u5DF2\u66F4\u65B0:"));
1447
- console.log(chalk14.gray(` - ${getCodexConfigPath2()}`));
1448
- console.log(chalk14.gray(` - ${getCodexAuthPath2()}`));
3365
+ console.log(chalk14.gray(` - ${getCodexConfigPath()}`));
3366
+ console.log(chalk14.gray(` - ${getCodexAuthPath()}`));
1449
3367
  console.log();
1450
3368
  } catch (error) {
1451
3369
  if (error instanceof ProviderNotFoundError) {
@@ -1464,12 +3382,12 @@ function useCommand(program2) {
1464
3382
  }
1465
3383
 
1466
3384
  // src/commands/codex/current.ts
3385
+ init_dist();
1467
3386
  import chalk15 from "chalk";
1468
- import { createCodexManager as createCodexManager7 } from "@ccman/core";
1469
3387
  function currentCommand(program2) {
1470
3388
  program2.command("current").description("\u663E\u793A\u5F53\u524D\u4F7F\u7528\u7684 Codex \u670D\u52A1\u5546").action(async () => {
1471
3389
  try {
1472
- const manager = createCodexManager7();
3390
+ const manager = createCodexManager();
1473
3391
  const current = manager.getCurrent();
1474
3392
  if (!current) {
1475
3393
  console.log(chalk15.yellow("\n\u26A0\uFE0F \u672A\u9009\u62E9\u4EFB\u4F55 Codex \u670D\u52A1\u5546\n"));
@@ -1495,13 +3413,13 @@ function currentCommand(program2) {
1495
3413
  }
1496
3414
 
1497
3415
  // src/commands/codex/remove.ts
3416
+ init_dist();
1498
3417
  import chalk16 from "chalk";
1499
3418
  import inquirer10 from "inquirer";
1500
- import { createCodexManager as createCodexManager8, ProviderNotFoundError as ProviderNotFoundError2 } from "@ccman/core";
1501
3419
  function removeCommand(program2) {
1502
3420
  program2.command("remove [name]").alias("rm").description("\u5220\u9664 Codex \u670D\u52A1\u5546").action(async (name) => {
1503
3421
  try {
1504
- const manager = createCodexManager8();
3422
+ const manager = createCodexManager();
1505
3423
  const providers = manager.list();
1506
3424
  if (providers.length === 0) {
1507
3425
  console.log(chalk16.yellow("\n\u26A0\uFE0F \u6682\u65E0 Codex \u670D\u52A1\u5546\n"));
@@ -1512,7 +3430,7 @@ function removeCommand(program2) {
1512
3430
  if (name) {
1513
3431
  const provider = manager.findByName(name);
1514
3432
  if (!provider) {
1515
- throw new ProviderNotFoundError2(name);
3433
+ throw new ProviderNotFoundError(name);
1516
3434
  }
1517
3435
  targetId = provider.id;
1518
3436
  targetName = provider.name;
@@ -1549,7 +3467,7 @@ function removeCommand(program2) {
1549
3467
  console.log(chalk16.green(`\u2705 \u5DF2\u5220\u9664: ${targetName}`));
1550
3468
  console.log();
1551
3469
  } catch (error) {
1552
- if (error instanceof ProviderNotFoundError2) {
3470
+ if (error instanceof ProviderNotFoundError) {
1553
3471
  console.error(chalk16.red(`
1554
3472
  \u274C \u670D\u52A1\u5546\u4E0D\u5B58\u5728
1555
3473
  `));
@@ -1565,13 +3483,13 @@ function removeCommand(program2) {
1565
3483
  }
1566
3484
 
1567
3485
  // src/commands/codex/edit.ts
3486
+ init_dist();
1568
3487
  import chalk17 from "chalk";
1569
3488
  import inquirer11 from "inquirer";
1570
- import { createCodexManager as createCodexManager9, ProviderNotFoundError as ProviderNotFoundError3 } from "@ccman/core";
1571
3489
  function editCommand(program2) {
1572
3490
  program2.command("edit [name]").description("\u7F16\u8F91 Codex \u670D\u52A1\u5546").action(async (name) => {
1573
3491
  try {
1574
- const manager = createCodexManager9();
3492
+ const manager = createCodexManager();
1575
3493
  const providers = manager.list();
1576
3494
  if (providers.length === 0) {
1577
3495
  console.log(chalk17.yellow("\n\u26A0\uFE0F \u6682\u65E0 Codex \u670D\u52A1\u5546\n"));
@@ -1581,7 +3499,7 @@ function editCommand(program2) {
1581
3499
  if (name) {
1582
3500
  const provider2 = manager.findByName(name);
1583
3501
  if (!provider2) {
1584
- throw new ProviderNotFoundError3(name);
3502
+ throw new ProviderNotFoundError(name);
1585
3503
  }
1586
3504
  targetId = provider2.id;
1587
3505
  } else {
@@ -1653,13 +3571,13 @@ function editCommand(program2) {
1653
3571
  }
1654
3572
 
1655
3573
  // src/commands/codex/clone.ts
3574
+ init_dist();
1656
3575
  import chalk18 from "chalk";
1657
3576
  import inquirer12 from "inquirer";
1658
- import { createCodexManager as createCodexManager10, ProviderNotFoundError as ProviderNotFoundError4 } from "@ccman/core";
1659
3577
  function cloneCommand(program2) {
1660
3578
  program2.command("clone [source-name] [new-name]").description("\u514B\u9686 Codex \u670D\u52A1\u5546").action(async (sourceName, newName) => {
1661
3579
  try {
1662
- const manager = createCodexManager10();
3580
+ const manager = createCodexManager();
1663
3581
  const providers = manager.list();
1664
3582
  if (providers.length === 0) {
1665
3583
  console.log(chalk18.yellow("\n\u26A0\uFE0F \u6682\u65E0 Codex \u670D\u52A1\u5546\n"));
@@ -1669,7 +3587,7 @@ function cloneCommand(program2) {
1669
3587
  if (sourceName) {
1670
3588
  const provider = manager.findByName(sourceName);
1671
3589
  if (!provider) {
1672
- throw new ProviderNotFoundError4(sourceName);
3590
+ throw new ProviderNotFoundError(sourceName);
1673
3591
  }
1674
3592
  sourceId = provider.id;
1675
3593
  } else {
@@ -1731,17 +3649,13 @@ function createCodexCommands(program2) {
1731
3649
  }
1732
3650
 
1733
3651
  // src/commands/claude/add.ts
3652
+ init_dist();
1734
3653
  import chalk19 from "chalk";
1735
3654
  import inquirer13 from "inquirer";
1736
- import {
1737
- createClaudeManager as createClaudeManager4,
1738
- CC_PRESETS,
1739
- getClaudeConfigPath
1740
- } from "@ccman/core";
1741
3655
  function addCommand2(program2) {
1742
3656
  program2.command("add").description("\u6DFB\u52A0\u65B0\u7684 Claude Code \u670D\u52A1\u5546(\u4EA4\u4E92\u5F0F)").action(async () => {
1743
3657
  try {
1744
- const manager = createClaudeManager4();
3658
+ const manager = createClaudeManager();
1745
3659
  console.log(chalk19.bold("\n\u{1F4DD} \u6DFB\u52A0 Claude Code \u670D\u52A1\u5546\n"));
1746
3660
  const { usePreset } = await inquirer13.prompt([
1747
3661
  {
@@ -1857,12 +3771,12 @@ function addCommand2(program2) {
1857
3771
  }
1858
3772
 
1859
3773
  // src/commands/claude/list.ts
3774
+ init_dist();
1860
3775
  import chalk20 from "chalk";
1861
- import { createClaudeManager as createClaudeManager5 } from "@ccman/core";
1862
3776
  function listCommand2(program2) {
1863
3777
  program2.command("list").alias("ls").description("\u5217\u51FA\u6240\u6709 Claude Code \u670D\u52A1\u5546").action(async () => {
1864
3778
  try {
1865
- const manager = createClaudeManager5();
3779
+ const manager = createClaudeManager();
1866
3780
  const providers = manager.list();
1867
3781
  const current = manager.getCurrent();
1868
3782
  if (providers.length === 0) {
@@ -1883,17 +3797,13 @@ function listCommand2(program2) {
1883
3797
  }
1884
3798
 
1885
3799
  // src/commands/claude/use.ts
3800
+ init_dist();
1886
3801
  import chalk21 from "chalk";
1887
3802
  import inquirer14 from "inquirer";
1888
- import {
1889
- createClaudeManager as createClaudeManager6,
1890
- ProviderNotFoundError as ProviderNotFoundError5,
1891
- getClaudeConfigPath as getClaudeConfigPath2
1892
- } from "@ccman/core";
1893
3803
  function useCommand2(program2) {
1894
3804
  program2.command("use [name]").description("\u5207\u6362 Claude Code \u670D\u52A1\u5546").action(async (name) => {
1895
3805
  try {
1896
- const manager = createClaudeManager6();
3806
+ const manager = createClaudeManager();
1897
3807
  const providers = manager.list();
1898
3808
  if (providers.length === 0) {
1899
3809
  console.log(chalk21.yellow("\n\u26A0\uFE0F \u6682\u65E0 Claude Code \u670D\u52A1\u5546\n"));
@@ -1904,7 +3814,7 @@ function useCommand2(program2) {
1904
3814
  if (name) {
1905
3815
  const provider2 = manager.findByName(name);
1906
3816
  if (!provider2) {
1907
- throw new ProviderNotFoundError5(name);
3817
+ throw new ProviderNotFoundError(name);
1908
3818
  }
1909
3819
  targetId = provider2.id;
1910
3820
  } else {
@@ -1930,10 +3840,10 @@ function useCommand2(program2) {
1930
3840
  console.log(` ${chalk21.gray(`URL: ${provider.baseUrl}`)}`);
1931
3841
  console.log();
1932
3842
  console.log(chalk21.gray("\u914D\u7F6E\u5DF2\u66F4\u65B0:"));
1933
- console.log(chalk21.gray(` - ${getClaudeConfigPath2()}`));
3843
+ console.log(chalk21.gray(` - ${getClaudeConfigPath()}`));
1934
3844
  console.log();
1935
3845
  } catch (error) {
1936
- if (error instanceof ProviderNotFoundError5) {
3846
+ if (error instanceof ProviderNotFoundError) {
1937
3847
  console.error(chalk21.red(`
1938
3848
  \u274C \u670D\u52A1\u5546\u4E0D\u5B58\u5728: ${error.message}
1939
3849
  `));
@@ -1949,12 +3859,12 @@ function useCommand2(program2) {
1949
3859
  }
1950
3860
 
1951
3861
  // src/commands/claude/current.ts
3862
+ init_dist();
1952
3863
  import chalk22 from "chalk";
1953
- import { createClaudeManager as createClaudeManager7 } from "@ccman/core";
1954
3864
  function currentCommand2(program2) {
1955
3865
  program2.command("current").description("\u663E\u793A\u5F53\u524D\u4F7F\u7528\u7684 Claude Code \u670D\u52A1\u5546").action(async () => {
1956
3866
  try {
1957
- const manager = createClaudeManager7();
3867
+ const manager = createClaudeManager();
1958
3868
  const current = manager.getCurrent();
1959
3869
  if (!current) {
1960
3870
  console.log(chalk22.yellow("\n\u26A0\uFE0F \u672A\u9009\u62E9\u4EFB\u4F55 Claude Code \u670D\u52A1\u5546\n"));
@@ -1980,13 +3890,13 @@ function currentCommand2(program2) {
1980
3890
  }
1981
3891
 
1982
3892
  // src/commands/claude/remove.ts
3893
+ init_dist();
1983
3894
  import chalk23 from "chalk";
1984
3895
  import inquirer15 from "inquirer";
1985
- import { createClaudeManager as createClaudeManager8, ProviderNotFoundError as ProviderNotFoundError6 } from "@ccman/core";
1986
3896
  function removeCommand2(program2) {
1987
3897
  program2.command("remove [name]").alias("rm").description("\u5220\u9664 Claude Code \u670D\u52A1\u5546").action(async (name) => {
1988
3898
  try {
1989
- const manager = createClaudeManager8();
3899
+ const manager = createClaudeManager();
1990
3900
  const providers = manager.list();
1991
3901
  if (providers.length === 0) {
1992
3902
  console.log(chalk23.yellow("\n\u26A0\uFE0F \u6682\u65E0 Claude Code \u670D\u52A1\u5546\n"));
@@ -1997,7 +3907,7 @@ function removeCommand2(program2) {
1997
3907
  if (name) {
1998
3908
  const provider = manager.findByName(name);
1999
3909
  if (!provider) {
2000
- throw new ProviderNotFoundError6(name);
3910
+ throw new ProviderNotFoundError(name);
2001
3911
  }
2002
3912
  targetId = provider.id;
2003
3913
  targetName = provider.name;
@@ -2034,7 +3944,7 @@ function removeCommand2(program2) {
2034
3944
  console.log(chalk23.green(`\u2705 \u5DF2\u5220\u9664: ${targetName}`));
2035
3945
  console.log();
2036
3946
  } catch (error) {
2037
- if (error instanceof ProviderNotFoundError6) {
3947
+ if (error instanceof ProviderNotFoundError) {
2038
3948
  console.error(chalk23.red(`
2039
3949
  \u274C \u670D\u52A1\u5546\u4E0D\u5B58\u5728
2040
3950
  `));
@@ -2050,13 +3960,13 @@ function removeCommand2(program2) {
2050
3960
  }
2051
3961
 
2052
3962
  // src/commands/claude/edit.ts
3963
+ init_dist();
2053
3964
  import chalk24 from "chalk";
2054
3965
  import inquirer16 from "inquirer";
2055
- import { createClaudeManager as createClaudeManager9, ProviderNotFoundError as ProviderNotFoundError7 } from "@ccman/core";
2056
3966
  function editCommand2(program2) {
2057
3967
  program2.command("edit [name]").description("\u7F16\u8F91 Claude Code \u670D\u52A1\u5546").action(async (name) => {
2058
3968
  try {
2059
- const manager = createClaudeManager9();
3969
+ const manager = createClaudeManager();
2060
3970
  const providers = manager.list();
2061
3971
  if (providers.length === 0) {
2062
3972
  console.log(chalk24.yellow("\n\u26A0\uFE0F \u6682\u65E0 Claude Code \u670D\u52A1\u5546\n"));
@@ -2066,7 +3976,7 @@ function editCommand2(program2) {
2066
3976
  if (name) {
2067
3977
  const provider2 = manager.findByName(name);
2068
3978
  if (!provider2) {
2069
- throw new ProviderNotFoundError7(name);
3979
+ throw new ProviderNotFoundError(name);
2070
3980
  }
2071
3981
  targetId = provider2.id;
2072
3982
  } else {
@@ -2138,13 +4048,13 @@ function editCommand2(program2) {
2138
4048
  }
2139
4049
 
2140
4050
  // src/commands/claude/clone.ts
4051
+ init_dist();
2141
4052
  import chalk25 from "chalk";
2142
4053
  import inquirer17 from "inquirer";
2143
- import { createClaudeManager as createClaudeManager10, ProviderNotFoundError as ProviderNotFoundError8 } from "@ccman/core";
2144
4054
  function cloneCommand2(program2) {
2145
4055
  program2.command("clone [source-name] [new-name]").description("\u514B\u9686 Claude Code \u670D\u52A1\u5546").action(async (sourceName, newName) => {
2146
4056
  try {
2147
- const manager = createClaudeManager10();
4057
+ const manager = createClaudeManager();
2148
4058
  const providers = manager.list();
2149
4059
  if (providers.length === 0) {
2150
4060
  console.log(chalk25.yellow("\n\u26A0\uFE0F \u6682\u65E0 Claude Code \u670D\u52A1\u5546\n"));
@@ -2154,7 +4064,7 @@ function cloneCommand2(program2) {
2154
4064
  if (sourceName) {
2155
4065
  const provider = manager.findByName(sourceName);
2156
4066
  if (!provider) {
2157
- throw new ProviderNotFoundError8(sourceName);
4067
+ throw new ProviderNotFoundError(sourceName);
2158
4068
  }
2159
4069
  sourceId = provider.id;
2160
4070
  } else {
@@ -2205,10 +4115,10 @@ function cloneCommand2(program2) {
2205
4115
  }
2206
4116
 
2207
4117
  // src/commands/clean.ts
4118
+ init_dist();
2208
4119
  import chalk26 from "chalk";
2209
4120
  import inquirer18 from "inquirer";
2210
- import { analyzeClaudeJson, cleanClaudeJson, CleanPresets } from "@ccman/core";
2211
- function formatBytes(bytes) {
4121
+ function formatBytes2(bytes) {
2212
4122
  if (bytes < 1024) return `${bytes} B`;
2213
4123
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
2214
4124
  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
@@ -2231,9 +4141,9 @@ function displayAnalysis() {
2231
4141
  }
2232
4142
  console.log();
2233
4143
  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))}`);
4144
+ console.log(` ${chalk26.green("\u4FDD\u5B88\u6E05\u7406")} (\u4FDD\u755910\u6761): ${chalk26.bold(formatBytes2(analysis.estimatedSavings.conservative))}`);
4145
+ console.log(` ${chalk26.yellow("\u4E2D\u7B49\u6E05\u7406")} (\u4FDD\u75595\u6761): ${chalk26.bold(formatBytes2(analysis.estimatedSavings.moderate))}`);
4146
+ console.log(` ${chalk26.red("\u6FC0\u8FDB\u6E05\u7406")} (\u6E05\u7A7A\u5386\u53F2): ${chalk26.bold(formatBytes2(analysis.estimatedSavings.aggressive))}`);
2237
4147
  console.log();
2238
4148
  console.log(chalk26.blue(`\u{1F4A1} \u6267\u884C\u6E05\u7406: ccman cc clean
2239
4149
  `));
@@ -2278,9 +4188,9 @@ function cleanCommand(program2) {
2278
4188
  console.log(chalk26.cyan("\n\u6B63\u5728\u6E05\u7406...\n"));
2279
4189
  const result = cleanClaudeJson(cleanOptions);
2280
4190
  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)}%)`);
4191
+ console.log(`\u6E05\u7406\u524D: ${chalk26.bold(formatBytes2(result.sizeBefore))}`);
4192
+ console.log(`\u6E05\u7406\u540E: ${chalk26.bold(formatBytes2(result.sizeAfter))}`);
4193
+ console.log(`\u8282\u7701\u7A7A\u95F4: ${chalk26.green.bold(formatBytes2(result.saved))} (${(result.saved / result.sizeBefore * 100).toFixed(1)}%)`);
2284
4194
  console.log();
2285
4195
  if (result.cleanedItems.projectHistory > 0) {
2286
4196
  console.log(`\u6E05\u7406\u5386\u53F2\u8BB0\u5F55: ${chalk26.bold(result.cleanedItems.projectHistory)} \u6761`);
@@ -2346,15 +4256,15 @@ async function promptForOptions(analysis) {
2346
4256
  message: "\u9009\u62E9\u6E05\u7406\u65B9\u6848:",
2347
4257
  choices: [
2348
4258
  {
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)})`,
4259
+ 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
4260
  value: "conservative"
2351
4261
  },
2352
4262
  {
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)})`,
4263
+ 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
4264
  value: "moderate"
2355
4265
  },
2356
4266
  {
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)})`,
4267
+ 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
4268
  value: "aggressive"
2359
4269
  },
2360
4270
  {
@@ -2422,9 +4332,9 @@ function createClaudeCommands(program2) {
2422
4332
  }
2423
4333
 
2424
4334
  // src/commands/mcp/add.ts
4335
+ init_dist();
2425
4336
  import chalk27 from "chalk";
2426
4337
  import inquirer19 from "inquirer";
2427
- import { createMCPManager, MCP_PRESETS_DETAIL, getClaudeConfigPath as getClaudeConfigPath3 } from "@ccman/core";
2428
4338
  function addCommand3(program2) {
2429
4339
  program2.command("add").description("\u6DFB\u52A0\u65B0\u7684 MCP \u670D\u52A1\u5668(\u4EA4\u4E92\u5F0F)").action(async () => {
2430
4340
  try {
@@ -2571,7 +4481,7 @@ function addCommand3(program2) {
2571
4481
  console.log(chalk27.green("\u2705 \u914D\u7F6E\u5DF2\u81EA\u52A8\u540C\u6B65\u5230 ~/.claude.json"));
2572
4482
  console.log();
2573
4483
  console.log(chalk27.gray("\u914D\u7F6E\u6587\u4EF6:"));
2574
- console.log(chalk27.gray(` - ${getClaudeConfigPath3()}`));
4484
+ console.log(chalk27.gray(` - ${getClaudeConfigPath()}`));
2575
4485
  console.log();
2576
4486
  } catch (error) {
2577
4487
  console.error(chalk27.red(`
@@ -2583,12 +4493,12 @@ function addCommand3(program2) {
2583
4493
  }
2584
4494
 
2585
4495
  // src/commands/mcp/list.ts
4496
+ init_dist();
2586
4497
  import chalk28 from "chalk";
2587
- import { createMCPManager as createMCPManager2 } from "@ccman/core";
2588
4498
  function listCommand3(program2) {
2589
4499
  program2.command("list").alias("ls").description("\u5217\u51FA\u6240\u6709 MCP \u670D\u52A1\u5668").action(async () => {
2590
4500
  try {
2591
- const manager = createMCPManager2();
4501
+ const manager = createMCPManager();
2592
4502
  const providers = manager.list();
2593
4503
  if (providers.length === 0) {
2594
4504
  console.log(chalk28.yellow("\n\u26A0\uFE0F \u6682\u65E0 MCP \u670D\u52A1\u5668\n"));
@@ -2629,13 +4539,13 @@ function listCommand3(program2) {
2629
4539
  }
2630
4540
 
2631
4541
  // src/commands/mcp/remove.ts
4542
+ init_dist();
2632
4543
  import chalk29 from "chalk";
2633
4544
  import inquirer20 from "inquirer";
2634
- import { createMCPManager as createMCPManager3, ProviderNotFoundError as ProviderNotFoundError9, getClaudeConfigPath as getClaudeConfigPath4 } from "@ccman/core";
2635
4545
  function removeCommand3(program2) {
2636
4546
  program2.command("remove [name]").alias("rm").description("\u5220\u9664 MCP \u670D\u52A1\u5668").action(async (name) => {
2637
4547
  try {
2638
- const manager = createMCPManager3();
4548
+ const manager = createMCPManager();
2639
4549
  const providers = manager.list();
2640
4550
  if (providers.length === 0) {
2641
4551
  console.log(chalk29.yellow("\n\u26A0\uFE0F \u6682\u65E0 MCP \u670D\u52A1\u5668\n"));
@@ -2646,7 +4556,7 @@ function removeCommand3(program2) {
2646
4556
  if (name) {
2647
4557
  const provider = manager.findByName(name);
2648
4558
  if (!provider) {
2649
- throw new ProviderNotFoundError9(name);
4559
+ throw new ProviderNotFoundError(name);
2650
4560
  }
2651
4561
  targetId = provider.id;
2652
4562
  targetName = provider.name;
@@ -2685,10 +4595,10 @@ function removeCommand3(program2) {
2685
4595
  console.log(chalk29.green("\u2705 \u914D\u7F6E\u5DF2\u81EA\u52A8\u540C\u6B65\u5230 ~/.claude.json"));
2686
4596
  console.log();
2687
4597
  console.log(chalk29.gray("\u914D\u7F6E\u6587\u4EF6:"));
2688
- console.log(chalk29.gray(` - ${getClaudeConfigPath4()}`));
4598
+ console.log(chalk29.gray(` - ${getClaudeConfigPath()}`));
2689
4599
  console.log();
2690
4600
  } catch (error) {
2691
- if (error instanceof ProviderNotFoundError9) {
4601
+ if (error instanceof ProviderNotFoundError) {
2692
4602
  console.error(chalk29.red(`
2693
4603
  \u274C MCP \u670D\u52A1\u5668\u4E0D\u5B58\u5728
2694
4604
  `));
@@ -2704,13 +4614,13 @@ function removeCommand3(program2) {
2704
4614
  }
2705
4615
 
2706
4616
  // src/commands/mcp/edit.ts
4617
+ init_dist();
2707
4618
  import chalk30 from "chalk";
2708
4619
  import inquirer21 from "inquirer";
2709
- import { createMCPManager as createMCPManager4, ProviderNotFoundError as ProviderNotFoundError10, getClaudeConfigPath as getClaudeConfigPath5 } from "@ccman/core";
2710
4620
  function editCommand3(program2) {
2711
4621
  program2.command("edit [name]").description("\u7F16\u8F91 MCP \u670D\u52A1\u5668").action(async (name) => {
2712
4622
  try {
2713
- const manager = createMCPManager4();
4623
+ const manager = createMCPManager();
2714
4624
  const providers = manager.list();
2715
4625
  if (providers.length === 0) {
2716
4626
  console.log(chalk30.yellow("\n\u26A0\uFE0F \u6682\u65E0 MCP \u670D\u52A1\u5668\n"));
@@ -2720,7 +4630,7 @@ function editCommand3(program2) {
2720
4630
  if (name) {
2721
4631
  const provider2 = manager.findByName(name);
2722
4632
  if (!provider2) {
2723
- throw new ProviderNotFoundError10(name);
4633
+ throw new ProviderNotFoundError(name);
2724
4634
  }
2725
4635
  targetId = provider2.id;
2726
4636
  } else {
@@ -2803,7 +4713,7 @@ function editCommand3(program2) {
2803
4713
  console.log(chalk30.green("\u2705 \u914D\u7F6E\u5DF2\u81EA\u52A8\u540C\u6B65\u5230 ~/.claude.json"));
2804
4714
  console.log();
2805
4715
  console.log(chalk30.gray("\u914D\u7F6E\u6587\u4EF6:"));
2806
- console.log(chalk30.gray(` - ${getClaudeConfigPath5()}`));
4716
+ console.log(chalk30.gray(` - ${getClaudeConfigPath()}`));
2807
4717
  console.log();
2808
4718
  } catch (error) {
2809
4719
  console.error(chalk30.red(`
@@ -2826,9 +4736,9 @@ function createMCPCommands(program2) {
2826
4736
  init_sync();
2827
4737
 
2828
4738
  // src/commands/export.ts
4739
+ init_dist();
2829
4740
  import chalk31 from "chalk";
2830
- import path from "path";
2831
- import { exportConfig, validateExport } from "@ccman/core";
4741
+ import path10 from "path";
2832
4742
  function exportCommand(program2) {
2833
4743
  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
4744
  try {
@@ -2839,7 +4749,7 @@ function exportCommand(program2) {
2839
4749
  `));
2840
4750
  process.exit(1);
2841
4751
  }
2842
- const resolvedPath = targetDir.startsWith("~") ? path.join(process.env.HOME || "", targetDir.slice(1)) : path.resolve(targetDir);
4752
+ const resolvedPath = targetDir.startsWith("~") ? path10.join(process.env.HOME || "", targetDir.slice(1)) : path10.resolve(targetDir);
2843
4753
  console.log("\u5BFC\u51FA\u6587\u4EF6:");
2844
4754
  console.log(` ${chalk31.cyan("codex.json")} - Codex \u914D\u7F6E`);
2845
4755
  console.log(` ${chalk31.cyan("claude.json")} - Claude \u914D\u7F6E`);
@@ -2868,14 +4778,14 @@ function exportCommand(program2) {
2868
4778
  }
2869
4779
 
2870
4780
  // src/commands/import.ts
4781
+ init_dist();
2871
4782
  import chalk32 from "chalk";
2872
4783
  import inquirer22 from "inquirer";
2873
- import path2 from "path";
2874
- import { importConfig, validateImportDir } from "@ccman/core";
4784
+ import path11 from "path";
2875
4785
  function importCommand(program2) {
2876
4786
  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
4787
  try {
2878
- const resolvedPath = sourceDir.startsWith("~") ? path2.join(process.env.HOME || "", sourceDir.slice(1)) : path2.resolve(sourceDir);
4788
+ const resolvedPath = sourceDir.startsWith("~") ? path11.join(process.env.HOME || "", sourceDir.slice(1)) : path11.resolve(sourceDir);
2879
4789
  console.log(chalk32.bold("\n\u{1F4E5} \u5BFC\u5165\u914D\u7F6E\n"));
2880
4790
  const validation = validateImportDir(resolvedPath);
2881
4791
  if (!validation.valid) {
@@ -2950,7 +4860,7 @@ function importCommand(program2) {
2950
4860
  }
2951
4861
 
2952
4862
  // src/index.ts
2953
- import { getCcmanDir, getCodexDir, getClaudeDir, VERSION as VERSION2 } from "@ccman/core";
4863
+ init_dist();
2954
4864
  if (process.env.NODE_ENV === "development") {
2955
4865
  console.log(chalk33.gray("\n[\u5F00\u53D1\u6A21\u5F0F] \u914D\u7F6E\u76EE\u5F55:"));
2956
4866
  console.log(chalk33.gray(` ccman: ${getCcmanDir()}`));
@@ -2959,7 +4869,7 @@ if (process.env.NODE_ENV === "development") {
2959
4869
  console.log();
2960
4870
  }
2961
4871
  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) => {
4872
+ program.name("ccman").description("Codex/Claude Code API \u670D\u52A1\u5546\u914D\u7F6E\u7BA1\u7406\u5DE5\u5177").version(VERSION).showHelpAfterError(false).exitOverride((err) => {
2963
4873
  if (err.code === "commander.helpDisplayed" || err.code === "commander.version") {
2964
4874
  process.exit(0);
2965
4875
  }