跳转至

Skill 菜单与展示优化

背景

Web 端 Skills 按钮在移动端存在多个严重问题:点击崩溃、菜单内容过时、技能数据为空。Dad 要求彻底修复交互问题并升级技能分类展示,最终推动了从前端 UI 修复到协议字段设计的完整演进。


2026-04-03:移动端 Skills 按钮崩溃修复

问题:手机视窗点击 Skills 按钮后页面 crash,触发 React Error #300(Rendered fewer hooks than expected)。

根因:组件内部存在 React Rules of Hooks 违规 —— 某些条件路径下 hook 数量不一致,点击 Skills 触发渲染分支变化导致崩溃。onOpenSlashMenu 本身只做 setInputValue('/') + setShowSlashMenu(true),并非直接原因。

解决:修复 SuggestionBar / ChatRoom 中条件 hook 调用问题,重新 build + deploy 后在手机视窗复测通过。

里程碑:移动端 Skills 按钮从"点击即崩"恢复为可用。


2026-04-03:斜杠命令菜单升级到 OpenClaw 2026.4.1

问题:Dad 反馈 Skills 按钮虽不崩溃了,但菜单内容仍是旧版命令集。

Dad 决策:要求按最新 OpenClaw 支持的 slash commands 更新菜单。

技术方案:前端 slash menu 改为按 section 分组展示,分为 4 组:

Section 命令示例
COMMANDS /help, /commands, /status, /whoami, /skill, /stop
SESSION /new, /reset, /model
DIRECTIVES 指令类命令
ADVANCED 高级命令

里程碑:斜杠菜单从单列表升级为 section 分组结构,对齐 OpenClaw 2026.4.1。


2026-04-03:Skills 数据为空 — 服务端扫描路径错误

问题:斜杠菜单中技能列表为空,之前有数据现在消失了。

根因:前端链路 agent.list → saveCachedAgents → getAgentInfo → agentInfo.skills 本身是通的,但 channel 插件只扫描 ~/.npm-global/lib/node_modules/openclaw/skills/,而 Owl 实际安装位置是 /usr/lib/node_modules/openclaw/skills/

解决:扩展 scanInstalledSkills 的扫描路径,改为查找 OpenClaw 实际安装路径,不再硬编码单一目录。

里程碑:修复服务端 skills 扫描路径错误,恢复 agent.list 中 skills 数据来源。


2026-04-03:ChatRoom 未主动请求 agent.list

问题:服务端已能返回 skills,但客户端经常显示 skills: []

根因ChatRoomconnection.open 后只请求 selectAgentrequestHistory,不请求 requestAgentList。用户未经 ChatList 页面时,agentList 缓存为空。

解决: - 在 connection.open 后自动请求 agent.list - 收到响应后刷新 agentInfo - ChatRoom 不再依赖 ChatList 预热缓存

结果agentList 缓存成功建立,每个 agent 可拿到完整 skills(示例中 53 个),slash menu Skills 区域正常显示。


2026-04-04:技能分类展示需求 — 区分内置与已加载

Dad 决策:提出明确的展示层级要求: 1. 系统内置技能折叠起来 2. 只展示已加载的技能 3. 未加载技能灰色显示,放到最后 4. 斜杠消息点击后直接发送

第一次方案:channel 端拆分 skillsconfiguredSkills,前端用 skills - configuredSkills 推断 built-in。

问题configuredSkills 实际已包含所有(user + npm),导致 skills == configuredSkills,built-in section 永远为空。

转折点:这是第一次把"技能分类展示"从前端 UI 问题升级为"协议字段设计问题"。


2026-04-04:Skills 按钮难以触发

问题:Dad 反馈"Skills 按钮要点好几遍才能点出来,有时候还不出来"。

解决:排查 SuggestionBaronOpenSlashMenu 链路,修复 3 个相关问题 —— Skills 按钮触发链路、slash menu 打开条件、SuggestionBar 按钮显示逻辑。部署后触发稳定性显著提升。


2026-04-05:最终方案 — 显式 builtinSkills 字段

这是本主题最关键的结构化落地。

核心决策:不再靠前端差集推断 builtin,由 channel 插件显式提供 builtinSkills 字段。

实施步骤: 1. Channel 插件在 agent entry 构建时新增 builtinSkills 字段 2. 前端 AgentInfo 类型更新,支持 builtinSkills 3. ChatRoom.tsx 技能展示逻辑重构,基于明确字段分类

字段演进

// 阶段一
skills: string[]
configuredSkills: string[]

// 阶段二(最终)
skills: string[]
configuredSkills: string[]
builtinSkills: string[]     // 新增

展示逻辑: - configuredSkills → 优先展示,已加载技能 - builtinSkills → 系统内置,折叠展示 - 其余 → 灰色显示,放末尾

结果:channel repo type check 通过,client-web build 通过,已提交并部署到 Owl。

里程碑:前端从"推断分类"升级为"显式字段驱动"的技能分类展示。


关键决策总览

时间 决策者 决策
04-03 09:03 Dad slash menu 必须对齐最新 OpenClaw 命令集
04-03 10:51 Bot skills 缺失定位为服务端扫描路径问题
04-03 22:57 Bot ChatRoom 技能缺失因未请求 agent.list
04-04 21:27 Dad 内置技能折叠、已加载优先、未加载灰显
04-04 21:32 Bot 引入 configuredSkills 概念(首次尝试)
04-05 13:42 Bot 新增 builtinSkills,放弃前端差集推断

最终状态

截至 2026-04-05 13:45,完整闭环:

  1. ✅ Skills 按钮崩溃修复(React Hooks 违规)
  2. ✅ Skills 按钮触发稳定性修复
  3. ✅ Slash menu 对齐 OpenClaw 2026.4.1 命令集
  4. ✅ ChatRoom 主动拉取 agent.list,skills 不依赖缓存
  5. ✅ Channel 插件新增 builtinSkills 字段
  6. ✅ 前端区分 builtinSkills / configuredSkills 展示
  7. ✅ 技能分类从"推断"升级为"显式字段驱动"