ccman 3.0.20 → 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 +108 -120
- 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",
|
|
@@ -16309,24 +16309,14 @@ function decryptApiKey(encryptedApiKey, password) {
|
|
|
16309
16309
|
}
|
|
16310
16310
|
function encryptProviders(providers, password) {
|
|
16311
16311
|
return providers.map((provider) => ({
|
|
16312
|
-
|
|
16313
|
-
|
|
16314
|
-
baseUrl: provider.baseUrl,
|
|
16315
|
-
encryptedApiKey: encryptApiKey(provider.apiKey, password),
|
|
16316
|
-
createdAt: provider.createdAt,
|
|
16317
|
-
lastModified: provider.lastModified,
|
|
16318
|
-
lastUsedAt: provider.lastUsedAt
|
|
16312
|
+
...provider,
|
|
16313
|
+
apiKey: encryptApiKey(provider.apiKey, password)
|
|
16319
16314
|
}));
|
|
16320
16315
|
}
|
|
16321
16316
|
function decryptProviders(encryptedProviders, password) {
|
|
16322
16317
|
return encryptedProviders.map((provider) => ({
|
|
16323
|
-
|
|
16324
|
-
|
|
16325
|
-
baseUrl: provider.baseUrl,
|
|
16326
|
-
apiKey: decryptApiKey(provider.encryptedApiKey, password),
|
|
16327
|
-
createdAt: provider.createdAt,
|
|
16328
|
-
lastModified: provider.lastModified,
|
|
16329
|
-
lastUsedAt: provider.lastUsedAt
|
|
16318
|
+
...provider,
|
|
16319
|
+
apiKey: decryptApiKey(provider.apiKey, password)
|
|
16330
16320
|
}));
|
|
16331
16321
|
}
|
|
16332
16322
|
var crypto, ALGORITHM, KEY_LENGTH, IV_LENGTH, SALT_LENGTH, TAG_LENGTH, PBKDF2_ITERATIONS;
|
|
@@ -16344,15 +16334,6 @@ var init_crypto2 = __esm({
|
|
|
16344
16334
|
});
|
|
16345
16335
|
|
|
16346
16336
|
// ../core/dist/sync/merge-advanced.js
|
|
16347
|
-
function ensureLastModified(provider) {
|
|
16348
|
-
if (provider.lastModified === void 0) {
|
|
16349
|
-
return {
|
|
16350
|
-
...provider,
|
|
16351
|
-
lastModified: provider.createdAt
|
|
16352
|
-
};
|
|
16353
|
-
}
|
|
16354
|
-
return provider;
|
|
16355
|
-
}
|
|
16356
16337
|
function isSameConfig(a, b) {
|
|
16357
16338
|
return a.baseUrl === b.baseUrl && a.apiKey === b.apiKey;
|
|
16358
16339
|
}
|
|
@@ -16377,49 +16358,26 @@ function resolveNameConflict(existingProviders, newProvider) {
|
|
|
16377
16358
|
};
|
|
16378
16359
|
}
|
|
16379
16360
|
function mergeProviders(local, remote) {
|
|
16380
|
-
const localProviders = local.map(ensureLastModified);
|
|
16381
|
-
const remoteProviders = remote.map(ensureLastModified);
|
|
16382
16361
|
const mergedMap = /* @__PURE__ */ new Map();
|
|
16383
16362
|
let hasChanges = false;
|
|
16384
|
-
for (const localProvider of
|
|
16363
|
+
for (const localProvider of local) {
|
|
16385
16364
|
mergedMap.set(localProvider.id, localProvider);
|
|
16386
16365
|
}
|
|
16387
|
-
for (const remoteProvider of
|
|
16388
|
-
|
|
16389
|
-
|
|
16390
|
-
|
|
16391
|
-
|
|
16392
|
-
|
|
16393
|
-
hasChanges = true;
|
|
16394
|
-
} else if (remoteProvider.lastModified < localProvider.lastModified) {
|
|
16395
|
-
console.log(`provider ${remoteProvider.id} \u672C\u5730\u66F4\u65B0\uFF0C\u4F7F\u7528\u672C\u5730\u7248\u672C`);
|
|
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)) {
|
|
16396
16372
|
hasChanges = true;
|
|
16397
|
-
|
|
16398
|
-
if (!isProviderEqual(localProvider, remoteProvider)) {
|
|
16399
|
-
console.log(`provider ${remoteProvider.id} \u65F6\u95F4\u6233\u76F8\u540C\u4F46\u5185\u5BB9\u4E0D\u540C\uFF0C\u4F7F\u7528\u8FDC\u7A0B\u7248\u672C`);
|
|
16400
|
-
mergedMap.set(remoteProvider.id, remoteProvider);
|
|
16401
|
-
hasChanges = true;
|
|
16402
|
-
}
|
|
16373
|
+
console.log(`\u76F8\u540C\u914D\u7F6E (${remoteProvider.baseUrl})\uFF0C\u4F7F\u7528\u4E91\u7AEF\u6570\u636E`);
|
|
16403
16374
|
}
|
|
16404
16375
|
} else {
|
|
16405
|
-
const
|
|
16406
|
-
|
|
16407
|
-
|
|
16408
|
-
|
|
16409
|
-
|
|
16410
|
-
mergedMap.set(remoteProvider.id, remoteProvider);
|
|
16411
|
-
hasChanges = true;
|
|
16412
|
-
} else {
|
|
16413
|
-
console.log(`\u76F8\u540C\u914D\u7F6E (${remoteProvider.baseUrl})\uFF0C\u672C\u5730\u66F4\u65B0\uFF0C\u4FDD\u7559 ${existingWithSameConfig.id}`);
|
|
16414
|
-
hasChanges = true;
|
|
16415
|
-
}
|
|
16416
|
-
} else {
|
|
16417
|
-
console.log(`\u65B0 provider ${remoteProvider.id}\uFF0C\u6DFB\u52A0\u5230\u5408\u5E76\u5217\u8868`);
|
|
16418
|
-
const existingProviders = Array.from(mergedMap.values());
|
|
16419
|
-
const resolvedProvider = resolveNameConflict(existingProviders, remoteProvider);
|
|
16420
|
-
mergedMap.set(resolvedProvider.id, resolvedProvider);
|
|
16421
|
-
hasChanges = true;
|
|
16422
|
-
}
|
|
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`);
|
|
16423
16381
|
}
|
|
16424
16382
|
}
|
|
16425
16383
|
const merged = Array.from(mergedMap.values());
|
|
@@ -16428,6 +16386,43 @@ function mergeProviders(local, remote) {
|
|
|
16428
16386
|
hasChanges
|
|
16429
16387
|
};
|
|
16430
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
|
+
}
|
|
16431
16426
|
var init_merge_advanced = __esm({
|
|
16432
16427
|
"../core/dist/sync/merge-advanced.js"() {
|
|
16433
16428
|
"use strict";
|
|
@@ -16444,12 +16439,16 @@ async function uploadToCloud(config, password) {
|
|
|
16444
16439
|
const encryptedCodexProviders = encryptProviders(codexConfig.providers, password);
|
|
16445
16440
|
const encryptedClaudeProviders = encryptProviders(claudeConfig.providers, password);
|
|
16446
16441
|
const encryptedCodexConfig = {
|
|
16447
|
-
|
|
16442
|
+
...codexConfig,
|
|
16443
|
+
// 保留所有字段
|
|
16448
16444
|
providers: encryptedCodexProviders
|
|
16445
|
+
// 只替换 providers(加密后的)
|
|
16449
16446
|
};
|
|
16450
16447
|
const encryptedClaudeConfig = {
|
|
16451
|
-
|
|
16448
|
+
...claudeConfig,
|
|
16449
|
+
// 保留所有字段
|
|
16452
16450
|
providers: encryptedClaudeProviders
|
|
16451
|
+
// 只替换 providers(加密后的)
|
|
16453
16452
|
};
|
|
16454
16453
|
const codexJson = JSON.stringify(encryptedCodexConfig, null, 2);
|
|
16455
16454
|
const claudeJson = JSON.stringify(encryptedClaudeConfig, null, 2);
|
|
@@ -16494,24 +16493,22 @@ async function downloadFromCloud(config, password) {
|
|
|
16494
16493
|
throw new Error(`\u5907\u4EFD\u5931\u8D25: ${error.message}`);
|
|
16495
16494
|
}
|
|
16496
16495
|
try {
|
|
16497
|
-
const currentCodexConfig = readJSON(codexConfigPath);
|
|
16498
|
-
const currentClaudeConfig = readJSON(claudeConfigPath);
|
|
16499
16496
|
if (remoteCodexConfig && decryptedCodexProviders) {
|
|
16500
16497
|
const newCodexConfig = {
|
|
16501
|
-
|
|
16502
|
-
|
|
16503
|
-
|
|
16504
|
-
//
|
|
16498
|
+
...remoteCodexConfig,
|
|
16499
|
+
// 使用云端配置的所有字段
|
|
16500
|
+
providers: decryptedCodexProviders
|
|
16501
|
+
// 只替换 providers(解密后的)
|
|
16505
16502
|
};
|
|
16506
16503
|
writeJSON(codexConfigPath, newCodexConfig);
|
|
16507
16504
|
applyCurrentProvider("codex", newCodexConfig);
|
|
16508
16505
|
}
|
|
16509
16506
|
if (remoteClaudeConfig && decryptedClaudeProviders) {
|
|
16510
16507
|
const newClaudeConfig = {
|
|
16511
|
-
|
|
16512
|
-
|
|
16513
|
-
|
|
16514
|
-
//
|
|
16508
|
+
...remoteClaudeConfig,
|
|
16509
|
+
// 使用云端配置的所有字段
|
|
16510
|
+
providers: decryptedClaudeProviders
|
|
16511
|
+
// 只替换 providers(解密后的)
|
|
16515
16512
|
};
|
|
16516
16513
|
writeJSON(claudeConfigPath, newClaudeConfig);
|
|
16517
16514
|
applyCurrentProvider("claude", newClaudeConfig);
|
|
@@ -16581,16 +16578,24 @@ async function mergeSync(config, password) {
|
|
|
16581
16578
|
} catch (error) {
|
|
16582
16579
|
throw new Error(`\u5907\u4EFD\u5931\u8D25: ${error.message}`);
|
|
16583
16580
|
}
|
|
16581
|
+
const mergedCodexPresets = mergePresets(localCodexConfig.presets, remoteCodexConfig?.presets);
|
|
16582
|
+
const mergedClaudePresets = mergePresets(localClaudeConfig.presets, remoteClaudeConfig?.presets);
|
|
16584
16583
|
try {
|
|
16585
16584
|
const mergedCodexConfig = {
|
|
16586
|
-
|
|
16585
|
+
...localCodexConfig,
|
|
16586
|
+
// 保留本地配置的所有字段
|
|
16587
16587
|
providers: codexMergeResult.merged,
|
|
16588
|
-
|
|
16588
|
+
// 替换为合并后的 providers
|
|
16589
|
+
presets: mergedCodexPresets
|
|
16590
|
+
// 替换为合并后的 presets
|
|
16589
16591
|
};
|
|
16590
16592
|
const mergedClaudeConfig = {
|
|
16591
|
-
|
|
16593
|
+
...localClaudeConfig,
|
|
16594
|
+
// 保留本地配置的所有字段
|
|
16592
16595
|
providers: claudeMergeResult.merged,
|
|
16593
|
-
|
|
16596
|
+
// 替换为合并后的 providers
|
|
16597
|
+
presets: mergedClaudePresets
|
|
16598
|
+
// 替换为合并后的 presets
|
|
16594
16599
|
};
|
|
16595
16600
|
writeJSON(codexConfigPath, mergedCodexConfig);
|
|
16596
16601
|
writeJSON(claudeConfigPath, mergedClaudeConfig);
|
|
@@ -16599,12 +16604,16 @@ async function mergeSync(config, password) {
|
|
|
16599
16604
|
const encryptedCodexProviders = encryptProviders(codexMergeResult.merged, password);
|
|
16600
16605
|
const encryptedClaudeProviders = encryptProviders(claudeMergeResult.merged, password);
|
|
16601
16606
|
const encryptedCodexConfig = {
|
|
16602
|
-
|
|
16607
|
+
...mergedCodexConfig,
|
|
16608
|
+
// 保留合并后配置的所有字段
|
|
16603
16609
|
providers: encryptedCodexProviders
|
|
16610
|
+
// 只替换 providers(加密后的)
|
|
16604
16611
|
};
|
|
16605
16612
|
const encryptedClaudeConfig = {
|
|
16606
|
-
|
|
16613
|
+
...mergedClaudeConfig,
|
|
16614
|
+
// 保留合并后配置的所有字段
|
|
16607
16615
|
providers: encryptedClaudeProviders
|
|
16616
|
+
// 只替换 providers(加密后的)
|
|
16608
16617
|
};
|
|
16609
16618
|
const codexJson2 = JSON.stringify(encryptedCodexConfig, null, 2);
|
|
16610
16619
|
const claudeJson2 = JSON.stringify(encryptedClaudeConfig, null, 2);
|
|
@@ -16824,45 +16833,12 @@ var init_dist4 = __esm({
|
|
|
16824
16833
|
});
|
|
16825
16834
|
|
|
16826
16835
|
// src/utils/sync-config.ts
|
|
16827
|
-
function getMachineId() {
|
|
16828
|
-
return import_crypto4.default.createHash("sha256").update(import_os.default.hostname() + import_os.default.userInfo().username).digest();
|
|
16829
|
-
}
|
|
16830
|
-
function encrypt(text) {
|
|
16831
|
-
const key = getMachineId();
|
|
16832
|
-
const iv = import_crypto4.default.randomBytes(16);
|
|
16833
|
-
const cipher = import_crypto4.default.createCipheriv("aes-256-cbc", key, iv);
|
|
16834
|
-
let encrypted = cipher.update(text, "utf8", "hex");
|
|
16835
|
-
encrypted += cipher.final("hex");
|
|
16836
|
-
return iv.toString("hex") + ":" + encrypted;
|
|
16837
|
-
}
|
|
16838
|
-
function decrypt(encrypted) {
|
|
16839
|
-
const parts = encrypted.split(":");
|
|
16840
|
-
const iv = Buffer.from(parts[0], "hex");
|
|
16841
|
-
const encryptedText = parts[1];
|
|
16842
|
-
const key = getMachineId();
|
|
16843
|
-
const decipher = import_crypto4.default.createDecipheriv("aes-256-cbc", key, iv);
|
|
16844
|
-
let decrypted = decipher.update(encryptedText, "hex", "utf8");
|
|
16845
|
-
decrypted += decipher.final("utf8");
|
|
16846
|
-
return decrypted;
|
|
16847
|
-
}
|
|
16848
16836
|
function loadSyncConfig() {
|
|
16849
16837
|
try {
|
|
16850
16838
|
const config = getSyncConfig();
|
|
16851
16839
|
if (!config) {
|
|
16852
16840
|
return null;
|
|
16853
16841
|
}
|
|
16854
|
-
if (config.password && config.password.includes(":")) {
|
|
16855
|
-
try {
|
|
16856
|
-
config.password = decrypt(config.password);
|
|
16857
|
-
} catch {
|
|
16858
|
-
}
|
|
16859
|
-
}
|
|
16860
|
-
if (config.syncPassword && config.syncPassword.includes(":")) {
|
|
16861
|
-
try {
|
|
16862
|
-
config.syncPassword = decrypt(config.syncPassword);
|
|
16863
|
-
} catch {
|
|
16864
|
-
}
|
|
16865
|
-
}
|
|
16866
16842
|
return config;
|
|
16867
16843
|
} catch (error) {
|
|
16868
16844
|
throw new Error(`\u8BFB\u53D6\u540C\u6B65\u914D\u7F6E\u5931\u8D25: ${error.message}`);
|
|
@@ -16871,12 +16847,7 @@ function loadSyncConfig() {
|
|
|
16871
16847
|
function saveSyncConfig2(config) {
|
|
16872
16848
|
try {
|
|
16873
16849
|
const configToSave = { ...config };
|
|
16874
|
-
if (configToSave.
|
|
16875
|
-
configToSave.password = encrypt(configToSave.password);
|
|
16876
|
-
}
|
|
16877
|
-
if (configToSave.syncPassword && configToSave.rememberSyncPassword) {
|
|
16878
|
-
configToSave.syncPassword = encrypt(configToSave.syncPassword);
|
|
16879
|
-
} else {
|
|
16850
|
+
if (!configToSave.rememberSyncPassword) {
|
|
16880
16851
|
delete configToSave.syncPassword;
|
|
16881
16852
|
}
|
|
16882
16853
|
configToSave.lastSync = Date.now();
|
|
@@ -16888,12 +16859,9 @@ function saveSyncConfig2(config) {
|
|
|
16888
16859
|
function getSyncConfigPath() {
|
|
16889
16860
|
return getConfigPath();
|
|
16890
16861
|
}
|
|
16891
|
-
var import_crypto4, import_os;
|
|
16892
16862
|
var init_sync_config = __esm({
|
|
16893
16863
|
"src/utils/sync-config.ts"() {
|
|
16894
16864
|
"use strict";
|
|
16895
|
-
import_crypto4 = __toESM(require("crypto"));
|
|
16896
|
-
import_os = __toESM(require("os"));
|
|
16897
16865
|
init_dist4();
|
|
16898
16866
|
}
|
|
16899
16867
|
});
|
|
@@ -19119,6 +19087,26 @@ program.name("ccman").description("Codex/Claude Code API \u670D\u52A1\u5546\u914
|
|
|
19119
19087
|
}
|
|
19120
19088
|
throw err;
|
|
19121
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
|
+
});
|
|
19122
19110
|
var cx = program.command("cx").description("\u7BA1\u7406 Codex \u670D\u52A1\u5546");
|
|
19123
19111
|
createCodexCommands(cx);
|
|
19124
19112
|
cx.action(async () => {
|