ccman 3.3.15-beta.1 → 3.3.16
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 +147 -21
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -15,7 +15,7 @@ var init_package = __esm({
|
|
|
15
15
|
"../core/package.json"() {
|
|
16
16
|
package_default = {
|
|
17
17
|
name: "@ccman/core",
|
|
18
|
-
version: "3.3.
|
|
18
|
+
version: "3.3.16",
|
|
19
19
|
type: "module",
|
|
20
20
|
description: "Core business logic for ccman - Manage Codex, Claude Code, Gemini CLI, OpenCode, OpenClaw, and MCP configurations",
|
|
21
21
|
main: "./dist/index.js",
|
|
@@ -260,6 +260,13 @@ function backupFile(filePath) {
|
|
|
260
260
|
fs.chmodSync(backupPath, 384);
|
|
261
261
|
return backupPath;
|
|
262
262
|
}
|
|
263
|
+
function backupFileOrThrow(filePath, operation) {
|
|
264
|
+
try {
|
|
265
|
+
return backupFile(filePath);
|
|
266
|
+
} catch (error) {
|
|
267
|
+
throw new Error(`\u5907\u4EFD\u5931\u8D25\uFF0C\u5DF2\u4E2D\u6B62\u540E\u7EED\u5199\u5165\uFF08${operation}\uFF09: ${error.message}`);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
263
270
|
var init_file = __esm({
|
|
264
271
|
"../core/dist/utils/file.js"() {
|
|
265
272
|
"use strict";
|
|
@@ -306,12 +313,6 @@ function loadCodexTemplateConfig() {
|
|
|
306
313
|
function writeCodexConfig(provider) {
|
|
307
314
|
ensureDir(getCodexDir());
|
|
308
315
|
const configPath = getCodexConfigPath();
|
|
309
|
-
if (fileExists(configPath)) {
|
|
310
|
-
try {
|
|
311
|
-
backupFile(configPath);
|
|
312
|
-
} catch {
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
316
|
const templateConfig = loadCodexTemplateConfig();
|
|
316
317
|
const nextConfig = { ...templateConfig };
|
|
317
318
|
if (nextConfig.features && typeof nextConfig.features === "object" && !Array.isArray(nextConfig.features) && "web_search_request" in nextConfig.features) {
|
|
@@ -333,12 +334,6 @@ function writeCodexConfig(provider) {
|
|
|
333
334
|
};
|
|
334
335
|
fs2.writeFileSync(configPath, stringifyToml(nextConfig), { mode: 384 });
|
|
335
336
|
const authPath = getCodexAuthPath();
|
|
336
|
-
if (fileExists(authPath)) {
|
|
337
|
-
try {
|
|
338
|
-
backupFile(authPath);
|
|
339
|
-
} catch {
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
337
|
const auth = { OPENAI_API_KEY: provider.apiKey };
|
|
343
338
|
writeJSON(authPath, auth);
|
|
344
339
|
}
|
|
@@ -894,7 +889,9 @@ function saveEnvFile(envPath, env) {
|
|
|
894
889
|
lines.push(`${key}=${String(env[key])}`);
|
|
895
890
|
}
|
|
896
891
|
const content = lines.join("\n") + (lines.length ? "\n" : "");
|
|
897
|
-
|
|
892
|
+
const tempPath = `${envPath}.tmp`;
|
|
893
|
+
fs5.writeFileSync(tempPath, content, { mode: 384 });
|
|
894
|
+
fs5.renameSync(tempPath, envPath);
|
|
898
895
|
}
|
|
899
896
|
function writeGeminiConfig(provider) {
|
|
900
897
|
const settingsPath = getGeminiSettingsPath();
|
|
@@ -2209,6 +2206,7 @@ function backupConfig(configPath, keepCount = 3) {
|
|
|
2209
2206
|
const timestamp = Date.now();
|
|
2210
2207
|
const backupPath = `${configPath}.backup.${timestamp}`;
|
|
2211
2208
|
fs9.copyFileSync(configPath, backupPath);
|
|
2209
|
+
fs9.chmodSync(backupPath, 384);
|
|
2212
2210
|
cleanupOldBackups(configPath, keepCount);
|
|
2213
2211
|
return backupPath;
|
|
2214
2212
|
}
|
|
@@ -2582,6 +2580,9 @@ function exportConfig(targetDir) {
|
|
|
2582
2580
|
const src = path12.join(ccmanDir2, file);
|
|
2583
2581
|
const dst = path12.join(targetDir, file);
|
|
2584
2582
|
if (fileExists(src)) {
|
|
2583
|
+
if (fileExists(dst)) {
|
|
2584
|
+
backupFileOrThrow(dst, `export.${file}`);
|
|
2585
|
+
}
|
|
2585
2586
|
fs11.copyFileSync(src, dst);
|
|
2586
2587
|
exportedFiles.push(file);
|
|
2587
2588
|
}
|
|
@@ -2658,8 +2659,13 @@ function getFileSize(filePath) {
|
|
|
2658
2659
|
function backupFile2(filePath) {
|
|
2659
2660
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/:/g, "-").split(".")[0];
|
|
2660
2661
|
const backupPath = `${filePath}.backup-${timestamp}`;
|
|
2661
|
-
|
|
2662
|
-
|
|
2662
|
+
try {
|
|
2663
|
+
fs12.copyFileSync(filePath, backupPath);
|
|
2664
|
+
fs12.chmodSync(backupPath, 384);
|
|
2665
|
+
return backupPath;
|
|
2666
|
+
} catch (error) {
|
|
2667
|
+
throw new Error(`\u5907\u4EFD\u5931\u8D25\uFF0C\u5DF2\u4E2D\u6B62\u540E\u7EED\u5199\u5165\uFF08claude-clean\uFF09: ${error.message}`);
|
|
2668
|
+
}
|
|
2663
2669
|
}
|
|
2664
2670
|
function saveJsonAtomic(filePath, data) {
|
|
2665
2671
|
const tempPath = `${filePath}.tmp`;
|
|
@@ -3289,8 +3295,8 @@ function downloadCommand(program2) {
|
|
|
3289
3295
|
console.log();
|
|
3290
3296
|
if (backupPaths.length > 0) {
|
|
3291
3297
|
console.log(chalk7.gray("\u672C\u5730\u5907\u4EFD:"));
|
|
3292
|
-
backupPaths.forEach((
|
|
3293
|
-
console.log(chalk7.gray(` ${
|
|
3298
|
+
backupPaths.forEach((path16) => {
|
|
3299
|
+
console.log(chalk7.gray(` ${path16}`));
|
|
3294
3300
|
});
|
|
3295
3301
|
console.log();
|
|
3296
3302
|
}
|
|
@@ -3351,8 +3357,8 @@ function mergeCommand(program2) {
|
|
|
3351
3357
|
console.log();
|
|
3352
3358
|
if (result.backupPaths.length > 0) {
|
|
3353
3359
|
console.log(chalk8.gray("\u5907\u4EFD:"));
|
|
3354
|
-
result.backupPaths.forEach((
|
|
3355
|
-
console.log(chalk8.gray(` ${
|
|
3360
|
+
result.backupPaths.forEach((path16) => {
|
|
3361
|
+
console.log(chalk8.gray(` ${path16}`));
|
|
3356
3362
|
});
|
|
3357
3363
|
console.log();
|
|
3358
3364
|
}
|
|
@@ -7141,6 +7147,8 @@ function importCommand(program2) {
|
|
|
7141
7147
|
|
|
7142
7148
|
// src/commands/gmn.ts
|
|
7143
7149
|
init_dist2();
|
|
7150
|
+
import fs13 from "fs";
|
|
7151
|
+
import path15 from "path";
|
|
7144
7152
|
import chalk54 from "chalk";
|
|
7145
7153
|
import inquirer38 from "inquirer";
|
|
7146
7154
|
var DEFAULT_PROVIDER_NAME2 = "gmn";
|
|
@@ -7283,6 +7291,72 @@ function findPreferredProvider(providers, targetName) {
|
|
|
7283
7291
|
const lowerTarget = targetName.toLowerCase();
|
|
7284
7292
|
return providers.find((p) => p.name.trim().toLowerCase() === lowerTarget);
|
|
7285
7293
|
}
|
|
7294
|
+
function getPlatformTargetFiles(platform) {
|
|
7295
|
+
const ccmanDir2 = getCcmanDir();
|
|
7296
|
+
switch (platform) {
|
|
7297
|
+
case "codex":
|
|
7298
|
+
return [path15.join(ccmanDir2, "codex.json"), getCodexConfigPath(), getCodexAuthPath()];
|
|
7299
|
+
case "opencode":
|
|
7300
|
+
return [path15.join(ccmanDir2, "opencode.json"), getOpenCodeConfigPath()];
|
|
7301
|
+
case "openclaw":
|
|
7302
|
+
return [
|
|
7303
|
+
path15.join(ccmanDir2, "openclaw.json"),
|
|
7304
|
+
getOpenClawConfigPath(),
|
|
7305
|
+
getOpenClawModelsPath()
|
|
7306
|
+
];
|
|
7307
|
+
}
|
|
7308
|
+
}
|
|
7309
|
+
function createPlatformBackupOrThrow(platform, backupRootDir) {
|
|
7310
|
+
const backupDir = path15.join(backupRootDir, platform);
|
|
7311
|
+
const entries = [];
|
|
7312
|
+
const targetFiles = getPlatformTargetFiles(platform);
|
|
7313
|
+
fs13.mkdirSync(backupDir, { recursive: true, mode: 448 });
|
|
7314
|
+
for (const [index, originalPath] of targetFiles.entries()) {
|
|
7315
|
+
const existed = fs13.existsSync(originalPath);
|
|
7316
|
+
if (!existed) {
|
|
7317
|
+
entries.push({ originalPath, backupPath: null, existed: false });
|
|
7318
|
+
continue;
|
|
7319
|
+
}
|
|
7320
|
+
const fileName = path15.basename(originalPath).replace(/[^\w.-]/g, "_");
|
|
7321
|
+
const backupPath = path15.join(backupDir, `${String(index).padStart(2, "0")}-${fileName}.bak`);
|
|
7322
|
+
try {
|
|
7323
|
+
fs13.copyFileSync(originalPath, backupPath);
|
|
7324
|
+
fs13.chmodSync(backupPath, 384);
|
|
7325
|
+
entries.push({ originalPath, backupPath, existed: true });
|
|
7326
|
+
} catch (error) {
|
|
7327
|
+
throw new Error(`\u5907\u4EFD\u5931\u8D25\uFF0C\u5DF2\u4E2D\u6B62\u540E\u7EED\u5199\u5165\uFF08${platform}\uFF09: ${error.message}`);
|
|
7328
|
+
}
|
|
7329
|
+
}
|
|
7330
|
+
const manifestPath = path15.join(backupDir, "manifest.json");
|
|
7331
|
+
const manifest = {
|
|
7332
|
+
platform,
|
|
7333
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7334
|
+
entries
|
|
7335
|
+
};
|
|
7336
|
+
fs13.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2), { mode: 384 });
|
|
7337
|
+
return { backupDir, entries };
|
|
7338
|
+
}
|
|
7339
|
+
function rollbackFromBackupOrThrow(result) {
|
|
7340
|
+
const errors = [];
|
|
7341
|
+
for (const entry of result.entries) {
|
|
7342
|
+
try {
|
|
7343
|
+
if (entry.existed) {
|
|
7344
|
+
if (!entry.backupPath || !fs13.existsSync(entry.backupPath)) {
|
|
7345
|
+
throw new Error(`\u5907\u4EFD\u6587\u4EF6\u7F3A\u5931: ${entry.backupPath || entry.originalPath}`);
|
|
7346
|
+
}
|
|
7347
|
+
fs13.mkdirSync(path15.dirname(entry.originalPath), { recursive: true });
|
|
7348
|
+
fs13.copyFileSync(entry.backupPath, entry.originalPath);
|
|
7349
|
+
} else if (fs13.existsSync(entry.originalPath)) {
|
|
7350
|
+
fs13.rmSync(entry.originalPath, { force: true });
|
|
7351
|
+
}
|
|
7352
|
+
} catch (error) {
|
|
7353
|
+
errors.push(`${entry.originalPath}: ${error.message}`);
|
|
7354
|
+
}
|
|
7355
|
+
}
|
|
7356
|
+
if (errors.length > 0) {
|
|
7357
|
+
throw new Error(`\u56DE\u6EDA\u5931\u8D25: ${errors.join("; ")}`);
|
|
7358
|
+
}
|
|
7359
|
+
}
|
|
7286
7360
|
async function gmnCommand(apiKey, platformArg, providerNameArg) {
|
|
7287
7361
|
printBanner();
|
|
7288
7362
|
let platforms;
|
|
@@ -7328,6 +7402,14 @@ ${renderStep(3, TOTAL_STEPS, "\u5F00\u59CB\u5199\u5165\u914D\u7F6E")}`));
|
|
|
7328
7402
|
}
|
|
7329
7403
|
printWriteTargets(platforms);
|
|
7330
7404
|
console.log();
|
|
7405
|
+
const backupRootDir = path15.join(
|
|
7406
|
+
getCcmanDir(),
|
|
7407
|
+
"backups",
|
|
7408
|
+
`gmn-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`
|
|
7409
|
+
);
|
|
7410
|
+
fs13.mkdirSync(backupRootDir, { recursive: true, mode: 448 });
|
|
7411
|
+
console.log(chalk54.gray(`\u5907\u4EFD\u6839\u76EE\u5F55: ${backupRootDir}`));
|
|
7412
|
+
console.log();
|
|
7331
7413
|
const ALL_TOOLS = {
|
|
7332
7414
|
codex: { name: "Codex", manager: createCodexManager() },
|
|
7333
7415
|
opencode: { name: "OpenCode", manager: createOpenCodeManager() },
|
|
@@ -7337,22 +7419,66 @@ ${renderStep(3, TOTAL_STEPS, "\u5F00\u59CB\u5199\u5165\u914D\u7F6E")}`));
|
|
|
7337
7419
|
platform,
|
|
7338
7420
|
...ALL_TOOLS[platform]
|
|
7339
7421
|
}));
|
|
7422
|
+
const successBackups = [];
|
|
7340
7423
|
let completed = 0;
|
|
7341
7424
|
for (const { platform, name, manager } of tools) {
|
|
7425
|
+
let backupResult = null;
|
|
7342
7426
|
try {
|
|
7343
7427
|
console.log(chalk54.gray(`\u2192 \u914D\u7F6E ${name}...`));
|
|
7428
|
+
backupResult = createPlatformBackupOrThrow(platform, backupRootDir);
|
|
7429
|
+
const backupFiles = backupResult.entries.map((entry) => entry.backupPath).filter((p) => p !== null);
|
|
7430
|
+
if (backupFiles.length > 0) {
|
|
7431
|
+
console.log(chalk54.gray(` \u5DF2\u5907\u4EFD ${backupFiles.length} \u4E2A\u6587\u4EF6`));
|
|
7432
|
+
} else {
|
|
7433
|
+
console.log(chalk54.gray(" \u65E0\u5386\u53F2\u6587\u4EF6\u53EF\u5907\u4EFD"));
|
|
7434
|
+
}
|
|
7344
7435
|
const baseUrl = platformBaseUrls[platform];
|
|
7345
7436
|
const existing = findPreferredProvider(manager.list(), providerName);
|
|
7346
7437
|
const provider = existing ? manager.edit(existing.id, { name: providerName, baseUrl, apiKey: resolvedApiKey }) : manager.add({ name: providerName, baseUrl, apiKey: resolvedApiKey });
|
|
7347
7438
|
manager.switch(provider.id);
|
|
7348
7439
|
completed += 1;
|
|
7349
7440
|
console.log(chalk54.green(`\u2705 ${name}`));
|
|
7441
|
+
successBackups.push({
|
|
7442
|
+
name,
|
|
7443
|
+
backupDir: backupResult.backupDir,
|
|
7444
|
+
backupFiles
|
|
7445
|
+
});
|
|
7350
7446
|
} catch (error) {
|
|
7351
|
-
|
|
7447
|
+
const operationError = error;
|
|
7448
|
+
if (backupResult !== null) {
|
|
7449
|
+
try {
|
|
7450
|
+
rollbackFromBackupOrThrow(backupResult);
|
|
7451
|
+
console.error(chalk54.red(`\u274C ${name}: ${operationError.message}\uFF08\u5DF2\u56DE\u6EDA\u5386\u53F2\u6587\u4EF6\uFF09`));
|
|
7452
|
+
} catch (rollbackError) {
|
|
7453
|
+
console.error(
|
|
7454
|
+
chalk54.red(
|
|
7455
|
+
`\u274C ${name}: ${operationError.message}\uFF1B\u56DE\u6EDA\u4E5F\u5931\u8D25: ${rollbackError.message}`
|
|
7456
|
+
)
|
|
7457
|
+
);
|
|
7458
|
+
}
|
|
7459
|
+
} else {
|
|
7460
|
+
console.error(chalk54.red(`\u274C ${name}: ${operationError.message}`));
|
|
7461
|
+
}
|
|
7352
7462
|
}
|
|
7353
7463
|
}
|
|
7354
7464
|
console.log(chalk54.green(`
|
|
7355
7465
|
\u{1F389} GMN \u914D\u7F6E\u5B8C\u6210\uFF01(${completed}/${tools.length})`));
|
|
7466
|
+
console.log();
|
|
7467
|
+
console.log(chalk54.bold("\u5907\u4EFD\u4FE1\u606F:"));
|
|
7468
|
+
if (successBackups.length === 0) {
|
|
7469
|
+
console.log(chalk54.gray(" \u65E0\u6210\u529F\u914D\u7F6E\u9879\uFF0C\u672A\u751F\u6210\u53EF\u7528\u5907\u4EFD\u76EE\u5F55\u3002"));
|
|
7470
|
+
} else {
|
|
7471
|
+
for (const item of successBackups) {
|
|
7472
|
+
console.log(chalk54.gray(` ${item.name}: ${item.backupDir}`));
|
|
7473
|
+
if (item.backupFiles.length === 0) {
|
|
7474
|
+
console.log(chalk54.gray(" - \u65E0\u5386\u53F2\u6587\u4EF6\u53EF\u5907\u4EFD"));
|
|
7475
|
+
} else {
|
|
7476
|
+
for (const file of item.backupFiles) {
|
|
7477
|
+
console.log(chalk54.gray(` - ${file}`));
|
|
7478
|
+
}
|
|
7479
|
+
}
|
|
7480
|
+
}
|
|
7481
|
+
}
|
|
7356
7482
|
console.log(chalk54.gray("\u63D0\u793A\uFF1A\u8BF7\u91CD\u542F\u5BF9\u5E94\u5DE5\u5177/\u63D2\u4EF6\u4EE5\u4F7F\u914D\u7F6E\u751F\u6548\u3002"));
|
|
7357
7483
|
}
|
|
7358
7484
|
|
package/package.json
CHANGED