@cc-claw/code 0.6.12 → 0.6.14

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 +54 -54
  2. package/bin/cc-code +19 -19
  3. package/install.js +172 -172
  4. package/package.json +43 -43
package/README.md CHANGED
@@ -1,54 +1,54 @@
1
- # cc-code
2
-
3
- **用开源模型跑 Agent Loop — Rust 写的终端编程助手,兼容 Claude Code 全家桶**
4
-
5
- [![npm](https://img.shields.io/npm/v/@cc-claw/code)](https://www.npmjs.com/package/@cc-claw/code)
6
- [![License](https://img.shields.io/badge/license-Apache%202.0-blue)](LICENSE)
7
-
8
- ## 安装
9
-
10
- ```bash
11
- npm install -g @cc-claw/code
12
- ```
13
-
14
- ## 升级
15
-
16
- ```bash
17
- npm update -g @cc-claw/code
18
- ```
19
-
20
- ## 快速开始
21
-
22
- ```bash
23
- # 启动交互式 TUI
24
- peri
25
-
26
- # 直接给任务
27
- peri "解释这个项目的目录结构"
28
-
29
- # 指定模型
30
- peri --model deepseek/deepseek-chat "重构这个函数"
31
- ```
32
-
33
- ## 支持的平台
34
-
35
- | 平台 | 架构 |
36
- |------|------|
37
- | Linux | x86_64, aarch64, riscv64 |
38
- | macOS | x86_64 (Intel), aarch64 (Apple Silicon) |
39
- | Windows | x86_64 |
40
-
41
- ## 为什么选 cc-code?
42
-
43
- | 对比项 | 其他终端 Agent | cc-code |
44
- |--------|---------------|------|
45
- | 运行时 | Node.js / Bun,动辄吃 1GB 内存 | Rust 原生,启动快,~50MB 内存 |
46
- | 模型绑定 | 锁死一家 LLM | 随便换:Anthropic、OpenAI 兼容、DeepSeek、GLM |
47
- | Prompt 缓存 | 每轮重算,token 白烧 | 冻结 system prompt,95-99% 缓存命中率 |
48
- | Claude Code 生态 | 不兼容 | 直接用 `.claude/` 配置、agents、skills、hooks、MCP |
49
-
50
- ## 链接
51
-
52
- - [GitHub](https://github.com/cc-claws/cc-code)
53
- - [Issues](https://github.com/cc-claws/cc-code/issues)
54
- - [English README](https://github.com/cc-claws/cc-code#readme)
1
+ # cc-code
2
+
3
+ **用开源模型跑 Agent Loop — Rust 写的终端编程助手,兼容 Claude Code 全家桶**
4
+
5
+ [![npm](https://img.shields.io/npm/v/@cc-claw/code)](https://www.npmjs.com/package/@cc-claw/code)
6
+ [![License](https://img.shields.io/badge/license-Apache%202.0-blue)](LICENSE)
7
+
8
+ ## 安装
9
+
10
+ ```bash
11
+ npm install -g @cc-claw/code
12
+ ```
13
+
14
+ ## 升级
15
+
16
+ ```bash
17
+ npm update -g @cc-claw/code
18
+ ```
19
+
20
+ ## 快速开始
21
+
22
+ ```bash
23
+ # 启动交互式 TUI
24
+ cc-code
25
+
26
+ # 直接给任务
27
+ cc-code "解释这个项目的目录结构"
28
+
29
+ # 指定模型
30
+ cc-code --model deepseek/deepseek-chat "重构这个函数"
31
+ ```
32
+
33
+ ## 支持的平台
34
+
35
+ | 平台 | 架构 |
36
+ |------|------|
37
+ | Linux | x86_64, aarch64, riscv64 |
38
+ | macOS | x86_64 (Intel), aarch64 (Apple Silicon) |
39
+ | Windows | x86_64 |
40
+
41
+ ## 为什么选 cc-code?
42
+
43
+ | 对比项 | 其他终端 Agent | cc-code |
44
+ |--------|---------------|------|
45
+ | 运行时 | Node.js / Bun,动辄吃 1GB 内存 | Rust 原生,启动快,~50MB 内存 |
46
+ | 模型绑定 | 锁死一家 LLM | 随便换:Anthropic、OpenAI 兼容、DeepSeek、GLM |
47
+ | Prompt 缓存 | 每轮重算,token 白烧 | 冻结 system prompt,95-99% 缓存命中率 |
48
+ | Claude Code 生态 | 不兼容 | 直接用 `.claude/` 配置、agents、skills、hooks、MCP |
49
+
50
+ ## 链接
51
+
52
+ - [GitHub](https://github.com/cc-claws/cc-code)
53
+ - [Issues](https://github.com/cc-claws/cc-code/issues)
54
+ - [English README](https://github.com/cc-claws/cc-code#readme)
package/bin/cc-code CHANGED
@@ -1,19 +1,19 @@
1
- #!/usr/bin/env node
2
-
3
- const { existsSync } = require("fs");
4
- const { join, dirname } = require("path");
5
- const { execFileSync } = require("child_process");
6
-
7
- const dir = dirname(__filename);
8
- const binPath = existsSync(join(dir, "peri-bin"))
9
- ? join(dir, "peri-bin")
10
- : join(dir, "peri.exe");
11
-
12
- try {
13
- execFileSync(binPath, process.argv.slice(2), { stdio: "inherit" });
14
- } catch (err) {
15
- if (err.status !== null) {
16
- process.exit(err.status);
17
- }
18
- throw err;
19
- }
1
+ #!/usr/bin/env node
2
+
3
+ const { existsSync } = require("fs");
4
+ const { join, dirname } = require("path");
5
+ const { execFileSync } = require("child_process");
6
+
7
+ const dir = dirname(__filename);
8
+ const binPath = existsSync(join(dir, "cc-code-bin"))
9
+ ? join(dir, "cc-code-bin")
10
+ : join(dir, "cc-code.exe");
11
+
12
+ try {
13
+ execFileSync(binPath, process.argv.slice(2), { stdio: "inherit" });
14
+ } catch (err) {
15
+ if (err.status !== null) {
16
+ process.exit(err.status);
17
+ }
18
+ throw err;
19
+ }
package/install.js CHANGED
@@ -1,172 +1,172 @@
1
- #!/usr/bin/env node
2
-
3
- const { createWriteStream, mkdirSync, chmodSync, existsSync, renameSync, unlinkSync, writeFileSync } = require("fs");
4
- const { join } = require("path");
5
- const { execSync } = require("child_process");
6
-
7
- const VERSION = require("./package.json").version;
8
- const REPO = "cc-claws/cc-code";
9
- const BASE_URL = `https://github.com/${REPO}/releases/download/npm-v${VERSION}`;
10
-
11
- const PLATFORMS = {
12
- "linux-x64": { os: "linux", arch: "x64", suffix: "linux-x86_64", ext: "tar.gz" },
13
- "linux-arm64": { os: "linux", arch: "arm64", suffix: "linux-aarch64", ext: "tar.gz" },
14
- "darwin-x64": { os: "darwin", arch: "x64", suffix: "macos-x86_64", ext: "tar.gz" },
15
- "darwin-arm64": { os: "darwin", arch: "arm64", suffix: "macos-aarch64", ext: "tar.gz" },
16
- "win32-x64": { os: "win32", arch: "x64", suffix: "windows-x86_64", ext: "zip" },
17
- };
18
-
19
- function getPlatformKey() {
20
- const key = `${process.platform}-${process.arch}`;
21
- if (!PLATFORMS[key]) {
22
- throw new Error(`Unsupported platform: ${key}. Supported: ${Object.keys(PLATFORMS).join(", ")}`);
23
- }
24
- return key;
25
- }
26
-
27
- function getProxyUrl() {
28
- // Check common proxy environment variables
29
- const proxy = process.env.HTTPS_PROXY || process.env.https_proxy
30
- || process.env.HTTP_PROXY || process.env.http_proxy
31
- || process.env.ALL_PROXY || process.env.all_proxy;
32
- return proxy || null;
33
- }
34
-
35
- function download(url) {
36
- const proxyUrl = getProxyUrl();
37
-
38
- if (proxyUrl) {
39
- return downloadViaProxy(url, proxyUrl);
40
- }
41
- return downloadDirect(url);
42
- }
43
-
44
- function downloadDirect(url) {
45
- const { get } = require("https");
46
- return new Promise((resolve, reject) => {
47
- get(url, (res) => {
48
- if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
49
- downloadDirect(res.headers.location).then(resolve, reject);
50
- return;
51
- }
52
- if (res.statusCode !== 200) {
53
- reject(new Error(`Download failed: HTTP ${res.statusCode} for ${url}`));
54
- return;
55
- }
56
- const chunks = [];
57
- res.on("data", (chunk) => chunks.push(chunk));
58
- res.on("end", () => resolve(Buffer.concat(chunks)));
59
- res.on("error", reject);
60
- }).on("error", reject);
61
- });
62
- }
63
-
64
- function downloadViaProxy(url, proxyUrl) {
65
- const { URL } = require("url");
66
- const target = new URL(url);
67
- const proxy = new URL(proxyUrl);
68
-
69
- const isHttps = proxy.protocol === "https:" || proxy.protocol === "HTTPS:";
70
- const proxyModule = isHttps ? require("https") : require("http");
71
-
72
- const proxyOpts = {
73
- hostname: proxy.hostname,
74
- port: proxy.port || (isHttps ? 443 : 80),
75
- path: url,
76
- method: "GET",
77
- headers: { "Host": target.hostname, "User-Agent": "peri-installer" },
78
- };
79
-
80
- // Support proxy auth
81
- if (proxy.username) {
82
- const auth = decodeURIComponent(`${proxy.username}:${proxy.password || ""}`);
83
- proxyOpts.headers["Proxy-Authorization"] = `Basic ${Buffer.from(auth).toString("base64")}`;
84
- }
85
-
86
- console.log(` Using proxy: ${proxy.hostname}:${proxy.port || (isHttps ? 443 : 80)}`);
87
-
88
- return new Promise((resolve, reject) => {
89
- const req = proxyModule.request(proxyOpts, (res) => {
90
- if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
91
- download(res.headers.location).then(resolve, reject);
92
- return;
93
- }
94
- if (res.statusCode !== 200) {
95
- reject(new Error(`Download failed: HTTP ${res.statusCode} for ${url}`));
96
- return;
97
- }
98
- const chunks = [];
99
- res.on("data", (chunk) => chunks.push(chunk));
100
- res.on("end", () => resolve(Buffer.concat(chunks)));
101
- res.on("error", reject);
102
- });
103
- req.on("error", reject);
104
- req.end();
105
- });
106
- }
107
-
108
- function extractTarGz(buffer, dest) {
109
- const tmpFile = join(dest, "peri.tar.gz");
110
- writeFileSync(tmpFile, buffer);
111
- execSync(`tar -xzf "${tmpFile}" -C "${dest}"`, { stdio: "ignore" });
112
- unlinkSync(tmpFile);
113
- }
114
-
115
- function extractZip(buffer, dest) {
116
- const AdmZip = require("adm-zip");
117
- const zip = new AdmZip(buffer);
118
- zip.extractAllTo(dest, true);
119
- }
120
-
121
- async function main() {
122
- const key = getPlatformKey();
123
- const platform = PLATFORMS[key];
124
- const fileName = `peri-${platform.suffix}.${platform.ext}`;
125
- const url = `${BASE_URL}/${fileName}`;
126
- const binDir = join(__dirname, "bin");
127
-
128
- if (!existsSync(binDir)) {
129
- mkdirSync(binDir, { recursive: true });
130
- }
131
-
132
- console.log(`Downloading peri ${VERSION} for ${platform.os}-${platform.arch}...`);
133
- console.log(` URL: ${url}`);
134
-
135
- const buffer = await download(url);
136
-
137
- if (platform.ext === "tar.gz") {
138
- extractTarGz(buffer, binDir);
139
- } else {
140
- extractZip(buffer, binDir);
141
- }
142
-
143
- const extractedName = platform.os === "win32"
144
- ? `peri-${platform.suffix}.exe`
145
- : `peri-${platform.suffix}`;
146
- const finalName = platform.os === "win32" ? "peri.exe" : "peri-bin";
147
- const extractedPath = join(binDir, extractedName);
148
- const finalPath = join(binDir, finalName);
149
-
150
- if (existsSync(extractedPath)) {
151
- if (existsSync(finalPath)) unlinkSync(finalPath);
152
- renameSync(extractedPath, finalPath);
153
- }
154
-
155
- if (platform.os !== "win32") {
156
- chmodSync(finalPath, 0o755);
157
- const wrapperPath = join(__dirname, "bin", "peri");
158
- if (existsSync(wrapperPath)) chmodSync(wrapperPath, 0o755);
159
- } else {
160
- // Generate Windows batch wrapper so npm's peri.cmd/peri.ps1 can invoke it
161
- const binDirPath = join(__dirname, "bin");
162
- writeFileSync(join(binDirPath, "peri.cmd"), `@echo off\r\n"%~dp0peri.exe" %*\r\n`);
163
- writeFileSync(join(binDirPath, "peri.ps1"), `$basedir = Split-Path $MyInvocation.MyCommand.Definition -Parent\r\n& "$basedir\\peri.exe" @args\r\nexit $LASTEXITCODE\r\n`);
164
- }
165
-
166
- console.log(`peri ${VERSION} installed successfully.`);
167
- }
168
-
169
- main().catch((err) => {
170
- console.error("Failed to install peri:", err.message);
171
- process.exit(1);
172
- });
1
+ #!/usr/bin/env node
2
+
3
+ const { createWriteStream, mkdirSync, chmodSync, existsSync, renameSync, unlinkSync, writeFileSync } = require("fs");
4
+ const { join } = require("path");
5
+ const { execSync } = require("child_process");
6
+
7
+ const VERSION = require("./package.json").version;
8
+ const REPO = "cc-claws/cc-code";
9
+ const BASE_URL = `https://github.com/${REPO}/releases/download/npm-v${VERSION}`;
10
+
11
+ const PLATFORMS = {
12
+ "linux-x64": { os: "linux", arch: "x64", suffix: "linux-x86_64", ext: "tar.gz" },
13
+ "linux-arm64": { os: "linux", arch: "arm64", suffix: "linux-aarch64", ext: "tar.gz" },
14
+ "darwin-x64": { os: "darwin", arch: "x64", suffix: "macos-x86_64", ext: "tar.gz" },
15
+ "darwin-arm64": { os: "darwin", arch: "arm64", suffix: "macos-aarch64", ext: "tar.gz" },
16
+ "win32-x64": { os: "win32", arch: "x64", suffix: "windows-x86_64", ext: "zip" },
17
+ };
18
+
19
+ function getPlatformKey() {
20
+ const key = `${process.platform}-${process.arch}`;
21
+ if (!PLATFORMS[key]) {
22
+ throw new Error(`Unsupported platform: ${key}. Supported: ${Object.keys(PLATFORMS).join(", ")}`);
23
+ }
24
+ return key;
25
+ }
26
+
27
+ function getProxyUrl() {
28
+ // Check common proxy environment variables
29
+ const proxy = process.env.HTTPS_PROXY || process.env.https_proxy
30
+ || process.env.HTTP_PROXY || process.env.http_proxy
31
+ || process.env.ALL_PROXY || process.env.all_proxy;
32
+ return proxy || null;
33
+ }
34
+
35
+ function download(url) {
36
+ const proxyUrl = getProxyUrl();
37
+
38
+ if (proxyUrl) {
39
+ return downloadViaProxy(url, proxyUrl);
40
+ }
41
+ return downloadDirect(url);
42
+ }
43
+
44
+ function downloadDirect(url) {
45
+ const { get } = require("https");
46
+ return new Promise((resolve, reject) => {
47
+ get(url, (res) => {
48
+ if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
49
+ downloadDirect(res.headers.location).then(resolve, reject);
50
+ return;
51
+ }
52
+ if (res.statusCode !== 200) {
53
+ reject(new Error(`Download failed: HTTP ${res.statusCode} for ${url}`));
54
+ return;
55
+ }
56
+ const chunks = [];
57
+ res.on("data", (chunk) => chunks.push(chunk));
58
+ res.on("end", () => resolve(Buffer.concat(chunks)));
59
+ res.on("error", reject);
60
+ }).on("error", reject);
61
+ });
62
+ }
63
+
64
+ function downloadViaProxy(url, proxyUrl) {
65
+ const { URL } = require("url");
66
+ const target = new URL(url);
67
+ const proxy = new URL(proxyUrl);
68
+
69
+ const isHttps = proxy.protocol === "https:" || proxy.protocol === "HTTPS:";
70
+ const proxyModule = isHttps ? require("https") : require("http");
71
+
72
+ const proxyOpts = {
73
+ hostname: proxy.hostname,
74
+ port: proxy.port || (isHttps ? 443 : 80),
75
+ path: url,
76
+ method: "GET",
77
+ headers: { "Host": target.hostname, "User-Agent": "cc-code-installer" },
78
+ };
79
+
80
+ // Support proxy auth
81
+ if (proxy.username) {
82
+ const auth = decodeURIComponent(`${proxy.username}:${proxy.password || ""}`);
83
+ proxyOpts.headers["Proxy-Authorization"] = `Basic ${Buffer.from(auth).toString("base64")}`;
84
+ }
85
+
86
+ console.log(` Using proxy: ${proxy.hostname}:${proxy.port || (isHttps ? 443 : 80)}`);
87
+
88
+ return new Promise((resolve, reject) => {
89
+ const req = proxyModule.request(proxyOpts, (res) => {
90
+ if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
91
+ download(res.headers.location).then(resolve, reject);
92
+ return;
93
+ }
94
+ if (res.statusCode !== 200) {
95
+ reject(new Error(`Download failed: HTTP ${res.statusCode} for ${url}`));
96
+ return;
97
+ }
98
+ const chunks = [];
99
+ res.on("data", (chunk) => chunks.push(chunk));
100
+ res.on("end", () => resolve(Buffer.concat(chunks)));
101
+ res.on("error", reject);
102
+ });
103
+ req.on("error", reject);
104
+ req.end();
105
+ });
106
+ }
107
+
108
+ function extractTarGz(buffer, dest) {
109
+ const tmpFile = join(dest, "cc-code.tar.gz");
110
+ writeFileSync(tmpFile, buffer);
111
+ execSync(`tar -xzf "${tmpFile}" -C "${dest}"`, { stdio: "ignore" });
112
+ unlinkSync(tmpFile);
113
+ }
114
+
115
+ function extractZip(buffer, dest) {
116
+ const AdmZip = require("adm-zip");
117
+ const zip = new AdmZip(buffer);
118
+ zip.extractAllTo(dest, true);
119
+ }
120
+
121
+ async function main() {
122
+ const key = getPlatformKey();
123
+ const platform = PLATFORMS[key];
124
+ const fileName = `cc-code-${platform.suffix}.${platform.ext}`;
125
+ const url = `${BASE_URL}/${fileName}`;
126
+ const binDir = join(__dirname, "bin");
127
+
128
+ if (!existsSync(binDir)) {
129
+ mkdirSync(binDir, { recursive: true });
130
+ }
131
+
132
+ console.log(`Downloading cc-code ${VERSION} for ${platform.os}-${platform.arch}...`);
133
+ console.log(` URL: ${url}`);
134
+
135
+ const buffer = await download(url);
136
+
137
+ if (platform.ext === "tar.gz") {
138
+ extractTarGz(buffer, binDir);
139
+ } else {
140
+ extractZip(buffer, binDir);
141
+ }
142
+
143
+ const extractedName = platform.os === "win32"
144
+ ? `cc-code-${platform.suffix}.exe`
145
+ : `cc-code-${platform.suffix}`;
146
+ const finalName = platform.os === "win32" ? "cc-code.exe" : "cc-code-bin";
147
+ const extractedPath = join(binDir, extractedName);
148
+ const finalPath = join(binDir, finalName);
149
+
150
+ if (existsSync(extractedPath)) {
151
+ if (existsSync(finalPath)) unlinkSync(finalPath);
152
+ renameSync(extractedPath, finalPath);
153
+ }
154
+
155
+ if (platform.os !== "win32") {
156
+ chmodSync(finalPath, 0o755);
157
+ const wrapperPath = join(__dirname, "bin", "cc-code");
158
+ if (existsSync(wrapperPath)) chmodSync(wrapperPath, 0o755);
159
+ } else {
160
+ // Generate Windows batch wrapper so npm's cc-code.cmd/ps1 can invoke it
161
+ const binDirPath = join(__dirname, "bin");
162
+ writeFileSync(join(binDirPath, "cc-code.cmd"), `@echo off\r\n"%~dp0cc-code.exe" %*\r\n`);
163
+ writeFileSync(join(binDirPath, "cc-code.ps1"), `$basedir = Split-Path $MyInvocation.MyCommand.Definition -Parent\r\n& "$basedir\\cc-code.exe" @args\r\nexit $LASTEXITCODE\r\n`);
164
+ }
165
+
166
+ console.log(`cc-code ${VERSION} installed successfully.`);
167
+ }
168
+
169
+ main().catch((err) => {
170
+ console.error("Failed to install cc-code:", err.message);
171
+ process.exit(1);
172
+ });
package/package.json CHANGED
@@ -1,43 +1,43 @@
1
- {
2
- "name": "@cc-claw/code",
3
- "version": "0.6.12",
4
- "description": "cc-code — Terminal coding agent powered by open-source models — Rust-built, Claude Code compatible",
5
- "keywords": [
6
- "agent",
7
- "coding",
8
- "terminal",
9
- "rust",
10
- "llm",
11
- "claude-code"
12
- ],
13
- "repository": {
14
- "type": "git",
15
- "url": "git+https://github.com/cc-claws/cc-code.git"
16
- },
17
- "homepage": "https://github.com/cc-claws/cc-code",
18
- "bugs": {
19
- "url": "https://github.com/cc-claws/cc-code/issues"
20
- },
21
- "license": "Apache-2.0",
22
- "bin": {
23
- "cc-code": "bin/cc-code"
24
- },
25
- "scripts": {
26
- "postinstall": "node install.js"
27
- },
28
- "os": [
29
- "linux",
30
- "darwin",
31
- "win32"
32
- ],
33
- "cpu": [
34
- "x64",
35
- "arm64"
36
- ],
37
- "engines": {
38
- "node": ">=16"
39
- },
40
- "dependencies": {
41
- "adm-zip": "^0.5.16"
42
- }
43
- }
1
+ {
2
+ "name": "@cc-claw/code",
3
+ "version": "0.6.14",
4
+ "description": "cc-code — Terminal coding agent powered by open-source models — Rust-built, Claude Code compatible",
5
+ "keywords": [
6
+ "agent",
7
+ "coding",
8
+ "terminal",
9
+ "rust",
10
+ "llm",
11
+ "claude-code"
12
+ ],
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://github.com/cc-claws/cc-code.git"
16
+ },
17
+ "homepage": "https://github.com/cc-claws/cc-code",
18
+ "bugs": {
19
+ "url": "https://github.com/cc-claws/cc-code/issues"
20
+ },
21
+ "license": "Apache-2.0",
22
+ "bin": {
23
+ "cc-code": "bin/cc-code"
24
+ },
25
+ "scripts": {
26
+ "postinstall": "node install.js"
27
+ },
28
+ "os": [
29
+ "linux",
30
+ "darwin",
31
+ "win32"
32
+ ],
33
+ "cpu": [
34
+ "x64",
35
+ "arm64"
36
+ ],
37
+ "engines": {
38
+ "node": ">=16"
39
+ },
40
+ "dependencies": {
41
+ "adm-zip": "^0.5.16"
42
+ }
43
+ }