# claude-code-web **Repository Path**: uthelei/claude-code-web ## Basic Information - **Project Name**: claude-code-web - **Description**: claude-code, 告别cli,带web前端,体验感爆表 - **Primary Language**: TypeScript - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2026-04-16 - **Last Updated**: 2026-04-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Claude Code Web 基于 Claude Code 泄露源码修复的**本地可运行版本**,支持接入任意 Anthropic 兼容 API(如 MiniMax,qianwen等)。 > 原始泄露源码无法直接运行。本仓库修复了启动链路中的多个阻塞问题,使完整的 Ink TUI 交互界面可以在本地工作。 > 并添加web gui前端交互方式,类似deepseek网页版交互,用户体验感更好,告别CMD。

运行截图

## 功能 - 完整的Web交互界面(自研),方便用户使用 - 完整的 Ink TUI 交互界面(与官方 Claude Code 一致) - `--print` 无头模式(脚本/CI 场景) - 支持 MCP 服务器、插件、Skills - 支持自定义 API 端点和模型 - 降级 Recovery CLI 模式 --- ## 架构概览 浏览器 ↔ WebSocket,子进程 ↔ 标准输入/输出(stdio)。主程序(bin/claude-haha)只认 stdin 上的 stream-json 行,不认 WS。 1. 整体数据流 浏览器 --WebSocket--> Bun server --stdin 管道--> claude-haha 子进程 <--WebSocket-- <--stdout 管道-- 下行(你发消息):WS 收到 JSON → server.ts 拼成一行 NDJSON → proc.stdin.write(line + '\n')。 上行(模型/事件):子进程往 stdout 打 NDJSON → server 按行 JSON.parse → send(ws, { type: 'event', event })。 也就是说:和主程序交互的是子进程的 stdin,不是 WebSocket。 2. server.ts 里具体在哪儿接 WS、在哪儿写给主程序 把浏览器消息写进子进程 stdin(用户输入、权限回复、取消等): ``` switch (msg.type) { case 'user': { try { const line = JSON.stringify({ type: 'user', session_id: '', message: { role: 'user', content: msg.content }, parent_tool_use_id: null, }); if (proc.stdin && typeof proc.stdin !== 'number') proc.stdin.write(line + '\n'); } catch { // ignore } break; } case 'control_response': { try { const response = msg.allow ? { behavior: 'allow', updatedInput: {} } : { behavior: 'deny', message: 'Rejected by user', interrupt: true }; const line = JSON.stringify({ type: 'control_response', response: { request_id: msg.requestId, subtype: 'success', response, }, }); if (proc.stdin && typeof proc.stdin !== 'number') proc.stdin.write(line + '\n'); break; } } ``` 子进程 stdout → 再转成 WS 发给浏览器: ``` function flushStdoutLines(ws: any, session: Session) { for (;;) { const idx = session.stdoutBuffer.indexOf('\n'); if (idx === -1) break; const line = session.stdoutBuffer.slice(0, idx).trimEnd(); session.stdoutBuffer = session.stdoutBuffer.slice(idx + 1); if (!line) continue; try { const event = JSON.parse(line); send(ws, { type: 'event', event }); ``` 3. 主程序「在哪儿接收」这些消息? 主程序是 --input-format=stream-json 启动的 CLI。入口里在非 TTY 且为 stream-json 时,输入源就是 process.stdin(即上面管道接到的那一端): ``` async function getInputPrompt(prompt: string, inputFormat: 'text' | 'stream-json'): Promise> { if (!process.stdin.isTTY && // Input hijacking breaks MCP. !process.argv.includes('mcp')) { if (inputFormat === 'stream-json') { return process.stdin; ``` 后面 StructuredIO 会按行读这个流,解析成 user / control_response 等(与 server.ts 写入的 JSON 格式对应)。没有任何「在主程序里监听 WebSocket」的逻辑;WS 只存在于 web/server.ts 的 Bun serve 里。 4. 总结 层级 作用 Bun web/server.ts WebSocket ↔ 浏览器;把 WS 消息转成 stdin 行 喂给子进程;把子进程 stdout 行 转回 WS。 claude-haha 子进程 只从 process.stdin 读 stream-json,往 stdout 写 stream-json(print.ts / structuredIO 等)。 --- ## 快速开始 ### 1. 安装依赖 需要 [Bun](https://bun.sh) >= 1.1 和 Node.js >= 18。 ```bash npm install ``` ### 2. 配置环境变量 复制示例文件并填入你的 API Key: ```bash cp .env.example .env ``` 编辑 `.env`: ```env # API 认证(二选一) ANTHROPIC_API_KEY=sk-xxx # 标准 API Key(x-api-key 头) ANTHROPIC_AUTH_TOKEN=sk-xxx # Bearer Token(Authorization 头) # API 端点(可选,默认 Anthropic 官方) ANTHROPIC_BASE_URL=https://api.minimaxi.com/anthropic # 模型配置 ANTHROPIC_MODEL=MiniMax-M2.7-highspeed ANTHROPIC_DEFAULT_SONNET_MODEL=MiniMax-M2.7-highspeed ANTHROPIC_DEFAULT_HAIKU_MODEL=MiniMax-M2.7-highspeed ANTHROPIC_DEFAULT_OPUS_MODEL=MiniMax-M2.7-highspeed # 超时(毫秒) API_TIMEOUT_MS=3000000 # 禁用遥测和非必要网络请求 DISABLE_TELEMETRY=1 CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 ``` ### 3. 启动 ```bash # Web模式(完整界面) windows ./bin/claude-haha-web.cmd 并在浏览器请求 http://127.0.0.1:8787/ # 交互 TUI 模式(完整界面) windows ./bin/claude-haha-cmd linux ./bin/claude-haha # 无头模式(单次问答) ./bin/claude-haha -p "your prompt here" # 管道输入 echo "explain this code" | ./bin/claude-haha -p # 查看所有选项 ./bin/claude-haha --help ``` --- ## 环境变量说明 | 变量 | 必填 | 说明 | |------|------|------| | `ANTHROPIC_API_KEY` | 二选一 | API Key,通过 `x-api-key` 头发送 | | `ANTHROPIC_AUTH_TOKEN` | 二选一 | Auth Token,通过 `Authorization: Bearer` 头发送 | | `ANTHROPIC_BASE_URL` | 否 | 自定义 API 端点,默认 Anthropic 官方 | | `ANTHROPIC_MODEL` | 否 | 默认模型 | | `ANTHROPIC_DEFAULT_SONNET_MODEL` | 否 | Sonnet 级别模型映射 | | `ANTHROPIC_DEFAULT_HAIKU_MODEL` | 否 | Haiku 级别模型映射 | | `ANTHROPIC_DEFAULT_OPUS_MODEL` | 否 | Opus 级别模型映射 | | `API_TIMEOUT_MS` | 否 | API 请求超时,默认 600000 (10min) | | `DISABLE_TELEMETRY` | 否 | 设为 `1` 禁用遥测 | | `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` | 否 | 设为 `1` 禁用非必要网络请求 | --- ## 降级模式 如果完整 TUI 出现问题,可以使用简化版 readline 交互模式: ```bash CLAUDE_CODE_FORCE_RECOVERY_CLI=1 ./bin/claude-haha ``` --- ## 相对于原始泄露源码的修复 泄露的源码无法直接运行,主要修复了以下问题: | 问题 | 根因 | 修复 | |------|------|------| | TUI 不启动 | 入口脚本把无参数启动路由到了 recovery CLI | 恢复走 `cli.tsx` 完整入口 | | 启动卡死 | `verify` skill 导入缺失的 `.md` 文件,Bun text loader 无限挂起 | 创建 stub `.md` 文件 | | `--print` 卡死 | `filePersistence/types.ts` 缺失 | 创建类型桩文件 | | `--print` 卡死 | `ultraplan/prompt.txt` 缺失 | 创建资源桩文件 | | **Enter 键无响应** | `modifiers-napi` native 包缺失,`isModifierPressed()` 抛异常导致 `handleEnter` 中断,`onSubmit` 永远不执行 | 加 try-catch 容错 | | setup 被跳过 | `preload.ts` 自动设置 `LOCAL_RECOVERY=1` 跳过全部初始化 | 移除默认设置 | --- ## 项目结构 ``` claude-code-web/ ├── .git/ ├── bin/ # 可执行入口脚本 ├── docs/ # 文档与配图 ├── node_modules/ # 依赖(略) ├── src/ # 主源码 ├── stubs/ # 类型/构建桩 ├── .env / .env.example ├── package.json ├── bun.lock / bunfig.toml ├── tsconfig.json ├── preload.ts ├── README.md └── … ``` src/ ``` src/ ├── main.tsx ├── QueryEngine.ts ├── commands.ts / tools.ts / … ├── assistant/ ├── bootstrap/ ├── bridge/ ├── buddy/ ├── cli/ ├── commands/ # 大量子命令(子目录很多) ├── components/ ├── entrypoints/ # web.ts / cli.tsx / mcp.ts / sdk/ … ├── services/ ├── utils/ ├── web/ # 本地 Web UI(见下) └── … # 其它业务目录(体量很大) ``` src/web/(当前 Web 相关,完整展开) ``` src/web/ ├── protocol.ts ├── server.ts ├── sessionList.ts ├── transcript.ts └── ui/ ├── app.js ├── index.html ├── styles.css ├── marked.min.js └── xss.min.js ``` src/entrypoints/ ``` entrypoints/ ├── web.ts ├── cli.tsx ├── mcp.ts ├── init.ts ├── agentSdkTypes.ts ├── sandboxTypes.ts └── sdk/ # 各类 generated / 类型定义 ``` --- ## 技术栈 | 类别 | 技术 | |------|----------------------------------------------------| | 运行时 | [Bun](https://bun.sh) | | 语言 | TypeScript/Html/Js | | 终端 UI | React + [Ink](https://github.com/vadimdemedes/ink) | | CLI 解析 | Commander.js | | API | Anthropic SDK | | 协议 | MCP, LSP | --- ## Disclaimer 本仓库基于 2026-03-31 从 Anthropic npm registry 泄露的 Claude Code 源码。所有原始源码版权归 [Anthropic](https://www.anthropic.com) 所有。仅供学习和研究用途。