# haha
**Repository Path**: Lyong9102/haha
## Basic Information
- **Project Name**: haha
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: MIT
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-08-03
- **Last Updated**: 2026-08-03
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# Claude Code Haha — 纯 Web Agent 工作台
[](LICENSE)
[](README.zh-CN.md)
[](README.md)
[English](README.md) · **简体中文**
**面向 Agent CLI 的自托管浏览器工作台** — 支持 Claude Code、Codex、Gemini、Grok、Kimi、Mistral、OpenCode、Pi 等。
本仓库是 **独立的纯 Web 产品**:React SPA + Bun Server + 宿主机 CLI 子进程。**无 Electron / Tauri 壳**、无桌面宠物、无 H5 远程 Token 产品路径。单一管理员账号、Cookie 会话;在浏览器内管理模型服务商、会话、Skills/MCP、IM 适配器与 Agent CLI 工具。
| 能力 | 状态 |
|------|------|
| 浏览器 SPA + Bun REST / WebSocket | **支持** |
| 管理员初始化(账号 + 密码)+ HttpOnly Cookie | **支持** |
| 多 Agent CLI(Claude / Codex / Gemini / Grok / …) | **支持** |
| 模型服务商 + OAuth(Claude / ChatGPT / Grok) | **支持** |
| Grok 官方多账号池 + 额度同步 | **支持** |
| 从 Claude Code / 桌面 `cc-haha` 导入服务商(用户勾选) | **支持** |
| IM 适配器(Telegram / 飞书 / 微信 / 钉钉 / WhatsApp) | **支持**(由 Server 拉起) |
| 打开宿主机默认终端(服务进程用户权限) | **支持** |
| Electron / Tauri / 桌面宠物 / H5 Token | **已移除** |
| 浏览器内嵌 PTY 终端 | **不可用**(改为打开系统终端) |
---
## 产品是什么
Haha 把本机的各类编码 Agent CLI 统一到 **一个浏览器 UI**:
1. **管理员**首次初始化并强制登录(失败 10 次按浏览器指纹 + IP 锁定 1 小时)。
2. **服务商** API Key / OAuth 仅保存在服务端数据目录。
3. **工作台** 流式对话、权限审批、工作区/Diff、多会话标签。
4. **Agent CLI 管理** 探测、安装/升级、切换当前宿主机 CLI 品牌(每个 SPA 标签页只激活一个 CLI)。
5. **IM** 可由 Server 拉起,手机端可不打开 Web UI 控制同一会话。
运行时结构:
```text
浏览器 SPA (web/ → 仓库根 dist/)
│ Cookie 会话(仅管理员)
▼
Bun Server (src/server · Bun.serve)
├── /api · /ws · /proxy · /health · SPA 静态资源
├── web-control SQLite(管理员 / 在线 / CLI 偏好)
├── providers.json + settings(HAHA_DATA_DIR)
├── Grok 账号池 · OAuth 回调
├── 会话 JSONL (~/.claude/projects)
├── Agent CLI 注册表 · 探测 · 安装 · 运行时适配器
├── IM 适配器子进程 (adapters/)
└── 打开宿主机终端 / Host Shell(与 Server 同用户)
│
▼
宿主机 Agent CLI 进程
(claude, codex, gemini, grok, …)
```
---
## 支持的 Agent CLI
注册表:`src/server/services/agentCli/registry.ts`。Logo:`web/public/cli-logos/`。
| ID | 显示名 | 成熟度 | 说明 |
|----|--------|--------|------|
| `claude-code` | Claude Code | **full** | 一等公民:JSONL 会话 + 完整工作台流式对话 |
| `codex` | Codex CLI | **beta** | npm `@openai/codex`;升级走重装(避免假 `codex update`) |
| `gemini` | Gemini CLI | **beta** | npm `@google/gemini-cli` |
| `opencode` | OpenCode CLI | **beta** | 官方安装脚本 + npm 回退 |
| `kimi` | Kimi Code CLI | **manage-only** | 检测 / 安装 / 打开宿主机 Shell |
| `grok` | Grok CLI(xAI) | **manage-only** | 原生 `~/.grok/bin` 路径 |
| `mistral` | Mistral CLI | **manage-only** | PATH 探测与生命周期管理 |
| `pi` | Pi | **manage-only** | npm `@mariozechner/pi-coding-agent` |
**成熟度含义**
- **full** — 完整 UI 历史 + 流式对话(既有 conversation 路径)
- **beta** — 探测/安装/升级 + 部分会话/运行时桥接
- **manage-only** — 生命周期管理 + 打开宿主机 Shell;深度流式对等不保证
默认激活 CLI:**Claude Code**。若未安装/不可运行任何 CLI,对话入口会门禁,并引导到「系统管理 → Agent CLI」。
---
## 快速开始
**环境:** Node(pnpm)、[Bun](https://bun.sh) **1.3+**,Windows / macOS / Linux。
> 本仓库为 **单一纯 Web 产品线**(默认分支即可)。**不要** 执行 `git checkout web` — 历史上的桌面/`web` 双分支模型已取消。
```bash
# 1) 工具
corepack enable && corepack prepare pnpm@11.17.0 --activate
# 安装 Bun:https://bun.sh (Server / CLI 运行时)
# 2) 依赖(根目录 + SPA,两者都要装)
pnpm install
cd web && pnpm install && cd ..
# 3) 构建 SPA → 仓库根 dist/ (也可交给 start 首次自动构建)
pnpm run web:build
# 4) 启动纯 Web 服务 → http://127.0.0.1:3456
pnpm run web:start
# 等价命令:
# pnpm run dev
# bun run ./bin/claude-haha-web.ts start
```
`pnpm run web:start` 与 `pnpm run dev` 都会执行 `bin/claude-haha-web.ts start`,并强制 `HAHA_WEB_AUTH=1` / `HAHA_WEB_MODE=1`(管理员 Cookie 登录)。
**新机器克隆注意**
- 需安装 Bun([bun.sh](https://bun.sh))。启动器使用 `process.execPath`(当前 Bun 本体)拉起服务,Windows 上 **不必** 再把 `bun` 加进 PATH。
- SPA 产物在仓库根 **`dist/`**;若缺失,`web:start` / `dev` 会在 `web/` 下自动执行一次 `bun run build`(需已有 `web/node_modules`)。
- 明确构建请用 `pnpm run web:build`;一步构建并启动用 `pnpm run web:dev`。
然后:
1. 打开 **http://127.0.0.1:3456**
2. **首次访问**:系统初始化 — 管理员 **账号 + 密码 + 确认密码**
3. **设置 → 服务商** 中配置模型 / OAuth
4. 安装或选择 **Agent CLI**(系统管理或 Logo 切换器)
5. 新建或打开会话(Claude 历史与 CLI 共用 `~/.claude/projects/...` 下 JSONL)
### 常用命令
| 命令 | 说明 |
|------|------|
| `pnpm run web:start` | **启动纯 Web 服务**(推荐) |
| `pnpm run web:stop` | 按 pid 文件停止服务 |
| `pnpm run web:status` | 查看服务状态 / health |
| `pnpm run dev` | 与 `web:start` 相同 |
| `pnpm run web:build` | 仅构建 SPA → 仓库根 `dist/` |
| `pnpm run web:dev` | 先构建 SPA 再启动 |
| `pnpm run check:no-electron` | 校验无 Electron 产品依赖 |
| `docker compose -f docker-compose.web.yml up --build -d` | 可选容器部署 |
CLI 入口(与 `web:start` 同一进程):
```bash
bun run ./bin/claude-haha-web.ts start --host 0.0.0.0 --port 3456
# 可选: --data-dir PATH --work-dir PATH --dist PATH --skip-build
bun run ./bin/claude-haha-web.ts status
bun run ./bin/claude-haha-web.ts stop
bun run ./bin/claude-haha-web.ts reset-password
```
### 端口占用(`Failed to start server. Is port 3456 in use?`)
默认监听 **`127.0.0.1:3456`**。若已有健康实例,再次 `web:start` 会失败。
```bash
pnpm run web:status # 查看 health 与 pid
pnpm run web:stop # 有 pid 文件时可停止
# 若 stop 提示无 pid 文件,但 /health 仍可达,请手动释放端口:
# Windows: netstat -ano | findstr :3456 → taskkill /PID /F
# Linux: ss -ltnp 'sport = :3456' → kill
# 或换端口:
pnpm run web:start -- --port 3457
```
若 `web:status` 已显示 healthy,直接打开 **http://127.0.0.1:3456** 即可,无需再启动。
设计与部署:[docs/prds/web/deploy.md](docs/prds/web/deploy.md) · [纯 Web 设计](docs/prds/web/pure-web-design.md) · [Agent CLI 设计](docs/prds/web/agent-cli-management-design.md)
---
## 功能概览
- **工作台**:多会话、项目、工作区/Diff、权限审批、主题(中/英)
- **模型服务商**:Claude / ChatGPT / Grok 官方 OAuth,第三方 Anthropic/OpenAI 兼容 API,本地网关,服务端请求代理
- **外部服务商导入(用户选择)**:可发现 Claude Code(`~/.claude/settings.json`)与桌面端 **`cc-haha`**(`~/.claude/cc-haha/providers.json`);**由你勾选导入**。不会静默合并。重名时附加来源后缀(如 `DeepSeek (cc-haha)`)
- **Grok 官方账号池**:多账号列表、sticky 默认账号、健康账号轮询、周限 + 月限额度同步、凭据刷新、auth.json 风格导出
- **Agent CLI 管理**:列表/探测/安装/升级、设为当前与默认、打开宿主机 Shell、成熟度徽章
- **Agents / Skills / MCP / 插件 / 市场**
- **定时任务**:由 Server 托管的 cron 风格任务
- **IM 适配器**:Telegram / 飞书 / 微信 / 钉钉 / WhatsApp(Server 拉起,无需 Electron)
- **系统管理**:在线用户(Web + IM,**只读**、不踢人)、IM 进程启停、退出登录
- **安全**:强制管理员登录;登录失败 10 次锁定 1 小时(FingerprintJS + IP);密码可见切换;Key 仅服务端
- **宿主机终端 / Host Shell**:打开系统默认终端,权限与 **Web Server 进程用户** 一致,工作目录优先当前会话项目路径
---
## 仓库结构
| 路径 | 作用 |
|------|------|
| `web/` | 纯 SPA(React + Vite + Zustand + Tailwind)。构建产物 → `../dist` |
| `src/server/` | Bun HTTP/WS 宿主:鉴权、会话、服务商、Agent CLI、代理、静态 SPA |
| `src/` 其余 | 与 CLI 侧共享的 Agent 运行时、工具、服务 |
| `bin/claude-haha-web.ts` | 产品 CLI:`start` / `stop` / `status` / `reset-password` |
| `adapters/` | IM 平台适配器(可由 Server 启停进程) |
| `docs/prds/web/` | 纯 Web 设计、部署、Agent CLI 设计、进度 |
| `docs/`、`docs/en/` | 文档站内容源(部分页面仍可能提及历史桌面路径) |
| `site/` | 文档站构建 |
| `scripts/check-no-electron.mjs` | 保证产品依赖不含 Electron |
---
## 数据目录(重要)
服务商与纯 Web 控制面状态位于 **产品数据目录下的文件 / SQLite**,不是“仓库内某个数据库”。
| 路径 | 作用 |
|------|------|
| `HAHA_DATA_DIR`(或 `--data-dir`) | **当前进程的写入根目录**。默认:**`~/.haha`** |
| `~/.haha/db/web-control-v1.sqlite` | 管理员鉴权、在线、Agent CLI 偏好(WAL) |
| `~/.claude/haha-web` · `~/.claude/haha` · `~/.claude/cc-haha` | **历史**产品目录 — 若 `~/.haha` 为空会**自动迁移**一次 |
| `~/.claude/settings.json` | Claude Code 用户设置 — 仅外部导入 |
| `~/.claude/projects/...` | 与 CLI 共享的 Claude 会话 transcript(JSONL) |
**隔离规则**
1. 运行中的实例只 **写入** 自己的活动数据目录(`HAHA_DATA_DIR` / 默认 **`~/.haha`**)。
2. 首次启动时,若 `~/.haha` 为空且存在旧目录(如 `~/.claude/haha-web`),会 **移动** 到 `~/.haha`。
3. 全新环境会创建空的 `~/.haha` 并进入 **系统初始化**;若未安装任何 Agent CLI,会显示 **安装选择页**(至少装一个,或稍后)。
4. Claude Code / 桌面 `cc-haha` 仅用于 **发现**;导入在 **设置 → 服务商 → 外部设置来源** 中手动勾选。
```bash
export HAHA_DATA_DIR="$HOME/.haha-dev"
pnpm run web:start
```
---
## 环境变量
| 变量 | 说明 | 默认 |
|------|------|------|
| `SERVER_HOST` | 监听地址 | `127.0.0.1` |
| `SERVER_PORT` | 端口 | `3456` |
| `HAHA_DATA_DIR` | 数据目录 | `~/.haha` |
| `CLAUDE_H5_DIST_DIR` / `WEB_APP_DIST` | SPA 产物目录 | 仓库根 `dist/` |
| `CLAUDE_CLI_PATH` | Claude CLI 可执行路径覆盖 | 自动解析 |
| `HAHA_WEB_MODE` / `HAHA_WEB_AUTH` | 强制纯 Web 管理员登录 | `claude-haha-web start` 时设为 `1` |
公开端点(无需会话):`GET /health`、`GET /api/auth/status`、`POST /api/auth/setup`(仅需初始化时)、`POST /api/auth/login`、SPA 静态资源。
**安全**:公网务必反代 HTTPS;勿将管理员密码或 API Key 写入日志/镜像层。
---
## 部署到服务器(生产 + Nginx)
**先分清两件事:**
| 命令 | 含义 |
|------|------|
| `pnpm run web:build` + `pnpm run web:start` | **生产运行方式**:构建 SPA → Bun 托管 `dist/` + API/WS(**不是** Vite 开发服务器) |
| `cd web && pnpm run dev` | 仅前端 Vite 热更新,**不要**用于服务器 |
Nginx **不能单独跑本项目**,只做 **HTTPS 反代**;后面必须有 **Bun 进程**。
```text
浏览器 ──443──► Nginx ──► Bun 127.0.0.1:3456(web:start)
└── 数据目录 HAHA_DATA_DIR(默认 ~/.haha)
```
完整步骤(systemd + Nginx + 证书)见:
**[docs/prds/web/deploy.md](docs/prds/web/deploy.md)**
### 最短生产路径
```bash
# 1) 服务器:装 Node / pnpm / Bun / nginx,克隆仓库
cd /opt/haha
pnpm install && cd web && pnpm install && cd ..
pnpm run web:build
# 2) 用 systemd 启动 Bun(只监听本机;见 deploy.md 完整 unit)
# bun run ./bin/claude-haha-web.ts start --host 127.0.0.1 --port 3456 --data-dir /var/lib/haha
# 3) Nginx 反代到 127.0.0.1:3456(必须带 WebSocket 头)
# 4) 浏览器打开 https://你的域名 → 系统初始化
```
### Docker Compose(可选)
```bash
docker compose -f docker-compose.web.yml up --build -d
curl -sS http://127.0.0.1:3456/health
```
容器内 Agent CLI 配置更麻烦;需要宿主机 `claude`/`codex` 时优先裸机 + Nginx。
---
## Docker(简)
```bash
docker compose -f docker-compose.web.yml up --build -d
curl -sS http://127.0.0.1:3456/health
```
镜像:构建阶段用 **pnpm** 构建 SPA;运行阶段用 **Bun** 执行 `claude-haha-web start`,`HAHA_DATA_DIR=/data`。
---
## 技术栈
| 层级 | 技术 |
|------|------|
| SPA | React 18 + Vite 8 + TypeScript + Zustand + Tailwind 4(`web/`) |
| 包管理 | **pnpm@11.17.0** |
| Server / CLI | **Bun**(`Bun.serve`、`bun:sqlite`) |
| 控制面 | SQLite WAL(`web-control`) |
| 登录设备指纹 | [@fingerprintjs/fingerprintjs](https://github.com/fingerprintjs/fingerprintjs) |
| 鉴权 | bcrypt 密码、HttpOnly Cookie、服务端锁定 |
---
## 开发与验证
```bash
pnpm run check:no-electron # 产品路径不得依赖 Electron
bun run check:server # Server 离线单测/集成
cd web && pnpm run lint && pnpm exec vitest run && pnpm run build
bun run check:impact # PR 影响面路由
bun run verify # 需要时跑完整 PR 质量门
```
贡献约定:[CONTRIBUTING.md](CONTRIBUTING.md) · [AGENTS.md](AGENTS.md) · [docs/internals/contributing.md](docs/internals/contributing.md)
---
## 更多文档
| 主题 | 文档 |
|------|------|
| 部署 / Docker / 环境变量 | [docs/prds/web/deploy.md](docs/prds/web/deploy.md) |
| 产品设计 | [docs/prds/web/pure-web-design.md](docs/prds/web/pure-web-design.md) |
| Agent CLI 管理 | [docs/prds/web/agent-cli-management-design.md](docs/prds/web/agent-cli-management-design.md) |
| 实现进度 | [docs/prds/web/PROGRESS.md](docs/prds/web/PROGRESS.md) |
| CLI 环境变量 | [docs/cli/env.md](docs/cli/env.md) |
| IM | [docs/im/index.md](docs/im/index.md) |
| Server 内部 | [docs/internals/server.md](docs/internals/server.md) |
文档站:(部分页面可能仍描述历史桌面打包路径)。
---
## 许可证
MIT — 见 [LICENSE](LICENSE)。