ccjk 1.5.0 → 2.0.2
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/README.ja.md +249 -297
- package/README.ko.md +241 -290
- package/README.md +222 -364
- package/README.zh-CN.md +553 -295
- package/dist/chunks/claude-code-config-manager.mjs +7 -7
- package/dist/chunks/claude-code-incremental-manager.mjs +1 -1
- package/dist/chunks/codex-config-switch.mjs +3 -3
- package/dist/chunks/codex-provider-manager.mjs +1 -1
- package/dist/chunks/codex-uninstaller.mjs +2 -2
- package/dist/chunks/commands.mjs +1 -1
- package/dist/chunks/features.mjs +10 -10
- package/dist/chunks/simple-config.mjs +321 -389
- package/dist/chunks/smart-guide.mjs +234 -0
- package/dist/cli.mjs +1795 -433
- package/dist/i18n/locales/en/configuration.json +12 -1
- package/dist/i18n/locales/en/marketplace.json +84 -0
- package/dist/i18n/locales/en/menu.json +38 -1
- package/dist/i18n/locales/en/skills.json +140 -0
- package/dist/i18n/locales/en/smartGuide.json +49 -0
- package/dist/i18n/locales/en/subagent.json +69 -0
- package/dist/i18n/locales/en/superpowers.json +58 -0
- package/dist/i18n/locales/zh-CN/configuration.json +12 -1
- package/dist/i18n/locales/zh-CN/marketplace.json +84 -0
- package/dist/i18n/locales/zh-CN/menu.json +38 -1
- package/dist/i18n/locales/zh-CN/skills.json +140 -0
- package/dist/i18n/locales/zh-CN/smartGuide.json +49 -0
- package/dist/i18n/locales/zh-CN/subagent.json +69 -0
- package/dist/i18n/locales/zh-CN/superpowers.json +58 -0
- package/dist/index.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +366 -7
- package/package.json +26 -27
- package/templates/common/skills/en/brainstorming.md +64 -0
- package/templates/common/skills/en/code-review.md +81 -0
- package/templates/common/skills/en/documentation-gen.md +808 -0
- package/templates/common/skills/en/executing-plans.md +75 -0
- package/templates/common/skills/en/git-commit.md +216 -0
- package/templates/common/skills/en/interview.md +223 -0
- package/templates/common/skills/en/migration-assistant.md +312 -0
- package/templates/common/skills/en/performance-profiling.md +576 -0
- package/templates/common/skills/en/pr-review.md +341 -0
- package/templates/common/skills/en/refactoring.md +384 -0
- package/templates/common/skills/en/security-audit.md +462 -0
- package/templates/common/skills/en/systematic-debugging.md +82 -0
- package/templates/common/skills/en/tdd-workflow.md +93 -0
- package/templates/common/skills/en/verification.md +81 -0
- package/templates/common/skills/en/workflow.md +370 -0
- package/templates/common/skills/en/writing-plans.md +78 -0
- package/templates/common/skills/zh-CN/documentation-gen.md +807 -0
- package/templates/common/skills/zh-CN/migration-assistant.md +318 -0
- package/templates/common/skills/zh-CN/performance-profiling.md +746 -0
- package/templates/common/skills/zh-CN/pr-review.md +341 -0
- package/templates/common/skills/zh-CN/refactoring.md +384 -0
- package/templates/common/skills/zh-CN/security-audit.md +462 -0
- package/templates/common/smart-guide/en/smart-guide.md +72 -0
- package/templates/common/smart-guide/zh-CN/smart-guide.md +72 -0
|
@@ -14,13 +14,13 @@ import toggleModule from 'inquirer-toggle';
|
|
|
14
14
|
import ora from 'ora';
|
|
15
15
|
import { exec, x } from 'tinyexec';
|
|
16
16
|
import semver from 'semver';
|
|
17
|
-
import { rm, mkdir, copyFile as copyFile$1 } from 'node:fs/promises';
|
|
17
|
+
import { readFile as readFile$1, rm, mkdir, copyFile as copyFile$1 } from 'node:fs/promises';
|
|
18
18
|
import { pathExists } from 'fs-extra';
|
|
19
19
|
import trash from 'trash';
|
|
20
20
|
import i18next from 'i18next';
|
|
21
21
|
import Backend from 'i18next-fs-backend';
|
|
22
22
|
|
|
23
|
-
const version = "
|
|
23
|
+
const version = "2.0.2";
|
|
24
24
|
const homepage = "https://github.com/miounet11/ccjk";
|
|
25
25
|
|
|
26
26
|
const i18n = i18next.createInstance();
|
|
@@ -38,10 +38,18 @@ const NAMESPACES = [
|
|
|
38
38
|
"interview",
|
|
39
39
|
// Interview-Driven Development
|
|
40
40
|
"language",
|
|
41
|
+
"marketplace",
|
|
42
|
+
// Marketplace system for plugins, skills, and workflows
|
|
41
43
|
"mcp",
|
|
42
44
|
"menu",
|
|
43
45
|
"multi-config",
|
|
44
46
|
"shencha",
|
|
47
|
+
"skills",
|
|
48
|
+
// Skills management system
|
|
49
|
+
"smartGuide",
|
|
50
|
+
// Smart Guide for quick actions
|
|
51
|
+
"superpowers",
|
|
52
|
+
// Superpowers plugin integration
|
|
45
53
|
"team",
|
|
46
54
|
"tools",
|
|
47
55
|
"uninstall",
|
|
@@ -2258,7 +2266,7 @@ function getFallbackPresets() {
|
|
|
2258
2266
|
];
|
|
2259
2267
|
}
|
|
2260
2268
|
|
|
2261
|
-
const execAsync$
|
|
2269
|
+
const execAsync$4 = promisify(exec$1);
|
|
2262
2270
|
const CCR_CONFIG_DIR = join(homedir(), ".claude-code-router");
|
|
2263
2271
|
const CCR_CONFIG_FILE = join(CCR_CONFIG_DIR, "config.json");
|
|
2264
2272
|
const CCR_BACKUP_DIR = CCR_CONFIG_DIR;
|
|
@@ -2425,10 +2433,10 @@ async function restartAndCheckCcrStatus() {
|
|
|
2425
2433
|
ensureI18nInitialized();
|
|
2426
2434
|
try {
|
|
2427
2435
|
console.log(ansis.cyan(`${i18n.t("ccr:restartingCcr")}`));
|
|
2428
|
-
await execAsync$
|
|
2436
|
+
await execAsync$4("ccr restart");
|
|
2429
2437
|
console.log(ansis.green(`\u2714 ${i18n.t("ccr:ccrRestartSuccess")}`));
|
|
2430
2438
|
console.log(ansis.cyan(`${i18n.t("ccr:checkingCcrStatus")}`));
|
|
2431
|
-
const { stdout } = await execAsync$
|
|
2439
|
+
const { stdout } = await execAsync$4("ccr status");
|
|
2432
2440
|
console.log(ansis.gray(stdout));
|
|
2433
2441
|
} catch (error) {
|
|
2434
2442
|
console.error(ansis.red(`${i18n.t("ccr:ccrRestartFailed")}:`), error.message || error);
|
|
@@ -2565,16 +2573,16 @@ const config = {
|
|
|
2565
2573
|
writeCcrConfig: writeCcrConfig
|
|
2566
2574
|
};
|
|
2567
2575
|
|
|
2568
|
-
const execAsync$
|
|
2576
|
+
const execAsync$3 = promisify(exec$1);
|
|
2569
2577
|
async function getInstalledVersion(command, maxRetries = 3) {
|
|
2570
2578
|
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
2571
2579
|
try {
|
|
2572
2580
|
let stdout;
|
|
2573
2581
|
try {
|
|
2574
|
-
const result = await execAsync$
|
|
2582
|
+
const result = await execAsync$3(`${command} -v`);
|
|
2575
2583
|
stdout = result.stdout;
|
|
2576
2584
|
} catch {
|
|
2577
|
-
const result = await execAsync$
|
|
2585
|
+
const result = await execAsync$3(`${command} --version`);
|
|
2578
2586
|
stdout = result.stdout;
|
|
2579
2587
|
}
|
|
2580
2588
|
const versionMatch = stdout.match(/(\d+\.\d+\.\d+(?:-[\w.]+)?)/);
|
|
@@ -2591,7 +2599,7 @@ async function getInstalledVersion(command, maxRetries = 3) {
|
|
|
2591
2599
|
async function getLatestVersion(packageName, maxRetries = 3) {
|
|
2592
2600
|
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
2593
2601
|
try {
|
|
2594
|
-
const { stdout } = await execAsync$
|
|
2602
|
+
const { stdout } = await execAsync$3(`npm view ${packageName} version`);
|
|
2595
2603
|
return stdout.trim();
|
|
2596
2604
|
} catch {
|
|
2597
2605
|
if (attempt === maxRetries) {
|
|
@@ -2620,7 +2628,7 @@ async function getClaudeCodeInstallationSource() {
|
|
|
2620
2628
|
return { isHomebrew: true, commandPath, source: "homebrew-cask" };
|
|
2621
2629
|
}
|
|
2622
2630
|
try {
|
|
2623
|
-
const { stdout: realPath } = await execAsync$
|
|
2631
|
+
const { stdout: realPath } = await execAsync$3(`readlink -f "${commandPath}" 2>/dev/null || realpath "${commandPath}" 2>/dev/null || echo "${commandPath}"`);
|
|
2624
2632
|
const resolvedPath = realPath.trim();
|
|
2625
2633
|
if (resolvedPath.includes("/Caskroom/claude-code/")) {
|
|
2626
2634
|
return { isHomebrew: true, commandPath, source: "homebrew-cask" };
|
|
@@ -2639,7 +2647,7 @@ async function detectAllClaudeCodeInstallations() {
|
|
|
2639
2647
|
let activeResolvedPath = null;
|
|
2640
2648
|
if (activeCommandPath) {
|
|
2641
2649
|
try {
|
|
2642
|
-
const { stdout } = await execAsync$
|
|
2650
|
+
const { stdout } = await execAsync$3(`readlink -f "${activeCommandPath}" 2>/dev/null || realpath "${activeCommandPath}" 2>/dev/null || echo "${activeCommandPath}"`);
|
|
2643
2651
|
activeResolvedPath = stdout.trim();
|
|
2644
2652
|
} catch {
|
|
2645
2653
|
activeResolvedPath = activeCommandPath;
|
|
@@ -2647,7 +2655,7 @@ async function detectAllClaudeCodeInstallations() {
|
|
|
2647
2655
|
}
|
|
2648
2656
|
async function getVersionFromPath(path) {
|
|
2649
2657
|
try {
|
|
2650
|
-
const { stdout } = await execAsync$
|
|
2658
|
+
const { stdout } = await execAsync$3(`"${path}" -v 2>/dev/null || "${path}" --version 2>/dev/null`);
|
|
2651
2659
|
const versionMatch = stdout.match(/(\d+\.\d+\.\d+(?:-[\w.]+)?)/);
|
|
2652
2660
|
return versionMatch ? versionMatch[1] : null;
|
|
2653
2661
|
} catch {
|
|
@@ -2662,7 +2670,7 @@ async function detectAllClaudeCodeInstallations() {
|
|
|
2662
2670
|
async function addInstallation(path, source) {
|
|
2663
2671
|
let resolvedPath = path;
|
|
2664
2672
|
try {
|
|
2665
|
-
const { stdout } = await execAsync$
|
|
2673
|
+
const { stdout } = await execAsync$3(`readlink -f "${path}" 2>/dev/null || realpath "${path}" 2>/dev/null || echo "${path}"`);
|
|
2666
2674
|
resolvedPath = stdout.trim();
|
|
2667
2675
|
} catch {
|
|
2668
2676
|
}
|
|
@@ -2698,7 +2706,7 @@ async function detectAllClaudeCodeInstallations() {
|
|
|
2698
2706
|
}
|
|
2699
2707
|
}
|
|
2700
2708
|
try {
|
|
2701
|
-
await execAsync$
|
|
2709
|
+
await execAsync$3("brew list --cask claude-code");
|
|
2702
2710
|
const homebrewPrefixes = ["/opt/homebrew", "/usr/local"];
|
|
2703
2711
|
for (const prefix of homebrewPrefixes) {
|
|
2704
2712
|
const caskroomPath = `${prefix}/Caskroom/claude-code`;
|
|
@@ -2723,7 +2731,7 @@ async function detectAllClaudeCodeInstallations() {
|
|
|
2723
2731
|
if (nodeFs.existsSync(path)) {
|
|
2724
2732
|
let resolvedPath = path;
|
|
2725
2733
|
try {
|
|
2726
|
-
const { stdout } = await execAsync$
|
|
2734
|
+
const { stdout } = await execAsync$3(`readlink -f "${path}" 2>/dev/null || realpath "${path}" 2>/dev/null || echo "${path}"`);
|
|
2727
2735
|
resolvedPath = stdout.trim();
|
|
2728
2736
|
} catch {
|
|
2729
2737
|
}
|
|
@@ -2913,7 +2921,7 @@ async function handleDuplicateInstallations(skipPrompt = false) {
|
|
|
2913
2921
|
}
|
|
2914
2922
|
async function getHomebrewClaudeCodeVersion() {
|
|
2915
2923
|
try {
|
|
2916
|
-
const { stdout } = await execAsync$
|
|
2924
|
+
const { stdout } = await execAsync$3("brew info --cask claude-code --json=v2");
|
|
2917
2925
|
const info = JSON.parse(stdout);
|
|
2918
2926
|
if (info.casks && info.casks.length > 0) {
|
|
2919
2927
|
return info.casks[0].version;
|
|
@@ -3219,15 +3227,15 @@ const autoUpdater = {
|
|
|
3219
3227
|
updateCometixLine: updateCometixLine
|
|
3220
3228
|
};
|
|
3221
3229
|
|
|
3222
|
-
const execAsync$
|
|
3230
|
+
const execAsync$2 = promisify(exec$1);
|
|
3223
3231
|
async function isCcrInstalled() {
|
|
3224
3232
|
let commandExists = false;
|
|
3225
3233
|
try {
|
|
3226
|
-
await execAsync$
|
|
3234
|
+
await execAsync$2("ccr version");
|
|
3227
3235
|
commandExists = true;
|
|
3228
3236
|
} catch {
|
|
3229
3237
|
try {
|
|
3230
|
-
await execAsync$
|
|
3238
|
+
await execAsync$2("which ccr");
|
|
3231
3239
|
commandExists = true;
|
|
3232
3240
|
} catch {
|
|
3233
3241
|
commandExists = false;
|
|
@@ -3235,7 +3243,7 @@ async function isCcrInstalled() {
|
|
|
3235
3243
|
}
|
|
3236
3244
|
let hasCorrectPackage = false;
|
|
3237
3245
|
try {
|
|
3238
|
-
await execAsync$
|
|
3246
|
+
await execAsync$2("npm list -g @musistudio/claude-code-router");
|
|
3239
3247
|
hasCorrectPackage = true;
|
|
3240
3248
|
} catch {
|
|
3241
3249
|
hasCorrectPackage = false;
|
|
@@ -3255,10 +3263,10 @@ async function installCcr() {
|
|
|
3255
3263
|
}
|
|
3256
3264
|
if (isInstalled && !hasCorrectPackage) {
|
|
3257
3265
|
try {
|
|
3258
|
-
await execAsync$
|
|
3266
|
+
await execAsync$2("npm list -g claude-code-router");
|
|
3259
3267
|
console.log(ansis.yellow(`\u26A0 ${i18n.t("ccr:detectedIncorrectPackage")}`));
|
|
3260
3268
|
try {
|
|
3261
|
-
await execAsync$
|
|
3269
|
+
await execAsync$2("npm uninstall -g claude-code-router");
|
|
3262
3270
|
console.log(ansis.green(`\u2714 ${i18n.t("ccr:uninstalledIncorrectPackage")}`));
|
|
3263
3271
|
} catch {
|
|
3264
3272
|
console.log(ansis.yellow(`\u26A0 ${i18n.t("ccr:failedToUninstallIncorrectPackage")}`));
|
|
@@ -3273,7 +3281,7 @@ async function installCcr() {
|
|
|
3273
3281
|
if (usedSudo) {
|
|
3274
3282
|
console.log(ansis.yellow(`\u2139 ${i18n.t("installation:usingSudo")}`));
|
|
3275
3283
|
}
|
|
3276
|
-
await execAsync$
|
|
3284
|
+
await execAsync$2([command, ...args].join(" "));
|
|
3277
3285
|
console.log(ansis.green(`\u2714 ${i18n.t("ccr:ccrInstallSuccess")}`));
|
|
3278
3286
|
} catch (error) {
|
|
3279
3287
|
if (error.message?.includes("EEXIST")) {
|
|
@@ -5371,10 +5379,10 @@ const COMETIX_COMMANDS = {
|
|
|
5371
5379
|
TUI_CONFIG: `${COMETIX_COMMAND_NAME} -c`
|
|
5372
5380
|
};
|
|
5373
5381
|
|
|
5374
|
-
const execAsync = promisify(exec$1);
|
|
5382
|
+
const execAsync$1 = promisify(exec$1);
|
|
5375
5383
|
async function isCometixLineInstalled() {
|
|
5376
5384
|
try {
|
|
5377
|
-
await execAsync(COMETIX_COMMANDS.CHECK_INSTALL);
|
|
5385
|
+
await execAsync$1(COMETIX_COMMANDS.CHECK_INSTALL);
|
|
5378
5386
|
return true;
|
|
5379
5387
|
} catch {
|
|
5380
5388
|
return false;
|
|
@@ -5388,7 +5396,7 @@ async function installCometixLine() {
|
|
|
5388
5396
|
if (usedSudo) {
|
|
5389
5397
|
console.log(ansis.yellow(`\u2139 ${i18n.t("installation:usingSudo")}`));
|
|
5390
5398
|
}
|
|
5391
|
-
await execAsync([command, ...args].join(" "));
|
|
5399
|
+
await execAsync$1([command, ...args].join(" "));
|
|
5392
5400
|
};
|
|
5393
5401
|
const isInstalled = await isCometixLineInstalled();
|
|
5394
5402
|
if (isInstalled) {
|
|
@@ -6607,6 +6615,208 @@ async function handleMultipleInstallations(status) {
|
|
|
6607
6615
|
}
|
|
6608
6616
|
}
|
|
6609
6617
|
|
|
6618
|
+
const execAsync = promisify(exec$1);
|
|
6619
|
+
function getClaudePluginDir() {
|
|
6620
|
+
return join(homedir(), ".claude", "plugins");
|
|
6621
|
+
}
|
|
6622
|
+
function getSuperpowersPath() {
|
|
6623
|
+
return join(getClaudePluginDir(), "superpowers");
|
|
6624
|
+
}
|
|
6625
|
+
async function checkSuperpowersInstalled() {
|
|
6626
|
+
const superpowersPath = getSuperpowersPath();
|
|
6627
|
+
if (!existsSync(superpowersPath)) {
|
|
6628
|
+
return { installed: false };
|
|
6629
|
+
}
|
|
6630
|
+
try {
|
|
6631
|
+
const packageJsonPath = join(superpowersPath, "package.json");
|
|
6632
|
+
if (existsSync(packageJsonPath)) {
|
|
6633
|
+
const packageJson = JSON.parse(await readFile$1(packageJsonPath, "utf-8"));
|
|
6634
|
+
const skillsDir = join(superpowersPath, "skills");
|
|
6635
|
+
let skillCount = 0;
|
|
6636
|
+
if (existsSync(skillsDir)) {
|
|
6637
|
+
const { readdir } = await import('node:fs/promises');
|
|
6638
|
+
const entries = await readdir(skillsDir, { withFileTypes: true });
|
|
6639
|
+
skillCount = entries.filter((e) => e.isDirectory()).length;
|
|
6640
|
+
}
|
|
6641
|
+
return {
|
|
6642
|
+
installed: true,
|
|
6643
|
+
version: packageJson.version,
|
|
6644
|
+
skillCount,
|
|
6645
|
+
path: superpowersPath
|
|
6646
|
+
};
|
|
6647
|
+
}
|
|
6648
|
+
return { installed: true, path: superpowersPath };
|
|
6649
|
+
} catch {
|
|
6650
|
+
return { installed: true, path: superpowersPath };
|
|
6651
|
+
}
|
|
6652
|
+
}
|
|
6653
|
+
async function installSuperpowers(_options) {
|
|
6654
|
+
try {
|
|
6655
|
+
const status = await checkSuperpowersInstalled();
|
|
6656
|
+
if (status.installed) {
|
|
6657
|
+
return {
|
|
6658
|
+
success: true,
|
|
6659
|
+
message: i18n.t("superpowers:alreadyInstalled")
|
|
6660
|
+
};
|
|
6661
|
+
}
|
|
6662
|
+
console.log(i18n.t("superpowers:addingMarketplace"));
|
|
6663
|
+
try {
|
|
6664
|
+
await execAsync("claude /plugin marketplace add obra/superpowers-marketplace", {
|
|
6665
|
+
timeout: 6e4
|
|
6666
|
+
});
|
|
6667
|
+
} catch {
|
|
6668
|
+
}
|
|
6669
|
+
console.log(i18n.t("superpowers:installing"));
|
|
6670
|
+
await execAsync("claude /plugin install superpowers@superpowers-marketplace", {
|
|
6671
|
+
timeout: 12e4
|
|
6672
|
+
});
|
|
6673
|
+
const newStatus = await checkSuperpowersInstalled();
|
|
6674
|
+
if (newStatus.installed) {
|
|
6675
|
+
return {
|
|
6676
|
+
success: true,
|
|
6677
|
+
message: i18n.t("superpowers:installSuccess")
|
|
6678
|
+
};
|
|
6679
|
+
}
|
|
6680
|
+
return {
|
|
6681
|
+
success: false,
|
|
6682
|
+
message: i18n.t("superpowers:installFailed"),
|
|
6683
|
+
error: "Installation completed but plugin not found"
|
|
6684
|
+
};
|
|
6685
|
+
} catch (error) {
|
|
6686
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
6687
|
+
return {
|
|
6688
|
+
success: false,
|
|
6689
|
+
message: i18n.t("superpowers:installFailed"),
|
|
6690
|
+
error: errorMessage
|
|
6691
|
+
};
|
|
6692
|
+
}
|
|
6693
|
+
}
|
|
6694
|
+
async function installSuperpowersViaGit() {
|
|
6695
|
+
try {
|
|
6696
|
+
const pluginDir = getClaudePluginDir();
|
|
6697
|
+
const superpowersPath = getSuperpowersPath();
|
|
6698
|
+
const { mkdir } = await import('node:fs/promises');
|
|
6699
|
+
await mkdir(pluginDir, { recursive: true });
|
|
6700
|
+
console.log(i18n.t("superpowers:cloning"));
|
|
6701
|
+
await execAsync(
|
|
6702
|
+
`git clone https://github.com/obra/superpowers.git "${superpowersPath}"`,
|
|
6703
|
+
{ timeout: 12e4 }
|
|
6704
|
+
);
|
|
6705
|
+
const status = await checkSuperpowersInstalled();
|
|
6706
|
+
if (status.installed) {
|
|
6707
|
+
return {
|
|
6708
|
+
success: true,
|
|
6709
|
+
message: i18n.t("superpowers:installSuccess")
|
|
6710
|
+
};
|
|
6711
|
+
}
|
|
6712
|
+
return {
|
|
6713
|
+
success: false,
|
|
6714
|
+
message: i18n.t("superpowers:installFailed")
|
|
6715
|
+
};
|
|
6716
|
+
} catch (error) {
|
|
6717
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
6718
|
+
return {
|
|
6719
|
+
success: false,
|
|
6720
|
+
message: i18n.t("superpowers:installFailed"),
|
|
6721
|
+
error: errorMessage
|
|
6722
|
+
};
|
|
6723
|
+
}
|
|
6724
|
+
}
|
|
6725
|
+
async function uninstallSuperpowers() {
|
|
6726
|
+
try {
|
|
6727
|
+
const status = await checkSuperpowersInstalled();
|
|
6728
|
+
if (!status.installed) {
|
|
6729
|
+
return {
|
|
6730
|
+
success: true,
|
|
6731
|
+
message: i18n.t("superpowers:notInstalled")
|
|
6732
|
+
};
|
|
6733
|
+
}
|
|
6734
|
+
try {
|
|
6735
|
+
await execAsync("claude /plugin uninstall superpowers", {
|
|
6736
|
+
timeout: 6e4
|
|
6737
|
+
});
|
|
6738
|
+
} catch {
|
|
6739
|
+
const superpowersPath = getSuperpowersPath();
|
|
6740
|
+
if (existsSync(superpowersPath)) {
|
|
6741
|
+
const { rm } = await import('node:fs/promises');
|
|
6742
|
+
await rm(superpowersPath, { recursive: true, force: true });
|
|
6743
|
+
}
|
|
6744
|
+
}
|
|
6745
|
+
const newStatus = await checkSuperpowersInstalled();
|
|
6746
|
+
if (!newStatus.installed) {
|
|
6747
|
+
return {
|
|
6748
|
+
success: true,
|
|
6749
|
+
message: i18n.t("superpowers:uninstallSuccess")
|
|
6750
|
+
};
|
|
6751
|
+
}
|
|
6752
|
+
return {
|
|
6753
|
+
success: false,
|
|
6754
|
+
message: i18n.t("superpowers:uninstallFailed")
|
|
6755
|
+
};
|
|
6756
|
+
} catch (error) {
|
|
6757
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
6758
|
+
return {
|
|
6759
|
+
success: false,
|
|
6760
|
+
message: i18n.t("superpowers:uninstallFailed"),
|
|
6761
|
+
error: errorMessage
|
|
6762
|
+
};
|
|
6763
|
+
}
|
|
6764
|
+
}
|
|
6765
|
+
async function updateSuperpowers() {
|
|
6766
|
+
try {
|
|
6767
|
+
const status = await checkSuperpowersInstalled();
|
|
6768
|
+
if (!status.installed) {
|
|
6769
|
+
return {
|
|
6770
|
+
success: false,
|
|
6771
|
+
message: i18n.t("superpowers:notInstalled")
|
|
6772
|
+
};
|
|
6773
|
+
}
|
|
6774
|
+
try {
|
|
6775
|
+
await execAsync("claude /plugin update superpowers", {
|
|
6776
|
+
timeout: 12e4
|
|
6777
|
+
});
|
|
6778
|
+
return {
|
|
6779
|
+
success: true,
|
|
6780
|
+
message: i18n.t("superpowers:updateSuccess")
|
|
6781
|
+
};
|
|
6782
|
+
} catch {
|
|
6783
|
+
const superpowersPath = getSuperpowersPath();
|
|
6784
|
+
await execAsync("git pull", {
|
|
6785
|
+
cwd: superpowersPath,
|
|
6786
|
+
timeout: 6e4
|
|
6787
|
+
});
|
|
6788
|
+
return {
|
|
6789
|
+
success: true,
|
|
6790
|
+
message: i18n.t("superpowers:updateSuccess")
|
|
6791
|
+
};
|
|
6792
|
+
}
|
|
6793
|
+
} catch (error) {
|
|
6794
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
6795
|
+
return {
|
|
6796
|
+
success: false,
|
|
6797
|
+
message: i18n.t("superpowers:updateFailed"),
|
|
6798
|
+
error: errorMessage
|
|
6799
|
+
};
|
|
6800
|
+
}
|
|
6801
|
+
}
|
|
6802
|
+
async function getSuperpowersSkills() {
|
|
6803
|
+
try {
|
|
6804
|
+
const status = await checkSuperpowersInstalled();
|
|
6805
|
+
if (!status.installed || !status.path) {
|
|
6806
|
+
return [];
|
|
6807
|
+
}
|
|
6808
|
+
const skillsDir = join(status.path, "skills");
|
|
6809
|
+
if (!existsSync(skillsDir)) {
|
|
6810
|
+
return [];
|
|
6811
|
+
}
|
|
6812
|
+
const { readdir } = await import('node:fs/promises');
|
|
6813
|
+
const entries = await readdir(skillsDir, { withFileTypes: true });
|
|
6814
|
+
return entries.filter((e) => e.isDirectory()).map((e) => e.name);
|
|
6815
|
+
} catch {
|
|
6816
|
+
return [];
|
|
6817
|
+
}
|
|
6818
|
+
}
|
|
6819
|
+
|
|
6610
6820
|
function getRootDir() {
|
|
6611
6821
|
const currentFilePath = fileURLToPath(import.meta.url);
|
|
6612
6822
|
const distDir = dirname(dirname(currentFilePath));
|
|
@@ -6854,6 +7064,12 @@ async function validateSkipPromptOptions(options) {
|
|
|
6854
7064
|
if (options.installCometixLine === void 0) {
|
|
6855
7065
|
options.installCometixLine = true;
|
|
6856
7066
|
}
|
|
7067
|
+
if (typeof options.installSuperpowers === "string") {
|
|
7068
|
+
options.installSuperpowers = options.installSuperpowers.toLowerCase() === "true";
|
|
7069
|
+
}
|
|
7070
|
+
if (options.installSuperpowers === void 0) {
|
|
7071
|
+
options.installSuperpowers = false;
|
|
7072
|
+
}
|
|
6857
7073
|
if (options.configAction && !["new", "backup", "merge", "docs-only", "skip"].includes(options.configAction)) {
|
|
6858
7074
|
throw new Error(
|
|
6859
7075
|
i18n.t("errors:invalidConfigAction", { value: options.configAction })
|
|
@@ -6943,6 +7159,53 @@ async function validateSkipPromptOptions(options) {
|
|
|
6943
7159
|
options.workflows = WORKFLOW_CONFIG_BASE.map((w) => w.id);
|
|
6944
7160
|
}
|
|
6945
7161
|
}
|
|
7162
|
+
async function handleSuperpowersInstallation(options) {
|
|
7163
|
+
try {
|
|
7164
|
+
const status = await checkSuperpowersInstalled();
|
|
7165
|
+
if (status.installed) {
|
|
7166
|
+
console.log(ansis.green(`\u2714 ${i18n.t("superpowers:alreadyInstalled")}`));
|
|
7167
|
+
if (status.version) {
|
|
7168
|
+
console.log(ansis.gray(` ${i18n.t("superpowers:status.version", { version: status.version })}`));
|
|
7169
|
+
}
|
|
7170
|
+
if (status.skillCount) {
|
|
7171
|
+
console.log(ansis.gray(` ${i18n.t("superpowers:status.skillCount", { count: status.skillCount })}`));
|
|
7172
|
+
}
|
|
7173
|
+
return;
|
|
7174
|
+
}
|
|
7175
|
+
let shouldInstall = false;
|
|
7176
|
+
if (options.skipPrompt) {
|
|
7177
|
+
shouldInstall = options.installSuperpowers === true;
|
|
7178
|
+
} else {
|
|
7179
|
+
console.log(ansis.cyan(`
|
|
7180
|
+
${i18n.t("superpowers:title")}`));
|
|
7181
|
+
console.log(ansis.gray(i18n.t("superpowers:description")));
|
|
7182
|
+
console.log(ansis.gray(i18n.t("superpowers:installPromptDescription")));
|
|
7183
|
+
shouldInstall = await promptBoolean({
|
|
7184
|
+
message: i18n.t("superpowers:installPrompt"),
|
|
7185
|
+
defaultValue: false
|
|
7186
|
+
});
|
|
7187
|
+
}
|
|
7188
|
+
if (!shouldInstall) {
|
|
7189
|
+
console.log(ansis.yellow(i18n.t("common:skip")));
|
|
7190
|
+
return;
|
|
7191
|
+
}
|
|
7192
|
+
const result = await installSuperpowers({
|
|
7193
|
+
lang: i18n.language,
|
|
7194
|
+
skipPrompt: options.skipPrompt
|
|
7195
|
+
});
|
|
7196
|
+
if (result.success) {
|
|
7197
|
+
console.log(ansis.green(`\u2714 ${result.message}`));
|
|
7198
|
+
} else {
|
|
7199
|
+
console.error(ansis.red(`\u2716 ${result.message}`));
|
|
7200
|
+
if (result.error) {
|
|
7201
|
+
console.error(ansis.gray(` ${result.error}`));
|
|
7202
|
+
}
|
|
7203
|
+
}
|
|
7204
|
+
} catch (error) {
|
|
7205
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
7206
|
+
console.error(ansis.red(`${i18n.t("superpowers:installFailed")}: ${errorMessage}`));
|
|
7207
|
+
}
|
|
7208
|
+
}
|
|
6946
7209
|
async function init(options = {}) {
|
|
6947
7210
|
if (options.skipPrompt) {
|
|
6948
7211
|
await validateSkipPromptOptions(options);
|
|
@@ -7460,6 +7723,18 @@ async function init(options = {}) {
|
|
|
7460
7723
|
} else {
|
|
7461
7724
|
console.log(ansis.green(`\u2714 ${i18n.t("cometix:cometixAlreadyInstalled")}`));
|
|
7462
7725
|
}
|
|
7726
|
+
if (!options.skipPrompt || options.installSuperpowers) {
|
|
7727
|
+
await handleSuperpowersInstallation(options);
|
|
7728
|
+
}
|
|
7729
|
+
try {
|
|
7730
|
+
const { injectSmartGuide } = await import('./smart-guide.mjs');
|
|
7731
|
+
const smartGuideSuccess = await injectSmartGuide(configLang);
|
|
7732
|
+
if (smartGuideSuccess) {
|
|
7733
|
+
console.log(ansis.green(`\u2714 ${i18n.t("smartGuide:enabled")}`));
|
|
7734
|
+
}
|
|
7735
|
+
} catch {
|
|
7736
|
+
console.log(ansis.gray(`\u2139 ${i18n.t("smartGuide:skipped")}`));
|
|
7737
|
+
}
|
|
7463
7738
|
updateZcfConfig({
|
|
7464
7739
|
version,
|
|
7465
7740
|
preferredLang: i18n.language,
|
|
@@ -7469,9 +7744,25 @@ async function init(options = {}) {
|
|
|
7469
7744
|
aiOutputLang,
|
|
7470
7745
|
codeToolType
|
|
7471
7746
|
});
|
|
7472
|
-
console.log(
|
|
7473
|
-
console.log(
|
|
7474
|
-
|
|
7747
|
+
console.log("");
|
|
7748
|
+
console.log(ansis.bold.green("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
|
|
7749
|
+
console.log(ansis.bold.green("\u2551") + ansis.bold.white(` ${i18n.t("configuration:setupCompleteTitle")}`.padEnd(62)) + ansis.bold.green("\u2551"));
|
|
7750
|
+
console.log(ansis.bold.green("\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"));
|
|
7751
|
+
console.log(`${ansis.bold.green("\u2551")} ${ansis.bold.green("\u2551")}`);
|
|
7752
|
+
console.log(ansis.bold.green("\u2551") + ansis.cyan(` ${i18n.t("configuration:nextSteps")}`.padEnd(62)) + ansis.bold.green("\u2551"));
|
|
7753
|
+
console.log(`${ansis.bold.green("\u2551")} ${ansis.bold.green("\u2551")}`);
|
|
7754
|
+
console.log(ansis.bold.green("\u2551") + ` ${i18n.t("configuration:guidanceStep1")}`.padEnd(62) + ansis.bold.green("\u2551"));
|
|
7755
|
+
console.log(ansis.bold.green("\u2551") + ansis.dim(` ${i18n.t("configuration:guidanceStep1Detail")}`.padEnd(62)) + ansis.bold.green("\u2551"));
|
|
7756
|
+
console.log(ansis.bold.green("\u2551") + ansis.dim(` ${i18n.t("configuration:guidanceStep1Detail2")}`.padEnd(62)) + ansis.bold.green("\u2551"));
|
|
7757
|
+
console.log(`${ansis.bold.green("\u2551")} ${ansis.bold.green("\u2551")}`);
|
|
7758
|
+
console.log(ansis.bold.green("\u2551") + ` ${i18n.t("configuration:guidanceStep2")}`.padEnd(62) + ansis.bold.green("\u2551"));
|
|
7759
|
+
console.log(ansis.bold.green("\u2551") + ansis.cyan(` ${i18n.t("configuration:guidanceStep2Example")}`.padEnd(62)) + ansis.bold.green("\u2551"));
|
|
7760
|
+
console.log(`${ansis.bold.green("\u2551")} ${ansis.bold.green("\u2551")}`);
|
|
7761
|
+
console.log(ansis.bold.green("\u2551") + ` ${i18n.t("configuration:guidanceStep3")} `.padEnd(44) + ansis.yellow(i18n.t("configuration:guidanceStep3Command")).padEnd(18) + ansis.bold.green("\u2551"));
|
|
7762
|
+
console.log(ansis.bold.green("\u2551") + ` ${i18n.t("configuration:guidanceStep4")} `.padEnd(44) + ansis.yellow(i18n.t("configuration:guidanceStep4Command")).padEnd(18) + ansis.bold.green("\u2551"));
|
|
7763
|
+
console.log(`${ansis.bold.green("\u2551")} ${ansis.bold.green("\u2551")}`);
|
|
7764
|
+
console.log(ansis.bold.green("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"));
|
|
7765
|
+
console.log("");
|
|
7475
7766
|
} catch (error) {
|
|
7476
7767
|
if (!handleExitPromptError(error)) {
|
|
7477
7768
|
handleGeneralError(error);
|
|
@@ -9661,365 +9952,6 @@ Upgraded ${pluginResults.filter((r) => r.success).length}/${pluginResults.length
|
|
|
9661
9952
|
console.log("");
|
|
9662
9953
|
}
|
|
9663
9954
|
|
|
9664
|
-
async function checkClaudeCodeInstallation() {
|
|
9665
|
-
try {
|
|
9666
|
-
const versionInfo = await checkClaudeCodeVersion();
|
|
9667
|
-
if (versionInfo.current === "unknown") {
|
|
9668
|
-
return {
|
|
9669
|
-
name: "Claude Code",
|
|
9670
|
-
status: "fail",
|
|
9671
|
-
message: "Not installed",
|
|
9672
|
-
fixable: true,
|
|
9673
|
-
fixCommand: "npm install -g @anthropic-ai/claude-code"
|
|
9674
|
-
};
|
|
9675
|
-
}
|
|
9676
|
-
if (versionInfo.updateAvailable) {
|
|
9677
|
-
return {
|
|
9678
|
-
name: "Claude Code",
|
|
9679
|
-
status: "warn",
|
|
9680
|
-
message: `v${versionInfo.current} (update to v${versionInfo.latest} available)`,
|
|
9681
|
-
fixable: true,
|
|
9682
|
-
fixCommand: "ccjk upgrade claude-code"
|
|
9683
|
-
};
|
|
9684
|
-
}
|
|
9685
|
-
return {
|
|
9686
|
-
name: "Claude Code",
|
|
9687
|
-
status: "pass",
|
|
9688
|
-
message: `v${versionInfo.current} (latest)`
|
|
9689
|
-
};
|
|
9690
|
-
} catch (error) {
|
|
9691
|
-
return {
|
|
9692
|
-
name: "Claude Code",
|
|
9693
|
-
status: "fail",
|
|
9694
|
-
message: "Check failed",
|
|
9695
|
-
details: error instanceof Error ? error.message : "Unknown error"
|
|
9696
|
-
};
|
|
9697
|
-
}
|
|
9698
|
-
}
|
|
9699
|
-
async function checkCcjkInstallation() {
|
|
9700
|
-
try {
|
|
9701
|
-
const versionInfo = await checkCcjkVersion();
|
|
9702
|
-
if (versionInfo.updateAvailable) {
|
|
9703
|
-
return {
|
|
9704
|
-
name: "CCJK",
|
|
9705
|
-
status: "warn",
|
|
9706
|
-
message: `v${versionInfo.current} (update to v${versionInfo.latest} available)`,
|
|
9707
|
-
fixable: true,
|
|
9708
|
-
fixCommand: "ccjk upgrade ccjk"
|
|
9709
|
-
};
|
|
9710
|
-
}
|
|
9711
|
-
return {
|
|
9712
|
-
name: "CCJK",
|
|
9713
|
-
status: "pass",
|
|
9714
|
-
message: `v${versionInfo.current} (latest)`
|
|
9715
|
-
};
|
|
9716
|
-
} catch {
|
|
9717
|
-
return {
|
|
9718
|
-
name: "CCJK",
|
|
9719
|
-
status: "pass",
|
|
9720
|
-
message: `v${version}`
|
|
9721
|
-
};
|
|
9722
|
-
}
|
|
9723
|
-
}
|
|
9724
|
-
async function checkNodeVersion() {
|
|
9725
|
-
try {
|
|
9726
|
-
const result = await exec("node", ["--version"], { throwOnError: false });
|
|
9727
|
-
const nodeVersion = result.stdout.trim().replace("v", "");
|
|
9728
|
-
const major = Number.parseInt(nodeVersion.split(".")[0]);
|
|
9729
|
-
if (major < 18) {
|
|
9730
|
-
return {
|
|
9731
|
-
name: "Node.js",
|
|
9732
|
-
status: "fail",
|
|
9733
|
-
message: `v${nodeVersion} (requires v18+)`,
|
|
9734
|
-
fixable: false
|
|
9735
|
-
};
|
|
9736
|
-
}
|
|
9737
|
-
if (major < 20) {
|
|
9738
|
-
return {
|
|
9739
|
-
name: "Node.js",
|
|
9740
|
-
status: "warn",
|
|
9741
|
-
message: `v${nodeVersion} (v20+ recommended)`
|
|
9742
|
-
};
|
|
9743
|
-
}
|
|
9744
|
-
return {
|
|
9745
|
-
name: "Node.js",
|
|
9746
|
-
status: "pass",
|
|
9747
|
-
message: `v${nodeVersion}`
|
|
9748
|
-
};
|
|
9749
|
-
} catch {
|
|
9750
|
-
return {
|
|
9751
|
-
name: "Node.js",
|
|
9752
|
-
status: "fail",
|
|
9753
|
-
message: "Not found"
|
|
9754
|
-
};
|
|
9755
|
-
}
|
|
9756
|
-
}
|
|
9757
|
-
async function checkNpmVersion() {
|
|
9758
|
-
try {
|
|
9759
|
-
const result = await exec("npm", ["--version"], { throwOnError: false });
|
|
9760
|
-
const npmVersion = result.stdout.trim();
|
|
9761
|
-
return {
|
|
9762
|
-
name: "npm",
|
|
9763
|
-
status: "pass",
|
|
9764
|
-
message: `v${npmVersion}`
|
|
9765
|
-
};
|
|
9766
|
-
} catch {
|
|
9767
|
-
return {
|
|
9768
|
-
name: "npm",
|
|
9769
|
-
status: "fail",
|
|
9770
|
-
message: "Not found"
|
|
9771
|
-
};
|
|
9772
|
-
}
|
|
9773
|
-
}
|
|
9774
|
-
async function checkGitInstallation() {
|
|
9775
|
-
try {
|
|
9776
|
-
const result = await exec("git", ["--version"], { throwOnError: false });
|
|
9777
|
-
const match = result.stdout.match(/(\d+\.\d+\.\d+)/);
|
|
9778
|
-
const gitVersion = match ? match[1] : "unknown";
|
|
9779
|
-
return {
|
|
9780
|
-
name: "Git",
|
|
9781
|
-
status: "pass",
|
|
9782
|
-
message: `v${gitVersion}`
|
|
9783
|
-
};
|
|
9784
|
-
} catch {
|
|
9785
|
-
return {
|
|
9786
|
-
name: "Git",
|
|
9787
|
-
status: "warn",
|
|
9788
|
-
message: "Not found (optional)"
|
|
9789
|
-
};
|
|
9790
|
-
}
|
|
9791
|
-
}
|
|
9792
|
-
async function checkApiConnectivity() {
|
|
9793
|
-
try {
|
|
9794
|
-
const start = Date.now();
|
|
9795
|
-
const result = await exec("curl", ["-s", "-o", "/dev/null", "-w", "%{http_code}", "https://api.anthropic.com/health"], {
|
|
9796
|
-
throwOnError: false,
|
|
9797
|
-
timeout: 1e4
|
|
9798
|
-
});
|
|
9799
|
-
const elapsed = Date.now() - start;
|
|
9800
|
-
if (result.stdout.trim() === "200" || result.stdout.trim() === "404") {
|
|
9801
|
-
return {
|
|
9802
|
-
name: "API Connectivity",
|
|
9803
|
-
status: "pass",
|
|
9804
|
-
message: `OK (${elapsed}ms)`
|
|
9805
|
-
};
|
|
9806
|
-
}
|
|
9807
|
-
return {
|
|
9808
|
-
name: "API Connectivity",
|
|
9809
|
-
status: "warn",
|
|
9810
|
-
message: `Response: ${result.stdout.trim()}`
|
|
9811
|
-
};
|
|
9812
|
-
} catch {
|
|
9813
|
-
return {
|
|
9814
|
-
name: "API Connectivity",
|
|
9815
|
-
status: "info",
|
|
9816
|
-
message: "Could not test (curl not available)"
|
|
9817
|
-
};
|
|
9818
|
-
}
|
|
9819
|
-
}
|
|
9820
|
-
function checkConfigValidity() {
|
|
9821
|
-
const configs = detectAllConfigs();
|
|
9822
|
-
const existingConfigs = configs.filter((c) => c.exists);
|
|
9823
|
-
if (existingConfigs.length === 0) {
|
|
9824
|
-
return {
|
|
9825
|
-
name: "Config Files",
|
|
9826
|
-
status: "info",
|
|
9827
|
-
message: "No config files (run ccjk init)",
|
|
9828
|
-
fixable: true,
|
|
9829
|
-
fixCommand: "ccjk init"
|
|
9830
|
-
};
|
|
9831
|
-
}
|
|
9832
|
-
if (existingConfigs.length > 1) {
|
|
9833
|
-
return {
|
|
9834
|
-
name: "Config Files",
|
|
9835
|
-
status: "warn",
|
|
9836
|
-
message: `${existingConfigs.length} found (consolidation recommended)`,
|
|
9837
|
-
fixable: true,
|
|
9838
|
-
fixCommand: "ccjk config consolidate"
|
|
9839
|
-
};
|
|
9840
|
-
}
|
|
9841
|
-
return {
|
|
9842
|
-
name: "Config Files",
|
|
9843
|
-
status: "pass",
|
|
9844
|
-
message: "1 config file"
|
|
9845
|
-
};
|
|
9846
|
-
}
|
|
9847
|
-
function checkPermissions() {
|
|
9848
|
-
try {
|
|
9849
|
-
const templateId = getCurrentTemplateId();
|
|
9850
|
-
if (templateId) {
|
|
9851
|
-
return {
|
|
9852
|
-
name: "Permissions",
|
|
9853
|
-
status: "pass",
|
|
9854
|
-
message: `${templateId} template active`
|
|
9855
|
-
};
|
|
9856
|
-
}
|
|
9857
|
-
return {
|
|
9858
|
-
name: "Permissions",
|
|
9859
|
-
status: "info",
|
|
9860
|
-
message: "Custom permissions"
|
|
9861
|
-
};
|
|
9862
|
-
} catch {
|
|
9863
|
-
return {
|
|
9864
|
-
name: "Permissions",
|
|
9865
|
-
status: "info",
|
|
9866
|
-
message: "Not configured"
|
|
9867
|
-
};
|
|
9868
|
-
}
|
|
9869
|
-
}
|
|
9870
|
-
async function checkDiskSpace() {
|
|
9871
|
-
try {
|
|
9872
|
-
if (process.platform === "win32") {
|
|
9873
|
-
return {
|
|
9874
|
-
name: "Disk Space",
|
|
9875
|
-
status: "info",
|
|
9876
|
-
message: "Check skipped (Windows)"
|
|
9877
|
-
};
|
|
9878
|
-
}
|
|
9879
|
-
const result = await exec("df", ["-h", homedir()], { throwOnError: false });
|
|
9880
|
-
const lines = result.stdout.trim().split("\n");
|
|
9881
|
-
if (lines.length >= 2) {
|
|
9882
|
-
const parts = lines[1].split(/\s+/);
|
|
9883
|
-
const available = parts[3];
|
|
9884
|
-
const usePercent = Number.parseInt(parts[4]);
|
|
9885
|
-
if (usePercent > 90) {
|
|
9886
|
-
return {
|
|
9887
|
-
name: "Disk Space",
|
|
9888
|
-
status: "warn",
|
|
9889
|
-
message: `${available} available (${usePercent}% used)`
|
|
9890
|
-
};
|
|
9891
|
-
}
|
|
9892
|
-
return {
|
|
9893
|
-
name: "Disk Space",
|
|
9894
|
-
status: "pass",
|
|
9895
|
-
message: `${available} available`
|
|
9896
|
-
};
|
|
9897
|
-
}
|
|
9898
|
-
return {
|
|
9899
|
-
name: "Disk Space",
|
|
9900
|
-
status: "info",
|
|
9901
|
-
message: "Could not determine"
|
|
9902
|
-
};
|
|
9903
|
-
} catch {
|
|
9904
|
-
return {
|
|
9905
|
-
name: "Disk Space",
|
|
9906
|
-
status: "info",
|
|
9907
|
-
message: "Check skipped"
|
|
9908
|
-
};
|
|
9909
|
-
}
|
|
9910
|
-
}
|
|
9911
|
-
function calculateScore(checks) {
|
|
9912
|
-
let score = 100;
|
|
9913
|
-
const weights = {
|
|
9914
|
-
"Claude Code": 25,
|
|
9915
|
-
"CCJK": 15,
|
|
9916
|
-
"Node.js": 20,
|
|
9917
|
-
"npm": 10,
|
|
9918
|
-
"Git": 5,
|
|
9919
|
-
"API Connectivity": 10,
|
|
9920
|
-
"Config Files": 10,
|
|
9921
|
-
"Permissions": 5
|
|
9922
|
-
};
|
|
9923
|
-
for (const check of checks) {
|
|
9924
|
-
const checkWeight = weights[check.name] || 5;
|
|
9925
|
-
if (check.status === "fail") {
|
|
9926
|
-
score -= checkWeight;
|
|
9927
|
-
} else if (check.status === "warn") {
|
|
9928
|
-
score -= checkWeight * 0.5;
|
|
9929
|
-
}
|
|
9930
|
-
}
|
|
9931
|
-
return Math.max(0, Math.min(100, Math.round(score)));
|
|
9932
|
-
}
|
|
9933
|
-
function generateRecommendations(checks) {
|
|
9934
|
-
const recommendations = [];
|
|
9935
|
-
for (const check of checks) {
|
|
9936
|
-
if (check.fixable && check.fixCommand && (check.status === "fail" || check.status === "warn")) {
|
|
9937
|
-
recommendations.push(`Run '${check.fixCommand}' to fix ${check.name.toLowerCase()}`);
|
|
9938
|
-
}
|
|
9939
|
-
}
|
|
9940
|
-
return recommendations;
|
|
9941
|
-
}
|
|
9942
|
-
async function runHealthCheck() {
|
|
9943
|
-
const spinner = ora("Running health check...").start();
|
|
9944
|
-
const checks = [];
|
|
9945
|
-
spinner.text = "Checking Claude Code...";
|
|
9946
|
-
checks.push(await checkClaudeCodeInstallation());
|
|
9947
|
-
spinner.text = "Checking CCJK...";
|
|
9948
|
-
checks.push(await checkCcjkInstallation());
|
|
9949
|
-
spinner.text = "Checking Node.js...";
|
|
9950
|
-
checks.push(await checkNodeVersion());
|
|
9951
|
-
spinner.text = "Checking npm...";
|
|
9952
|
-
checks.push(await checkNpmVersion());
|
|
9953
|
-
spinner.text = "Checking Git...";
|
|
9954
|
-
checks.push(await checkGitInstallation());
|
|
9955
|
-
spinner.text = "Checking API connectivity...";
|
|
9956
|
-
checks.push(await checkApiConnectivity());
|
|
9957
|
-
spinner.text = "Checking config files...";
|
|
9958
|
-
checks.push(checkConfigValidity());
|
|
9959
|
-
spinner.text = "Checking permissions...";
|
|
9960
|
-
checks.push(checkPermissions());
|
|
9961
|
-
spinner.text = "Checking disk space...";
|
|
9962
|
-
checks.push(await checkDiskSpace());
|
|
9963
|
-
spinner.stop();
|
|
9964
|
-
const score = calculateScore(checks);
|
|
9965
|
-
const recommendations = generateRecommendations(checks);
|
|
9966
|
-
return {
|
|
9967
|
-
timestamp: /* @__PURE__ */ new Date(),
|
|
9968
|
-
score,
|
|
9969
|
-
checks,
|
|
9970
|
-
recommendations
|
|
9971
|
-
};
|
|
9972
|
-
}
|
|
9973
|
-
function displayHealthReport(report) {
|
|
9974
|
-
console.log(ansis.cyan("\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 CCJK Environment Health \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n"));
|
|
9975
|
-
for (const check of report.checks) {
|
|
9976
|
-
switch (check.status) {
|
|
9977
|
-
case "pass":
|
|
9978
|
-
console.log(STATUS.success(`${check.name.padEnd(20)} ${check.message}`));
|
|
9979
|
-
break;
|
|
9980
|
-
case "warn":
|
|
9981
|
-
console.log(STATUS.warning(`${check.name.padEnd(20)} ${check.message}`));
|
|
9982
|
-
break;
|
|
9983
|
-
case "fail":
|
|
9984
|
-
console.log(STATUS.error(`${check.name.padEnd(20)} ${check.message}`));
|
|
9985
|
-
break;
|
|
9986
|
-
case "info":
|
|
9987
|
-
console.log(STATUS.info(`${check.name.padEnd(20)} ${check.message}`));
|
|
9988
|
-
break;
|
|
9989
|
-
}
|
|
9990
|
-
}
|
|
9991
|
-
console.log("");
|
|
9992
|
-
console.log(`Score: ${ansis.cyan(report.score.toString())}/100`);
|
|
9993
|
-
console.log(renderProgressBar(report.score, 40));
|
|
9994
|
-
if (report.recommendations.length > 0) {
|
|
9995
|
-
console.log(ansis.yellow("\nRecommendations:"));
|
|
9996
|
-
for (const rec of report.recommendations) {
|
|
9997
|
-
console.log(ansis.yellow(` \u2022 ${rec}`));
|
|
9998
|
-
}
|
|
9999
|
-
}
|
|
10000
|
-
console.log("");
|
|
10001
|
-
}
|
|
10002
|
-
async function runDoctor(fix = false) {
|
|
10003
|
-
const report = await runHealthCheck();
|
|
10004
|
-
displayHealthReport(report);
|
|
10005
|
-
if (fix && report.recommendations.length > 0) {
|
|
10006
|
-
console.log(ansis.cyan("\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 Attempting Fixes \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n"));
|
|
10007
|
-
for (const check of report.checks) {
|
|
10008
|
-
if (check.fixable && check.fixCommand && (check.status === "fail" || check.status === "warn")) {
|
|
10009
|
-
const spinner = ora(`Fixing ${check.name}...`).start();
|
|
10010
|
-
try {
|
|
10011
|
-
const parts = check.fixCommand.split(" ");
|
|
10012
|
-
await exec(parts[0], parts.slice(1), { throwOnError: true });
|
|
10013
|
-
spinner.succeed(`Fixed ${check.name}`);
|
|
10014
|
-
} catch (_error) {
|
|
10015
|
-
spinner.fail(`Failed to fix ${check.name}`);
|
|
10016
|
-
}
|
|
10017
|
-
}
|
|
10018
|
-
}
|
|
10019
|
-
console.log("");
|
|
10020
|
-
}
|
|
10021
|
-
}
|
|
10022
|
-
|
|
10023
9955
|
const KNOWLEDGE_BASE_FILE = join(CCJK_CONFIG_DIR, "knowledge-base.json");
|
|
10024
9956
|
function simpleHash(content) {
|
|
10025
9957
|
let hash = 0;
|
|
@@ -10459,4 +10391,4 @@ async function openSettingsJson() {
|
|
|
10459
10391
|
}
|
|
10460
10392
|
}
|
|
10461
10393
|
|
|
10462
|
-
export {
|
|
10394
|
+
export { isCodeToolType as $, AIDER_DIR as A, CLAUDE_MD_FILE as B, CCJK_PLUGINS_DIR as C, ClAUDE_CONFIG_FILE as D, CLAUDE_VSC_CONFIG_FILE as E, CODEX_DIR as F, CODEX_CONFIG_FILE as G, CODEX_AUTH_FILE as H, CODEX_AGENTS_FILE as I, CODEX_PROMPTS_DIR as J, CLINE_DIR as K, CLINE_CONFIG_FILE as L, CURSOR_DIR as M, CURSOR_CONFIG_FILE as N, CCJK_CONFIG_DIR as O, CCJK_CONFIG_FILE as P, LEGACY_ZCF_CONFIG_DIR as Q, LEGACY_ZCF_CONFIG_FILE as R, STATUS as S, LEGACY_ZCF_CONFIG_FILES as T, ZCF_CONFIG_FILE as U, CODE_TOOL_TYPES as V, DEFAULT_CODE_TOOL_TYPE as W, CODE_TOOL_BANNERS as X, CODE_TOOL_ALIASES as Y, ZCF_CONFIG_DIR as Z, CODE_TOOL_INFO as _, CCJK_SKILLS_DIR as a, switchToProvider as a$, API_DEFAULT_URL as a0, API_ENV_KEY as a1, resolveCodeToolType as a2, SUPPORTED_LANGS as a3, LANG_LABELS as a4, AI_OUTPUT_LANGUAGES as a5, getAiOutputLanguageLabel as a6, detectPackageManager as a7, detectFrameworks as a8, detectBuildTools as a9, backupCodexFiles as aA, backupCodexPrompts as aB, checkCodexUpdate as aC, switchToOfficialLogin as aD, configureCodexApi as aE, createBackupDirectory as aF, ensureEnvKeyMigration as aG, getBackupMessage as aH, getCodexVersion as aI, getCurrentCodexProvider as aJ, installCodexCli as aK, isCodexInstalled$1 as aL, listCodexProviders as aM, migrateEnvKeyInContent as aN, migrateEnvKeyToTempEnvKey as aO, needsEnvKeyMigration as aP, parseCodexConfig as aQ, readCodexConfig as aR, renderCodexConfig as aS, runCodexFullInit as aT, runCodexSystemPromptSelection as aU, runCodexUninstall as aV, runCodexUpdate as aW, runCodexWorkflowImport as aX, runCodexWorkflowImportWithLanguageSelection as aY, runCodexWorkflowSelection as aZ, switchCodexProvider as a_, detectTestFrameworks as aa, detectCICDSystems as ab, detectLanguages as ac, determineProjectType as ad, detectProject as ae, generateSuggestions as af, getProjectSummary as ag, displayBanner as ah, displayBannerWithInfo as ai, boxify as aj, menuItem as ak, getMcpConfigPath as al, readMcpConfig as am, writeMcpConfig as an, backupMcpConfig as ao, mergeMcpServers as ap, buildMcpServerConfig as aq, fixWindowsMcpConfig as ar, addCompletedOnboarding as as, ensureApiKeyApproved as at, removeApiKeyFromRejected as au, manageApiKeyApproval as av, setPrimaryApiKey as aw, backupCodexAgents as ax, backupCodexComplete as ay, backupCodexConfig as az, CCJK_GROUPS_DIR as b, applyTemplate as b$, writeAuthFile as b0, writeCodexConfig as b1, detectConfigManagementMode as b2, shouldShowManagementMode as b3, getAvailableManagementActions as b4, configureCodexMcp as b5, applyCodexPlatformCommand as b6, getToolConfigPath as b7, getToolDir as b8, isToolInstalled as b9, removeRedundantConfigs as bA, displayConfigScan as bB, isClaudeCodeInstalled as bC, installClaudeCode as bD, isCodexInstalled as bE, installCodex as bF, isLocalClaudeCodeInstalled as bG, getInstallationStatus as bH, removeLocalClaudeCode as bI, uninstallCodeTool as bJ, setInstallMethod as bK, detectInstalledVersion as bL, selectInstallMethod as bM, executeInstallMethod as bN, handleInstallFailure as bO, verifyInstallation as bP, createHomebrewSymlink as bQ, displayVerificationResult as bR, loadKnowledgeBase as bS, saveKnowledgeBase as bT, runOnboarding as bU, quickSync as bV, getProjectKnowledge as bW, exportProjectKnowledge as bX, PERMISSION_TEMPLATES as bY, readPermissions as bZ, writePermissions as b_, getToolVersion as ba, getToolStatus as bb, getAllToolsStatus as bc, getInstalledTools as bd, installTool as be, getToolInfo as bf, getAllToolsInfo as bg, getToolsByCategory as bh, formatToolStatus as bi, getRecommendedTools as bj, ensureClaudeDir as bk, backupExistingConfig as bl, copyConfigFiles as bm, configureApi as bn, mergeConfigs as bo, updateCustomModel as bp, updateDefaultModel as bq, mergeSettingsFile as br, getExistingModelConfig as bs, getExistingApiConfig as bt, applyAiLanguageDirective as bu, switchToOfficialLogin$1 as bv, promptApiConfigurationAction as bw, compareConfigs as bx, consolidateConfigs as by, writeConsolidatedConfig as bz, AIDER_CONFIG_FILE as c, configureOutputStyle as c$, trustDirectory as c0, untrustDirectory as c1, isPermissionAllowed as c2, isDirectoryTrusted as c3, addAutoApprovePattern as c4, removeAutoApprovePattern as c5, resetPermissions as c6, exportPermissions as c7, importPermissions as c8, displayPermissions as c9, readZcfConfig as cA, readJsonConfig as cB, writeJsonConfig as cC, moveToTrash as cD, updateZcfConfig as cE, resolveAiOutputLanguage as cF, updatePromptOnly as cG, selectAndInstallWorkflows as cH, checkClaudeCodeVersionAndPrompt as cI, checkSuperpowersInstalled as cJ, getSuperpowersSkills as cK, updateSuperpowers as cL, uninstallSuperpowers as cM, installSuperpowers as cN, installSuperpowersViaGit as cO, readZcfConfigAsync as cP, initI18n as cQ, selectScriptLanguage as cR, changeLanguage as cS, validateApiKey$1 as cT, ensureDir as cU, readDefaultTomlConfig as cV, createDefaultTomlConfig as cW, exists as cX, writeTomlConfig as cY, clearModelEnv as cZ, copyFile as c_, checkPluginVersions as ca, upgradeClaudeCode as cb, upgradeCcjk as cc, upgradePlugin as cd, upgradeAllPlugins as ce, checkAllVersions as cf, upgradeAll as cg, i18n as ch, testApiConnection as ci, quickSetup as cj, format as ck, getAllPresets as cl, ensureI18nInitialized as cm, readCcrConfig as cn, isCcrInstalled as co, installCcr as cp, configureCcrFeature as cq, promptBoolean as cr, handleExitPromptError as cs, handleGeneralError as ct, COMETIX_COMMAND_NAME as cu, COMETIX_COMMANDS as cv, installCometixLine as cw, addNumbersToChoices as cx, checkAndUpdateTools as cy, resolveCodeType as cz, AIDER_ENV_FILE as d, isWindows as d0, selectMcpServices as d1, getMcpServices as d2, setupCcrConfiguration as d3, modifyApiConfigPartially as d4, formatApiKeyDisplay as d5, index as d6, fsOperations as d7, jsonConfig as d8, claudeConfig as d9, config$1 as da, config as db, prompts as dc, codex as dd, installer as de, CONTINUE_DIR as e, CONTINUE_CONFIG_FILE as f, checkClaudeCodeVersion as g, checkCcjkVersion as h, detectAllConfigs as i, getCurrentTemplateId as j, COLORS as k, init as l, displayCurrentStatus as m, runConfigWizard as n, cleanupPermissions as o, mergeAndCleanPermissions as p, commandExists as q, renderProgressBar as r, sectionDivider as s, getPlatform as t, importRecommendedEnv as u, version as v, importRecommendedPermissions as w, openSettingsJson as x, CLAUDE_DIR$1 as y, SETTINGS_FILE$1 as z };
|