ccman 3.0.21 → 3.0.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +319 -168
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -39,7 +39,7 @@ var init_package = __esm({
|
|
|
39
39
|
"../core/package.json"() {
|
|
40
40
|
package_default = {
|
|
41
41
|
name: "@ccman/core",
|
|
42
|
-
version: "3.0.
|
|
42
|
+
version: "3.0.22",
|
|
43
43
|
type: "module",
|
|
44
44
|
description: "Core business logic for ccman",
|
|
45
45
|
main: "./dist/index.js",
|
|
@@ -2357,20 +2357,20 @@ var init_claude2 = __esm({
|
|
|
2357
2357
|
});
|
|
2358
2358
|
|
|
2359
2359
|
// ../core/dist/tool-manager.js
|
|
2360
|
-
function
|
|
2361
|
-
const
|
|
2362
|
-
const
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
}
|
|
2360
|
+
function generateId(tool) {
|
|
2361
|
+
const timestamp = Date.now();
|
|
2362
|
+
const random = Math.random().toString(36).substring(2, 8);
|
|
2363
|
+
return `${tool}-${timestamp}-${random}`;
|
|
2364
|
+
}
|
|
2365
|
+
function createCodexManager() {
|
|
2366
|
+
const configPath = path3.join(getCcmanDir(), "codex.json");
|
|
2368
2367
|
function loadConfig2() {
|
|
2369
2368
|
if (!fileExists(configPath)) {
|
|
2370
2369
|
ensureDir(getCcmanDir());
|
|
2371
2370
|
const initialConfig = {
|
|
2372
2371
|
providers: [],
|
|
2373
2372
|
presets: []
|
|
2373
|
+
// 只存储用户自定义预置
|
|
2374
2374
|
};
|
|
2375
2375
|
writeJSON(configPath, initialConfig);
|
|
2376
2376
|
return initialConfig;
|
|
@@ -2389,11 +2389,12 @@ function createToolManager(tool) {
|
|
|
2389
2389
|
}
|
|
2390
2390
|
const timestamp = Date.now();
|
|
2391
2391
|
const provider = {
|
|
2392
|
-
id: generateId(),
|
|
2392
|
+
id: generateId("codex"),
|
|
2393
2393
|
name: input.name,
|
|
2394
2394
|
baseUrl: input.baseUrl,
|
|
2395
2395
|
apiKey: input.apiKey,
|
|
2396
2396
|
model: input.model,
|
|
2397
|
+
// 保存 model 字段
|
|
2397
2398
|
createdAt: timestamp,
|
|
2398
2399
|
lastModified: timestamp
|
|
2399
2400
|
};
|
|
@@ -2427,7 +2428,7 @@ function createToolManager(tool) {
|
|
|
2427
2428
|
config.currentProviderId = id;
|
|
2428
2429
|
provider.lastUsedAt = Date.now();
|
|
2429
2430
|
saveConfig2(config);
|
|
2430
|
-
|
|
2431
|
+
writeCodexConfig(provider);
|
|
2431
2432
|
},
|
|
2432
2433
|
getCurrent() {
|
|
2433
2434
|
const config = loadConfig2();
|
|
@@ -2460,7 +2461,7 @@ function createToolManager(tool) {
|
|
|
2460
2461
|
provider.lastModified = Date.now();
|
|
2461
2462
|
saveConfig2(config);
|
|
2462
2463
|
if (config.currentProviderId === id) {
|
|
2463
|
-
|
|
2464
|
+
writeCodexConfig(provider);
|
|
2464
2465
|
}
|
|
2465
2466
|
return provider;
|
|
2466
2467
|
},
|
|
@@ -2486,7 +2487,7 @@ function createToolManager(tool) {
|
|
|
2486
2487
|
const timestamp = Date.now();
|
|
2487
2488
|
const newProvider = {
|
|
2488
2489
|
...source,
|
|
2489
|
-
id: generateId(),
|
|
2490
|
+
id: generateId("codex"),
|
|
2490
2491
|
name: newName,
|
|
2491
2492
|
createdAt: timestamp,
|
|
2492
2493
|
lastModified: timestamp,
|
|
@@ -2501,7 +2502,7 @@ function createToolManager(tool) {
|
|
|
2501
2502
|
if (!config.presets) {
|
|
2502
2503
|
config.presets = [];
|
|
2503
2504
|
}
|
|
2504
|
-
const allPresets = [...
|
|
2505
|
+
const allPresets = [...CODEX_PRESETS, ...config.presets];
|
|
2505
2506
|
const nameExists = allPresets.some((p) => p.name === input.name);
|
|
2506
2507
|
if (nameExists) {
|
|
2507
2508
|
throw new PresetNameConflictError(input.name);
|
|
@@ -2513,23 +2514,12 @@ function createToolManager(tool) {
|
|
|
2513
2514
|
};
|
|
2514
2515
|
config.presets.push(preset);
|
|
2515
2516
|
saveConfig2(config);
|
|
2516
|
-
return
|
|
2517
|
-
...preset,
|
|
2518
|
-
isBuiltIn: false
|
|
2519
|
-
};
|
|
2517
|
+
return preset;
|
|
2520
2518
|
},
|
|
2521
2519
|
listPresets() {
|
|
2522
2520
|
const config = loadConfig2();
|
|
2523
2521
|
const userPresets = config.presets || [];
|
|
2524
|
-
|
|
2525
|
-
...p,
|
|
2526
|
-
isBuiltIn: true
|
|
2527
|
-
}));
|
|
2528
|
-
const userWithFlag = userPresets.map((p) => ({
|
|
2529
|
-
...p,
|
|
2530
|
-
isBuiltIn: false
|
|
2531
|
-
}));
|
|
2532
|
-
return [...builtinWithFlag, ...userWithFlag];
|
|
2522
|
+
return [...CODEX_PRESETS, ...userPresets];
|
|
2533
2523
|
},
|
|
2534
2524
|
editPreset(name, updates) {
|
|
2535
2525
|
const config = loadConfig2();
|
|
@@ -2541,7 +2531,7 @@ function createToolManager(tool) {
|
|
|
2541
2531
|
throw new Error(`\u9884\u7F6E\u4E0D\u5B58\u5728: ${name}`);
|
|
2542
2532
|
}
|
|
2543
2533
|
if (updates.name !== void 0 && updates.name !== preset.name) {
|
|
2544
|
-
const allPresets = [...
|
|
2534
|
+
const allPresets = [...CODEX_PRESETS, ...config.presets];
|
|
2545
2535
|
const nameConflict = allPresets.some((p) => p.name !== name && p.name === updates.name);
|
|
2546
2536
|
if (nameConflict) {
|
|
2547
2537
|
throw new PresetNameConflictError(updates.name);
|
|
@@ -2554,10 +2544,7 @@ function createToolManager(tool) {
|
|
|
2554
2544
|
if (updates.description !== void 0)
|
|
2555
2545
|
preset.description = updates.description;
|
|
2556
2546
|
saveConfig2(config);
|
|
2557
|
-
return
|
|
2558
|
-
...preset,
|
|
2559
|
-
isBuiltIn: false
|
|
2560
|
-
};
|
|
2547
|
+
return preset;
|
|
2561
2548
|
},
|
|
2562
2549
|
removePreset(name) {
|
|
2563
2550
|
const config = loadConfig2();
|
|
@@ -2573,13 +2560,201 @@ function createToolManager(tool) {
|
|
|
2573
2560
|
}
|
|
2574
2561
|
};
|
|
2575
2562
|
}
|
|
2576
|
-
function createCodexManager() {
|
|
2577
|
-
return createToolManager("codex");
|
|
2578
|
-
}
|
|
2579
2563
|
function createClaudeManager() {
|
|
2580
|
-
|
|
2564
|
+
const configPath = path3.join(getCcmanDir(), "claude.json");
|
|
2565
|
+
function loadConfig2() {
|
|
2566
|
+
if (!fileExists(configPath)) {
|
|
2567
|
+
ensureDir(getCcmanDir());
|
|
2568
|
+
const initialConfig = {
|
|
2569
|
+
providers: [],
|
|
2570
|
+
presets: []
|
|
2571
|
+
// 只存储用户自定义预置
|
|
2572
|
+
};
|
|
2573
|
+
writeJSON(configPath, initialConfig);
|
|
2574
|
+
return initialConfig;
|
|
2575
|
+
}
|
|
2576
|
+
return readJSON(configPath);
|
|
2577
|
+
}
|
|
2578
|
+
function saveConfig2(config) {
|
|
2579
|
+
writeJSON(configPath, config);
|
|
2580
|
+
}
|
|
2581
|
+
return {
|
|
2582
|
+
add(input) {
|
|
2583
|
+
const config = loadConfig2();
|
|
2584
|
+
const nameExists = config.providers.some((p) => p.name === input.name);
|
|
2585
|
+
if (nameExists) {
|
|
2586
|
+
throw new ProviderNameConflictError(input.name);
|
|
2587
|
+
}
|
|
2588
|
+
const timestamp = Date.now();
|
|
2589
|
+
const provider = {
|
|
2590
|
+
id: generateId("claude"),
|
|
2591
|
+
name: input.name,
|
|
2592
|
+
baseUrl: input.baseUrl,
|
|
2593
|
+
apiKey: input.apiKey,
|
|
2594
|
+
createdAt: timestamp,
|
|
2595
|
+
lastModified: timestamp
|
|
2596
|
+
};
|
|
2597
|
+
config.providers.push(provider);
|
|
2598
|
+
saveConfig2(config);
|
|
2599
|
+
return provider;
|
|
2600
|
+
},
|
|
2601
|
+
list() {
|
|
2602
|
+
const config = loadConfig2();
|
|
2603
|
+
return config.providers;
|
|
2604
|
+
},
|
|
2605
|
+
get(id) {
|
|
2606
|
+
const config = loadConfig2();
|
|
2607
|
+
const provider = config.providers.find((p) => p.id === id);
|
|
2608
|
+
if (!provider) {
|
|
2609
|
+
throw new ProviderNotFoundError(id);
|
|
2610
|
+
}
|
|
2611
|
+
return provider;
|
|
2612
|
+
},
|
|
2613
|
+
findByName(name) {
|
|
2614
|
+
const config = loadConfig2();
|
|
2615
|
+
const lowerName = name.toLowerCase();
|
|
2616
|
+
return config.providers.find((p) => p.name.toLowerCase() === lowerName);
|
|
2617
|
+
},
|
|
2618
|
+
switch(id) {
|
|
2619
|
+
const config = loadConfig2();
|
|
2620
|
+
const provider = config.providers.find((p) => p.id === id);
|
|
2621
|
+
if (!provider) {
|
|
2622
|
+
throw new ProviderNotFoundError(id);
|
|
2623
|
+
}
|
|
2624
|
+
config.currentProviderId = id;
|
|
2625
|
+
provider.lastUsedAt = Date.now();
|
|
2626
|
+
saveConfig2(config);
|
|
2627
|
+
writeClaudeConfig(provider);
|
|
2628
|
+
},
|
|
2629
|
+
getCurrent() {
|
|
2630
|
+
const config = loadConfig2();
|
|
2631
|
+
if (!config.currentProviderId) {
|
|
2632
|
+
return null;
|
|
2633
|
+
}
|
|
2634
|
+
const provider = config.providers.find((p) => p.id === config.currentProviderId);
|
|
2635
|
+
return provider || null;
|
|
2636
|
+
},
|
|
2637
|
+
edit(id, updates) {
|
|
2638
|
+
const config = loadConfig2();
|
|
2639
|
+
const provider = config.providers.find((p) => p.id === id);
|
|
2640
|
+
if (!provider) {
|
|
2641
|
+
throw new ProviderNotFoundError(id);
|
|
2642
|
+
}
|
|
2643
|
+
if (updates.name !== void 0 && updates.name !== provider.name) {
|
|
2644
|
+
const nameConflict = config.providers.some((p) => p.id !== id && p.name === updates.name);
|
|
2645
|
+
if (nameConflict) {
|
|
2646
|
+
throw new ProviderNameConflictError(updates.name);
|
|
2647
|
+
}
|
|
2648
|
+
}
|
|
2649
|
+
if (updates.name !== void 0)
|
|
2650
|
+
provider.name = updates.name;
|
|
2651
|
+
if (updates.baseUrl !== void 0)
|
|
2652
|
+
provider.baseUrl = updates.baseUrl;
|
|
2653
|
+
if (updates.apiKey !== void 0)
|
|
2654
|
+
provider.apiKey = updates.apiKey;
|
|
2655
|
+
provider.lastModified = Date.now();
|
|
2656
|
+
saveConfig2(config);
|
|
2657
|
+
if (config.currentProviderId === id) {
|
|
2658
|
+
writeClaudeConfig(provider);
|
|
2659
|
+
}
|
|
2660
|
+
return provider;
|
|
2661
|
+
},
|
|
2662
|
+
remove(id) {
|
|
2663
|
+
const config = loadConfig2();
|
|
2664
|
+
const index = config.providers.findIndex((p) => p.id === id);
|
|
2665
|
+
if (index === -1) {
|
|
2666
|
+
throw new ProviderNotFoundError(id);
|
|
2667
|
+
}
|
|
2668
|
+
if (config.currentProviderId === id) {
|
|
2669
|
+
config.currentProviderId = void 0;
|
|
2670
|
+
}
|
|
2671
|
+
config.providers.splice(index, 1);
|
|
2672
|
+
saveConfig2(config);
|
|
2673
|
+
},
|
|
2674
|
+
clone(sourceId, newName) {
|
|
2675
|
+
const source = this.get(sourceId);
|
|
2676
|
+
const config = loadConfig2();
|
|
2677
|
+
const nameExists = config.providers.some((p) => p.name === newName);
|
|
2678
|
+
if (nameExists) {
|
|
2679
|
+
throw new ProviderNameConflictError(newName);
|
|
2680
|
+
}
|
|
2681
|
+
const timestamp = Date.now();
|
|
2682
|
+
const newProvider = {
|
|
2683
|
+
...source,
|
|
2684
|
+
id: generateId("claude"),
|
|
2685
|
+
name: newName,
|
|
2686
|
+
createdAt: timestamp,
|
|
2687
|
+
lastModified: timestamp,
|
|
2688
|
+
lastUsedAt: void 0
|
|
2689
|
+
};
|
|
2690
|
+
config.providers.push(newProvider);
|
|
2691
|
+
saveConfig2(config);
|
|
2692
|
+
return newProvider;
|
|
2693
|
+
},
|
|
2694
|
+
addPreset(input) {
|
|
2695
|
+
const config = loadConfig2();
|
|
2696
|
+
if (!config.presets) {
|
|
2697
|
+
config.presets = [];
|
|
2698
|
+
}
|
|
2699
|
+
const allPresets = [...CC_PRESETS, ...config.presets];
|
|
2700
|
+
const nameExists = allPresets.some((p) => p.name === input.name);
|
|
2701
|
+
if (nameExists) {
|
|
2702
|
+
throw new PresetNameConflictError(input.name);
|
|
2703
|
+
}
|
|
2704
|
+
const preset = {
|
|
2705
|
+
name: input.name,
|
|
2706
|
+
baseUrl: input.baseUrl,
|
|
2707
|
+
description: input.description
|
|
2708
|
+
};
|
|
2709
|
+
config.presets.push(preset);
|
|
2710
|
+
saveConfig2(config);
|
|
2711
|
+
return preset;
|
|
2712
|
+
},
|
|
2713
|
+
listPresets() {
|
|
2714
|
+
const config = loadConfig2();
|
|
2715
|
+
const userPresets = config.presets || [];
|
|
2716
|
+
return [...CC_PRESETS, ...userPresets];
|
|
2717
|
+
},
|
|
2718
|
+
editPreset(name, updates) {
|
|
2719
|
+
const config = loadConfig2();
|
|
2720
|
+
if (!config.presets) {
|
|
2721
|
+
config.presets = [];
|
|
2722
|
+
}
|
|
2723
|
+
const preset = config.presets.find((p) => p.name === name);
|
|
2724
|
+
if (!preset) {
|
|
2725
|
+
throw new Error(`\u9884\u7F6E\u4E0D\u5B58\u5728: ${name}`);
|
|
2726
|
+
}
|
|
2727
|
+
if (updates.name !== void 0 && updates.name !== preset.name) {
|
|
2728
|
+
const allPresets = [...CC_PRESETS, ...config.presets];
|
|
2729
|
+
const nameConflict = allPresets.some((p) => p.name !== name && p.name === updates.name);
|
|
2730
|
+
if (nameConflict) {
|
|
2731
|
+
throw new PresetNameConflictError(updates.name);
|
|
2732
|
+
}
|
|
2733
|
+
}
|
|
2734
|
+
if (updates.name !== void 0)
|
|
2735
|
+
preset.name = updates.name;
|
|
2736
|
+
if (updates.baseUrl !== void 0)
|
|
2737
|
+
preset.baseUrl = updates.baseUrl;
|
|
2738
|
+
if (updates.description !== void 0)
|
|
2739
|
+
preset.description = updates.description;
|
|
2740
|
+
saveConfig2(config);
|
|
2741
|
+
return preset;
|
|
2742
|
+
},
|
|
2743
|
+
removePreset(name) {
|
|
2744
|
+
const config = loadConfig2();
|
|
2745
|
+
if (!config.presets) {
|
|
2746
|
+
return;
|
|
2747
|
+
}
|
|
2748
|
+
const index = config.presets.findIndex((p) => p.name === name);
|
|
2749
|
+
if (index === -1) {
|
|
2750
|
+
throw new Error(`Preset not found: ${name}`);
|
|
2751
|
+
}
|
|
2752
|
+
config.presets.splice(index, 1);
|
|
2753
|
+
saveConfig2(config);
|
|
2754
|
+
}
|
|
2755
|
+
};
|
|
2581
2756
|
}
|
|
2582
|
-
var path3, ProviderNotFoundError, ProviderNameConflictError, PresetNameConflictError
|
|
2757
|
+
var path3, ProviderNotFoundError, ProviderNameConflictError, PresetNameConflictError;
|
|
2583
2758
|
var init_tool_manager = __esm({
|
|
2584
2759
|
"../core/dist/tool-manager.js"() {
|
|
2585
2760
|
"use strict";
|
|
@@ -2608,18 +2783,6 @@ var init_tool_manager = __esm({
|
|
|
2608
2783
|
this.name = "PresetNameConflictError";
|
|
2609
2784
|
}
|
|
2610
2785
|
};
|
|
2611
|
-
TOOL_CONFIGS = {
|
|
2612
|
-
codex: {
|
|
2613
|
-
configPath: path3.join(getCcmanDir(), "codex.json"),
|
|
2614
|
-
builtinPresets: CODEX_PRESETS,
|
|
2615
|
-
writer: writeCodexConfig
|
|
2616
|
-
},
|
|
2617
|
-
claude: {
|
|
2618
|
-
configPath: path3.join(getCcmanDir(), "claude.json"),
|
|
2619
|
-
builtinPresets: CC_PRESETS,
|
|
2620
|
-
writer: writeClaudeConfig
|
|
2621
|
-
}
|
|
2622
|
-
};
|
|
2623
2786
|
}
|
|
2624
2787
|
});
|
|
2625
2788
|
|
|
@@ -16146,24 +16309,14 @@ function decryptApiKey(encryptedApiKey, password) {
|
|
|
16146
16309
|
}
|
|
16147
16310
|
function encryptProviders(providers, password) {
|
|
16148
16311
|
return providers.map((provider) => ({
|
|
16149
|
-
|
|
16150
|
-
|
|
16151
|
-
baseUrl: provider.baseUrl,
|
|
16152
|
-
encryptedApiKey: encryptApiKey(provider.apiKey, password),
|
|
16153
|
-
createdAt: provider.createdAt,
|
|
16154
|
-
lastModified: provider.lastModified,
|
|
16155
|
-
lastUsedAt: provider.lastUsedAt
|
|
16312
|
+
...provider,
|
|
16313
|
+
apiKey: encryptApiKey(provider.apiKey, password)
|
|
16156
16314
|
}));
|
|
16157
16315
|
}
|
|
16158
16316
|
function decryptProviders(encryptedProviders, password) {
|
|
16159
16317
|
return encryptedProviders.map((provider) => ({
|
|
16160
|
-
|
|
16161
|
-
|
|
16162
|
-
baseUrl: provider.baseUrl,
|
|
16163
|
-
apiKey: decryptApiKey(provider.encryptedApiKey, password),
|
|
16164
|
-
createdAt: provider.createdAt,
|
|
16165
|
-
lastModified: provider.lastModified,
|
|
16166
|
-
lastUsedAt: provider.lastUsedAt
|
|
16318
|
+
...provider,
|
|
16319
|
+
apiKey: decryptApiKey(provider.apiKey, password)
|
|
16167
16320
|
}));
|
|
16168
16321
|
}
|
|
16169
16322
|
var crypto, ALGORITHM, KEY_LENGTH, IV_LENGTH, SALT_LENGTH, TAG_LENGTH, PBKDF2_ITERATIONS;
|
|
@@ -16181,15 +16334,6 @@ var init_crypto2 = __esm({
|
|
|
16181
16334
|
});
|
|
16182
16335
|
|
|
16183
16336
|
// ../core/dist/sync/merge-advanced.js
|
|
16184
|
-
function ensureLastModified(provider) {
|
|
16185
|
-
if (provider.lastModified === void 0) {
|
|
16186
|
-
return {
|
|
16187
|
-
...provider,
|
|
16188
|
-
lastModified: provider.createdAt
|
|
16189
|
-
};
|
|
16190
|
-
}
|
|
16191
|
-
return provider;
|
|
16192
|
-
}
|
|
16193
16337
|
function isSameConfig(a, b) {
|
|
16194
16338
|
return a.baseUrl === b.baseUrl && a.apiKey === b.apiKey;
|
|
16195
16339
|
}
|
|
@@ -16214,49 +16358,26 @@ function resolveNameConflict(existingProviders, newProvider) {
|
|
|
16214
16358
|
};
|
|
16215
16359
|
}
|
|
16216
16360
|
function mergeProviders(local, remote) {
|
|
16217
|
-
const localProviders = local.map(ensureLastModified);
|
|
16218
|
-
const remoteProviders = remote.map(ensureLastModified);
|
|
16219
16361
|
const mergedMap = /* @__PURE__ */ new Map();
|
|
16220
16362
|
let hasChanges = false;
|
|
16221
|
-
for (const localProvider of
|
|
16363
|
+
for (const localProvider of local) {
|
|
16222
16364
|
mergedMap.set(localProvider.id, localProvider);
|
|
16223
16365
|
}
|
|
16224
|
-
for (const remoteProvider of
|
|
16225
|
-
|
|
16226
|
-
|
|
16227
|
-
|
|
16228
|
-
|
|
16229
|
-
|
|
16366
|
+
for (const remoteProvider of remote) {
|
|
16367
|
+
const existingLocal = Array.from(mergedMap.values()).find((p) => isSameConfig(p, remoteProvider));
|
|
16368
|
+
if (existingLocal) {
|
|
16369
|
+
mergedMap.delete(existingLocal.id);
|
|
16370
|
+
mergedMap.set(remoteProvider.id, remoteProvider);
|
|
16371
|
+
if (!isProviderEqual(existingLocal, remoteProvider)) {
|
|
16230
16372
|
hasChanges = true;
|
|
16231
|
-
|
|
16232
|
-
console.log(`provider ${remoteProvider.id} \u672C\u5730\u66F4\u65B0\uFF0C\u4F7F\u7528\u672C\u5730\u7248\u672C`);
|
|
16233
|
-
hasChanges = true;
|
|
16234
|
-
} else {
|
|
16235
|
-
if (!isProviderEqual(localProvider, remoteProvider)) {
|
|
16236
|
-
console.log(`provider ${remoteProvider.id} \u65F6\u95F4\u6233\u76F8\u540C\u4F46\u5185\u5BB9\u4E0D\u540C\uFF0C\u4F7F\u7528\u8FDC\u7A0B\u7248\u672C`);
|
|
16237
|
-
mergedMap.set(remoteProvider.id, remoteProvider);
|
|
16238
|
-
hasChanges = true;
|
|
16239
|
-
}
|
|
16373
|
+
console.log(`\u76F8\u540C\u914D\u7F6E (${remoteProvider.baseUrl})\uFF0C\u4F7F\u7528\u4E91\u7AEF\u6570\u636E`);
|
|
16240
16374
|
}
|
|
16241
16375
|
} else {
|
|
16242
|
-
const
|
|
16243
|
-
|
|
16244
|
-
|
|
16245
|
-
|
|
16246
|
-
|
|
16247
|
-
mergedMap.set(remoteProvider.id, remoteProvider);
|
|
16248
|
-
hasChanges = true;
|
|
16249
|
-
} else {
|
|
16250
|
-
console.log(`\u76F8\u540C\u914D\u7F6E (${remoteProvider.baseUrl})\uFF0C\u672C\u5730\u66F4\u65B0\uFF0C\u4FDD\u7559 ${existingWithSameConfig.id}`);
|
|
16251
|
-
hasChanges = true;
|
|
16252
|
-
}
|
|
16253
|
-
} else {
|
|
16254
|
-
console.log(`\u65B0 provider ${remoteProvider.id}\uFF0C\u6DFB\u52A0\u5230\u5408\u5E76\u5217\u8868`);
|
|
16255
|
-
const existingProviders = Array.from(mergedMap.values());
|
|
16256
|
-
const resolvedProvider = resolveNameConflict(existingProviders, remoteProvider);
|
|
16257
|
-
mergedMap.set(resolvedProvider.id, resolvedProvider);
|
|
16258
|
-
hasChanges = true;
|
|
16259
|
-
}
|
|
16376
|
+
const existingProviders = Array.from(mergedMap.values());
|
|
16377
|
+
const resolvedProvider = resolveNameConflict(existingProviders, remoteProvider);
|
|
16378
|
+
mergedMap.set(resolvedProvider.id, resolvedProvider);
|
|
16379
|
+
hasChanges = true;
|
|
16380
|
+
console.log(`\u65B0 provider ${resolvedProvider.name}\uFF0C\u6DFB\u52A0\u5230\u5408\u5E76\u5217\u8868`);
|
|
16260
16381
|
}
|
|
16261
16382
|
}
|
|
16262
16383
|
const merged = Array.from(mergedMap.values());
|
|
@@ -16265,6 +16386,43 @@ function mergeProviders(local, remote) {
|
|
|
16265
16386
|
hasChanges
|
|
16266
16387
|
};
|
|
16267
16388
|
}
|
|
16389
|
+
function resolvePresetNameConflict(existingPresets, newPreset) {
|
|
16390
|
+
const existingNames = new Set(existingPresets.map((p) => p.name));
|
|
16391
|
+
if (!existingNames.has(newPreset.name)) {
|
|
16392
|
+
return newPreset;
|
|
16393
|
+
}
|
|
16394
|
+
let suffix = 2;
|
|
16395
|
+
let newName = `${newPreset.name}_${suffix}`;
|
|
16396
|
+
while (existingNames.has(newName)) {
|
|
16397
|
+
suffix++;
|
|
16398
|
+
newName = `${newPreset.name}_${suffix}`;
|
|
16399
|
+
}
|
|
16400
|
+
console.log(`preset name \u51B2\u7A81\uFF1A\u5C06 "${newPreset.name}" \u91CD\u547D\u540D\u4E3A "${newName}"`);
|
|
16401
|
+
return {
|
|
16402
|
+
...newPreset,
|
|
16403
|
+
name: newName
|
|
16404
|
+
};
|
|
16405
|
+
}
|
|
16406
|
+
function mergePresets(local, remote) {
|
|
16407
|
+
const localPresets = local || [];
|
|
16408
|
+
const remotePresets = remote || [];
|
|
16409
|
+
const mergedMap = /* @__PURE__ */ new Map();
|
|
16410
|
+
for (const preset of localPresets) {
|
|
16411
|
+
mergedMap.set(preset.baseUrl, preset);
|
|
16412
|
+
}
|
|
16413
|
+
for (const remotePreset of remotePresets) {
|
|
16414
|
+
const existingLocal = mergedMap.get(remotePreset.baseUrl);
|
|
16415
|
+
if (existingLocal) {
|
|
16416
|
+
mergedMap.set(remotePreset.baseUrl, remotePreset);
|
|
16417
|
+
console.log(`preset ${remotePreset.name} (${remotePreset.baseUrl})\uFF0C\u4F7F\u7528\u4E91\u7AEF\u6570\u636E`);
|
|
16418
|
+
} else {
|
|
16419
|
+
const existingPresets = Array.from(mergedMap.values());
|
|
16420
|
+
const resolvedPreset = resolvePresetNameConflict(existingPresets, remotePreset);
|
|
16421
|
+
mergedMap.set(resolvedPreset.baseUrl, resolvedPreset);
|
|
16422
|
+
}
|
|
16423
|
+
}
|
|
16424
|
+
return Array.from(mergedMap.values());
|
|
16425
|
+
}
|
|
16268
16426
|
var init_merge_advanced = __esm({
|
|
16269
16427
|
"../core/dist/sync/merge-advanced.js"() {
|
|
16270
16428
|
"use strict";
|
|
@@ -16281,12 +16439,16 @@ async function uploadToCloud(config, password) {
|
|
|
16281
16439
|
const encryptedCodexProviders = encryptProviders(codexConfig.providers, password);
|
|
16282
16440
|
const encryptedClaudeProviders = encryptProviders(claudeConfig.providers, password);
|
|
16283
16441
|
const encryptedCodexConfig = {
|
|
16284
|
-
|
|
16442
|
+
...codexConfig,
|
|
16443
|
+
// 保留所有字段
|
|
16285
16444
|
providers: encryptedCodexProviders
|
|
16445
|
+
// 只替换 providers(加密后的)
|
|
16286
16446
|
};
|
|
16287
16447
|
const encryptedClaudeConfig = {
|
|
16288
|
-
|
|
16448
|
+
...claudeConfig,
|
|
16449
|
+
// 保留所有字段
|
|
16289
16450
|
providers: encryptedClaudeProviders
|
|
16451
|
+
// 只替换 providers(加密后的)
|
|
16290
16452
|
};
|
|
16291
16453
|
const codexJson = JSON.stringify(encryptedCodexConfig, null, 2);
|
|
16292
16454
|
const claudeJson = JSON.stringify(encryptedClaudeConfig, null, 2);
|
|
@@ -16331,24 +16493,22 @@ async function downloadFromCloud(config, password) {
|
|
|
16331
16493
|
throw new Error(`\u5907\u4EFD\u5931\u8D25: ${error.message}`);
|
|
16332
16494
|
}
|
|
16333
16495
|
try {
|
|
16334
|
-
const currentCodexConfig = readJSON(codexConfigPath);
|
|
16335
|
-
const currentClaudeConfig = readJSON(claudeConfigPath);
|
|
16336
16496
|
if (remoteCodexConfig && decryptedCodexProviders) {
|
|
16337
16497
|
const newCodexConfig = {
|
|
16338
|
-
|
|
16339
|
-
|
|
16340
|
-
|
|
16341
|
-
//
|
|
16498
|
+
...remoteCodexConfig,
|
|
16499
|
+
// 使用云端配置的所有字段
|
|
16500
|
+
providers: decryptedCodexProviders
|
|
16501
|
+
// 只替换 providers(解密后的)
|
|
16342
16502
|
};
|
|
16343
16503
|
writeJSON(codexConfigPath, newCodexConfig);
|
|
16344
16504
|
applyCurrentProvider("codex", newCodexConfig);
|
|
16345
16505
|
}
|
|
16346
16506
|
if (remoteClaudeConfig && decryptedClaudeProviders) {
|
|
16347
16507
|
const newClaudeConfig = {
|
|
16348
|
-
|
|
16349
|
-
|
|
16350
|
-
|
|
16351
|
-
//
|
|
16508
|
+
...remoteClaudeConfig,
|
|
16509
|
+
// 使用云端配置的所有字段
|
|
16510
|
+
providers: decryptedClaudeProviders
|
|
16511
|
+
// 只替换 providers(解密后的)
|
|
16352
16512
|
};
|
|
16353
16513
|
writeJSON(claudeConfigPath, newClaudeConfig);
|
|
16354
16514
|
applyCurrentProvider("claude", newClaudeConfig);
|
|
@@ -16418,16 +16578,24 @@ async function mergeSync(config, password) {
|
|
|
16418
16578
|
} catch (error) {
|
|
16419
16579
|
throw new Error(`\u5907\u4EFD\u5931\u8D25: ${error.message}`);
|
|
16420
16580
|
}
|
|
16581
|
+
const mergedCodexPresets = mergePresets(localCodexConfig.presets, remoteCodexConfig?.presets);
|
|
16582
|
+
const mergedClaudePresets = mergePresets(localClaudeConfig.presets, remoteClaudeConfig?.presets);
|
|
16421
16583
|
try {
|
|
16422
16584
|
const mergedCodexConfig = {
|
|
16423
|
-
|
|
16585
|
+
...localCodexConfig,
|
|
16586
|
+
// 保留本地配置的所有字段
|
|
16424
16587
|
providers: codexMergeResult.merged,
|
|
16425
|
-
|
|
16588
|
+
// 替换为合并后的 providers
|
|
16589
|
+
presets: mergedCodexPresets
|
|
16590
|
+
// 替换为合并后的 presets
|
|
16426
16591
|
};
|
|
16427
16592
|
const mergedClaudeConfig = {
|
|
16428
|
-
|
|
16593
|
+
...localClaudeConfig,
|
|
16594
|
+
// 保留本地配置的所有字段
|
|
16429
16595
|
providers: claudeMergeResult.merged,
|
|
16430
|
-
|
|
16596
|
+
// 替换为合并后的 providers
|
|
16597
|
+
presets: mergedClaudePresets
|
|
16598
|
+
// 替换为合并后的 presets
|
|
16431
16599
|
};
|
|
16432
16600
|
writeJSON(codexConfigPath, mergedCodexConfig);
|
|
16433
16601
|
writeJSON(claudeConfigPath, mergedClaudeConfig);
|
|
@@ -16436,12 +16604,16 @@ async function mergeSync(config, password) {
|
|
|
16436
16604
|
const encryptedCodexProviders = encryptProviders(codexMergeResult.merged, password);
|
|
16437
16605
|
const encryptedClaudeProviders = encryptProviders(claudeMergeResult.merged, password);
|
|
16438
16606
|
const encryptedCodexConfig = {
|
|
16439
|
-
|
|
16607
|
+
...mergedCodexConfig,
|
|
16608
|
+
// 保留合并后配置的所有字段
|
|
16440
16609
|
providers: encryptedCodexProviders
|
|
16610
|
+
// 只替换 providers(加密后的)
|
|
16441
16611
|
};
|
|
16442
16612
|
const encryptedClaudeConfig = {
|
|
16443
|
-
|
|
16613
|
+
...mergedClaudeConfig,
|
|
16614
|
+
// 保留合并后配置的所有字段
|
|
16444
16615
|
providers: encryptedClaudeProviders
|
|
16616
|
+
// 只替换 providers(加密后的)
|
|
16445
16617
|
};
|
|
16446
16618
|
const codexJson2 = JSON.stringify(encryptedCodexConfig, null, 2);
|
|
16447
16619
|
const claudeJson2 = JSON.stringify(encryptedClaudeConfig, null, 2);
|
|
@@ -16661,45 +16833,12 @@ var init_dist4 = __esm({
|
|
|
16661
16833
|
});
|
|
16662
16834
|
|
|
16663
16835
|
// src/utils/sync-config.ts
|
|
16664
|
-
function getMachineId() {
|
|
16665
|
-
return import_crypto4.default.createHash("sha256").update(import_os.default.hostname() + import_os.default.userInfo().username).digest();
|
|
16666
|
-
}
|
|
16667
|
-
function encrypt(text) {
|
|
16668
|
-
const key = getMachineId();
|
|
16669
|
-
const iv = import_crypto4.default.randomBytes(16);
|
|
16670
|
-
const cipher = import_crypto4.default.createCipheriv("aes-256-cbc", key, iv);
|
|
16671
|
-
let encrypted = cipher.update(text, "utf8", "hex");
|
|
16672
|
-
encrypted += cipher.final("hex");
|
|
16673
|
-
return iv.toString("hex") + ":" + encrypted;
|
|
16674
|
-
}
|
|
16675
|
-
function decrypt(encrypted) {
|
|
16676
|
-
const parts = encrypted.split(":");
|
|
16677
|
-
const iv = Buffer.from(parts[0], "hex");
|
|
16678
|
-
const encryptedText = parts[1];
|
|
16679
|
-
const key = getMachineId();
|
|
16680
|
-
const decipher = import_crypto4.default.createDecipheriv("aes-256-cbc", key, iv);
|
|
16681
|
-
let decrypted = decipher.update(encryptedText, "hex", "utf8");
|
|
16682
|
-
decrypted += decipher.final("utf8");
|
|
16683
|
-
return decrypted;
|
|
16684
|
-
}
|
|
16685
16836
|
function loadSyncConfig() {
|
|
16686
16837
|
try {
|
|
16687
16838
|
const config = getSyncConfig();
|
|
16688
16839
|
if (!config) {
|
|
16689
16840
|
return null;
|
|
16690
16841
|
}
|
|
16691
|
-
if (config.password && config.password.includes(":")) {
|
|
16692
|
-
try {
|
|
16693
|
-
config.password = decrypt(config.password);
|
|
16694
|
-
} catch {
|
|
16695
|
-
}
|
|
16696
|
-
}
|
|
16697
|
-
if (config.syncPassword && config.syncPassword.includes(":")) {
|
|
16698
|
-
try {
|
|
16699
|
-
config.syncPassword = decrypt(config.syncPassword);
|
|
16700
|
-
} catch {
|
|
16701
|
-
}
|
|
16702
|
-
}
|
|
16703
16842
|
return config;
|
|
16704
16843
|
} catch (error) {
|
|
16705
16844
|
throw new Error(`\u8BFB\u53D6\u540C\u6B65\u914D\u7F6E\u5931\u8D25: ${error.message}`);
|
|
@@ -16708,12 +16847,7 @@ function loadSyncConfig() {
|
|
|
16708
16847
|
function saveSyncConfig2(config) {
|
|
16709
16848
|
try {
|
|
16710
16849
|
const configToSave = { ...config };
|
|
16711
|
-
if (configToSave.
|
|
16712
|
-
configToSave.password = encrypt(configToSave.password);
|
|
16713
|
-
}
|
|
16714
|
-
if (configToSave.syncPassword && configToSave.rememberSyncPassword) {
|
|
16715
|
-
configToSave.syncPassword = encrypt(configToSave.syncPassword);
|
|
16716
|
-
} else {
|
|
16850
|
+
if (!configToSave.rememberSyncPassword) {
|
|
16717
16851
|
delete configToSave.syncPassword;
|
|
16718
16852
|
}
|
|
16719
16853
|
configToSave.lastSync = Date.now();
|
|
@@ -16725,12 +16859,9 @@ function saveSyncConfig2(config) {
|
|
|
16725
16859
|
function getSyncConfigPath() {
|
|
16726
16860
|
return getConfigPath();
|
|
16727
16861
|
}
|
|
16728
|
-
var import_crypto4, import_os;
|
|
16729
16862
|
var init_sync_config = __esm({
|
|
16730
16863
|
"src/utils/sync-config.ts"() {
|
|
16731
16864
|
"use strict";
|
|
16732
|
-
import_crypto4 = __toESM(require("crypto"));
|
|
16733
|
-
import_os = __toESM(require("os"));
|
|
16734
16865
|
init_dist4();
|
|
16735
16866
|
}
|
|
16736
16867
|
});
|
|
@@ -18956,6 +19087,26 @@ program.name("ccman").description("Codex/Claude Code API \u670D\u52A1\u5546\u914
|
|
|
18956
19087
|
}
|
|
18957
19088
|
throw err;
|
|
18958
19089
|
});
|
|
19090
|
+
program.on("command:*", (operands) => {
|
|
19091
|
+
const unknownCommand = operands[0];
|
|
19092
|
+
console.error(import_chalk27.default.red(`
|
|
19093
|
+
\u274C \u672A\u77E5\u547D\u4EE4: ${unknownCommand}
|
|
19094
|
+
`));
|
|
19095
|
+
const availableCommands = ["cx", "cc", "sync", "export", "import"];
|
|
19096
|
+
const suggestions = availableCommands.filter(
|
|
19097
|
+
(cmd) => cmd.includes(unknownCommand) || unknownCommand.includes(cmd)
|
|
19098
|
+
);
|
|
19099
|
+
if (suggestions.length > 0) {
|
|
19100
|
+
console.log(import_chalk27.default.yellow("\u{1F4A1} \u4F60\u662F\u4E0D\u662F\u60F3\u8F93\u5165:"));
|
|
19101
|
+
suggestions.forEach((cmd) => {
|
|
19102
|
+
console.log(import_chalk27.default.cyan(` ccman ${cmd}`));
|
|
19103
|
+
});
|
|
19104
|
+
console.log();
|
|
19105
|
+
}
|
|
19106
|
+
console.log(import_chalk27.default.gray("\u67E5\u770B\u6240\u6709\u53EF\u7528\u547D\u4EE4: ") + import_chalk27.default.cyan("ccman --help"));
|
|
19107
|
+
console.log();
|
|
19108
|
+
process.exit(1);
|
|
19109
|
+
});
|
|
18959
19110
|
var cx = program.command("cx").description("\u7BA1\u7406 Codex \u670D\u52A1\u5546");
|
|
18960
19111
|
createCodexCommands(cx);
|
|
18961
19112
|
cx.action(async () => {
|