cc-web-control
v3.1.4
Published
通过 Web 页面以对话框形式控制本地 tmux 会话
Maintainers
Readme
Claude Code Web
通过 Web 页面对话形式控制本地 Claude Code,实现双向同步:Web 输入发送给 Claude Code,Claude Code 输出显示在 Web 上。
另支持 hub 多机模式:一条 cc-web-control hub 子命令聚合多台机器的 cc-web-control,提供统一看板、点卡片新标签直达任一单机、多选批量广播。详见下文 hub 多机模式。
快速开始
# 方式一:无需安装,直接运行
npx cc-web-control
# 方式二:全局安装后使用
npm install -g cc-web-control
cc-web-control前置依赖
本工具在本机通过 tmux 操控 claude CLI,运行前请确保已安装:
- Node.js ≥ 18
- tmux(macOS:
brew install tmux;Ubuntu:sudo apt install tmux) - Claude Code CLI(已完成 Claude 登录认证)
首次启动若缺少依赖,程序会打印安装提示并退出(exit code 1)。
部署与运维入口:
docs/部署使用文档.md
完整中文手册:docs/操作手册.md
功能特性
- 自动启动 Claude Code:
npm start自动创建 tmux 会话并启动 Claude Code - 对话式界面: Web 端以聊天形式与 Claude Code 交互
- 实时双向同步: WebSocket 实时同步终端内容
- 深色主题: 类似 Claude Code 的深色界面风格
- 单行输入: Enter 发送(当前输入框为单行)
- 补全/命令面板按键: 支持
Tab补全、↑/↓选择、Esc退出(输入框为空时发送按键) - 多机 hub 聚合:
cc-web-control hub子命令聚合 N 台机器,统一全局看板 / 点卡片新标签直达单机 / 多选批量广播
技术架构
┌─────────────┐ WebSocket ┌─────────────┐ tmux cmd ┌─────────────┐
│ 浏览器 │ ◄────────────────► │ Node.js │ ◄──────────────► │ tmux │
│ (对话界面) │ 实时双向通信 │ (服务端) │ capture-pane │ claude-web │
│ │ │ │ send-keys │ -session │
└─────────────┘ └─────────────┘ └─────────────┘快速开始
1. 安装依赖
cd <项目目录>/cc-web-control
npm install2. 启动服务
npm start服务将在 http://localhost:7684 启动,并自动打开浏览器。
3. 使用说明
- 在底部输入框输入消息
- 按 Enter 发送消息给 Claude Code
- Claude Code 的回复将实时显示在对话区域
- 补全/命令面板:
Tab:发送给 tmux 用于补全- 输入框为空时:
↑/↓/Esc/Enter会作为按键发送给 tmux(用于在面板里移动/确认/退出)
文件结构
tmux-web-control/
├── package.json # 项目配置
├── server.js # HTTP + WebSocket 服务
├── tmux.js # tmux 控制封装
├── claude-wrapper.sh # Claude Code 启动包装脚本
├── README.md # 项目说明
└── public/
├── index.html # 页面结构
├── style.css # 对话式界面样式
└── client.js # 前端逻辑关键技术
| 组件 | 用途 |
|------|------|
| tmux capture-pane -p | 捕获 Claude Code 输出 |
| tmux send-keys | 向 Claude Code 发送输入 |
| WebSocket | 实时双向通信 |
| claude-wrapper.sh | 绕过嵌套会话检测 |
数据流
- 输入方向: Web 输入 → WebSocket →
send-keys→ tmux → Claude Code - 输出方向: Claude Code → tmux →
capture-pane→ WebSocket → 对话界面
环境要求
- Node.js >= 18
- tmux >= 3.0
- Claude Code CLI 已安装
- 现代浏览器(支持 WebSocket)
注意事项
- 启动时会自动创建名为
claude-web-session的 tmux 会话 - 通过
claude-wrapper.sh绕过 Claude Code 的嵌套会话检测 - WebSocket 实时捕获会话内容(每 100ms)
- 关闭服务端不会终止 Claude Code 会话(会话保持运行)
项目切换(多项目/多会话)
这个工具的“项目”本质上对应一个 tmux session(每个 session 可在不同目录启动 claude)。
1) 开启项目列表(推荐)
设置允许扫描的项目根目录(逗号分隔):
export CC_WEB_PROJECT_ROOTS="<项目父目录>"启动服务后,页面顶部会出现 Project 下拉框,选择项目并点击 启动 会:
- 创建一个新会话(会话名形如
claude-<project>) - 在该项目目录里启动
claude
2) 手动切换会话
页面顶部 Session 下拉框可直接切换到其它 tmux session。
也可以通过 URL 参数指定:
http://127.0.0.1:7684/?session=claude-web-session“/” 命令面板
Claude Code 有些交互会在输入 / 后弹出命令面板(不一定需要回车)。
本项目默认会在你只输入 / 并回车发送时,仅发送 / 不附带 Enter,避免把 / 当作一条完整命令提交。
配置项(环境变量 / 启动参数)
CC_WEB_HOST:监听地址(默认127.0.0.1)CC_WEB_PORT:端口(默认7684)CC_WEB_SESSION:默认会话名(默认claude-web-session)CC_WEB_POLL_INTERVAL:输出轮询间隔 ms(默认100)CC_WEB_CAPTURE_HISTORY:控制台可回看的 tmux scrollback 历史行数。未设/0=原行为(只抓当前可见屏);正整数 N=抓当前屏 + 往上 N 行(受 tmuxhistory-limit上限约束,默认 2000)。例:CC_WEB_CAPTURE_HISTORY=2000让滚动条能回看更早的历史输出。CC_WEB_PROJECT_ROOTS:允许扫描的项目根目录(逗号分隔;不设置则不展示项目下拉框)CC_WEB_AUTH_TOKEN:开启鉴权(设置后需要先访问/login输入 token 才能进入主页面;WS/API 同样受保护)CC_WEB_CLAUDE_CONTINUE=1:当服务端需要新启动claude时,使用claude -c/--continue(在项目目录继续最近一次对话,减少“记忆断层”)CC_WEB_WEB_ONLY=1或--web-only:只启动 Web(不创建/附加 tmux 会话)CC_WEB_NO_OPEN=1或--no-open:不自动打开浏览器CC_WEB_NO_ATTACH=1或--no-attach:不在当前终端 attach 到 tmux 会话
配置文件(可选)
除了环境变量,也可以用 JSON 配置文件管理启动参数。适合多参数 / 固定配置 / 不想污染 shell 环境的场景。
文件路径与 flag
- 单机(7684):
~/.cc-web-control/config.json - hub 多机(7685):
~/.cc-web-control/hub-config.json
用 --config <path> flag 覆盖默认路径(两个入口都支持):
cc-web-control --config /path/to/my-config.json
cc-web-control hub --config /path/to/my-hub-config.json优先级与向后兼容
每个字段按 环境变量 > 文件值 > 代码默认 解析:
- 环境变量是逃生口,适合 CI / 临时调试;
- 文件值是日常固定配置;
- 两者都没有则用代码默认 —— 不写配置文件 = 现状行为完全不变,纯 env / 默认仍照旧。
字段清单
字段名、类型、默认值的权威清单见仓库根的两份模板(避免本节与 schema 漂移):
- 单机 21 字段(含 6 个 hub 注册字段
hubUrl/hubToken/hubRegisterToken/machineId/machineName/publicUrl):config.example.json - hub 12 顶层字段(含
hubRegisterToken,及mainAgent子对象):hub-config.example.json
复制模板作起点:
cp config.example.json ~/.cc-web-control/config.json # 单机
cp hub-config.example.json ~/.cc-web-control/hub-config.json # hub然后按需改字段值即可。
字段约定
- bool:文件里写字面
true/false(勿加引号);环境变量里'1'= true。 - number:文件里写裸数字(如
100,勿加引号)。 - projectRoots:文件里是 JSON 数组(环境变量则逗号分隔)。
- 路径字段写绝对路径:
projectRoots、mainAgent.dataDir等路径字段在 JSON 里写绝对路径,不要写~/。JSON 中~是字面字符串,loader 不展开 homedir。 - mainAgent 数值非法:
mainAgent.settleMs等数值字段若 ≤0 或非数字,hub 启动逻辑会自动 clamp 回默认值,不阻断启动。
token 安全
authToken / hubToken 在配置文件里是明文,建议收紧文件权限:
chmod 600 ~/.cc-web-control/config.json
chmod 600 ~/.cc-web-control/hub-config.jsonloader 检测到文件权限过松(group/other 可读)且含非空 token 时,启动会打印 warning(不阻断)。
hub 多机模式
cc-web-control hub 启动一个中央服务,聚合多台机器上各自运行的 cc-web-control 实例:一个全局看板轮询所有机器、点行切换任一会话终端、多选会话批量广播同一条输入。浏览器只连 hub,单一入口、单一 token。
1) 机器侧准备(单机反向注册)
每台被聚合的机器照常运行 cc-web-control,做两件事:
(a) 对内网暴露 + 设本机 token(hub 看板轮询要回连单机的 /api/dashboard,需要这把 token 鉴权):
# 在每台机器上
CC_WEB_HOST=0.0.0.0 CC_WEB_AUTH_TOKEN=<各机 token> cc-web-control也可把
CC_WEB_HOST设为该机的局域网 IP(如192.168.1.10)。CC_WEB_AUTH_TOKEN必设——裸奔危险。
(b) 配置指向 hub 的注册信息(单机启动即自动连 hub 注册、断线自愈重连):
# 在每台机器上
CC_WEB_HUB_URL=http://<hub 所在机>:7685 \
CC_WEB_HUB_TOKEN=<hub token> \
cc-web-control相关环境变量(也可写进单机 config.json,见下文「配置文件」):
CC_WEB_HUB_URL— hub 的地址(含端口),如http://hub-host:7685。CC_WEB_HUB_TOKEN— 单机用来连 hub 注册的 token。默认与 hub 看板登录 token 同一把(分发到单机后,单机操作者也能登录 hub 看板;多操作者/不可信网络请改用CC_WEB_HUB_REGISTER_TOKEN)。CC_WEB_HUB_REGISTER_TOKEN— 可选的独立注册 token,与看板登录 token 分离:单机只能注册、不能登录看板。CC_WEB_MACHINE_ID— 稳定标识,正则^[A-Za-z0-9._-]{1,32}$,禁止含/(全局会话键分隔符)。不设默认取 hostname(多机环境可能冲突,建议显式设置)。CC_WEB_MACHINE_NAME— 显示名(可省略,默认取id)。CC_WEB_PUBLIC_URL— hub 回连单机用的地址。不设默认http://<CC_WEB_HOST>:<CC_WEB_PORT>;若单机CC_WEB_HOST是127.0.0.1但 hub 在远端,务必显式设为 hub 可达的地址(局域网 IP / 隧道地址),否则看板显示该机不可达。
只设了 CC_WEB_HUB_URL + CC_WEB_HUB_TOKEN(或 CC_WEB_HUB_REGISTER_TOKEN)即启用注册;两个都没设则单机独立运行(现状行为不变)。
2) hub 侧配置
hub 只需一把看板访问 token(注册机器运行时自动加入看板,无需预登记):
CC_WEB_HUB_TOKEN=<hub 访问 token> cc-web-control hub多操作者/不可信网络建议额外设
CC_WEB_HUB_REGISTER_TOKEN=<独立注册 token>,把「单机注册」与「看板登录」权限分离。
迁移指引(hub-machines.json → 单机注册)
旧版 hub 靠 ~/.cc-web-control/hub-machines.json 静态登记机器清单(字段:id / name / url / token)。自本版起该文件 deprecated:
- hub 启动若仍检测到该文件,会作静态种子加载并打印 deprecate 警告,机器照常出现在看板;
- 请逐步迁移到上面的「单机反向注册」——新机器只需在单机侧配
CC_WEB_HUB_URL+CC_WEB_HUB_TOKEN,hub 侧重启无需改动; - 该文件将在后续版本移除。
3) 启动 hub
CC_WEB_HUB_TOKEN=<hub 访问 token> cc-web-control hubhub 专用环境变量:
CC_WEB_HUB_TOKEN— 浏览器访问 hub 用的 token(必设,否则裸奔退出)。CC_WEB_HUB_REGISTER_TOKEN— 可选的独立注册 token,与看板登录 token 分离(单机只能注册、不能登录看板)。CC_WEB_HUB_MACHINES_FILE— 旧版静态机器清单路径(默认~/.cc-web-control/hub-machines.json),已 deprecated:若存在仍作种子加载并打印警告,请迁移到单机反向注册(见上方「迁移指引」)。CC_WEB_HUB_HOST— hub 监听地址(默认127.0.0.1)。CC_WEB_HUB_PORT— hub 端口(默认7685,避开单机默认 7684)。CC_WEB_HUB_DASHBOARD_INTERVAL_MS— 看板聚合轮询间隔(默认2000ms)。CC_WEB_HUB_NO_OPEN— 设为1(或传--no-open)禁用 hub 启动后自动开浏览器(对齐单机CC_WEB_NO_OPEN)。
4) 使用
浏览器打开 http://<hub 所在机>:7685/ → 输入 CC_WEB_HUB_TOKEN 登录 → 进入多机看板(hub 只服务 /dashboard.html):
- 看板:顶部全局 dashboard 展示所有机器及其会话状态(每 2s 聚合一次)。
- 点卡片新标签直达:点任一会话卡片 → hub 颁一张 15s TTL 一次性 ticket 并 302 → 浏览器新标签打开该机
:7684单机页(已登录态)。中键 / Cmd+点击 等浏览器原生行为均可用。 - 批量广播:多选若干会话 → 在广播栏输入 → 一次性扇出到所有选中会话。
http://<hub>/?token=<CC_WEB_HUB_TOKEN>直链可跳过登录页,仅供本地测试,勿用于日常/外网。
5) 安全提示
三层 token 各自独立、互不通用:
- 浏览器 → hub:
CC_WEB_HUB_TOKEN,登录后写 httpOnly + sameSite=lax cookie(cc_web_hub_auth,与单机cc_web_auth同 localhost 不互染)。 - hub → 各机:单机注册时把本机
CC_WEB_AUTH_TOKEN作为token字段上报给 hub;hub 看板轮询与 WS 终端代理都用它以Authorization: Bearer <token>回连各机 HTTP 与 WS。 - 各机对内网暴露:各机自己的
CC_WEB_AUTH_TOKEN把关。
注册 token 的分发语义:CC_WEB_HUB_TOKEN 分发到单机后,单机操作者即可登录 hub 看板;多操作者/不可信网络请用独立的 CC_WEB_HUB_REGISTER_TOKEN——它只能注册、不能登录看板。
SSRF 面:单机注册上报的 url 会经 hub 主动请求(看板轮询)。hub 不对注册 url 做地址白名单校验(loopback/私网/公网均可达),防护完全依赖 registerToken 准入——因此 token 只应发给可信机器;跨不可信网络须启用 https/wss。
明文风险:hub 走 http/ws 时,注册帧与回连都明文传输单机 token;跨不可信网络(hub 与单机不在同一可信内网)务必启用 https/wss。
建议把 hub 部署在内网,如需外网访问请走安全隧道(见下节)并保留 CC_WEB_HUB_TOKEN 鉴权。
反向代理部署时,登录限流按 socket 对端 IP 计数(未启用 trust proxy),内网单用户无影响;公网部署需自行配置 trust proxy。
外网访问(安全隧道 / 手机访问)
推荐用 Cloudflare Quick Tunnel(cloudflared)把本机服务安全暴露到外网,并开启 token 鉴权。
一键重启并打印 URL + 新 token
脚本:scripts/restart_tunnel.sh
cd <项目目录>
bash scripts/restart_tunnel.sh输出会包含:
URL: https://*.trycloudflare.comTOKEN: <new token>
手机打开 URL 后会进入 /login,输入 token 才能进入主页面。
代理(按需开启)
scripts/restart_tunnel.sh 默认不走代理;仅在设置 CC_WEB_PROXY_URL 时启用。
可按需覆盖:
CC_WEB_PROXY_URL="http://127.0.0.1:7890" bash scripts/restart_tunnel.sh