cc-hub-cli 1.1.10 → 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.
Files changed (2) hide show
  1. package/dist/index.js +131 -3
  2. 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 Command6 } from "commander";
4
+ import { Command as Command7 } from "commander";
5
5
  import { createRequire } from "module";
6
6
 
7
7
  // src/profiles/commands.ts
@@ -2168,6 +2168,7 @@ _cc-hub() {
2168
2168
  'hook:Manage Claude Code hooks in settings.json'
2169
2169
  'session:Manage Claude Code sessions'
2170
2170
  'provider:Manage provider types'
2171
+ 'cache:Manage Claude Code cache and backup files'
2171
2172
  'completion:Print shell completion functions'
2172
2173
  'help:Display help for a command'
2173
2174
  )
@@ -2177,6 +2178,11 @@ _cc-hub() {
2177
2178
  'list:List available provider types'
2178
2179
  )
2179
2180
 
2181
+ local -a cache_subcmds
2182
+ cache_subcmds=(
2183
+ 'restore:Restore ~/.claude/.claude.json.backup to ~/.claude.json'
2184
+ )
2185
+
2180
2186
 
2181
2187
  local -a profile_subcmds
2182
2188
  profile_subcmds=(
@@ -2284,6 +2290,11 @@ _cc-hub() {
2284
2290
  _describe -t hooks-subcmds 'hook subcommand' hooks_subcmds
2285
2291
  fi
2286
2292
  ;;
2293
+ cache)
2294
+ if (( CURRENT == 2 )); then
2295
+ _describe -t cache-subcmds 'cache subcommand' cache_subcmds
2296
+ fi
2297
+ ;;
2287
2298
  session)
2288
2299
  if (( CURRENT == 2 )); then
2289
2300
  _describe -t session-subcmds 'session subcommand' session_subcmds
@@ -2344,13 +2355,14 @@ _cc-hub() {
2344
2355
  COMPREPLY=()
2345
2356
  cur="\${COMP_WORDS[COMP_CWORD]}"
2346
2357
  prev="\${COMP_WORDS[COMP_CWORD-1]}"
2347
- commands="profile use run hook session provider completion help"
2358
+ commands="profile use run hook session provider cache completion help"
2348
2359
 
2349
2360
  local profile_subcmds="add update list view remove rename default sync"
2350
2361
  local provider_subcmds="list"
2351
2362
  local provider_types="anthropic openai"
2352
2363
  local hooks_subcmds="list add remove enable disable"
2353
2364
  local session_subcmds="list show search ps stats clean troubleshoot"
2365
+ local cache_subcmds="restore"
2354
2366
 
2355
2367
  # Top-level command
2356
2368
  if [[ \${COMP_CWORD} -eq 1 ]]; then
@@ -2404,6 +2416,11 @@ _cc-hub() {
2404
2416
  COMPREPLY=($(compgen -W "$hooks_subcmds" -- "$cur"))
2405
2417
  fi
2406
2418
  ;;
2419
+ cache)
2420
+ if [[ \${COMP_CWORD} -eq 2 ]]; then
2421
+ COMPREPLY=($(compgen -W "$cache_subcmds" -- "$cur"))
2422
+ fi
2423
+ ;;
2407
2424
  session)
2408
2425
  if [[ \${COMP_CWORD} -eq 2 ]]; then
2409
2426
  COMPREPLY=($(compgen -W "$session_subcmds" -- "$cur"))
@@ -2435,6 +2452,7 @@ var POWERSHELL_COMPLETION = `Register-ArgumentCompleter -Native -CommandName cc-
2435
2452
  'hook:Manage Claude Code hooks in settings.json'
2436
2453
  'session:Manage Claude Code sessions'
2437
2454
  'provider:Manage provider types'
2455
+ 'cache:Manage Claude Code cache and backup files'
2438
2456
  'completion:Print shell completion functions'
2439
2457
  'help:Display help for a command'
2440
2458
  )
@@ -2442,6 +2460,7 @@ var POWERSHELL_COMPLETION = `Register-ArgumentCompleter -Native -CommandName cc-
2442
2460
  $profileSubcmds = @('add', 'update', 'list', 'view', 'remove', 'rename', 'default', 'sync')
2443
2461
  $hookSubcmds = @('list', 'add', 'remove', 'enable', 'disable')
2444
2462
  $sessionSubcmds = @('list', 'show', 'search', 'ps', 'stats', 'clean', 'troubleshoot')
2463
+ $cacheSubcmds = @('restore')
2445
2464
  $providerSubcmds = @('list')
2446
2465
 
2447
2466
  $tokens = $commandAst.CommandElements | ForEach-Object { $_.ToString() }
@@ -2482,6 +2501,12 @@ var POWERSHELL_COMPLETION = `Register-ArgumentCompleter -Native -CommandName cc-
2482
2501
  return
2483
2502
  }
2484
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
+ }
2485
2510
  'use' {
2486
2511
  $opts = @('--built-in')
2487
2512
  $opts | ForEach-Object { if ($_ -like "$wordToComplete*") { $_ } }
@@ -2515,6 +2540,108 @@ function completionCommand() {
2515
2540
  }));
2516
2541
  }
2517
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
+
2518
2645
  // src/index.ts
2519
2646
  var _require = createRequire(import.meta.url);
2520
2647
  var { version } = _require("../package.json");
@@ -2522,7 +2649,7 @@ ensureSettingsFile();
2522
2649
  var settings = readJson(SETTINGS_FILE);
2523
2650
  setLogLevel(settings._cc_hub_logLevel || "INFO");
2524
2651
  installGlobalExceptionHandlers();
2525
- var program = new Command6();
2652
+ var program = new Command7();
2526
2653
  program.name("cc-hub").description("Manage Claude CLI profiles, hooks, and sessions").version(version);
2527
2654
  program.addCommand(profileCommand());
2528
2655
  program.addCommand(useCommand());
@@ -2532,6 +2659,7 @@ program.addCommand(sessionCommand());
2532
2659
  program.addCommand(completionCommand());
2533
2660
  program.addCommand(providerCommand());
2534
2661
  program.addCommand(proxyCommand());
2662
+ program.addCommand(cacheCommand());
2535
2663
  try {
2536
2664
  program.parse();
2537
2665
  } catch (err) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cc-hub-cli",
3
- "version": "1.1.10",
3
+ "version": "1.1.11",
4
4
  "description": "Manage Claude CLI profiles, hooks, and sessions",
5
5
  "type": "module",
6
6
  "bin": {