Happy 源码深度分析:20.3K Stars 的 Claude Code / Codex 移动端客户端
> 来源: GitHub - slopus/happy | DeepWiki | Happy Engineering
> 日期: 2026-05-08
> 作者: slopus (Bay Area 分布式团队) | 许可: MIT
> 语言: TypeScript (95.4%) | Star: 20.3K | Forks: 1.7K
> iOS: App Store | Android: Google Play | Web: app.happy.engineering
一句话版本
Happy 让你在手机上打开 App 就能操控电脑上的 Claude Code 或 Codex——就像它们在手机上运行一样,端到端加密、支持语音、推送通知,还能随时切回电脑继续。
它解决了什么问题?
和 Roam 解决的问题一样——离开电脑就没法继续跟 AI 编程 Agent 对话。但 Happy 的解法更"重"也更"完整":
- 不是临时方案,而是 构建了一整套"远程 Agent"产品(CLI + 原生 App + 后端服务器)
- 不仅仅是终端透传,而是 完整的会话同步和切换系统
- 有团队全职维护、有商业计划、有 466 个 Issue 活跃讨论
架构总览
移动设备 (iOS/Android/Web)
↓ E2E Encrypted WebSocket
Happy Server (认证 / 会话同步 / 推送通知)
↓ E2E Encrypted WebSocket
本机 CLI (happy 命令)
├── 代替 claude 命令 → 启动 Claude Code SDK
├── 代替 codex 命令 → 启动 Codex App Server
├── 代替 gemini 命令 → 启动 Gemini CLI (ACP)
└── 代替 openclaw 命令 → 启动 OpenClaw (ACP)
核心组件
| 包 | 职责 | 代码量 |
|---|---|---|
| **happy-cli** | CLI 主程序(入口、Agent 引擎、加密、守护进程) | ~200+ 源文件 |
| **happy-app** | Expo 移动端 + Web App | 大量 (Expo) |
| **happy-server** | 后端服务器(认证、会话同步、推送) | ~50+ 源文件 |
| **happy-agent** | 远程 Agent 控制 CLI | ~20 源文件 |
| **happy-wire** | 协议定义(消息、会话、语音) | ~10 源文件 |
核心源码分析
一、架构设计哲学
Happy 的做法是包装而不是替换:
# 传统用法
claude "帮我重构这个函数" → 直接调用 Claude Code
# Happy 用法
happy "帮我重构这个函数" → 包装 Claude Code,增加远程能力
happy codex "写个 React 组件" → 包装 Codex
happy gemini "分析代码" → 包装 Gemini CLI
当用户在本地时,Happy 就是 Claude Code 的一个薄包装。当用户从手机发送消息时,Happy 通过 E2E 加密信道接收指令并转发给 Claude Code。
二、CLI 入口 (index.ts)
入口采用纯手工参数解析(没有用 yargs/commander 等框架),~500 行代码处理:
子命令路由表:
(无参数) → Claude Code 模式(默认)
claude → Claude Code 模式
codex → Codex 模式
gemini [cmd] → Gemini 模式(含 model/project 子命令)
acp [agent] → 通用 ACP Agent 模式
openclaw → OpenClaw 模式
auth [cmd] → 认证管理
connect [vendor] → 连接 AI 供应商 API
resume <id> → 恢复 Happy 会话
sandbox → 沙箱配置
daemon [cmd] → 守护进程管理
doctor → 系统诊断
notify -p msg → 发送推送通知
bye → 退出
参数传递设计:Happy 会把所有未识别的参数透传给底层 agent(unknownArgs),所以 happy --model claude-sonnet-4-20250514 --resume 能正常工作。
三、Claude 模式运行流程 (runClaude.ts)
这是最核心的代码(~400 行):
export async function runClaude(credentials, options) {
// 1. 创建 API Session(连接 Happy Server)
const api = await ApiClient.create(credentials);
const response = await api.getOrCreateSession({ tag, metadata, state });
// 2. 初始化会话同步客户端
const session = api.sessionSyncClient(response);
// 3. 启动 MCP 服务器 + Hook 服务器
const happyServer = await startHappyServer(session);
const hookServer = await startHookServer({ onSessionHook: ... });
// 4. 启动 Happy Agent Loop
const exitCode = await loop({
path, model, permissionMode, messageQueue,
mcpServers: { 'happy': { type: 'http', url: happyServer.url } },
session, claudeEnvVars, claudeArgs, sandboxConfig
});
}
远程/本地模式切换:通过 onModeChange 回调切换:
- 本地模式:Claude Code 直接使用终端输入
- 远程模式:消息从 Happy Server 发来,CLI 封装后传给 Claude Code
消息流:
手机 App → E2E 加密 → Happy Server → E2E 解密 →
Happy CLI → session.onUserMessage → MessageQueue2 →
Claude SDK → Claude Code 执行 →
结果返回路径反向
四、Claude 本地执行 (claudeLocal.ts)
通过 claude_local_launcher.cjs 启动 Claude Code 子进程:
const child = crossSpawn('node', ['claude_local_launcher.cjs', ...args], {
stdio: ['inherit', 'inherit', 'inherit', 'pipe'],
cwd: opts.path,
env: { ...process.env, ...opts.claudeEnvVars }
});
会话 ID 管理:Happy 拦截并处理 Claude 的 --resume / --continue / --session-id 参数,用 Happy 的会话存储取代 Claude 的默认存储。
Thinking 状态追踪:通过 fd 3(自定义管道)从 Claude 进程读取 JSON 事件(fetch-start/fetch-end),判断 Claude 是否正在思考。
沙箱集成:支持通过 sandbox/manager 初始化 OS 级沙箱(仅 macOS/Linux)。
五、E2E 加密系统
所有数据在传输前使用端到端加密:
- 每会话派生独立密钥 (
deriveKey.ts) - HMAC-SHA512 完整性校验
- backupKey 支持跨设备密钥恢复
六、支持 Agent 矩阵
| Agent | 实现文件 | 启动方式 |
|---|---|---|
| Claude Code | `claude/runClaude.ts` | Claude SDK + JSONL 追踪 |
| Codex | `codex/runCodex.ts` | Codex App Server 客户端 |
| Gemini CLI | `gemini/runGemini.ts` | ACP 协议桥接 |
| OpenClaw | `openclaw/runOpenClaw.ts` | WebSocket → OpenClaw Gateway |
| ACP Generic | `agent/acp/runAcp.ts` | 通用 ACP 运行器 |
七、守护进程 (daemon/)
- macOS 优先(launchd 集成)
- 后台运行,管理会话生命周期
- 支持命令:
- happy daemon start → 启动后台进程
- happy daemon stop → 停止守护进程(会话保持)
- happy daemon list → 列出活跃会话
- happy daemon status → 守护进程状态
八、前端 (happy-app)
- Expo 框架(一套代码 iOS + Android + Web)
- 原生推送通知(APNs + FCM)
- 语音支持(LiveKit 引擎)
- Tauri 桌面版本(src-tauri/ 目录)
与 Roam 的对比
| 维度 | Happy | Roam |
|---|---|---|
| **Stars** | 20.3K | 16 |
| **团队** | 分布式团队 (Bay Area) | 个人 (valueriver) |
| **前端** | 原生 iOS/Android App + Web | 浏览器 SPA |
| **加密** | E2E 端到端加密 | 挑战-响应密码 |
| **推送通知** | ✅ APNs + FCM | ❌ |
| **语音** | ✅ LiveKit 实时语音 | ❌ |
| **Agent 支持** | Claude/Codex/Gemini/OpenClaw/ACP | 仅终端透传 |
| **守护进程** | ✅ macOS launchd | ❌ |
| **数据中继** | Happy Server(需要信任) | CF Worker(纯透传) |
| **部署复杂度** | 高(需注册/认证) | 低(npm install) |
| **成熟度** | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
核心区别:Roam 是一个工具(装好就能用的隧道),Happy 是一个产品(有后端、有 App、有团队)。
安全边界
| 风险 | 说明 |
|---|---|
| 信任 Happy Server | 虽然宣称 E2E 加密,但用户仍需信任 Happy 的后端服务器 |
| OpenClaw 密码明文 | `openclawAuth.ts` 中处理网关密码 |
| 依赖 npm 供应链 | 大量依赖,攻击面大 |
| 自建服务器选项 | docs 中提及可以自建,但默认使用官方服务器 |
与你的关联
最值得关注的点
1. OpenClaw 集成:Happy 已经原生支持 OpenClaw 作为 ACP Agent!packages/happy-cli/src/openclaw/ 目录包含 OpenClawBackend.ts、OpenClawSocket.ts、openclawAuth.ts 等文件。这意味着你的 OpenClaw 项目已经被这个 20.3K stars 的项目当作一等公民支持了。
2. Agent 引擎抽象:Happy 的 Agent 引擎设计(AgentRegistry → Backend → Transport 三层)是很好的参考模式。
3. MessageQueue2 去重机制:用 hashObject 作为消息指纹,避免重复投递。
4. 会话同步协议:packages/happy-wire/ 定义了完整的消息会话协议,值得研究。
值得借鉴的设计
| 设计 | 说明 |
|---|---|
| 守护进程架构 | macOS launchd 集成,后台管理会话 |
| 穿透式参数传递 | 未知参数自动透传到底层 agent |
| Thinking 状态追踪 | 通过子进程 fd 3 监控思考状态 |
| 远程/本地模式切换 | 一键切换设备控制权 |
评分
| 维度 | 分数 | 说明 |
|---|---|---|
| 代码质量 | ⭐⭐⭐⭐⭐ | 大型 monorepo,架构清晰,测试完善 |
| 实用价值 | ⭐⭐⭐⭐⭐ | 解决真实痛点,20.3K stars 验证 |
| 成熟度 | ⭐⭐⭐⭐⭐ | 产品级,iOS/Android/Web 全端覆盖 |
| 安全性 | ⭐⭐⭐⭐ | E2E 加密,但需信任第三方服务器 |
| 创新性 | ⭐⭐⭐ | 不是全新概念,但执行极其到位 |
| 你的关联度 | ⭐⭐⭐⭐⭐ | 已原生支持 OpenClaw! |
一句话再总结
> "Happy 用 20.3K stars 证明:给 Claude Code / Codex 加一个手机端是真实需求。它和 Roam 解法不同(产品 vs 工具),但都指向同一个方向——远程 AI Agent 控制正在成为基础设施。"
报告生成时间: 2026-05-08 12:22 UTC
分析基于 slopus/happy main branch 源码