cc-hub-cli 1.1.9 → 1.1.11
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 +136 -6
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
|
-
import { Command as
|
|
4
|
+
import { Command as Command7 } from "commander";
|
|
5
5
|
import { createRequire } from "module";
|
|
6
6
|
|
|
7
7
|
// src/profiles/commands.ts
|
|
@@ -1056,7 +1056,7 @@ function execClaude(profileName, p, extraArgs) {
|
|
|
1056
1056
|
).then(({ baseUrl, stop }) => {
|
|
1057
1057
|
env.ANTHROPIC_BASE_URL = baseUrl;
|
|
1058
1058
|
debug(`execClaude: proxy running at ${baseUrl}`);
|
|
1059
|
-
const child = spawn(cmd[0], cmd.slice(1), { stdio: "inherit", env });
|
|
1059
|
+
const child = spawn(cmd[0], cmd.slice(1), { stdio: "inherit", env, shell: process.platform === "win32" });
|
|
1060
1060
|
child.on("close", (code) => {
|
|
1061
1061
|
stop();
|
|
1062
1062
|
process.exit(code ?? 1);
|
|
@@ -1069,7 +1069,8 @@ function execClaude(profileName, p, extraArgs) {
|
|
|
1069
1069
|
} else {
|
|
1070
1070
|
const result = spawnSync2(cmd[0], cmd.slice(1), {
|
|
1071
1071
|
stdio: "inherit",
|
|
1072
|
-
env
|
|
1072
|
+
env,
|
|
1073
|
+
shell: process.platform === "win32"
|
|
1073
1074
|
});
|
|
1074
1075
|
process.exit(result.status ?? 1);
|
|
1075
1076
|
}
|
|
@@ -1085,7 +1086,8 @@ function execClaudeBuiltIn(extraArgs) {
|
|
|
1085
1086
|
info(`Launching Claude with built-in official models: binary=${binary}`);
|
|
1086
1087
|
const result = spawnSync2(cmd[0], cmd.slice(1), {
|
|
1087
1088
|
stdio: "inherit",
|
|
1088
|
-
env
|
|
1089
|
+
env,
|
|
1090
|
+
shell: process.platform === "win32"
|
|
1089
1091
|
});
|
|
1090
1092
|
process.exit(result.status ?? 1);
|
|
1091
1093
|
}
|
|
@@ -2166,6 +2168,7 @@ _cc-hub() {
|
|
|
2166
2168
|
'hook:Manage Claude Code hooks in settings.json'
|
|
2167
2169
|
'session:Manage Claude Code sessions'
|
|
2168
2170
|
'provider:Manage provider types'
|
|
2171
|
+
'cache:Manage Claude Code cache and backup files'
|
|
2169
2172
|
'completion:Print shell completion functions'
|
|
2170
2173
|
'help:Display help for a command'
|
|
2171
2174
|
)
|
|
@@ -2175,6 +2178,11 @@ _cc-hub() {
|
|
|
2175
2178
|
'list:List available provider types'
|
|
2176
2179
|
)
|
|
2177
2180
|
|
|
2181
|
+
local -a cache_subcmds
|
|
2182
|
+
cache_subcmds=(
|
|
2183
|
+
'restore:Restore ~/.claude/.claude.json.backup to ~/.claude.json'
|
|
2184
|
+
)
|
|
2185
|
+
|
|
2178
2186
|
|
|
2179
2187
|
local -a profile_subcmds
|
|
2180
2188
|
profile_subcmds=(
|
|
@@ -2282,6 +2290,11 @@ _cc-hub() {
|
|
|
2282
2290
|
_describe -t hooks-subcmds 'hook subcommand' hooks_subcmds
|
|
2283
2291
|
fi
|
|
2284
2292
|
;;
|
|
2293
|
+
cache)
|
|
2294
|
+
if (( CURRENT == 2 )); then
|
|
2295
|
+
_describe -t cache-subcmds 'cache subcommand' cache_subcmds
|
|
2296
|
+
fi
|
|
2297
|
+
;;
|
|
2285
2298
|
session)
|
|
2286
2299
|
if (( CURRENT == 2 )); then
|
|
2287
2300
|
_describe -t session-subcmds 'session subcommand' session_subcmds
|
|
@@ -2342,13 +2355,14 @@ _cc-hub() {
|
|
|
2342
2355
|
COMPREPLY=()
|
|
2343
2356
|
cur="\${COMP_WORDS[COMP_CWORD]}"
|
|
2344
2357
|
prev="\${COMP_WORDS[COMP_CWORD-1]}"
|
|
2345
|
-
commands="profile use run hook session provider completion help"
|
|
2358
|
+
commands="profile use run hook session provider cache completion help"
|
|
2346
2359
|
|
|
2347
2360
|
local profile_subcmds="add update list view remove rename default sync"
|
|
2348
2361
|
local provider_subcmds="list"
|
|
2349
2362
|
local provider_types="anthropic openai"
|
|
2350
2363
|
local hooks_subcmds="list add remove enable disable"
|
|
2351
2364
|
local session_subcmds="list show search ps stats clean troubleshoot"
|
|
2365
|
+
local cache_subcmds="restore"
|
|
2352
2366
|
|
|
2353
2367
|
# Top-level command
|
|
2354
2368
|
if [[ \${COMP_CWORD} -eq 1 ]]; then
|
|
@@ -2402,6 +2416,11 @@ _cc-hub() {
|
|
|
2402
2416
|
COMPREPLY=($(compgen -W "$hooks_subcmds" -- "$cur"))
|
|
2403
2417
|
fi
|
|
2404
2418
|
;;
|
|
2419
|
+
cache)
|
|
2420
|
+
if [[ \${COMP_CWORD} -eq 2 ]]; then
|
|
2421
|
+
COMPREPLY=($(compgen -W "$cache_subcmds" -- "$cur"))
|
|
2422
|
+
fi
|
|
2423
|
+
;;
|
|
2405
2424
|
session)
|
|
2406
2425
|
if [[ \${COMP_CWORD} -eq 2 ]]; then
|
|
2407
2426
|
COMPREPLY=($(compgen -W "$session_subcmds" -- "$cur"))
|
|
@@ -2433,6 +2452,7 @@ var POWERSHELL_COMPLETION = `Register-ArgumentCompleter -Native -CommandName cc-
|
|
|
2433
2452
|
'hook:Manage Claude Code hooks in settings.json'
|
|
2434
2453
|
'session:Manage Claude Code sessions'
|
|
2435
2454
|
'provider:Manage provider types'
|
|
2455
|
+
'cache:Manage Claude Code cache and backup files'
|
|
2436
2456
|
'completion:Print shell completion functions'
|
|
2437
2457
|
'help:Display help for a command'
|
|
2438
2458
|
)
|
|
@@ -2440,6 +2460,7 @@ var POWERSHELL_COMPLETION = `Register-ArgumentCompleter -Native -CommandName cc-
|
|
|
2440
2460
|
$profileSubcmds = @('add', 'update', 'list', 'view', 'remove', 'rename', 'default', 'sync')
|
|
2441
2461
|
$hookSubcmds = @('list', 'add', 'remove', 'enable', 'disable')
|
|
2442
2462
|
$sessionSubcmds = @('list', 'show', 'search', 'ps', 'stats', 'clean', 'troubleshoot')
|
|
2463
|
+
$cacheSubcmds = @('restore')
|
|
2443
2464
|
$providerSubcmds = @('list')
|
|
2444
2465
|
|
|
2445
2466
|
$tokens = $commandAst.CommandElements | ForEach-Object { $_.ToString() }
|
|
@@ -2480,6 +2501,12 @@ var POWERSHELL_COMPLETION = `Register-ArgumentCompleter -Native -CommandName cc-
|
|
|
2480
2501
|
return
|
|
2481
2502
|
}
|
|
2482
2503
|
}
|
|
2504
|
+
'cache' {
|
|
2505
|
+
if ($tokens.Count -eq 2 -or ($tokens.Count -eq 3 -and $wordToComplete -ne '')) {
|
|
2506
|
+
$cacheSubcmds | ForEach-Object { if ($_ -like "$wordToComplete*") { $_ } }
|
|
2507
|
+
return
|
|
2508
|
+
}
|
|
2509
|
+
}
|
|
2483
2510
|
'use' {
|
|
2484
2511
|
$opts = @('--built-in')
|
|
2485
2512
|
$opts | ForEach-Object { if ($_ -like "$wordToComplete*") { $_ } }
|
|
@@ -2513,6 +2540,108 @@ function completionCommand() {
|
|
|
2513
2540
|
}));
|
|
2514
2541
|
}
|
|
2515
2542
|
|
|
2543
|
+
// src/cache/commands.ts
|
|
2544
|
+
import { Command as Command6 } from "commander";
|
|
2545
|
+
import fs8 from "fs";
|
|
2546
|
+
import path8 from "path";
|
|
2547
|
+
import { spawnSync as spawnSync4 } from "child_process";
|
|
2548
|
+
import { createInterface } from "readline/promises";
|
|
2549
|
+
async function confirmPrompt(message) {
|
|
2550
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
2551
|
+
const answer = await rl.question(message);
|
|
2552
|
+
rl.close();
|
|
2553
|
+
return answer.trim().toLowerCase() === "y" || answer.trim().toLowerCase() === "yes";
|
|
2554
|
+
}
|
|
2555
|
+
function findClaudeProcesses() {
|
|
2556
|
+
const pids = [];
|
|
2557
|
+
const platform = process.platform;
|
|
2558
|
+
if (platform === "win32") {
|
|
2559
|
+
debug("cache restore: scanning Windows processes via tasklist");
|
|
2560
|
+
const result = spawnSync4("tasklist", ["/FO", "CSV", "/NH"], {
|
|
2561
|
+
encoding: "utf-8",
|
|
2562
|
+
shell: true
|
|
2563
|
+
});
|
|
2564
|
+
if (result.status === 0 && result.stdout) {
|
|
2565
|
+
const lines = result.stdout.trim().split("\n");
|
|
2566
|
+
for (const line of lines) {
|
|
2567
|
+
const parts = line.split('","');
|
|
2568
|
+
if (parts.length >= 2) {
|
|
2569
|
+
const imageName = parts[0].replace(/^"/, "").trim();
|
|
2570
|
+
const pidStr = parts[1].replace(/"$/, "").trim();
|
|
2571
|
+
const lowerName = imageName.toLowerCase();
|
|
2572
|
+
if (lowerName === "claude.exe" || lowerName === "claude") {
|
|
2573
|
+
const pid = parseInt(pidStr, 10);
|
|
2574
|
+
if (!isNaN(pid) && pid !== process.pid) {
|
|
2575
|
+
pids.push(pid);
|
|
2576
|
+
}
|
|
2577
|
+
}
|
|
2578
|
+
}
|
|
2579
|
+
}
|
|
2580
|
+
}
|
|
2581
|
+
} else {
|
|
2582
|
+
debug("cache restore: scanning Unix processes via ps");
|
|
2583
|
+
const result = spawnSync4("ps", ["-eo", "pid,comm"], {
|
|
2584
|
+
encoding: "utf-8"
|
|
2585
|
+
});
|
|
2586
|
+
if (result.status === 0 && result.stdout) {
|
|
2587
|
+
const lines = result.stdout.trim().split("\n");
|
|
2588
|
+
for (let i = 1; i < lines.length; i++) {
|
|
2589
|
+
const line = lines[i].trim();
|
|
2590
|
+
const match = line.match(/^(\d+)\s+(.+)$/);
|
|
2591
|
+
if (match) {
|
|
2592
|
+
const pid = parseInt(match[1], 10);
|
|
2593
|
+
const comm = match[2].trim();
|
|
2594
|
+
if ((comm === "claude" || comm === "Claude") && pid !== process.pid) {
|
|
2595
|
+
pids.push(pid);
|
|
2596
|
+
}
|
|
2597
|
+
}
|
|
2598
|
+
}
|
|
2599
|
+
}
|
|
2600
|
+
}
|
|
2601
|
+
debug(`cache restore: found ${pids.length} Claude process(es)`);
|
|
2602
|
+
return pids;
|
|
2603
|
+
}
|
|
2604
|
+
function killProcesses(pids) {
|
|
2605
|
+
if (pids.length === 0) return;
|
|
2606
|
+
if (process.platform === "win32") {
|
|
2607
|
+
for (const pid of pids) {
|
|
2608
|
+
debug(`cache restore: killing PID ${pid} via taskkill`);
|
|
2609
|
+
spawnSync4("taskkill", ["/F", "/PID", String(pid)], { shell: true });
|
|
2610
|
+
}
|
|
2611
|
+
} else {
|
|
2612
|
+
for (const pid of pids) {
|
|
2613
|
+
debug(`cache restore: killing PID ${pid} via kill`);
|
|
2614
|
+
spawnSync4("kill", ["-9", String(pid)]);
|
|
2615
|
+
}
|
|
2616
|
+
}
|
|
2617
|
+
}
|
|
2618
|
+
function cacheCommand() {
|
|
2619
|
+
const cache = new Command6("cache").description("Manage Claude Code cache and backup files");
|
|
2620
|
+
cache.command("restore").description("Restore ~/.claude/.claude.json.backup to ~/.claude.json").action(safeAction(async () => {
|
|
2621
|
+
const backupPath = path8.join(CLAUDE_DIR, ".claude.json.backup");
|
|
2622
|
+
const targetPath = CLAUDE_JSON;
|
|
2623
|
+
if (!fs8.existsSync(backupPath)) {
|
|
2624
|
+
throw new Error(`Backup not found: ${backupPath}`);
|
|
2625
|
+
}
|
|
2626
|
+
const confirmed = await confirmPrompt(
|
|
2627
|
+
"This will terminate all running Claude Code processes to prevent file conflicts. Continue? (y/N) "
|
|
2628
|
+
);
|
|
2629
|
+
if (!confirmed) {
|
|
2630
|
+
console.log("Restore cancelled.");
|
|
2631
|
+
return;
|
|
2632
|
+
}
|
|
2633
|
+
const pids = findClaudeProcesses();
|
|
2634
|
+
if (pids.length > 0) {
|
|
2635
|
+
console.log(`Terminating ${pids.length} Claude process(es)...`);
|
|
2636
|
+
killProcesses(pids);
|
|
2637
|
+
}
|
|
2638
|
+
fs8.copyFileSync(backupPath, targetPath);
|
|
2639
|
+
debug(`cache restore: restored ${backupPath} -> ${targetPath}`);
|
|
2640
|
+
console.log(`Restored ${backupPath} -> ${targetPath}`);
|
|
2641
|
+
}));
|
|
2642
|
+
return cache;
|
|
2643
|
+
}
|
|
2644
|
+
|
|
2516
2645
|
// src/index.ts
|
|
2517
2646
|
var _require = createRequire(import.meta.url);
|
|
2518
2647
|
var { version } = _require("../package.json");
|
|
@@ -2520,7 +2649,7 @@ ensureSettingsFile();
|
|
|
2520
2649
|
var settings = readJson(SETTINGS_FILE);
|
|
2521
2650
|
setLogLevel(settings._cc_hub_logLevel || "INFO");
|
|
2522
2651
|
installGlobalExceptionHandlers();
|
|
2523
|
-
var program = new
|
|
2652
|
+
var program = new Command7();
|
|
2524
2653
|
program.name("cc-hub").description("Manage Claude CLI profiles, hooks, and sessions").version(version);
|
|
2525
2654
|
program.addCommand(profileCommand());
|
|
2526
2655
|
program.addCommand(useCommand());
|
|
@@ -2530,6 +2659,7 @@ program.addCommand(sessionCommand());
|
|
|
2530
2659
|
program.addCommand(completionCommand());
|
|
2531
2660
|
program.addCommand(providerCommand());
|
|
2532
2661
|
program.addCommand(proxyCommand());
|
|
2662
|
+
program.addCommand(cacheCommand());
|
|
2533
2663
|
try {
|
|
2534
2664
|
program.parse();
|
|
2535
2665
|
} catch (err) {
|