@cc-claw/code 0.6.178 → 0.6.180
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 +4 -10
- package/bin/cc-code +214 -12
- package/package.json +11 -6
- package/install.js +0 -683
- package/install.test.js +0 -479
package/README.md
CHANGED
|
@@ -71,16 +71,12 @@ v0.6.129:输入 `@` 即显示文件候选。默认仅列当前目录,最多
|
|
|
71
71
|
npm install -g @cc-claw/code
|
|
72
72
|
```
|
|
73
73
|
|
|
74
|
-
> [!
|
|
75
|
-
>
|
|
74
|
+
> [!NOTE]
|
|
75
|
+
> **本包不执行任何安装脚本。** 二进制位于平台专属的可选依赖包(`@cc-claw/code-<平台>-<架构>`)中,npm 会按操作系统与架构自动只装匹配的那一个 —— 因此 `--ignore-scripts`、pnpm、bun 以及禁止 build script 的 npm 版本都能正常安装,安装期也不会访问 GitHub。
|
|
76
76
|
>
|
|
77
|
-
>
|
|
78
|
-
> npm install -g --allow-scripts=@cc-claw/code @cc-claw/code
|
|
79
|
-
> ```
|
|
77
|
+
> 用 `--omit=optional` / `--no-optional` 安装会拿不到二进制,此时 `cc-code` 会打印补救说明而不是 `ENOENT`。
|
|
80
78
|
>
|
|
81
|
-
>
|
|
82
|
-
>
|
|
83
|
-
> 用 **pnpm / bun**?它们同样阻止 build script —— 先 `pnpm approve-builds`,否则装不到二进制。
|
|
79
|
+
> Windows on ARM 暂无原生构建,可显式安装 x64 版本:`npm install -g --arch=x64 @cc-claw/code`。
|
|
84
80
|
|
|
85
81
|
## 升级
|
|
86
82
|
|
|
@@ -88,8 +84,6 @@ npm install -g @cc-claw/code
|
|
|
88
84
|
npm update -g @cc-claw/code
|
|
89
85
|
```
|
|
90
86
|
|
|
91
|
-
npm 12+ 需带同样的参数:`npm update -g --allow-scripts=@cc-claw/code @cc-claw/code`。
|
|
92
|
-
|
|
93
87
|
## 快速开始
|
|
94
88
|
|
|
95
89
|
```bash
|
package/bin/cc-code
CHANGED
|
@@ -1,19 +1,221 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
// cc-code launcher.
|
|
4
|
+
//
|
|
5
|
+
// The platform binary ships as a companion optional dependency package
|
|
6
|
+
// (`@cc-claw/code-<platform>-<arch>`), so installing this package runs no
|
|
7
|
+
// install script and touches no network beyond the npm registry:
|
|
8
|
+
//
|
|
9
|
+
// npm install -g @cc-claw/code
|
|
10
|
+
//
|
|
11
|
+
// npm selects the single platform package whose `os` / `cpu` fields match the
|
|
12
|
+
// host and skips the rest, so exactly one binary is downloaded.
|
|
13
|
+
|
|
14
|
+
const { spawn } = require("child_process");
|
|
3
15
|
const { existsSync } = require("fs");
|
|
4
|
-
const {
|
|
5
|
-
|
|
16
|
+
const { dirname, join } = require("path");
|
|
17
|
+
|
|
18
|
+
/// One entry per published platform package. `file` is resolved relative to
|
|
19
|
+
/// the platform package's own root directory.
|
|
20
|
+
const TARGETS = {
|
|
21
|
+
"win32-x64": { pkg: "@cc-claw/code-win32-x64", file: "cc-code.exe" },
|
|
22
|
+
"darwin-x64": { pkg: "@cc-claw/code-darwin-x64", file: "bin/cc-code" },
|
|
23
|
+
"darwin-arm64": { pkg: "@cc-claw/code-darwin-arm64", file: "bin/cc-code" },
|
|
24
|
+
"linux-x64": { pkg: "@cc-claw/code-linux-x64", file: "bin/cc-code" },
|
|
25
|
+
"linux-arm64": { pkg: "@cc-claw/code-linux-arm64", file: "bin/cc-code" },
|
|
26
|
+
};
|
|
6
27
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
28
|
+
/// Platforms cc-code knows about but does not publish a package for. Keyed the
|
|
29
|
+
/// same way as TARGETS so the diagnosis below stays specific instead of falling
|
|
30
|
+
/// back to a generic "unsupported platform".
|
|
31
|
+
const UNPUBLISHED = {
|
|
32
|
+
"win32-arm64": {
|
|
33
|
+
pkg: "@cc-claw/code-win32-arm64",
|
|
34
|
+
hint: [
|
|
35
|
+
"Windows on ARM has no native build yet. The x64 build runs under",
|
|
36
|
+
"emulation; install that one instead:",
|
|
37
|
+
"",
|
|
38
|
+
" npm install -g --arch=x64 @cc-claw/code",
|
|
39
|
+
],
|
|
40
|
+
},
|
|
41
|
+
};
|
|
11
42
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
|
|
43
|
+
function platformKey() {
|
|
44
|
+
return `${process.platform}-${process.arch}`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/// Resolve a file inside a platform package, or null when the package (or the
|
|
48
|
+
/// file) is absent.
|
|
49
|
+
///
|
|
50
|
+
/// Resolution goes through `<pkg>/package.json` rather than the binary path so
|
|
51
|
+
/// that it works under npm's flattened layout, pnpm's store layout and bun's
|
|
52
|
+
/// isolated layout alike: in all three the platform package is a real
|
|
53
|
+
/// dependency of this package and therefore resolvable from here.
|
|
54
|
+
function resolveInPackage(pkg, file) {
|
|
55
|
+
let root;
|
|
56
|
+
try {
|
|
57
|
+
root = dirname(require.resolve(`${pkg}/package.json`));
|
|
58
|
+
} catch {
|
|
59
|
+
return null;
|
|
17
60
|
}
|
|
18
|
-
|
|
61
|
+
const full = join(root, file);
|
|
62
|
+
return existsSync(full) ? full : null;
|
|
19
63
|
}
|
|
64
|
+
|
|
65
|
+
function missingBinaryMessage(key, target) {
|
|
66
|
+
const lines = [
|
|
67
|
+
`cc-code: no binary for ${key}.`,
|
|
68
|
+
"",
|
|
69
|
+
"This package installs its binary through the optional dependency",
|
|
70
|
+
`"${target.pkg}", which is not installed.`,
|
|
71
|
+
"",
|
|
72
|
+
"Common causes:",
|
|
73
|
+
" - installed with --no-optional / --omit=optional",
|
|
74
|
+
" - this platform has no published build",
|
|
75
|
+
];
|
|
76
|
+
if (key === "win32-arm64") {
|
|
77
|
+
lines.push("", ...UNPUBLISHED["win32-arm64"].hint);
|
|
78
|
+
} else {
|
|
79
|
+
lines.push(
|
|
80
|
+
"",
|
|
81
|
+
"Reinstall without --no-optional, or use the standalone binary:",
|
|
82
|
+
" https://github.com/cc-claws/cc-code#install",
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
return lines.join("\n");
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function unsupportedPlatformMessage(key) {
|
|
89
|
+
const known = UNPUBLISHED[key];
|
|
90
|
+
if (known) {
|
|
91
|
+
return [`cc-code: no binary for ${key}.`, "", ...known.hint].join("\n");
|
|
92
|
+
}
|
|
93
|
+
return (
|
|
94
|
+
`cc-code: unsupported platform ${key}.\n` +
|
|
95
|
+
`Supported: ${[...Object.keys(TARGETS), ...Object.keys(UNPUBLISHED)].join(", ")}.`
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/// Windows: a console Ctrl+C is broadcast as CTRL_C_EVENT to every process
|
|
100
|
+
/// attached to the console, this launcher included. A Node process without a
|
|
101
|
+
/// JS handler for SIGINT/SIGBREAK dies on it immediately, which tears the
|
|
102
|
+
/// console process group down from under the child (that is exactly the
|
|
103
|
+
/// regression #410 fixed by rewriting the npm shim to skip Node).
|
|
104
|
+
///
|
|
105
|
+
/// Registering a no-op handler keeps this launcher alive so the binary — which
|
|
106
|
+
/// installs its own SetConsoleCtrlHandler and re-injects a key event — stays
|
|
107
|
+
/// the only process deciding what Ctrl+C means. Nothing is forwarded: the
|
|
108
|
+
/// console already delivered the event to the child directly, and forwarding
|
|
109
|
+
/// would double-handle it.
|
|
110
|
+
function installWindowsCtrlHandlers() {
|
|
111
|
+
if (process.platform !== "win32") return;
|
|
112
|
+
const ignore = () => {};
|
|
113
|
+
process.on("SIGINT", ignore);
|
|
114
|
+
process.on("SIGBREAK", ignore);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/// True when Node was built for musl (Alpine and friends).
|
|
118
|
+
///
|
|
119
|
+
/// The published Linux binaries link against glibc, so on musl the spawn fails
|
|
120
|
+
/// with a bare ENOENT that looks like a missing file. Detecting the host lets
|
|
121
|
+
/// the error name the actual cause.
|
|
122
|
+
function isMuslHost() {
|
|
123
|
+
if (process.platform !== "linux") return false;
|
|
124
|
+
try {
|
|
125
|
+
const report = process.report.getReport();
|
|
126
|
+
if (report.header && report.header.glibcVersionRuntime) return false;
|
|
127
|
+
const so = report.sharedObjects || [];
|
|
128
|
+
return so.some((f) => f.includes("libc.musl-") || f.includes("ld-musl-"));
|
|
129
|
+
} catch {
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function launchFailureMessage(key, binPath, err) {
|
|
135
|
+
if (process.platform === "linux" && err && err.code === "ENOENT") {
|
|
136
|
+
if (isMuslHost()) {
|
|
137
|
+
return [
|
|
138
|
+
`cc-code: cannot run ${binPath}`,
|
|
139
|
+
"",
|
|
140
|
+
"This host uses musl libc (Alpine Linux and similar), but the",
|
|
141
|
+
"published binary is linked against glibc.",
|
|
142
|
+
"",
|
|
143
|
+
"Use the standalone install script instead, which does not depend on",
|
|
144
|
+
"the npm platform package:",
|
|
145
|
+
" https://github.com/cc-claws/cc-code#install",
|
|
146
|
+
].join("\n");
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return `cc-code: failed to start ${binPath}: ${err ? err.message : "unknown error"}`;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function main() {
|
|
153
|
+
const key = platformKey();
|
|
154
|
+
const target = TARGETS[key];
|
|
155
|
+
|
|
156
|
+
// Escape hatch, also used by the tests to drive the launcher on a host whose
|
|
157
|
+
// platform package is not installed.
|
|
158
|
+
const override = process.env.CC_CODE_BINARY;
|
|
159
|
+
|
|
160
|
+
if (!target && !override) {
|
|
161
|
+
console.error(unsupportedPlatformMessage(key));
|
|
162
|
+
process.exit(1);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
let binPath = override;
|
|
166
|
+
if (!binPath) {
|
|
167
|
+
binPath = resolveInPackage(target.pkg, target.file);
|
|
168
|
+
if (!binPath) {
|
|
169
|
+
console.error(missingBinaryMessage(key, target));
|
|
170
|
+
process.exit(1);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
installWindowsCtrlHandlers();
|
|
175
|
+
|
|
176
|
+
let child;
|
|
177
|
+
try {
|
|
178
|
+
child = spawn(binPath, process.argv.slice(2), { stdio: "inherit" });
|
|
179
|
+
} catch (err) {
|
|
180
|
+
console.error(launchFailureMessage(key, binPath, err));
|
|
181
|
+
process.exit(1);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
child.on("error", (err) => {
|
|
185
|
+
console.error(launchFailureMessage(key, binPath, err));
|
|
186
|
+
process.exit(1);
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
child.on("exit", (code, signal) => {
|
|
190
|
+
// Mirror the child's outcome. A null code means death by signal: exiting 0
|
|
191
|
+
// there would report success for a killed run.
|
|
192
|
+
if (signal) {
|
|
193
|
+
// Re-raise so shell callers see the real cause (`$?` = 128 + signo).
|
|
194
|
+
// SIGINT / SIGBREAK are handled above on Windows and would be swallowed,
|
|
195
|
+
// so those fall back to a plain failure exit.
|
|
196
|
+
if (process.platform === "win32") {
|
|
197
|
+
process.exit(1);
|
|
198
|
+
}
|
|
199
|
+
try {
|
|
200
|
+
process.kill(process.pid, signal);
|
|
201
|
+
return;
|
|
202
|
+
} catch {
|
|
203
|
+
process.exit(1);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
process.exit(code === null ? 1 : code);
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (require.main === module) {
|
|
211
|
+
main();
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
module.exports = {
|
|
215
|
+
TARGETS,
|
|
216
|
+
UNPUBLISHED,
|
|
217
|
+
platformKey,
|
|
218
|
+
resolveInPackage,
|
|
219
|
+
missingBinaryMessage,
|
|
220
|
+
unsupportedPlatformMessage,
|
|
221
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cc-claw/code",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.180",
|
|
4
4
|
"description": "cc-code — Terminal coding agent powered by open-source models — Rust-built, Claude Code compatible",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent",
|
|
@@ -22,9 +22,10 @@
|
|
|
22
22
|
"bin": {
|
|
23
23
|
"cc-code": "bin/cc-code"
|
|
24
24
|
},
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
|
|
25
|
+
"files": [
|
|
26
|
+
"bin/cc-code",
|
|
27
|
+
"README.md"
|
|
28
|
+
],
|
|
28
29
|
"os": [
|
|
29
30
|
"linux",
|
|
30
31
|
"darwin",
|
|
@@ -37,7 +38,11 @@
|
|
|
37
38
|
"engines": {
|
|
38
39
|
"node": ">=16"
|
|
39
40
|
},
|
|
40
|
-
"
|
|
41
|
-
"
|
|
41
|
+
"optionalDependencies": {
|
|
42
|
+
"@cc-claw/code-win32-x64": "0.6.180",
|
|
43
|
+
"@cc-claw/code-darwin-x64": "0.6.180",
|
|
44
|
+
"@cc-claw/code-darwin-arm64": "0.6.180",
|
|
45
|
+
"@cc-claw/code-linux-x64": "0.6.180",
|
|
46
|
+
"@cc-claw/code-linux-arm64": "0.6.180"
|
|
42
47
|
}
|
|
43
48
|
}
|