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.
Files changed (2) hide show
  1. package/dist/index.js +136 -6
  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
@@ -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 Command6();
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) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cc-hub-cli",
3
- "version": "1.1.9",
3
+ "version": "1.1.11",
4
4
  "description": "Manage Claude CLI profiles, hooks, and sessions",
5
5
  "type": "module",
6
6
  "bin": {