ccproxy-cli 0.1.0

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 (4) hide show
  1. package/README.md +53 -0
  2. package/bin.js +67 -0
  3. package/install.js +198 -0
  4. package/package.json +42 -0
package/README.md ADDED
@@ -0,0 +1,53 @@
1
+ # cc-proxy
2
+
3
+ A high-performance proxy for Claude API, built with Rust.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install -g cc-proxy
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```bash
14
+ # Start the proxy server
15
+ cc-proxy start
16
+
17
+ # Show help
18
+ cc-proxy --help
19
+ ```
20
+
21
+ ## What is this?
22
+
23
+ This npm package is a thin wrapper around the native `cc-proxy` binary built in Rust. On `npm install`, it automatically downloads the correct pre-built binary for your platform (macOS, Linux, Windows) and architecture (x64, arm64).
24
+
25
+ ## Supported Platforms
26
+
27
+ | Platform | Architecture | Status |
28
+ |----------|-------------|--------|
29
+ | macOS | x64 (Intel) | Supported |
30
+ | macOS | arm64 (Apple Silicon) | Supported |
31
+ | Linux | x64 | Supported |
32
+ | Windows | x64 | Supported |
33
+
34
+ ## Building from Source
35
+
36
+ If no pre-built binary is available for your platform:
37
+
38
+ ```bash
39
+ git clone https://github.com/fengshao1227/cc-proxy.git
40
+ cd cc-proxy
41
+ cargo build --release
42
+ ```
43
+
44
+ The binary will be at `target/release/cc-proxy`.
45
+
46
+ ## Links
47
+
48
+ - [GitHub Repository](https://github.com/fengshao1227/cc-proxy)
49
+ - [Report Issues](https://github.com/fengshao1227/cc-proxy/issues)
50
+
51
+ ## License
52
+
53
+ MIT
package/bin.js ADDED
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env node
2
+
3
+ "use strict";
4
+
5
+ const { spawn } = require("child_process");
6
+ const path = require("path");
7
+ const fs = require("fs");
8
+
9
+ const BIN_NAME = "cc-proxy";
10
+
11
+ function getBinaryPath() {
12
+ const ext = process.platform === "win32" ? ".exe" : "";
13
+ const localBin = path.join(__dirname, "bin", `${BIN_NAME}${ext}`);
14
+
15
+ if (fs.existsSync(localBin)) {
16
+ return localBin;
17
+ }
18
+
19
+ // Fallback: check if binary is in PATH
20
+ try {
21
+ const which = process.platform === "win32" ? "where" : "which";
22
+ const { execSync } = require("child_process");
23
+ const result = execSync(`${which} ${BIN_NAME}`, { encoding: "utf-8" }).trim();
24
+ if (result) return result.split("\n")[0];
25
+ } catch (_) {
26
+ // not in PATH
27
+ }
28
+
29
+ console.error(
30
+ `[cc-proxy] ERROR: Binary not found.\n` +
31
+ `[cc-proxy] 错误:未找到二进制文件。\n\n` +
32
+ ` Expected location / 预期路径: ${localBin}\n\n` +
33
+ ` Try reinstalling / 尝试重新安装:\n` +
34
+ ` npm install cc-proxy\n\n` +
35
+ ` Or build from source / 或从源码构建:\n` +
36
+ ` git clone https://github.com/fengshao1227/cc-proxy.git\n` +
37
+ ` cd cc-proxy && cargo build --release\n`
38
+ );
39
+ process.exit(1);
40
+ }
41
+
42
+ const binaryPath = getBinaryPath();
43
+
44
+ // Pass all arguments except node and this script
45
+ const args = process.argv.slice(2);
46
+
47
+ const child = spawn(binaryPath, args, {
48
+ stdio: "inherit",
49
+ env: process.env,
50
+ });
51
+
52
+ child.on("error", (err) => {
53
+ if (err.code === "EACCES") {
54
+ console.error(
55
+ `[cc-proxy] Permission denied. Try: chmod +x "${binaryPath}"\n` +
56
+ `[cc-proxy] 权限不足。请尝试: chmod +x "${binaryPath}"`
57
+ );
58
+ } else {
59
+ console.error(`[cc-proxy] Failed to start: ${err.message}`);
60
+ console.error(`[cc-proxy] 启动失败: ${err.message}`);
61
+ }
62
+ process.exit(1);
63
+ });
64
+
65
+ child.on("close", (code) => {
66
+ process.exit(code !== null ? code : 1);
67
+ });
package/install.js ADDED
@@ -0,0 +1,198 @@
1
+ #!/usr/bin/env node
2
+
3
+ "use strict";
4
+
5
+ const https = require("https");
6
+ const http = require("http");
7
+ const fs = require("fs");
8
+ const path = require("path");
9
+ const { execSync } = require("child_process");
10
+
11
+ const REPO = "fengshao1227/cc-proxy";
12
+ const BIN_NAME = "cc-proxy";
13
+
14
+ // Platform mapping: Node.js -> binary suffix
15
+ const PLATFORM_MAP = {
16
+ darwin: "darwin",
17
+ linux: "linux",
18
+ win32: "windows",
19
+ };
20
+
21
+ // Arch mapping: Node.js -> binary suffix
22
+ const ARCH_MAP = {
23
+ x64: "x86_64",
24
+ arm64: "arm64",
25
+ };
26
+
27
+ function getPlatformBinaryName() {
28
+ const platform = PLATFORM_MAP[process.platform];
29
+ const arch = ARCH_MAP[process.arch];
30
+
31
+ if (!platform) {
32
+ throw new Error(
33
+ `Unsupported platform: ${process.platform}\n` +
34
+ `不支持的操作系统: ${process.platform}\n` +
35
+ `Supported: darwin (macOS), linux, win32 (Windows)`
36
+ );
37
+ }
38
+
39
+ if (!arch) {
40
+ throw new Error(
41
+ `Unsupported architecture: ${process.arch}\n` +
42
+ `不支持的架构: ${process.arch}\n` +
43
+ `Supported: x64, arm64`
44
+ );
45
+ }
46
+
47
+ // Windows uses x86_64 only for now
48
+ if (process.platform === "win32" && process.arch !== "x64") {
49
+ throw new Error(
50
+ `Windows only supports x64 architecture.\n` +
51
+ `Windows 目前仅支持 x64 架构。`
52
+ );
53
+ }
54
+
55
+ // Linux arm64 not built yet in CI
56
+ if (process.platform === "linux" && process.arch === "arm64") {
57
+ throw new Error(
58
+ `Linux arm64 binaries are not yet available. Please build from source.\n` +
59
+ `Linux arm64 二进制文件暂未提供,请从源码构建。`
60
+ );
61
+ }
62
+
63
+ const ext = process.platform === "win32" ? ".exe" : "";
64
+ return `${BIN_NAME}-${platform}-${arch}${ext}`;
65
+ }
66
+
67
+ function getInstallDir() {
68
+ return path.join(__dirname, "bin");
69
+ }
70
+
71
+ function getLocalBinaryPath() {
72
+ const ext = process.platform === "win32" ? ".exe" : "";
73
+ return path.join(getInstallDir(), `${BIN_NAME}${ext}`);
74
+ }
75
+
76
+ /**
77
+ * Follow redirects and download a URL to a file.
78
+ */
79
+ function download(url, destPath, redirectCount) {
80
+ if (redirectCount === undefined) redirectCount = 0;
81
+ if (redirectCount > 10) {
82
+ throw new Error("Too many redirects / 重定向次数过多");
83
+ }
84
+
85
+ return new Promise((resolve, reject) => {
86
+ const client = url.startsWith("https") ? https : http;
87
+ const req = client.get(url, { headers: { "User-Agent": "cc-proxy-npm-install" } }, (res) => {
88
+ // Handle redirects (301, 302, 307, 308)
89
+ if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
90
+ let redirectUrl = res.headers.location;
91
+ if (redirectUrl.startsWith("/")) {
92
+ const parsed = new URL(url);
93
+ redirectUrl = `${parsed.protocol}//${parsed.host}${redirectUrl}`;
94
+ }
95
+ res.resume();
96
+ return resolve(download(redirectUrl, destPath, redirectCount + 1));
97
+ }
98
+
99
+ if (res.statusCode !== 200) {
100
+ res.resume();
101
+ return reject(
102
+ new Error(
103
+ `Failed to download binary (HTTP ${res.statusCode}).\n` +
104
+ `下载二进制文件失败 (HTTP ${res.statusCode}).\n` +
105
+ `URL: ${url}`
106
+ )
107
+ );
108
+ }
109
+
110
+ const fileStream = fs.createWriteStream(destPath);
111
+ res.pipe(fileStream);
112
+ fileStream.on("finish", () => {
113
+ fileStream.close(resolve);
114
+ });
115
+ fileStream.on("error", (err) => {
116
+ fs.unlink(destPath, () => {});
117
+ reject(err);
118
+ });
119
+ });
120
+
121
+ req.on("error", (err) => {
122
+ reject(
123
+ new Error(
124
+ `Network error downloading binary: ${err.message}\n` +
125
+ `下载二进制文件时网络错误: ${err.message}\n` +
126
+ `Please check your internet connection.`
127
+ )
128
+ );
129
+ });
130
+
131
+ req.setTimeout(120000, () => {
132
+ req.destroy();
133
+ reject(
134
+ new Error(
135
+ `Download timed out (120s).\n` + `下载超时 (120秒)。`
136
+ )
137
+ );
138
+ });
139
+ });
140
+ }
141
+
142
+ async function main() {
143
+ const binaryName = getPlatformBinaryName();
144
+ const version = require("./package.json").version;
145
+ const downloadUrl = `https://github.com/${REPO}/releases/download/v${version}/${binaryName}`;
146
+ const latestUrl = `https://github.com/${REPO}/releases/latest/download/${binaryName}`;
147
+
148
+ const installDir = getInstallDir();
149
+ const binaryPath = getLocalBinaryPath();
150
+
151
+ // Ensure install directory exists
152
+ fs.mkdirSync(installDir, { recursive: true });
153
+
154
+ console.log(`[cc-proxy] Downloading binary for ${process.platform}-${process.arch}...`);
155
+ console.log(`[cc-proxy] 正在下载 ${process.platform}-${process.arch} 平台的二进制文件...`);
156
+
157
+ // Try version-specific URL first, then fall back to latest
158
+ try {
159
+ await download(downloadUrl, binaryPath);
160
+ } catch (versionErr) {
161
+ console.log(`[cc-proxy] Version v${version} not found, trying latest release...`);
162
+ console.log(`[cc-proxy] 未找到 v${version} 版本,尝试最新版本...`);
163
+ try {
164
+ await download(latestUrl, binaryPath);
165
+ } catch (latestErr) {
166
+ console.error(
167
+ `\n[cc-proxy] ERROR: Failed to download binary.\n` +
168
+ `[cc-proxy] 错误:下载二进制文件失败。\n\n` +
169
+ ` Attempted URLs:\n` +
170
+ ` 1. ${downloadUrl}\n` +
171
+ ` 2. ${latestUrl}\n\n` +
172
+ ` Possible causes / 可能的原因:\n` +
173
+ ` - No release found for your platform / 没有适配您平台的发布版本\n` +
174
+ ` - Network issues / 网络问题\n` +
175
+ ` - GitHub API rate limit / GitHub API 限流\n\n` +
176
+ ` You can build from source / 您可以从源码构建:\n` +
177
+ ` git clone https://github.com/${REPO}.git\n` +
178
+ ` cd cc-proxy && cargo build --release\n`
179
+ );
180
+ process.exit(1);
181
+ }
182
+ }
183
+
184
+ // Make binary executable on Unix
185
+ if (process.platform !== "win32") {
186
+ fs.chmodSync(binaryPath, 0o755);
187
+ }
188
+
189
+ console.log(`[cc-proxy] Binary installed successfully!`);
190
+ console.log(`[cc-proxy] 二进制文件安装成功!`);
191
+ console.log(`[cc-proxy] Location / 路径: ${binaryPath}`);
192
+ }
193
+
194
+ main().catch((err) => {
195
+ console.error(`[cc-proxy] Installation failed: ${err.message}`);
196
+ console.error(`[cc-proxy] 安装失败: ${err.message}`);
197
+ process.exit(1);
198
+ });
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "ccproxy-cli",
3
+ "version": "0.1.0",
4
+ "description": "Claude Code Proxy - A high-performance proxy for Claude API, built with Rust",
5
+ "bin": {
6
+ "cc-proxy": "bin.js"
7
+ },
8
+ "scripts": {
9
+ "postinstall": "node install.js"
10
+ },
11
+ "files": [
12
+ "bin.js",
13
+ "install.js",
14
+ "README.md"
15
+ ],
16
+ "keywords": [
17
+ "claude",
18
+ "proxy",
19
+ "api",
20
+ "anthropic",
21
+ "claude-code"
22
+ ],
23
+ "author": "fengshao1227",
24
+ "license": "MIT",
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "https://github.com/fengshao1227/cc-proxy"
28
+ },
29
+ "homepage": "https://github.com/fengshao1227/cc-proxy#readme",
30
+ "engines": {
31
+ "node": ">=14"
32
+ },
33
+ "os": [
34
+ "darwin",
35
+ "linux",
36
+ "win32"
37
+ ],
38
+ "cpu": [
39
+ "x64",
40
+ "arm64"
41
+ ]
42
+ }