@adithya-13/cc-switch 1.0.5 → 1.0.6

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.md CHANGED
@@ -48,30 +48,6 @@ cc-switch add <name> # add a custom provider
48
48
  cc-switch doctor # check setup and saved keys
49
49
  ```
50
50
 
51
- ## Rate Limit Detection (cclaude)
52
-
53
- Instead of `claude`, use `cclaude` — it wraps Claude Code and notifies you when a rate limit is hit, with quick-switch suggestions:
54
-
55
- ```bash
56
- cclaude # same as claude, but with rate limit detection
57
- ```
58
-
59
- When a limit is hit:
60
-
61
- ```
62
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
63
- ⚠ Claude usage limit reached
64
-
65
- Available fallbacks:
66
-
67
- → z.ai (GLM) cc-switch use zai
68
- → Kimi K2 cc-switch use kimi
69
-
70
- Quick switch: cc-switch use zai
71
- Then restart: cclaude
72
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
73
- ```
74
-
75
51
  ## Key Storage
76
52
 
77
53
  API keys are saved in `~/.cc-switch/keys.json` (chmod 600). Never hardcoded or exposed.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adithya-13/cc-switch",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "description": "Switch Claude Code between providers (Claude Pro, z.ai, Kimi, OpenRouter, DeepSeek, and more)",
5
5
  "keywords": [
6
6
  "claude",
@@ -21,8 +21,7 @@
21
21
  },
22
22
  "type": "module",
23
23
  "bin": {
24
- "cc-switch": "./bin/cc-switch.js",
25
- "cclaude": "./bin/cclaude.js"
24
+ "cc-switch": "./bin/cc-switch.js"
26
25
  },
27
26
  "files": [
28
27
  "bin",
package/bin/cclaude.js DELETED
@@ -1,98 +0,0 @@
1
- #!/usr/bin/env node
2
- import { spawn } from "child_process";
3
- import chalk from "chalk";
4
- import { readSettings, getCurrentProvider } from "../src/settings.js";
5
- import { PRESETS } from "../src/presets.js";
6
- import { loadKeys, loadProfiles } from "../src/profiles.js";
7
-
8
- const RATE_LIMIT_PATTERNS = [
9
- /you['']ve hit your limit/i,
10
- /usage limit reached/i,
11
- /rate limit/i,
12
- /Claude\.ai usage limit/i,
13
- /exceeded.*limit/i,
14
- /quota exceeded/i,
15
- ];
16
-
17
- function getAvailableFallbacks(current) {
18
- const keys = loadKeys();
19
- const customProfiles = loadProfiles();
20
- const allProviders = { ...PRESETS, ...customProfiles };
21
-
22
- return Object.entries(allProviders)
23
- .filter(([name, preset]) => {
24
- if (name === current) return false;
25
- if (preset.requiresKey === false) return true; // pro (OAuth) always "available"
26
- return !!keys[name]; // only if key is saved
27
- })
28
- .map(([name, preset]) => ({ name, label: preset.name || name }));
29
- }
30
-
31
- function notifyRateLimit(current, fallbacks) {
32
- console.error("\n" + chalk.yellow("━".repeat(50)));
33
- console.error(chalk.yellow.bold(" ⚠ Claude usage limit reached"));
34
- console.error(chalk.yellow("━".repeat(50)));
35
-
36
- if (fallbacks.length === 0) {
37
- console.error(chalk.gray("\n No saved fallback providers."));
38
- console.error(chalk.gray(` Add one: ${chalk.cyan("cc-switch add <provider>")}\n`));
39
- return;
40
- }
41
-
42
- console.error(chalk.bold("\n Available fallbacks:\n"));
43
- fallbacks.forEach(({ name, label }) => {
44
- console.error(` ${chalk.cyan("→")} ${label.padEnd(20)} ${chalk.gray(`cc-switch use ${name}`)}`);
45
- });
46
-
47
- const top = fallbacks[0];
48
- console.error(
49
- `\n ${chalk.bold("Quick switch:")} ${chalk.cyan(`cc-switch use ${top.name}`)}\n` +
50
- ` Then restart: ${chalk.cyan("cclaude")}\n`
51
- );
52
- console.error(chalk.yellow("━".repeat(50)) + "\n");
53
- }
54
-
55
- // run claude, intercept output for rate limit signals
56
- const settings = readSettings();
57
- const current = getCurrentProvider(settings);
58
-
59
- // OAuth mode (pro/claude) sends rate limit to stdout, API providers to stderr
60
- const isOAuthMode = current === "pro" || current === "claude";
61
-
62
- const child = spawn("claude", process.argv.slice(2), {
63
- stdio: ["inherit", isOAuthMode ? "pipe" : "inherit", "pipe"], // always pipe stderr
64
- });
65
-
66
- let notified = false;
67
-
68
- function checkRateLimit(text) {
69
- if (notified) return;
70
- const isRateLimit = RATE_LIMIT_PATTERNS.some((p) => p.test(text));
71
- if (isRateLimit) {
72
- const fallbacks = getAvailableFallbacks(current);
73
- notifyRateLimit(current, fallbacks);
74
- notified = true; // only notify once
75
- }
76
- }
77
-
78
- // Only capture stdout for OAuth mode (pro/claude)
79
- if (isOAuthMode) {
80
- let buffer = "";
81
- child.stdout.on("data", (data) => {
82
- const text = data.toString();
83
- buffer += text;
84
- process.stdout.write(data); // forward to user
85
- checkRateLimit(buffer);
86
- });
87
- }
88
-
89
- // Always capture stderr for API providers' rate limit errors
90
- let stderrBuffer = "";
91
- child.stderr.on("data", (data) => {
92
- const text = data.toString();
93
- stderrBuffer += text;
94
- process.stderr.write(data); // forward to user
95
- checkRateLimit(stderrBuffer);
96
- });
97
-
98
- child.on("exit", (code) => process.exit(code ?? 0));