Skip to content

Web 管理界面(ui)

chainlesschain ui 会启动本地 Web 管理面板,并自动连接内置 WebSocket 服务。当前文档已对齐统一 runtime event、session record、后台任务增强、Worktree 合并助手和压缩观测的最新实现。

概述

ui 命令启动本地浏览器管理界面(HTTP 端口 18810 + WebSocket 端口 18800),将 CLI 已有能力以可视化方式呈现,覆盖 23 个页面(Dashboard、AI 对话、服务管理、技能配置、安全中心、P2P 网络等)。支持项目模式和全局模式,前端通过统一事件模型与 Runtime/WS Gateway 实时通信。

核心特性

  • 🖥️ Vue3 管理面板: 23 个功能页面,4 种颜色主题,支持项目级与全局两种工作模式
  • 🔗 自动对接 WebSocket: 启动 HTTP (18810) + 自动带起 WS (18800) 服务,无需单独配置
  • 🎨 主题与国际化: CSS 变量驱动 4 套主题,localStorage 持久化,一键切换
  • 🔐 Token 认证: 支持 --token 认证模式,Panel 加载后自动携带 token 与 WS 通信
  • 📊 统一事件模型: 所有会话、任务、压缩观测通过 runtime event 实时推送到面板
  • 🧩 三路面板检测: 优先使用 --web-panel-dir,其次源码产物,最后包内置产物,兜底经典 HTML
  • 🚀 零构建发布: npm 全局安装已内置 Panel dist,开箱即用
  • 🧪 可组合: 可单独作为前端接入外部 serve,也可一键复合启动

系统架构

Browser (http://127.0.0.1:18810)
    │  加载 Vue3 SPA + 注入 window.__CC_CONFIG__

    ▼  WebSocket (ws://127.0.0.1:18800)
┌───────────────────────────────────────┐
│  web-ui-server.js (Node HTTP)         │
│  ├── 三路 panel 检测 (dist / 内置 / 经典) │
│  └── 静态资源服务 + 配置注入             │
├───────────────────────────────────────┤
│  ws-server.js (与 serve 共享实现)      │
│  ├── 认证 / 心跳 / 消息分发              │
│  └── runtime event 广播                │
├───────────────────────────────────────┤
│  CLI Runtime (60+ 命令)                │
│  └── spawn 子进程 / Agent 会话          │
└───────────────────────────────────────┘

这是什么

chainlesschain ui 是 ChainlessChain 的本地浏览器管理界面。它的目标不是替代 CLI,而是把 CLI 已有能力以更适合观察、切换和联调的方式呈现出来。

它适合以下场景:

  • 用浏览器管理 Agent / Chat 会话
  • 查看后台任务、任务历史和完成通知
  • 查看压缩策略观测与会话运行状态
  • 在项目模式下,把对话绑定到某个项目根目录
  • 作为 chainlesschain serve 的内置前端使用

启动后会发生什么

执行:

bash
chainlesschain ui

会同时启动两类服务:

  • HTTP 服务,默认端口 18810
  • WebSocket 服务,默认端口 18800

浏览器页面负责展示界面,真正的会话、任务和运行状态仍然由本地 CLI 侧的 Runtime / WS Gateway 负责。

常用命令

bash
chainlesschain ui
chainlesschain ui --port 9000 --ws-port 9001
chainlesschain ui --token my-secret-token
chainlesschain ui --no-open
chainlesschain ui --web-panel-dir /custom/dist

常见用法:

  • 本机直接使用:chainlesschain ui
  • 联调其它前端或保留浏览器手动打开:chainlesschain ui --no-open
  • 需要认证:chainlesschain ui --token my-secret-token
  • 使用自定义构建产物:chainlesschain ui --web-panel-dir /custom/dist

配置参考

bash
# CLI 启动参数
chainlesschain ui [options]
  -p, --port <port>          # HTTP 端口 (默认 18810)
  --ws-port <port>           # WebSocket 端口 (默认 18800)
  -H, --host <host>          # 绑定地址 (默认 127.0.0.1)
  --no-open                  # 不自动打开浏览器
  --token <token>            # WebSocket 认证 token
  --web-panel-dir <dir>      # 自定义 dist/ 目录

# 环境变量
CC_UI_PORT=18810
CC_UI_WS_PORT=18800
CC_UI_HOST=127.0.0.1
CC_UI_TOKEN=<token>
CC_UI_WEB_PANEL_DIR=<dir>

# 运行时配置(注入到页面 window.__CC_CONFIG__)
{
  "wsUrl": "ws://127.0.0.1:18800",
  "token": "<token>",
  "projectRoot": "<cwd>",   // 项目模式时为项目根目录
  "mode": "project" | "global"
}

# 三路 panel 检测顺序
1. --web-panel-dir <dir>
2. packages/web-panel/dist/ (源码模式)
3. src/assets/web-panel/ (npm 内置)
4. 经典单页 HTML 兜底

性能指标

操作目标实际状态
面板首屏加载 (本地)< 1.5s~0.8s
WebSocket 连接建立< 100ms~40ms
页面切换 (Vue Router)< 100ms~35ms
runtime event 推送延迟< 50ms~20ms
主题切换过渡< 500ms~400ms
ui 启动 + WS ready< 2s~1.2s

运行模式

项目模式

从包含 .chainlesschain/ 的目录启动时,UI 会自动进入项目模式,并把 projectRoot 注入会话上下文。

适合:

  • 面向单个项目持续对话
  • 让 Agent 工具调用更明确地绑定项目目录
  • 区分项目级会话和全局会话

全局模式

从普通目录启动时,UI 作为全局管理面板运行。

适合:

  • 通用 AI 对话
  • 查看全局会话
  • 调试 Provider、技能和系统能力

页面能力概览

当前 Web Panel 覆盖 23 个页面,分为七大类:

概览:Dashboard、AI 对话、服务管理、日志查看

配置:技能管理、LLM 配置、MCP 工具

数据:笔记管理、记忆文件、定时任务、后台任务

高级:安全中心、权限管理、P2P 网络、备份同步、Git 与数据、项目管理

企业:钱包管理、组织管理、使用分析、模板中心

扩展:RSS 订阅、身份认证

Dashboard

Dashboard 负责展示全局摘要,而不是完整业务细节。当前已经能看到:

  • 会话数量
  • 压缩观测摘要
  • 时间窗口筛选后的统计
  • provider / model 切片的观测结果

Chat / Agent 会话

会话区域支持:

  • 新建 Agent / Chat 会话
  • 切换历史会话
  • 恢复会话 history
  • 流式 token 输出
  • 工具执行过程可视化
  • 交互式问题回答

后台任务

任务区域已对齐当前任务协议能力,支持:

  • 查询任务列表
  • 查询任务详情
  • 查询任务历史分页
  • 接收 task:notification
  • 查看任务输出摘要

压缩观测

压缩观测现在不是只显示一个总数字,而是支持:

  • windowMs 时间窗口筛选
  • provider / model 维度切片
  • 命中率
  • 节省 token
  • 净节省率
  • 策略分布
  • 变体分布

当前前端事件模型

Web Panel 已开始统一通过 onRuntimeEvent() 消费后端事件,而不是每个页面都直接监听原始 WS 消息。

已归一化的消息包括:

协议消息统一事件
task:notificationtask:notification
session-createdsession:start
session-resumedsession:resume
worktree-diffworktree:diff:ready
worktree-mergedworktree:merge:completed
compression-statscompression:summary

当前已接入统一事件入口的前端模块:

  • ws.js
  • tasks.js
  • chat.js
  • dashboard.js

这一步的意义是:

  • 前端主干页面开始共享一套标准事件流
  • 协议字段扩展时,不需要每个页面都重写一遍适配逻辑
  • Runtime / WS / Panel 三层开始真正共享同一模型

三类消息在前端的分工

当前前端实际同时接触三类消息:

1. 协议响应

用于回答某次主动请求的返回值。

典型包括:

  • session-list-result
  • tasks-list
  • tasks-detail
  • tasks-history
  • worktree-diff
  • worktree-merged
  • compression-stats

2. Runtime Event

用于描述“系统状态发生了什么”,由 ws.js 归一化后通过 onRuntimeEvent() 广播。

典型包括:

  • session:start
  • session:resume
  • session:end
  • task:notification
  • worktree:diff:ready
  • worktree:merge:completed
  • compression:summary

3. Session Stream

用于描述当前会话的流式输出过程,主要由 chat.js 直接消费。

典型包括:

  • response-token
  • response-complete
  • tool-executing
  • tool-result
  • question

当前口径是:

  • ws.js 负责协议响应 → runtime event 的归一化
  • chat.js 继续直接消费 session stream
  • 不要求把所有流式 token 消息都迁进 onRuntimeEvent()

Session Record

会话相关数据现在统一附带 record,用于让前后端对齐会话摘要结构。

标准字段包括:

  • id
  • type
  • provider
  • model
  • projectRoot
  • messageCount
  • history
  • status

当前会返回 record 的消息:

  • session-created
  • session-resumed
  • session-list-result

这意味着无论是:

  • 被动收到会话创建/恢复响应
  • 主动拉取会话列表

前端拿到的都是同一套 session summary 结构。

会话流转

一个典型会话流程如下:

  1. UI 建立 WebSocket 连接
  2. 如果配置了 token,先发送 auth
  3. 拉取 session-list
  4. 创建新会话,或恢复已有会话
  5. 发送 session-message
  6. 接收:
    • response-token
    • tool-executing
    • tool-result
    • question
    • response-complete

当前还有两个重要细节:

  • 会话关闭后,前端会本地补发 synthetic session:end,保持统一事件流连续。
  • 当本地没有缓存消息时,切换会话会自动调用 session-resume 拉回 history。

WebSocket 协议要点

事件方向说明
auth→服务端发送 token 认证
auth-result←服务端返回认证结果
session-list→服务端请求会话列表
session-list-result←服务端返回会话列表,sessions[] 每项带 record
session-create→服务端创建新会话
session-created←服务端返回 sessionIdsessionTyperecord
session-resume→服务端恢复历史会话
session-resumed←服务端返回 history[]record
session-close→服务端关闭会话
tasks-list→服务端查询后台任务
tasks-history→服务端查询任务历史分页
tasks-detail→服务端查询任务详情
compression-stats→服务端查询压缩观测摘要
worktree-diff→服务端查询 diff 预览
worktree-merge→服务端执行一键合并

serve 的关系

  • ui 面向浏览器用户,是完整管理界面入口。
  • serve 面向外部接入,是 WS Gateway 入口。
  • 二者不是两套完全独立系统,而是前后配合:
    • ui 负责页面
    • serve / 内置 WS 服务负责协议与 Runtime 暴露

如果你只是想打开浏览器管理界面,优先使用 chainlesschain ui。如果你要把 CLI 接到 IDE、插件或自定义前端,优先使用 chainlesschain serve

常见联调点

1. 页面有了,但状态不更新

优先检查:

  • 是否已经通过 onRuntimeEvent() 订阅
  • 当前消息是协议响应还是统一事件
  • sendRaw() 的 pending resolve 之后,事件是否仍然继续广播

2. 会话列表和会话详情字段不一致

优先检查:

  • session-list-result.sessions[] 是否带 record
  • session-created / session-resumed 是否带 record
  • 前端 listSessions() 是否做了统一归一化

3. 任务页没有收到完成通知

优先检查:

  • 是否有 task:notification
  • 任务页是否在消费 onRuntimeEvent()
  • 后台任务是否已经完成持久化与恢复初始化

4. Dashboard 统计不对

优先检查:

  • compression-stats 是否带了 windowMs
  • provider / model 筛选参数是否透传
  • 统计是否来自统一 runtime event,而不是旧的局部手动赋值

安全中心

安全中心覆盖三大模块:

  • DID 身份管理:列表、创建、签名验证
  • 文件加解密:AES-256-GCM 加密/解密
  • 审计日志:事件列表、统计卡片

P2P 网络

P2P 页面支持:

  • 设备列表与在线状态
  • 配对新设备
  • 发送加密消息
  • 同步状态查看与推送/拉取操作

Git 与数据

Git 页面包含两个 Tab:

  • Git 仓库:分支显示、变更计数、自动提交(带确认弹窗)
  • 导入导出:Markdown/PDF/Evernote 导入、静态站点导出

项目管理

项目页面支持:

  • 项目状态卡片(系统状态、LLM、初始化、配置)
  • 6 个项目模板初始化
  • 环境诊断(doctor 命令)

当前验证

  • Web Panel 单元测试:523/523(9 个文件,含批次 1+2 页面解析测试)
  • Web Panel 集成测试:40/40(web-ui-server + CLI 命令集成)
  • Web Panel E2E:12/12(WS 协议兼容) + 46 SPA 路由 + 资源文件测试
  • Web Panel 构建:通过

测试覆盖率

packages/web-panel/src/**/__tests__/
├── ✅ parsers.test.js           # 纯函数解析层 (技能/状态/MCP/记忆/Cron)
├── ✅ theme.test.js             # 4 主题切换 + localStorage 持久化
├── ✅ ws-store.test.js          # WS 连接状态管理
├── ✅ chat-store.test.js        # 会话与流式消息
├── ✅ tasks-store.test.js       # 后台任务状态
├── ✅ dashboard-store.test.js   # Dashboard 统计聚合
├── ✅ new-pages.test.js         # 批次 1 新页面解析
└── ✅ batch-pages.test.js       # 批次 2 新页面解析

packages/cli/__tests__/
├── integration/
│   ├── ✅ web-ui-server.test.js      # HTTP 静态 + 配置注入
│   └── ✅ cli-commands.test.js        # ui 命令选项解析
└── e2e/
    ├── ✅ ws-protocol-compat.test.js  # WS 协议兼容性
    └── ✅ panel.test.js               # SPA 路由 + 资源加载
  • 前端 Store: WS / Theme / Chat / Skills / Providers / Tasks / Dashboard
  • 页面解析: 23 个页面的纯函数解析层
  • 集成: ui 启动链路 + WS gateway 对接
  • E2E: WebSocket 协议、SPA 路由与静态资源

安全考虑

1. 输入验证

  • WebSocket 消息校验: 所有入站消息经过 message-dispatcher.js 的 type + schema 校验
  • XSS 防护: 面板渲染用户内容(会话、技能描述)通过 Vue 的自动转义 + marked.js 的 sanitize
  • 命令黑名单: WS 层禁止 serve / chat / agent / setup 等交互式命令(继承自 serve

2. 权限控制

  • 默认 localhost: 默认只监听 127.0.0.1,浏览器仅本机可访问
  • Token 必需模式: --token 设置后,Panel 加载时通过 URL 参数或 localStorage 读取,不符合立即踢出
  • 同源策略: Panel 与 WS 同源(loopback),浏览器 CORS 天然隔离
  • 会话隔离: 多浏览器窗口连接时,每个 WS 连接独立管理自己的 session ID

3. 审计

  • 访问日志: HTTP 请求记录到 ~/.chainlesschain/logs/web-ui.log
  • WS 连接日志: 每次 connect / auth 成功/失败 / disconnect 均记录 IP + 时间戳
  • 敏感操作溯源: 会话创建、任务触发、worktree merge 等操作在日志中可定位到具体 WS connId

4. 进程隔离

  • UI 服务与 WS 服务共享同一 Node 进程;命令执行仍通过 spawn 子进程隔离
  • Panel 前端通过 WS 协议调用 CLI,无本地文件写入权限

故障排查

Q: 启动后浏览器自动打开但页面空白 / 仅显示骨架?

  1. 打开浏览器 DevTools Console,查看是否有 WS 连接错误
  2. 确认 --ws-port 与实际 WS 端口一致(面板通过 window.__CC_CONFIG__.wsUrl 连接)
  3. 检查是否被浏览器扩展拦截(某些代理插件会阻断 ws://127.0.0.1

Q: 提示 "WebSocket 未连接" 且仪表板全空?

  1. 面板内置指数退避重连,等 3-5 秒看是否自动恢复
  2. 确认 --token 值服务端与浏览器完全一致(区分大小写)
  3. 运行 netstat -ano | findstr :18800(Windows)/ lsof -i :18800 确认 WS 端口存活
  4. 若使用 --web-panel-dir,确认该目录包含 index.html__CC_CONFIG__ 注入脚本

Q: Error: listen EADDRINUSE :::18810?

端口被占用。使用 --port 9000 --ws-port 9001 或杀掉占用进程后重试。

Q: 修改代码后 Panel 没更新?

npm 全局安装的用户,面板 dist 内置在包中,需要 npm update -g chainlesschain。源码用户运行 npm run build:web-panel 重建。

Q: 主题切换后刷新又变回默认?

主题存储在 localStorage;如使用无痕模式或浏览器清理了 localStorage,会回到默认。已登录的浏览器应该持久化。

Q: 项目模式没生效,Agent 工具不识别 projectRoot?

确认启动时 cwd 是包含 .chainlesschain/ 目录的项目根目录。运行 chainlesschain ui --verbose 可在控制台看到 mode: projectmode: global

关键文件

文件职责
packages/cli/src/commands/ui.jsui 命令入口,参数解析 + 启动编排
packages/cli/src/lib/web-ui-server.jsHTTP 服务器 + 静态资源 + __CC_CONFIG__ 注入
packages/cli/src/lib/ws-server.jsWebSocket 服务(与 serve 共享)
packages/web-panel/src/main.jsVue3 SPA 入口
packages/web-panel/src/stores/ws.jsWS 连接状态管理(指数退避重连)
packages/web-panel/src/stores/theme.js4 主题状态与 localStorage 持久化
packages/web-panel/src/utils/parsers.js纯函数解析层
packages/web-panel/src/views/23 个页面视图
packages/cli/src/assets/web-panel/npm 发布时内置的 dist 产物

使用示例

bash
# 默认启动
chainlesschain ui

# 指定端口 + token(面板与 WS 同步)
chainlesschain ui --port 9000 --ws-port 9001 --token mysecret

# 不自动打开浏览器(CI / 联调)
chainlesschain ui --no-open

# 局域网分享(绑定 0.0.0.0)
chainlesschain ui --host 0.0.0.0 --token strong-token

# 开发模式:使用本地构建产物
chainlesschain ui --web-panel-dir packages/web-panel/dist

# 复用已存在的 serve 服务(前后分离)
chainlesschain serve --port 18800 --token t1 &
chainlesschain ui --ws-port 18800 --token t1 --no-open

# 项目模式(cwd 自动识别)
cd /path/to/project && chainlesschain ui

# 通过环境变量配置
CC_UI_PORT=9000 CC_UI_TOKEN=secret chainlesschain ui

相关文档

基于 MIT 许可发布