# client 半身与配置页 > 状态:**v0.25.3(2026-10-20)**。本文是 client 半身的契约文档:配置页在哪、长什么样、 > 配置怎么分层、HTTP 面怎么调、保存后哪些东西立刻生效、样式怎么跟宿主主题一致。 > 总体架构见 [architecture.md](./architecture.md),配置项全表见 [config.md](./config.md)。 ## 1. 定位与注册落点 配置页画在**插件面板**里:左栏「插件」图标(`main` 面板 key `plugins`)→ 我的 / Bundles → `dsh-qq-relay` 组合包自己的页面。注册座位是 **`plugins.bundle.config`**,key 为包名 `dsh-qq-relay`;页面标题、描述、安装信息与**启停开关**由插件管理器负责,本插件只画表单内容 (官方契约:`view: 'page'` 的表单自带保存控件)。 - **为什么搬到这里**:配置跟着插件走,和「这个插件在哪启动 / 停用」放在同一页;设置里不再单列一块。 - **注册与行同生共死**:浏览器半身挂在插件的 Loader 行上,行被停用后这个页面(含配置块) 一起消失;重新启用并刷新页面后回来。 - **不新增顶级入口、不占右栏**;HTTP 面同源、无独立鉴权(GUI 默认只绑 loopback, 不要把本插件挂到公网监听上)。 - 排错顺序:插件面板里找不到这个组合包 → 没装入 profile / 没重启 GUI;组合包页里没有配置块 → client 半身没加载或注册失败(看浏览器控制台与插件页状态)。 页面是**二级结构**:固定的状态行 + 保存动作,下面是「连接 / 环境 / 项目 / 行为 / 画图·视频 / 预设 / 记录」七个二级页面(下划线 tab,沿用宿主插件页的分区风格)。 ## 2. 页面内容 ### 2.1 顶部(所有二级页面共享) | 区域 | 内容 | |---|---| | 状态行 | 状态点 + 文案:已连接(昵称 / QQ 号)· 连接中(断线自动重连)· 未启动(配置待补全 / 另一个实例持锁,显示 pid) | | 动作 | 「刷新」「重新连接」「保存并重连」(主按钮);任何二级页面都能直接保存 | | 提示 | host 校验问题逐条显示;保存成功 / 失败的提示;「有未保存的修改」 | ### 2.2 七个二级页面 | 页面 | 内容 | 动作 | |---|---|---| | 连接 | 运行状态卡(协议端地址 / 登录账号 / 单实例锁 / 群映射数 / problems);`wsUrl` · `accessToken`(只写,留空不修改)· `selfId` · `groups` | 刷新 / 重连 / 保存 | | 环境 | `environment.enabled` · `environment.dir` · `environment.webuiToken`(只写,留空不修改);7 步检查表(Docker CLI / 容器引擎 / compose 文件 / NapCat 容器 / QQ 登录 / OneBot 配置 / 插件回填),每步状态 + 证据 + 按钮;**修复计划**(将依次执行什么 + 下一步,v0.25.0);动作日志(脱敏);安全边界说明(v0.23.0) | 「一键修复」(逐步补全,含安装 / 启动 / 重启引擎时先确认)「重新检测」「打开 WebUI 扫码」+ 每步动作(安装 / 启动引擎 / 重启引擎 / 写 OneBot 需二次确认) | | 项目 | 默认 `workspace` · `sessionTitle`;群项目目录表(群号 / 会话 / 项目目录 / 操作);最近消息(按群展开,只读);workspace 挂载失败告警(v0.21.1,会话显示「未分组」时) | 「重新绑定」「消息」「解除绑定」「清空全部映射」 | | 行为 | `replyChunkSize` · `commandPrefixes`;闸门参数 `gate.debounce` / `gate.fastMinReplyInterval` / `gate.jevThreshold` / `gate.model`(v0.25.6)/ `gate.jevEndpoint`(v0.25.6)/ `gate.jevApiKey`(只写,留空不修改;保存即热切换分类器,v0.24.0 / v0.25.6)+ 闸门摘要(开关 / 分类器 / 阈值 / key 来源);**角色与人设**(agent preset 下拉 + 轻量人设开关 / 文本,v0.19.0);**代答**(开关 + 目标名单 + 沉默窗口,v0.18.0) | 保存(保存即重建 relay / 闸门,无需重启) | | 画图 / 视频 | ComfyUI 服务(启用画图 / 视频 / 服务地址 / 探测超时 3s..120s / 连接成功后加载 skill)+「测试连接」+ 运行状态(可达 / 版本 / GPU / 队列 / 最近检查 / **逐条** `comfy-image`、`comfy-video` 的加载状态与错误,v0.22.0) | 「测试连接」(只探测、不保存);保存 `comfy` 后立即探测并决定是否注册两个 skill,不重建 relay | | 预设 | 插件管理的 QQ 预设列表(名称 / 模型 / 权限 / 编辑 / 删除);新建 / 编辑表单:id · 名称 · 描述 · persona · provider / model / 思考层级 · 权限预设 · 排序(v0.20.0) | 保存预设 / 取消 / 删除(正在使用的预设在 host 侧拒绝删除) | | 记录 | `chatRetentionDays`(0 = 永不自动删除;7..3650 = 自动清理) | 「立即清理」(用输入框天数 1..3650,二次确认) | - 行为页还有**每群实时状态表**:待评估条数 / 最近发言 / 冷却 / DSH 忙 / 评估中,外加全局计数 (待评估消息 / 群、活动定时器、派发队列、发送队列);随状态轮询 5 秒刷新。 - 「代答」(v0.18.0):开关(默认关)+ 目标名单(QQ 号或群名片 / 昵称,逗号分隔)+ 沉默窗口(默认 `10m`,`0s` = 总是代答)。开启时名单不能为空,页面保存前就地校验。 - 「角色与人设」(v0.19.0):agent preset 下拉(空 = 跟随 DSH 默认;选项来自 host 的 `agentPresets.list()`,`broken` 的项标「(不可用)」并禁用)+ 轻量人设开关 / 多行文本框。 宿主没有 `agentPresets` 服务时下拉隐藏并提示;配置里的 preset 不在名册时提示 missing。 保存后 preset 只影响新建会话(已有群要 `/new` 或「重新绑定」),人设下一条消息生效。 - 「环境」(v0.23.0):数据源是 `GET /api/env`(见 [env.md](./env.md) §6),页面挂着时每 5 秒轮询 (有动作在跑时 2 秒);目录 / token 用顶部「保存并重连」落盘,保存后 host 用新目录重新探测。 步骤状态是 `ok / warn / error / skip` 四档;`skip` 表示前置缺失(不是失败)。 「一键修复」(v0.25.0 起**逐步补全**):host 下发 `status.fixPlan`(`sequence` / `titles` / `needsConfirm` / `next`),页面把它渲染成「一键修复将依次执行:… 下一步:…」一行; 点按钮时若 `needsConfirm` 先 `window.confirm` 一次,然后带 `confirm:true` 发给 host。 host 侧是**逐轮推进**:每执行一个动作就重新探测、重排计划,所以装完引擎会出现 `compose-up`、 容器起来后才会轮到 OneBot / 回填;被 `skip` 的步骤在前置补齐后自动变成可修复。 安装类动作单独点击时仍各自二次确认。 「打开 WebUI」由 host 拼 `http://127.0.0.1:6099/webui?token=…` 返回,页面新开标签页并把链接 同时渲染出来(弹窗被浏览器拦截时可手点)。命令类动作后台执行,进度看 `status.running` 与日志。 - 「画图 / 视频」(v0.22.0,页签文字就是「画图 / 视频」):四个字段 `comfy.enabled` / `baseUrl` / `timeoutMs` / `skillEnabled`;「测试连接」用**表单里填的**地址与超时探测一次 (不保存配置,返回 target / 可达 / 版本 / GPU / 队列 / 延迟 / 错误);「运行状态」表展示后台探测 结果,并**逐条**显示 `comfy-image`(出图)/ `comfy-video`(视频)两个 skill 的加载状态与错误。 宿主还是旧版本(没返回 `config.comfy`)时整页提示重启,字段按关闭兜底;旧 host 只返回单数 `comfy.skill` 时 client 兜底成单元素数组(页面只显示一个 skill)。详见 [comfy.md](./comfy.md)。 - 「最近消息」:该群最近 24 小时聊天记录(最多 20 条),只读显示时间 / 显示名 / @ 与引用标记 / 媒体标记(含 `[文件]` / `[群文件下载失败]`)。 - 「预设」页(v0.20.0):列表 + 编辑器;provider / model / 思考层级下拉来自宿主 `modelCatalog`,权限来自 `permissionCatalog`;宿主没有对应服务时模型字段退化为手填。 保存后 host 动态注册 preset(无需重启 GUI),但已有群会话要 `/new` 才换过去。 - 页面每 5 秒静默刷新一次状态(只刷新连接态与映射,不覆盖正在编辑的表单)。 - 破坏性动作(重新绑定 / 解除绑定 / 清空映射 / 立即清理)用浏览器 `confirm` 二次确认。 ## 3. 样式与主题 client 半身只依赖 React,**不能 import 宿主的 CSS Modules 或 ui-primitives**;因此 `src/view/theme.ts` 往 `document.head` 注入一份普通 CSS(`