@go-hare/claude-code 2.6.7 → 2.6.9

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 ADDED
@@ -0,0 +1,317 @@
1
+ # Claude Code
2
+
3
+ [![GitHub Stars](https://img.shields.io/github/stars/claude-code/claude-code?style=flat-square&logo=github&color=yellow)](https://github.com/claude-code/claude-code/stargazers)
4
+ [![GitHub Contributors](https://img.shields.io/github/contributors/claude-code/claude-code?style=flat-square&color=green)](https://github.com/claude-code/claude-code/graphs/contributors)
5
+ [![GitHub Issues](https://img.shields.io/github/issues/claude-code/claude-code?style=flat-square&color=orange)](https://github.com/claude-code/claude-code/issues)
6
+ [![GitHub License](https://img.shields.io/github/license/claude-code/claude-code?style=flat-square)](https://github.com/claude-code/claude-code/blob/main/LICENSE)
7
+ [![Last Commit](https://img.shields.io/github/last-commit/claude-code/claude-code?style=flat-square&color=blue)](https://github.com/claude-code/claude-code/commits/main)
8
+ [![Bun](https://img.shields.io/badge/runtime-Bun-black?style=flat-square&logo=bun)](https://bun.sh/)
9
+
10
+ > Which Claude do you like? The open source one is the best.
11
+
12
+ 本项目是基于官方 Claude Code CLI 工具进行源码还原、工程化重建与能力增强的开源项目。目标是在保留 Claude Code 交互体验的基础上,补齐多模型接入、远程控制、ACP、群控、MCP、插件、KAIROS 常驻助手、Buddy agent 宠物、可观测性与本地自动化等能力。
13
+
14
+ | 特性 | 说明 |
15
+ | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
16
+ | **Claude 群控技术** | Pipe IPC 多实例协作:同机 main/sub 自动编排 + LAN 跨机器零配置发现与通讯,`/pipes` 选择面板 + `Shift+↓` 交互 + 消息广播路由 |
17
+ | **ACP 协议一等一支持** | 支持接入 Zed、Cursor 等 IDE,支持会话恢复、Skills、权限桥接 |
18
+ | **Remote Control 私有部署** | Docker 自托管远程界面, 可以手机上看 CC |
19
+ | **Langfuse 监控** | 企业级 Agent 监控, 可以清晰看到每次 agent loop 细节, 可以一键转化为数据集 |
20
+ | **Web Search** | 内置网页搜索工具, 支持 bing 和 brave 搜索 |
21
+ | **Poor Mode** | 穷鬼模式,关闭记忆提取和键入建议,大幅度减少并发请求,`/poor` 可以开关 |
22
+ | **KAIROS 常驻助手** | 持久化 AI 助手模式,支持 brief 输出、后台等待、频道消息、每日记忆日志、PR 订阅与推送通知等主动 Agent 能力 |
23
+ | **Buddy Agent 宠物** | 终端里的 AI 伙伴/宠物系统,支持 `/buddy` 唤出、陪伴展示、互动摸摸、上下文反应与提示输入联动 |
24
+ | **Channels 频道通知** | MCP 服务器推送外部消息到会话(飞书/Slack/Discord/微信等),`--channels plugin:name@marketplace` 启用 |
25
+ | **自定义模型供应商** | OpenAI/Anthropic/Gemini/Grok 兼容(`/login`) |
26
+ | Voice Mode | 语音输入,支持豆包语言输入(`/voice doubao`) |
27
+ | Computer Use | 屏幕截图、键鼠控制 |
28
+ | Chrome Use | 浏览器自动化、表单填写、数据抓取 |
29
+ | Sentry | 企业级错误追踪 |
30
+ | GrowthBook | 企业级特性开关 |
31
+ | /dream 记忆整理 | 自动整理和优化记忆文件 |
32
+
33
+ ## 项目定位
34
+
35
+ 当前主线已融合 `core-clean` 的 Agent Core / runtime 分层。这个项目不再只是一个反编译 CLI 的功能堆叠,而是面向终端交互、headless 嵌入、direct-connect、server、bridge、daemon、ACP 和远程控制场景的 AI coding runtime。
36
+
37
+ 当前目标不是继续围绕单一 CLI 入口做大规模堆叠,而是:
38
+
39
+ - 保持 CLI / REPL 作为官方交互宿主
40
+ - 将可复用执行能力下沉到 `src/core` / `AgentSession`
41
+ - 让外部宿主通过 Agent Core 事件和 host adapter 接入
42
+ - 保留本项目已有的多模型、群控、KAIROS、Buddy、Remote Control、ACP、MCP、插件与可观测性能力
43
+ - 在不破坏主链行为的前提下持续收口 runtime 能力
44
+
45
+ ## Core-Clean 增强对比
46
+
47
+ 相比旧结构,这次融合后增强点主要是:
48
+
49
+ | 方向 | 旧结构 | 当前结构 |
50
+ | ---- | ------ | -------- |
51
+ | 执行主链 | CLI / REPL / server 各自直接接入 query lifecycle | `src/core` 提供 `AgentSession.stream()` 与 `AgentEvent` 主链 |
52
+ | 宿主接入 | headless、ACP、bridge、server 各自维护适配逻辑 | `src/hosts/*` 统一承接 CLI、headless、REPL、server、remote-control、daemon、terminal |
53
+ | runtime 能力 | 分散在入口、server、bridge、工具注册与状态模块中 | `src/runtime/capabilities/*` 收口 execution、server、bridge、daemon、mcp、persistence、tools、commands |
54
+ | 外部嵌入 | 主要依赖 CLI 或 REPL 行为 | `./core` 包级入口为 headless embedding / direct-connect / server host 打基础 |
55
+ | 事件协议 | SDKMessage、stream-json、UI state、server packet 混在各宿主里 | `AgentEvent` 作为 core event contract,宿主再投影为 stdout、Ink、ACP、WebSocket/SSE |
56
+ | 工具体系 | 工具列表直接面向当前入口装配 | runtime tool catalog 保留现有工具,同时提供统一描述、策略与过滤入口 |
57
+
58
+ ## 当前能力
59
+
60
+ - 交互式 CLI / REPL
61
+ - headless runtime session
62
+ - direct-connect / server
63
+ - ACP agent 模式
64
+ - bridge / remote-control / daemon host
65
+ - MCP、channels、plugins
66
+ - OpenAI / Anthropic / Gemini / Grok 兼容模型接入
67
+ - Buddy agent 宠物、KAIROS 常驻助手、Coordinator、task、subagent、team 主链
68
+ - computer-use / chrome bridge / remote-control 相关能力
69
+ - Langfuse、Sentry、GrowthBook 等可观测性与企业集成能力
70
+
71
+ ## 使用 Agent Core
72
+
73
+ 当前包级 core 入口已经通过 `package.json` 的 `./core` 子路径暴露:
74
+
75
+ ```ts
76
+ import { createAgent } from 'claude/core'
77
+ ```
78
+
79
+ 仓库内部的 headless、ACP、direct-connect、server、bridge、daemon 等场景正在向 `src/core`、`src/hosts` 与 `src/runtime` 收口。外部接入不建议直接建立在 `src/screens/REPL.tsx` 上,优先选择下面这些方向:
80
+
81
+ - headless embedding
82
+ - direct-connect client
83
+ - server host
84
+ - bridge / remote-control host
85
+ - daemon worker
86
+ - ACP / IDE agent host
87
+
88
+ ## 项目结构
89
+
90
+ - [`src/entrypoints/cli.tsx`](src/entrypoints/cli.tsx)
91
+ - CLI 入口与快速路径分发
92
+ - [`src/entrypoints/core.ts`](src/entrypoints/core.ts)
93
+ - 包级 Agent Core 入口
94
+ - [`src/core`](src/core)
95
+ - Agent Core session / turn / event 主链
96
+ - [`src/runtime/capabilities/execution/SessionRuntime.ts`](src/runtime/capabilities/execution/SessionRuntime.ts)
97
+ - 现有 query lifecycle 的 runtime execution asset
98
+ - [`src/runtime`](src/runtime)
99
+ - 内部 runtime capability 层
100
+ - [`src/hosts`](src/hosts)
101
+ - CLI、headless、REPL、server、remote-control、daemon、terminal 等宿主适配层
102
+ - [`src/main.tsx`](src/main.tsx)
103
+ - CLI 启动装配与模式分发
104
+ - [`src/screens/REPL.tsx`](src/screens/REPL.tsx)
105
+ - 官方终端交互宿主
106
+ - [`src/query.ts`](src/query.ts)
107
+ - turn loop 与 query orchestration
108
+
109
+ ## 开发原则
110
+
111
+ - CLI 主链优先稳定
112
+ - REPL 只做交互宿主,不把执行中枢继续当成重构主战场
113
+ - 新宿主优先通过 `src/core` / `AgentSession` / `src/hosts` / `src/runtime` 接入
114
+ - 共享行为变更优先补测试
115
+ - 不为“结构更优雅”发起高风险重排
116
+
117
+ - 🚀 [想要启动项目](#-快速开始源码版)
118
+ - 🐛 [想要调试项目](#vs-code-调试)
119
+ - 📖 [想要学习项目](#teach-me-学习项目)
120
+
121
+ ## ⚡ 快速开始(安装版)
122
+
123
+ 不用克隆仓库, 从 NPM 下载后, 直接使用
124
+
125
+ ```sh
126
+ npm i -g claude-code
127
+
128
+ # bun 安装比较多问题, 推荐 npm 装
129
+ # bun i -g claude-code
130
+ # bun pm -g trust claude-code @claude-code/mcp-chrome-bridge
131
+
132
+ claude # 以 nodejs 打开 claude code
133
+ claude-bun # 以 bun 形态打开
134
+ claude update # 更新到最新版本
135
+ CLAUDE_BRIDGE_BASE_URL=https://remote-control.claude-code.win/ CLAUDE_BRIDGE_OAUTH_TOKEN=test-my-key claude --remote-control # 我们有自部署的远程控制
136
+ ```
137
+
138
+ > **安装/更新失败?** 先 `npm rm -g claude-code` 清理旧版本,再 `npm i -g claude-code@latest`。仍失败则指定版本号:`npm i -g claude-code@<版本号>`
139
+
140
+ ## ⚡ 快速开始(源码版)
141
+
142
+ ### ⚙️ 环境要求
143
+
144
+ 一定要最新版本的 bun 啊, 不然一堆奇奇怪怪的 BUG!!! bun upgrade!!!
145
+
146
+ - 📦 [Bun](https://bun.sh/) >= 1.3.11
147
+
148
+ **安装 Bun:**
149
+
150
+ ```bash
151
+ # Linux 和 macOS
152
+ curl -fsSL https://bun.sh/install | bash
153
+
154
+ # Windows (PowerShell)
155
+ powershell -c "irm bun.sh/install.ps1 | iex"
156
+ ```
157
+
158
+ **安装后的操作:**
159
+
160
+ 1. **让当前终端识别 `bun` 命令**
161
+
162
+ 安装脚本会把 `~/.bun/bin` 写入对应的 shell 配置文件。macOS 默认 zsh 环境通常会看到:
163
+
164
+ ```text
165
+ Added "~/.bun/bin" to $PATH in "~/.zshrc"
166
+ ```
167
+
168
+ 可以按安装脚本提示重启当前 shell:
169
+
170
+ ```bash
171
+ exec /bin/zsh
172
+ ```
173
+
174
+ 如果你使用 bash,重新加载 bash 配置:
175
+
176
+ ```bash
177
+ source ~/.bashrc
178
+ ```
179
+
180
+ Windows PowerShell 用户关闭并重新打开 PowerShell 即可。
181
+
182
+ 2. **验证 Bun 是否可用**
183
+
184
+ ```bash
185
+ bun --help
186
+ bun --version
187
+ ```
188
+
189
+ 3. **如果已经安装过 Bun,更新到最新版本**
190
+
191
+ ```bash
192
+ bun upgrade
193
+ ```
194
+
195
+ - ⚙️ 常规的配置 CC 的方式, 各大提供商都有自己的配置方式
196
+
197
+ ### 📍 命令执行位置
198
+
199
+ - 安装或检查 Bun 的命令可以在任意目录执行:
200
+ `curl -fsSL https://bun.sh/install | bash`、`bun --help`、`bun --version`、`bun upgrade`
201
+ - 安装本项目依赖、启动开发模式、构建项目时,必须先进入本仓库根目录,也就是包含 `package.json` 的目录。
202
+
203
+ ### 📥 安装
204
+
205
+ ```bash
206
+ cd /path/to/claude-code
207
+ bun install
208
+ ```
209
+
210
+ ### ▶️ 运行
211
+
212
+ ```bash
213
+ # 开发模式, 看到版本号 888 说明就是对了
214
+ bun run dev
215
+
216
+ # 构建
217
+ bun run build
218
+ ```
219
+
220
+ 构建采用 code splitting 多文件打包(`build.ts`),产物输出到 `dist/` 目录(入口 `dist/cli.js` + 约 450 个 chunk 文件)。
221
+
222
+ 构建出的版本 bun 和 node 都可以启动, 你 publish 到私有源可以直接启动
223
+
224
+ 如果遇到 bug 请直接提一个 issues, 我们优先解决
225
+
226
+ ### 👤 新人配置 /login
227
+
228
+ 首次运行后,在 REPL 中输入 `/login` 命令进入登录配置界面,选择 **Anthropic Compatible** 即可对接第三方 API 兼容服务(无需 Anthropic 官方账号)。
229
+ 选择 OpenAI 和 Gemini 对应的栏目都是支持相应协议的
230
+
231
+ 需要填写的字段:
232
+
233
+
234
+ | 📌 字段 | 📝 说明 | 💡 示例 |
235
+ | ------------ | ------------- | ---------------------------- |
236
+ | Base URL | API 服务地址 | `https://api.example.com/v1` |
237
+ | API Key | 认证密钥 | `sk-xxx` |
238
+ | Haiku Model | 快速模型 ID | `claude-haiku-4-5-20251001` |
239
+ | Sonnet Model | 均衡模型 ID | `claude-sonnet-4-6` |
240
+ | Opus Model | 高性能模型 ID | `claude-opus-4-6` |
241
+
242
+ - ⌨️ **Tab / Shift+Tab** 切换字段,**Enter** 确认并跳到下一个,最后一个字段按 Enter 保存
243
+
244
+ > ℹ️ 支持所有 Anthropic API 兼容服务(如 OpenRouter、AWS Bedrock 代理等),只要接口兼容 Messages API 即可。
245
+
246
+ ## Feature Flags
247
+
248
+ 所有功能开关通过 `FEATURE_<FLAG_NAME>=1` 环境变量启用,例如:
249
+
250
+ ```bash
251
+ FEATURE_BUDDY=1 FEATURE_FORK_SUBAGENT=1 bun run dev
252
+ ```
253
+
254
+ ## VS Code 调试
255
+
256
+ TUI (REPL) 模式需要真实终端,无法直接通过 VS Code launch 启动调试。使用 **attach 模式**:
257
+
258
+ ### 步骤
259
+
260
+ 1. **终端启动 inspect 服务**:
261
+
262
+ ```bash
263
+ bun run dev:inspect
264
+ ```
265
+
266
+ 会输出类似 `ws://localhost:8888/xxxxxxxx` 的地址。
267
+ 2. **VS Code 附着调试器**:
268
+
269
+ - 在 `src/` 文件中打断点
270
+ - F5 → 选择 **"Attach to Bun (TUI debug)"**
271
+
272
+ ## Teach Me 学习项目
273
+
274
+ 我们新加了一个 teach-me skills, 通过问答式引导帮你理解这个项目的任何模块。(调整 [sigma skill 而来](https://github.com/sanyuan0704/sanyuan-skills))
275
+
276
+ ```bash
277
+ # 在 REPL 中直接输入
278
+ /teach-me Claude Code 架构
279
+ /teach-me React Ink 终端渲染 --level beginner
280
+ /teach-me Tool 系统 --resume
281
+ ```
282
+
283
+ ### 它能做什么
284
+
285
+ - **诊断水平** — 自动评估你对相关概念的掌握程度,跳过已知的、聚焦薄弱的
286
+ - **构建学习路径** — 将主题拆解为 5-15 个原子概念,按依赖排序逐步推进
287
+ - **苏格拉底式提问** — 用选项引导思考,而非直接给答案
288
+ - **错误概念追踪** — 发现并纠正深层误解
289
+ - **断点续学** — `--resume` 从上次进度继续
290
+
291
+ ### 学习记录
292
+
293
+ 学习进度保存在 `.claude/skills/teach-me/` 目录下,支持跨主题学习者档案。
294
+
295
+ ## Contributors
296
+
297
+ <a href="https://github.com/claude-code/claude-code/graphs/contributors">
298
+ <img src="contributors.svg" alt="Contributors" />
299
+ </a>
300
+
301
+ ## Star History
302
+
303
+ <a href="https://www.star-history.com/?repos=claude-code%2Fclaude-code&type=date&legend=top-left">
304
+ <picture>
305
+ <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/image?repos=claude-code/claude-code&type=date&theme=dark&legend=top-left" />
306
+ <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/image?repos=claude-code/claude-code&type=date&legend=top-left" />
307
+ <img alt="Star History Chart" src="https://api.star-history.com/image?repos=claude-code/claude-code&type=date&legend=top-left" />
308
+ </picture>
309
+ </a>
310
+
311
+ ## 致谢
312
+
313
+ - [doubaoime-asr](https://github.com/starccy/doubaoime-asr) — 豆包 ASR 语音识别 SDK,为 Voice Mode 提供无需 Anthropic OAuth 的语音输入方案
314
+
315
+ ## 许可证
316
+
317
+ 本项目仅供学习研究用途。Claude Code 的所有权利归 [Anthropic](https://www.anthropic.com/) 所有。
package/bin/claude.exe CHANGED
Binary file
package/cli-wrapper.cjs CHANGED
@@ -1,42 +1,103 @@
1
1
  #!/usr/bin/env node
2
- const { spawnSync } = require('child_process')
3
- const { arch, constants } = require('os')
4
- const path = require('path')
2
+ // Fallback launcher for the claude wrapper package.
3
+ //
4
+ // Normally the postinstall script copies the native binary over bin/claude.exe,
5
+ // so this file is never invoked. It exists for environments where postinstall
6
+ // doesn't run (--ignore-scripts).
5
7
 
6
- const PACKAGE_PREFIX = '@go-hare/claude-code'
7
- const BINARY_NAME = 'claude'
8
+ const { spawnSync } = require("child_process");
9
+ const { arch, constants } = require("os");
10
+ const path = require("path");
11
+
12
+ const PACKAGE_PREFIX = "@go-hare/claude-code";
13
+ const BINARY_NAME = "claude";
14
+ const WRAPPER_NAME = require("./package.json").name;
8
15
 
9
16
  const PLATFORMS = {
10
- 'darwin-arm64': { pkg: PACKAGE_PREFIX + '-darwin-arm64', bin: BINARY_NAME },
11
- 'darwin-x64': { pkg: PACKAGE_PREFIX + '-darwin-x64', bin: BINARY_NAME },
12
- 'linux-x64': { pkg: PACKAGE_PREFIX + '-linux-x64', bin: BINARY_NAME },
13
- 'linux-arm64': { pkg: PACKAGE_PREFIX + '-linux-arm64', bin: BINARY_NAME },
14
- 'win32-x64': { pkg: PACKAGE_PREFIX + '-win32-x64', bin: BINARY_NAME + '.exe' },
15
- 'win32-arm64': { pkg: PACKAGE_PREFIX + '-win32-arm64', bin: BINARY_NAME + '.exe' },
16
- }
17
+ "darwin-arm64": { pkg: PACKAGE_PREFIX + "-darwin-arm64", bin: BINARY_NAME },
18
+ "darwin-x64": { pkg: PACKAGE_PREFIX + "-darwin-x64", bin: BINARY_NAME },
19
+ "linux-x64": { pkg: PACKAGE_PREFIX + "-linux-x64", bin: BINARY_NAME },
20
+ "linux-arm64": { pkg: PACKAGE_PREFIX + "-linux-arm64", bin: BINARY_NAME },
21
+ "linux-x64-musl": {
22
+ pkg: PACKAGE_PREFIX + "-linux-x64-musl",
23
+ bin: BINARY_NAME,
24
+ },
25
+ "linux-arm64-musl": {
26
+ pkg: PACKAGE_PREFIX + "-linux-arm64-musl",
27
+ bin: BINARY_NAME,
28
+ },
29
+ "win32-x64": {
30
+ pkg: PACKAGE_PREFIX + "-win32-x64",
31
+ bin: BINARY_NAME + ".exe",
32
+ },
33
+ "win32-arm64": {
34
+ pkg: PACKAGE_PREFIX + "-win32-arm64",
35
+ bin: BINARY_NAME + ".exe",
36
+ },
37
+ };
17
38
 
39
+ function detectMusl() {
40
+ if (process.platform !== "linux") return false;
41
+ const report =
42
+ typeof process.report?.getReport === "function"
43
+ ? process.report.getReport()
44
+ : null;
45
+ return report != null && report.header?.glibcVersionRuntime === undefined;
46
+ }
18
47
  function getPlatformKey() {
19
- const platform = process.platform
20
- let cpu = arch()
21
- if (platform === 'darwin' && cpu === 'x64') {
22
- const r = spawnSync('sysctl', ['-n', 'sysctl.proc_translated'], { encoding: 'utf8' })
23
- if (r.stdout?.trim() === '1') cpu = 'arm64'
48
+ const platform = process.platform;
49
+ let cpu = arch();
50
+ if (platform === "linux") return "linux-" + cpu + (detectMusl() ? "-musl" : "");
51
+ if (platform === "darwin" && cpu === "x64") {
52
+ const r = spawnSync("sysctl", ["-n", "sysctl.proc_translated"], {
53
+ encoding: "utf8",
54
+ });
55
+ if (r.stdout?.trim() === "1") cpu = "arm64";
24
56
  }
25
- return platform + '-' + cpu
57
+ return platform + "-" + cpu;
26
58
  }
27
59
 
28
- function main() {
29
- const platformKey = getPlatformKey()
30
- const info = PLATFORMS[platformKey]
31
- if (!info) { console.error('Unsupported platform: ' + platformKey); process.exit(1) }
32
- let binaryPath
60
+ function getBinaryPath() {
61
+ const platformKey = getPlatformKey();
62
+ const info = PLATFORMS[platformKey];
63
+ if (!info) {
64
+ console.error(
65
+ `[${WRAPPER_NAME}] Unsupported platform: ${process.platform} ${arch()}`,
66
+ );
67
+ process.exit(1);
68
+ }
33
69
  try {
34
- const pkgDir = path.dirname(require.resolve(info.pkg + '/package.json'))
35
- binaryPath = path.join(pkgDir, info.bin)
36
- } catch { console.error('Native package not found: ' + info.pkg); process.exit(1) }
37
- const result = spawnSync(binaryPath, process.argv.slice(2), { stdio: 'inherit' })
38
- if (result.signal) process.exit(128 + (constants.signals[result.signal] ?? 0))
39
- else process.exit(result.status ?? 1)
70
+ const pkgDir = path.dirname(require.resolve(info.pkg + "/package.json"));
71
+ return path.join(pkgDir, info.bin);
72
+ } catch {
73
+ console.error(
74
+ `[${WRAPPER_NAME}] Could not find native binary package "${info.pkg}".`,
75
+ );
76
+ console.error(" Try reinstalling with: npm install");
77
+ process.exit(1);
78
+ }
40
79
  }
41
80
 
42
- main()
81
+ function main() {
82
+ const binaryPath = getBinaryPath();
83
+ const result = spawnSync(binaryPath, process.argv.slice(2), {
84
+ stdio: "inherit",
85
+ env: { ...process.env, CLAUDE_CODE_INSTALLED_VIA_NPM_WRAPPER: "1" },
86
+ });
87
+ if (result.error) {
88
+ console.error(
89
+ `[${WRAPPER_NAME}] Failed to execute native binary at ` + binaryPath,
90
+ );
91
+ console.error(" " + result.error.message);
92
+ process.exit(1);
93
+ }
94
+ if (result.signal) {
95
+ const signum = constants.signals[result.signal] ?? 0;
96
+ process.exit(128 + signum);
97
+ } else {
98
+ process.exit(result.status ?? 1);
99
+ }
100
+ }
101
+
102
+ main();
103
+
package/install.cjs CHANGED
@@ -1,56 +1,187 @@
1
1
  #!/usr/bin/env node
2
- const { spawnSync } = require('child_process')
3
- const { copyFileSync, linkSync, unlinkSync, chmodSync, readFileSync, writeFileSync, statSync } = require('fs')
4
- const { arch } = require('os')
5
- const path = require('path')
2
+ // Postinstall for the claude wrapper package.
3
+ //
4
+ // In development (monorepo with .git), delegates to the dev postinstall scripts.
5
+ // In production (npm install from registry), copies the native binary from the
6
+ // platform-specific optionalDependency into bin/claude.exe.
7
+ //
8
+ // Platform detection + PLATFORMS map is duplicated in cli-wrapper.cjs — keep in sync.
6
9
 
7
- const PACKAGE_PREFIX = '@go-hare/claude-code'
8
- const BINARY_NAME = 'claude'
9
- const WRAPPER_NAME = require('./package.json').name
10
+ const { spawnSync } = require("child_process");
11
+ const {
12
+ copyFileSync,
13
+ existsSync,
14
+ linkSync,
15
+ unlinkSync,
16
+ chmodSync,
17
+ readFileSync,
18
+ writeFileSync,
19
+ statSync,
20
+ } = require("fs");
21
+ const { arch } = require("os");
22
+ const path = require("path");
23
+
24
+ // Dev environment detection: if .git exists at package root, we're in the monorepo
25
+ if (existsSync(path.join(__dirname, ".git"))) {
26
+ const r = spawnSync(
27
+ "node",
28
+ [
29
+ "scripts/run-parallel.mjs",
30
+ "scripts/postinstall.cjs",
31
+ "scripts/setup-chrome-mcp.mjs",
32
+ ],
33
+ { cwd: __dirname, stdio: "inherit" },
34
+ );
35
+ process.exit(r.status ?? 0);
36
+ }
37
+
38
+ const PACKAGE_PREFIX = "@go-hare/claude-code";
39
+ const BINARY_NAME = "claude";
40
+ const WRAPPER_NAME = require("./package.json").name;
10
41
 
11
42
  const PLATFORMS = {
12
- 'darwin-arm64': { pkg: PACKAGE_PREFIX + '-darwin-arm64', bin: BINARY_NAME },
13
- 'darwin-x64': { pkg: PACKAGE_PREFIX + '-darwin-x64', bin: BINARY_NAME },
14
- 'linux-x64': { pkg: PACKAGE_PREFIX + '-linux-x64', bin: BINARY_NAME },
15
- 'linux-arm64': { pkg: PACKAGE_PREFIX + '-linux-arm64', bin: BINARY_NAME },
16
- 'win32-x64': { pkg: PACKAGE_PREFIX + '-win32-x64', bin: BINARY_NAME + '.exe' },
17
- 'win32-arm64': { pkg: PACKAGE_PREFIX + '-win32-arm64', bin: BINARY_NAME + '.exe' },
43
+ "darwin-arm64": { pkg: PACKAGE_PREFIX + "-darwin-arm64", bin: BINARY_NAME },
44
+ "darwin-x64": { pkg: PACKAGE_PREFIX + "-darwin-x64", bin: BINARY_NAME },
45
+ "linux-x64": { pkg: PACKAGE_PREFIX + "-linux-x64", bin: BINARY_NAME },
46
+ "linux-arm64": { pkg: PACKAGE_PREFIX + "-linux-arm64", bin: BINARY_NAME },
47
+ "linux-x64-musl": {
48
+ pkg: PACKAGE_PREFIX + "-linux-x64-musl",
49
+ bin: BINARY_NAME,
50
+ },
51
+ "linux-arm64-musl": {
52
+ pkg: PACKAGE_PREFIX + "-linux-arm64-musl",
53
+ bin: BINARY_NAME,
54
+ },
55
+ "linux-arm64-android": {
56
+ pkg: PACKAGE_PREFIX + "-linux-arm64-android",
57
+ bin: BINARY_NAME,
58
+ },
59
+ "linux-x64-android": {
60
+ pkg: PACKAGE_PREFIX + "-linux-x64-android",
61
+ bin: BINARY_NAME,
62
+ },
63
+ "freebsd-x64": { pkg: PACKAGE_PREFIX + "-freebsd-x64", bin: BINARY_NAME },
64
+ "freebsd-arm64": {
65
+ pkg: PACKAGE_PREFIX + "-freebsd-arm64",
66
+ bin: BINARY_NAME,
67
+ },
68
+ "win32-x64": {
69
+ pkg: PACKAGE_PREFIX + "-win32-x64",
70
+ bin: BINARY_NAME + ".exe",
71
+ },
72
+ "win32-arm64": {
73
+ pkg: PACKAGE_PREFIX + "-win32-arm64",
74
+ bin: BINARY_NAME + ".exe",
75
+ },
76
+ };
77
+
78
+ function detectMusl() {
79
+ if (process.platform !== "linux") return false;
80
+ const report =
81
+ typeof process.report?.getReport === "function"
82
+ ? process.report.getReport()
83
+ : null;
84
+ return report != null && report.header?.glibcVersionRuntime === undefined;
18
85
  }
19
86
 
20
87
  function getPlatformKey() {
21
- const platform = process.platform
22
- let cpu = arch()
23
- if (platform === 'darwin' && cpu === 'x64') {
24
- const r = spawnSync('sysctl', ['-n', 'sysctl.proc_translated'], { encoding: 'utf8' })
25
- if (r.stdout?.trim() === '1') cpu = 'arm64'
88
+ const platform = process.platform;
89
+ let cpu = arch();
90
+ if (platform === "android") return "linux-" + cpu + "-android";
91
+ if (platform === "linux") return "linux-" + cpu + (detectMusl() ? "-musl" : "");
92
+ if (platform === "darwin" && cpu === "x64") {
93
+ const r = spawnSync("sysctl", ["-n", "sysctl.proc_translated"], {
94
+ encoding: "utf8",
95
+ });
96
+ if (r.stdout?.trim() === "1") cpu = "arm64";
26
97
  }
27
- return platform + '-' + cpu
98
+ return platform + "-" + cpu;
28
99
  }
29
100
 
101
+ function placeBinary(src, dest) {
102
+ try {
103
+ linkSync(src, dest);
104
+ } catch (err) {
105
+ if (err.code === "EEXIST") {
106
+ const stub = statSync(dest).size < 4096 ? readFileSync(dest) : null;
107
+ unlinkSync(dest);
108
+ try {
109
+ linkSync(src, dest);
110
+ } catch {
111
+ try {
112
+ copyFileSync(src, dest);
113
+ } catch (copyErr) {
114
+ if (stub) {
115
+ try { writeFileSync(dest, stub, { mode: 0o755 }); } catch {}
116
+ }
117
+ throw copyErr;
118
+ }
119
+ }
120
+ } else if (err.code === "EXDEV" || err.code === "EPERM") {
121
+ copyFileSync(src, dest);
122
+ } else {
123
+ throw err;
124
+ }
125
+ }
126
+ if (process.platform !== "win32") chmodSync(dest, 0o755);
127
+ }
30
128
  function main() {
31
- const platformKey = getPlatformKey()
32
- const info = PLATFORMS[platformKey]
129
+ const platformKey = getPlatformKey();
130
+ const info = PLATFORMS[platformKey];
131
+
33
132
  if (!info) {
34
- console.error(`[${WRAPPER_NAME} postinstall] Unsupported platform: ${process.platform} ${arch()}`)
35
- return
133
+ console.error(
134
+ `[${WRAPPER_NAME} postinstall] Unsupported platform: ${process.platform} ${arch()}`,
135
+ );
136
+ console.error(` Supported: ${Object.keys(PLATFORMS).join(", ")}`);
137
+ return;
138
+ }
139
+
140
+ const optionalDeps = require("./package.json").optionalDependencies || {};
141
+ if (!optionalDeps[info.pkg]) {
142
+ console.error(
143
+ `[${WRAPPER_NAME} postinstall] Native binaries for ${platformKey} are not available on this release channel.`,
144
+ );
145
+ console.error(
146
+ ` Available: ${Object.keys(optionalDeps).map((p) => p.replace(PACKAGE_PREFIX + "-", "")).join(", ")}`,
147
+ );
148
+ return;
36
149
  }
37
- let src
150
+
151
+ let src;
38
152
  try {
39
- const pkgDir = path.dirname(require.resolve(info.pkg + '/package.json'))
40
- src = path.join(pkgDir, info.bin)
153
+ const pkgDir = path.dirname(require.resolve(info.pkg + "/package.json"));
154
+ src = path.join(pkgDir, info.bin);
41
155
  } catch {
42
- console.error(`[${WRAPPER_NAME} postinstall] Native package "${info.pkg}" not found.`)
43
- console.error(' This happens with --omit=optional. Fallback: node cli-wrapper.cjs')
44
- return
156
+ console.error(
157
+ `[${WRAPPER_NAME} postinstall] Native package "${info.pkg}" not found.`,
158
+ );
159
+ console.error(
160
+ " This happens with --omit=optional or when the download failed.",
161
+ );
162
+ console.error(
163
+ " The `claude` command will print instructions when invoked.",
164
+ );
165
+ console.error(
166
+ " Fallback: node " + path.join(__dirname, "cli-wrapper.cjs"),
167
+ );
168
+ return;
45
169
  }
46
- const dest = path.join(__dirname, 'bin', 'claude.exe')
170
+
171
+ const dest = path.join(__dirname, "bin", "claude.exe");
172
+
47
173
  try {
48
- try { unlinkSync(dest) } catch {}
49
- try { linkSync(src, dest) } catch { copyFileSync(src, dest) }
50
- if (process.platform !== 'win32') chmodSync(dest, 0o755)
174
+ placeBinary(src, dest);
51
175
  } catch (err) {
52
- console.error(`[${WRAPPER_NAME} postinstall] Failed: ${err.message}`)
176
+ console.error(
177
+ `[${WRAPPER_NAME} postinstall] Failed to place binary: ${err.message}`,
178
+ );
179
+ console.error(
180
+ " Fallback: node " + path.join(__dirname, "cli-wrapper.cjs"),
181
+ );
182
+ process.exitCode = 1;
53
183
  }
54
184
  }
55
185
 
56
- main()
186
+ main();
187
+
package/package.json CHANGED
@@ -1,29 +1,240 @@
1
1
  {
2
2
  "name": "@go-hare/claude-code",
3
- "version": "2.6.7",
4
- "description": "Reverse-engineered Anthropic Claude Code CLI — interactive AI coding assistant",
3
+ "version": "2.6.9",
4
+ "description": "Reverse-engineered Anthropic Claude Code CLI — interactive AI coding assistant in the terminal",
5
5
  "type": "module",
6
6
  "author": "DeQiang",
7
- "license": "MIT",
8
- "bin": {
9
- "claude": "bin/claude.exe"
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/go-hare/claude-code-1.git"
10
10
  },
11
- "scripts": {
12
- "postinstall": "node install.cjs"
11
+ "homepage": "https://github.com/go-hare/claude-code-1#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/go-hare/claude-code-1/issues"
13
14
  },
15
+ "keywords": [
16
+ "claude",
17
+ "anthropic",
18
+ "cli",
19
+ "ai",
20
+ "coding-assistant",
21
+ "terminal",
22
+ "repl"
23
+ ],
14
24
  "engines": {
15
25
  "node": ">=18.0.0"
16
26
  },
17
- "homepage": "https://github.com/go-hare/claude-code-1",
18
- "bugs": {
19
- "url": "https://github.com/go-hare/claude-code-1/issues"
20
- },
21
- "optionalDependencies": {
22
- "@go-hare/claude-code-darwin-arm64": "2.6.7"
27
+ "bin": {
28
+ "claude": "bin/claude.exe"
23
29
  },
30
+ "workspaces": [
31
+ "packages/*",
32
+ "packages/@ant/*",
33
+ "packages/@anthropic-ai/*",
34
+ "packages/@go-hare/*"
35
+ ],
24
36
  "files": [
25
37
  "bin/claude.exe",
26
38
  "install.cjs",
27
39
  "cli-wrapper.cjs"
28
- ]
40
+ ],
41
+ "optionalDependencies": {
42
+ "@go-hare/claude-code-darwin-arm64": "2.6.9",
43
+ "@go-hare/claude-code-darwin-x64": "2.6.9",
44
+ "@go-hare/claude-code-linux-x64": "2.6.9",
45
+ "@go-hare/claude-code-linux-arm64": "2.6.9",
46
+ "@go-hare/claude-code-linux-x64-musl": "2.6.9",
47
+ "@go-hare/claude-code-linux-arm64-musl": "2.6.9",
48
+ "@go-hare/claude-code-win32-x64": "2.6.9",
49
+ "@go-hare/claude-code-win32-arm64": "2.6.9",
50
+ "doubaoime-asr": "^0.1.0"
51
+ },
52
+ "scripts": {
53
+ "build": "bun run build.ts",
54
+ "build:vite": "vite build && bun run scripts/post-build.ts",
55
+ "build:vite:only": "vite build",
56
+ "build:bun": "bun run build.ts",
57
+ "build:compile": "bun run scripts/publish.ts --build-only",
58
+ "dev": "bun run scripts/dev.ts",
59
+ "dev:inspect": "bun run scripts/dev-debug.ts",
60
+ "prepublishOnly": "echo 'Use: bun run scripts/publish.ts'",
61
+ "lint": "biome lint .",
62
+ "lint:fix": "biome lint --fix .",
63
+ "format": "biome format --write .",
64
+ "check": "biome check .",
65
+ "check:fix": "biome check --fix .",
66
+ "prepare": "husky",
67
+ "test": "bun test",
68
+ "test:production": "bun run scripts/production-test.ts",
69
+ "test:production:offline": "bun run scripts/production-test.ts --offline",
70
+ "test:production:verbose": "bun run scripts/production-test.ts --verbose",
71
+ "test:production:bun": "bun run scripts/production-test.ts --bun",
72
+ "check:bundle": "bun run scripts/check-bundle-integrity.ts",
73
+ "check:unused": "knip-bun",
74
+ "health": "bun run scripts/health-check.ts",
75
+ "postinstall": "node install.cjs",
76
+ "docs:dev": "npx mintlify dev",
77
+ "typecheck": "tsc --noEmit",
78
+ "precheck": "bun run typecheck && bun run check:fix && bun test",
79
+ "rcs": "bun run scripts/rcs.ts"
80
+ },
81
+ "dependencies": {
82
+ "@agentclientprotocol/sdk": "^0.19.0",
83
+ "@claude-code-best/mcp-chrome-bridge": "^3.0.1",
84
+ "highlight.js": "^11.11.1",
85
+ "ws": "^8.20.0"
86
+ },
87
+ "devDependencies": {
88
+ "@alcalzone/ansi-tokenize": "^0.3.0",
89
+ "@ant/claude-for-chrome-mcp": "workspace:*",
90
+ "@ant/computer-use-input": "workspace:*",
91
+ "@ant/computer-use-mcp": "workspace:*",
92
+ "@ant/computer-use-swift": "workspace:*",
93
+ "@ant/model-provider": "workspace:*",
94
+ "@anthropic-ai/bedrock-sdk": "^0.29.0",
95
+ "@anthropic-ai/claude-agent-sdk": "^0.2.114",
96
+ "@anthropic-ai/foundry-sdk": "^0.2.3",
97
+ "@anthropic-ai/mcpb": "^2.1.2",
98
+ "@anthropic-ai/sandbox-runtime": "^0.0.44",
99
+ "@anthropic-ai/sdk": "^0.81.0",
100
+ "@anthropic-ai/vertex-sdk": "^0.16.0",
101
+ "@anthropic/ink": "workspace:*",
102
+ "@aws-sdk/client-bedrock": "^3.1037.0",
103
+ "@aws-sdk/client-bedrock-runtime": "^3.1037.0",
104
+ "@aws-sdk/client-sts": "^3.1037.0",
105
+ "@aws-sdk/credential-provider-node": "^3.972.36",
106
+ "@aws-sdk/credential-providers": "^3.1037.0",
107
+ "@azure/identity": "^4.13.1",
108
+ "@biomejs/biome": "^2.4.12",
109
+ "@claude-code/agent-tools": "workspace:*",
110
+ "@claude-code/builtin-tools": "workspace:*",
111
+ "@claude-code/mcp-client": "workspace:*",
112
+ "@claude-code/weixin": "workspace:*",
113
+ "@commander-js/extra-typings": "^14.0.0",
114
+ "@growthbook/growthbook": "^1.6.5",
115
+ "@langfuse/otel": "^5.1.0",
116
+ "@langfuse/tracing": "^5.1.0",
117
+ "@modelcontextprotocol/sdk": "^1.29.0",
118
+ "@opentelemetry/api": "^1.9.1",
119
+ "@opentelemetry/api-logs": "^0.215.0",
120
+ "@opentelemetry/core": "^2.7.0",
121
+ "@opentelemetry/exporter-logs-otlp-grpc": "^0.215.0",
122
+ "@opentelemetry/exporter-logs-otlp-http": "^0.215.0",
123
+ "@opentelemetry/exporter-logs-otlp-proto": "^0.215.0",
124
+ "@opentelemetry/exporter-metrics-otlp-grpc": "^0.215.0",
125
+ "@opentelemetry/exporter-metrics-otlp-http": "^0.215.0",
126
+ "@opentelemetry/exporter-metrics-otlp-proto": "^0.215.0",
127
+ "@opentelemetry/exporter-prometheus": "^0.215.0",
128
+ "@opentelemetry/exporter-trace-otlp-grpc": "^0.215.0",
129
+ "@opentelemetry/exporter-trace-otlp-http": "^0.215.0",
130
+ "@opentelemetry/exporter-trace-otlp-proto": "^0.215.0",
131
+ "@opentelemetry/resources": "^2.7.0",
132
+ "@opentelemetry/sdk-logs": "^0.215.0",
133
+ "@opentelemetry/sdk-metrics": "^2.7.0",
134
+ "@opentelemetry/sdk-trace-base": "^2.7.0",
135
+ "@opentelemetry/semantic-conventions": "^1.40.0",
136
+ "@sentry/node": "^10.49.0",
137
+ "@smithy/core": "^3.23.15",
138
+ "@smithy/node-http-handler": "^4.5.3",
139
+ "@types/bun": "^1.3.12",
140
+ "@types/cacache": "^20.0.1",
141
+ "@types/he": "^1.2.3",
142
+ "@types/lodash-es": "^4.17.12",
143
+ "@types/node": "^25.6.0",
144
+ "@types/picomatch": "^4.0.3",
145
+ "@types/plist": "^3.0.5",
146
+ "@types/proper-lockfile": "^4.1.4",
147
+ "@types/qrcode": "^1.5.6",
148
+ "@types/react": "^19.2.14",
149
+ "@types/react-reconciler": "^0.33.0",
150
+ "@types/semver": "^7.7.1",
151
+ "@types/sharp": "^0.32.0",
152
+ "@types/shell-quote": "^1.7.5",
153
+ "@types/stack-utils": "^2.0.3",
154
+ "@types/turndown": "^5.0.6",
155
+ "@types/ws": "^8.18.1",
156
+ "ajv": "^8.18.0",
157
+ "asciichart": "^1.5.25",
158
+ "audio-capture-napi": "workspace:*",
159
+ "auto-bind": "^5.0.1",
160
+ "axios": "^1.15.2",
161
+ "bidi-js": "^1.0.3",
162
+ "cacache": "^20.0.4",
163
+ "chalk": "^5.6.2",
164
+ "chokidar": "^5.0.0",
165
+ "cli-boxes": "^4.0.1",
166
+ "cli-highlight": "^2.1.11",
167
+ "code-excerpt": "^4.0.0",
168
+ "color-diff-napi": "workspace:*",
169
+ "diff": "^8.0.4",
170
+ "emoji-regex": "^10.6.0",
171
+ "env-paths": "^4.0.0",
172
+ "execa": "^9.6.1",
173
+ "fflate": "^0.8.2",
174
+ "figures": "^6.1.0",
175
+ "fuse.js": "^7.3.0",
176
+ "get-east-asian-width": "^1.5.0",
177
+ "google-auth-library": "^10.6.2",
178
+ "he": "^1.2.0",
179
+ "https-proxy-agent": "^8.0.0",
180
+ "husky": "^9.1.7",
181
+ "ignore": "^7.0.5",
182
+ "image-processor-napi": "workspace:*",
183
+ "indent-string": "^5.0.0",
184
+ "jsonc-parser": "^3.3.1",
185
+ "knip": "^6.4.1",
186
+ "lint-staged": "^16.4.0",
187
+ "lodash-es": "^4.18.1",
188
+ "lru-cache": "^11.3.5",
189
+ "marked": "^17.0.6",
190
+ "modifiers-napi": "workspace:*",
191
+ "openai": "^6.34.0",
192
+ "p-map": "^7.0.4",
193
+ "picomatch": "^4.0.4",
194
+ "plist": "^3.1.0",
195
+ "proper-lockfile": "^4.1.2",
196
+ "qrcode": "^1.5.4",
197
+ "react": "^19.2.5",
198
+ "react-compiler-runtime": "^1.0.0",
199
+ "react-reconciler": "^0.33.0",
200
+ "rollup": "^4.60.2",
201
+ "semver": "^7.7.4",
202
+ "sharp": "^0.34.5",
203
+ "shell-quote": "^1.8.3",
204
+ "signal-exit": "^4.1.0",
205
+ "stack-utils": "^2.0.6",
206
+ "strip-ansi": "^7.2.0",
207
+ "supports-hyperlinks": "^4.4.0",
208
+ "tree-kill": "^1.2.2",
209
+ "turndown": "^7.2.4",
210
+ "type-fest": "^5.6.0",
211
+ "typescript": "^6.0.3",
212
+ "undici": "^7.25.0",
213
+ "url-handler-napi": "workspace:*",
214
+ "usehooks-ts": "^3.1.1",
215
+ "vite": "^8.0.8",
216
+ "vscode-jsonrpc": "^8.2.1",
217
+ "vscode-languageserver-protocol": "^3.17.5",
218
+ "vscode-languageserver-types": "^3.17.5",
219
+ "wrap-ansi": "^10.0.0",
220
+ "xss": "^1.0.15",
221
+ "yaml": "^2.8.3",
222
+ "zod": "^4.3.6"
223
+ },
224
+ "overrides": {
225
+ "@inquirer/prompts": "8.4.2",
226
+ "@xmldom/xmldom": "0.8.13",
227
+ "follow-redirects": "1.16.0",
228
+ "hono": "4.12.15",
229
+ "postcss": "8.5.10",
230
+ "uuid": "14.0.0"
231
+ },
232
+ "lint-staged": {
233
+ "*.{ts,tsx,js,mjs,jsx}": [
234
+ "biome check --fix --no-errors-on-unmatched"
235
+ ],
236
+ "*.{json,jsonc}": [
237
+ "biome format --write --no-errors-on-unmatched"
238
+ ]
239
+ }
29
240
  }