Files
cc-web/README.md
2026-06-12 16:39:44 +08:00

323 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# CC-Web
Claude Code / Codex 轻量级 Web 远程工具 — 在浏览器中与本机 CLI Agent 交互。
![Node.js](https://img.shields.io/badge/Node.js-22+-339933?logo=node.js&logoColor=white)
![License](https://img.shields.io/badge/License-MIT-blue)
[English README](./README.en.md) | [更新日志](./CHANGELOG.md)
Vibe产物readme比较絮叨建议直接丢给CC拷打一番就好。
## 一键部署claude
```
https://github.com/ZgDaniel/cc-web 给我装!
```
<p align="center">
<img src="https://github.com/user-attachments/assets/747bca02-8861-446a-98fc-5f7417ceec4d" alt="截图1" width="20%" />
<img src="https://github.com/user-attachments/assets/556ec006-aff2-4a7f-b826-5c98a2f33467" alt="截图2" width="20%" />
<img src="https://github.com/user-attachments/assets/a9124f2c-b769-41c0-97f3-d69a6b1b9f80" alt="截图3" width="20%" />
<img src="https://github.com/user-attachments/assets/0c4da44c-a426-483a-8cb0-9cc483fd5ecc" alt="截图4" width="20%" />
</p>
## 功能特性
- **超轻量** — 后端性能占用少,前端通过 web 访问
- **双 Agent 会话** — 新建会话时可选择 Claude 或 Codex沿用相同的 Web 会话与后台任务模型
- **工作目录更顺手** — 新会话弹窗会显示默认目录、最近目录快捷项,也能直接弹出目录选择器
- **Agent 视图隔离** — 侧边栏切换 Claude / Codex 后,仅展示当前 Agent 的会话与最近记录,互不干扰
- **独立 Agent 设置** — Claude 与 Codex 拥有各自的设置入口与默认行为,保持贴近各自原生 CLI 的使用方式
- **多会话管理** — 创建、切换、重命名、删除会话,删除时同步清除本地 Claude 历史记录
- **会话续接** — 基于 `--resume` 实现跨消息上下文保持,也可通过 SSH 使用 `tmux attach -t claude` 命令加入会话
- **本地历史导入** — Claude 可导入 `~/.claude/projects/` 会话Codex 可导入 `~/.codex/sessions/` rollout 历史
- **后台任务** — 关闭浏览器后 Claude 进程继续运行,完成后推送通知
- **多渠道通知** — 支持 PushPlus / Telegram / Server酱 / 飞书机器人 / QQQmsgWeb UI 内可视化配置
- **进程持久化** — detached 进程 + PID 文件,服务重启不丢失运行中的任务
- **多 API 切换** — 可配置多个 API 方案UI 中一键切换,即时生效
- **密码认证** — 自动生成初始密码、首次登录强制改密、Web UI 修改密码
- **隔离式回归脚本** — `npm run regression` 在临时目录中使用 mock Claude / Codex CLI 校验主路径,不污染真实数据
## 前提条件
- **Node.js** >= 18
- **Claude Code CLI** 或 **Codex CLI** 已安装并配置
```bash
npm install -g @anthropic-ai/claude-code
npm install -g @openai/codex
```
## 快速开始
### Linux / macOS
```bash
git clone https://github.com/ZgDaniel/cc-web.git
cd cc-web
./start.sh
```
`start.sh` 会检查 Node.js/npm 环境,自动创建 `.env`(如不存在),引导输入初始登录密码,自动安装 PM2如未安装安装项目依赖并以 `ccweb` 为默认应用名启动或重启服务。
如只想前台临时运行,也可以手动执行:
```bash
npm install
npm start
```
### Windows
```cmd
git clone https://github.com/ZgDaniel/cc-web.git
cd cc-web
npm install
copy .env.example .env & REM 可选
```
然后双击 `start.bat`,或在终端运行 `node server.js`。
---
启动后访问 `http://localhost:8002`,输入密码即可使用。
## 配置
### 环境变量 (.env)
| 变量 | 必填 | 默认值 | 说明 |
|------|:---:|--------|------|
| `CC_WEB_PASSWORD` | 否 | 自动生成 | Web 登录密码(首次启动自动迁移到 `config/auth.json` |
| `PORT` | 否 | `8002` | 服务监听端口 |
| `CLAUDE_PATH` | 否 | `claude` | Claude CLI 可执行文件路径 |
| `CODEX_PATH` | 否 | `codex` | Codex CLI 可执行文件路径 |
| `CC_WEB_CONFIG_DIR` | 否 | `./config` | 配置目录覆写(主要供隔离测试使用) |
| `CC_WEB_SESSIONS_DIR` | 否 | `./sessions` | 会话目录覆写(主要供隔离测试使用) |
| `CC_WEB_LOGS_DIR` | 否 | `./logs` | 日志目录覆写(主要供隔离测试使用) |
| `PUSHPLUS_TOKEN` | 否 | - | PushPlus Token首次启动自动迁移到通知配置 |
### 通知配置
点击侧边栏底部的 **⚙ 设置按钮**,在 Web UI 中可视化配置推送通知:
| 通知方式 | 所需配置 | 获取方式 |
|---------|---------|---------|
| **PushPlus**(微信推送) | Token | [pushplus.plus](https://www.pushplus.plus/) 注册获取 |
| **Telegram** | Bot Token + Chat ID | [@BotFather](https://t.me/BotFather) 创建机器人 |
| **Server酱** | SendKey | [sct.ftqq.com](https://sct.ftqq.com/) 注册获取 |
| **飞书机器人** | Webhook URL | 飞书群 → 设置 → 群机器人 → 添加自定义机器人 |
| **QQQmsg** | Qmsg Key | [qmsg.zendee.cn](https://qmsg.zendee.cn/) 登录后获取,需添加接收 QQ 号 |
配置保存在 `config/notify.json`Token 在 UI 中脱敏显示仅显示前4后4位
### 密码管理
密码存储在 `config/auth.json`,支持自动生成与 Web UI 修改:
- **首次启动**(无 `.env` 密码、无 `auth.json`):自动生成 12 位随机密码,打印到控制台,首次登录强制修改
- **从 `.env` 迁移**:如已在 `.env` 设置 `CC_WEB_PASSWORD`,启动时自动迁移到 `auth.json`,无需改密
- **Web UI 修改**:设置面板 → 修改密码(需输入当前密码)
- **密码要求**:≥ 8 位,包含大写/小写/数字/特殊字符中的至少 2 种
- **改密后**:所有已登录会话失效,需重新认证
## 项目结构
```
cc-web/
├── server.js # Node.js 后端HTTP + WebSocket + 进程管理 + 通知)
├── lib/
│ ├── agent-runtime.js # Claude / Codex 运行时适配层
│ └── codex-rollouts.js # Codex rollout 历史解析
├── public/
│ ├── index.html # 页面结构
│ ├── app.js # 前端逻辑WebSocket 通信、UI 交互)
│ ├── style.css # 样式(和风暖色调主题)
│ └── sw.js # Service Worker移动端推送通知
├── config/
│ ├── codex.json # Codex 独立配置(运行时生成)
│ ├── notify.json # 通知渠道配置(运行时生成)
│ └── auth.json # 密码配置(运行时生成)
├── sessions/ # 对话历史 JSON 文件(运行时生成)
├── logs/ # 进程生命周期日志(运行时生成)
├── scripts/
│ ├── regression.js # 隔离式回归脚本
│ ├── mock-claude.js # 回归用 mock Claude CLI
│ └── mock-codex.js # 回归用 mock Codex CLI
├── .env.example # 环境变量模板
├── start.sh # Linux / macOS PM2 一键启动脚本
├── start.bat # Windows 一键启动脚本
├── .gitignore
├── package.json
└── README.md
```
## 架构设计
### 进程模型
```
浏览器 ←WebSocket→ Node.js (server.js) ←文件I/O→ Claude / Codex CLI (detached)
```
- 每条用户消息会根据当前会话 Agentspawn Claude 或 Codex 子进程
- 进程使用 `detached: true` + `proc.unref()`,独立于 Node.js 生命周期
- stdin/stdout/stderr 通过文件传递(`sessions/{id}-run/`),不使用 pipe
- PID 持久化到文件,服务重启后自动恢复(`recoverProcesses()`
- 使用 `FileTailer` 实时监听输出文件变化,流式推送给前端
- Claude / Codex 的 spawn spec 与事件解析分别由 `lib/agent-runtime.js` 管理
### 后台任务流程
1. 用户发送消息 → spawn Claude 进程
2. 用户关闭浏览器 → 进程继续运行detached
3. 进程完成 → PID 监控检测到退出
4. 发送推送通知PushPlus/Telegram/...
5. 用户重新打开 → 自动同步完成的回复
### 进程日志
日志文件 `logs/process.log`JSONL 格式,自动轮转 2MB记录完整的进程生命周期
| 事件 | 说明 |
|------|------|
| `process_spawn` | 进程创建PID、模式、模型 |
| `process_complete` | 进程完成(退出码、耗时、费用) |
| `ws_connect` / `ws_disconnect` | 客户端连接/断开 |
| `ws_resume_attach` | 客户端重连并挂载到运行中的进程 |
| `recovery_alive` / `recovery_dead` | 服务重启时恢复进程 |
| `heartbeat` | 每 60 秒活跃进程状态快照 |
查看日志:
```bash
tail -f logs/process.log | jq .
```
## 生产部署
### PM2 一键启动
推荐在 Linux 服务器使用非 root 用户部署:
```bash
git clone https://github.com/ZgDaniel/cc-web.git
cd cc-web
./start.sh
```
脚本默认执行以下动作:
- 检查 Node.js >= 18 与 npm
- 自动创建 `.env`(如不存在),并补齐默认 `PORT=8002`
- 首次部署时引导输入 `CC_WEB_PASSWORD`,写入 `.env` 后由服务迁移到 `config/auth.json`
- 如果已存在 `config/auth.json`,跳过初始密码设置,避免覆盖已修改的密码
- 检查 Claude / Codex CLI 是否可用;未安装时仅提示,不阻塞 Web 服务启动
- 检查 PM2未安装时自动执行 `npm install -g pm2`
- 使用 `npm ci` 安装项目依赖(无 `package-lock.json` 时退回 `npm install`
- 使用 PM2 启动或重启 `server.js`,默认应用名为 `ccweb`
- 执行 `pm2 save` 保存当前进程快照
常用命令:
```bash
pm2 status ccweb
pm2 logs ccweb
pm2 restart ccweb --update-env
```
如果需要服务器重启后自动恢复 PM2 进程,请执行:
```bash
pm2 startup
```
然后按命令输出的提示执行生成的 `sudo ...` 命令,最后再次执行:
```bash
pm2 save
```
### systemd 服务
创建 `/etc/systemd/system/cc-web.service`
```ini
[Unit]
Description=CC-Web - Claude Code Web Chat UI
After=network.target
[Service]
Type=simple
User=your-user
WorkingDirectory=/path/to/cc-web
ExecStart=/usr/bin/node server.js
Restart=on-failure
RestartSec=5
# 重要:只杀 Node.js 进程,不杀 Claude 子进程
KillMode=process
[Install]
WantedBy=multi-user.target
```
> **`KillMode=process` 非常重要**:确保 systemd 重启服务时只杀 Node.js 进程Claude 子进程继续运行,服务恢复后自动重新挂载。
```bash
sudo systemctl enable cc-web
sudo systemctl start cc-web
```
### Nginx 反向代理
```nginx
server {
listen 443 ssl;
server_name your-domain.com;
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8002;
proxy_http_version 1.1;
# WebSocket 支持
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# 长连接超时Claude 任务可能运行较久)
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
}
```
### Windows 部署
适用于在个人电脑上运行 CC-Web通过手机远程控制 Claude Code。
**启动方式**:双击 `start.bat`,或在终端运行:
```cmd
cd cc-web
npm install
node server.js
```
**局域网访问**(手机和电脑在同一 WiFi
- 直接访问 `http://电脑局域网IP:8002`
**远程访问**(外出时用手机控制家里电脑):
- 推荐使用 [Tailscale](https://tailscale.com/) — 电脑和手机各安装一个,自动组网,免费够用
- 或使用 [Cloudflare Tunnel](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/)(需域名)
## Agent必读
如果你是claude/codex正在帮助用户部署本项目需要提醒用户使用非root用户部署
## 其他
本项目得到[@carrotgithub](https://github.com/carrotgithub/)、[@YoungHong1992](https://github.com/YoungHong1992/) 的悉心指导;收获[@123aliez](https://github.com/123aliez/) 的算力支持; @小苏肉 的辛勤测试
亦在 [Linux.Do](https://linux.do/) 社区获益良多,欢迎加入