OpenClaw Custom Channel

浏览器插件安装引导 PRD

这是面向产品评审和开发交接的用户需求文档:当 agent 调用的工具依赖一个尚未安装的浏览器插件时,会话需要停下来引导用户安装,并在依赖就绪后继续原任务。 文档先用用户故事串起首次引导、自动续跑、拒绝降级、离开恢复、排障和不在场触发,再用状态机、操作矩阵和验收标准支撑实现。 读者不操作原型也应能通过本文档理解每个状态和它的退出方式。

当前目标:工具依赖缺失时的阻塞引导与恢复 复用 plugin approval,不新增协议 Channel 自渲染 两道平行门:安装 + 权限 依赖就绪自动续跑 产品文案英文 · 文档中文 每条路径必须有可见终点 审批硬上限 10 分钟

1. 一页结论

本文档是本轮工具依赖引导的产品和开发交付依据。评审时先确认这一节,再按用户故事阅读需求;完整交互原型用于补充体验验证。 贯穿全文的唯一硬原则是:每一条路径都必须落到一个用户可见的终点,没有「卡在那里」这个状态

用户问题

  • 用户提了一个正常需求,agent 干到一半停下来,用户不知道发生了什么。
  • 一句 Not connected 这类笼统提示无法区分没装、装错浏览器、装了但页面没刷新,用户会反复卡在同一步。
  • 用户去装插件时注意力已经离开对话;回来还要再点一次按钮,会觉得系统没记住他刚做过的事。
  • 用户没看到提示、点了拒绝、点了安装却没回来,这些都是常态;今天这些路径都会变成悬案。

本版目标

  • 工具执行前探测依赖,缺失时抬起一张停靠式引导卡,不先制造一次可见失败。
  • 依赖状态区分未安装与浏览器不匹配,并给不同的下一步;第二次失败进入内容不同的排障态。
  • 检测到依赖就绪时自动续跑原任务,用户不需要回来点确认。
  • 退出分两类:Skip/发新消息/超时把卡片折成可展开的 mini 条,× 才是彻底关闭且需二次确认。依赖事后就绪且意图仍在时反向唤醒。

范围边界

  • 本版覆盖两道平行的门:安装 Operator 扩展、开启 user scripts 权限。两者互不为前置,交互骨架共用,差异见第 8 节。
  • 这是产品文档,描述用户看到什么、系统该有什么行为。OpenClaw 是我们的运行底座,本文只在第 13 节集中列出对它的能力需求;正文不受它当前实现限制。
  • 依赖探测能力由我们自己的扩展提供,产品侧只消费探测结果。
  • 本 PRD 以浏览器能力为具体场景,机制对任何「操作前需要用户先完成外部一步」的能力通用。
  • 面向英文客户,所有产品文案为英文;本文档为中文,正文引用按钮时一律写真实英文串。第 8 节是文案定稿口径。

非目标

  • 不做插件本体的安装器、更新器或版本协商。
  • 不做跨设备的依赖状态同步;每台设备各自探测、各自显示。
  • 不在本版自建等待机制来绕开运行时的等待上限;该上限是待补能力,见第 13 节。

阅读方式

  • 产品评审先读用户故事和故事状态原型,确认每条异常路径都有终点。
  • 设计评审用完整交互原型走一遍全部用户故事,重点看状态之间的过渡文案。
  • 开发实现从用户故事映射到 FR、OP、AC,再看字段映射和显示规则;运行时能力的边界看第 13 节。

两个出口,一个镜子

  • Skip 是「先收起来」,折成 mini 条随时展开;× 是「拿走」,需二次确认且本会话不再出现。
  • 设置页是状态镜子加指路牌,不拥有开关——真正的开关在浏览器里(装/卸扩展、开/关权限)。
  • 产品侧因此没有「永久关闭能力」这回事,任何一次退出都不会让能力变成不可达。

2. 用户故事

用户故事是本文档的主线。每个故事右侧都嵌入同一套完整原型,并打开到该故事对应的初始状态;读者可以直接交互,也可以只阅读流程、边界和验收。 US-3 到 US-6 覆盖的是「用户不按剧本走」的路径,它们和主流程同等重要。

US-1:第一次遇到需要插件的能力

FR-1 FR-2 FR-3

作为提出了正常需求的用户,我希望在 agent 需要一个我还没安装的浏览器插件时,被清楚地告知还差哪一步,而不是看到一次失败或一段沉默。

可交互原型状态

US-2:安装完成后自动继续

FR-4 FR-11

作为刚装完插件的用户,我希望回到对话时任务已经在继续,而不是还有一个按钮在等我点——我刚刚已经完成了那个动作。

可交互原型状态

US-3:这次先不用,或者我不想装

FR-5 FR-6 FR-9

作为不想安装任何东西的用户,我希望能干脆地跳过,并且 agent 还能用别的方式帮到我,而不是沉默或者反复弹同一张卡。

可交互原型状态

US-4:中途离开,过一会儿才回来

FR-6 FR-7 FR-12

作为点了安装就去忙别的、或者压根没注意到卡片的用户,我希望回来时能看懂发生了什么,并且能接着做,而不是从头再问一遍。

可交互原型状态

US-5:装了,但还是不行

FR-3 FR-8

作为已经装了插件却仍被拦住的用户,我希望看到具体差在哪一步,而不是同一张卡再弹一次——那读起来就像按钮坏了。

可交互原型状态

US-7:开启 user scripts 权限

FR-16 FR-17 FR-18

作为要让 agent 代我操作页面的用户,我希望它清楚说明还需要我在 Chrome 里打开哪个开关、为什么,并且开完能自动接着做——而不是丢给我一句权限不足。

可交互原型状态

US-8:在设置里主动配好,或者把关掉的找回来

FR-19 FR-20

作为想让 Claw 控制浏览器的用户,我希望能在设置里一次看清还差哪几步并直接配好;作为之前关掉过提醒的用户,我希望还能找回这个能力,而不是从此再也打不开。

可交互原型状态

US-6:用户不在场时被触发

FR-10 FR-13

作为设置了定时任务的用户,我希望任务因为缺插件跑不起来时能被告知,而不是任务默默什么也没做。

可交互原型状态

3. 完整交互原型

原型是同一份实现,通过顶部状态切换器在十一个状态之间跳转。它用于验证过渡文案和信息层级,不是唯一需求来源;任何原型未覆盖的行为以第 10 节的状态机和操作矩阵为准。

建议评审路径

  • 从「待操作」开始,确认文案读起来是安装步骤而不是错误。
  • 切到「等待连接」,确认主按钮已让位给状态说明。
  • 切到「排障」,对比它和「待操作」的差异是否足够明显。
  • 切到「Skip(mini)」和「Close(关闭)」,确认两者留下的东西完全不同。
  • 切到「×(告知)」,确认 Cancel 能完整退回、Got it 才真正生效。
  • 最后切到分隔线下方的「设置页」,注意它是另一个 surface:浅色、无输入框、不出现任何引导卡。

开发重点

  • 卡片停靠在输入框上方,不是聊天气泡,也不是模态框。
  • 塌缩后的摘要行留在时间线上,不做定时清除。
  • 「Install」和「Already installed」必须是两个按钮,不能合并。
  • 动作区顺序固定为 Skip → 次要动作 → 主按钮;DOM 顺序即视觉顺序,键盘 tab 先到安全出口再到提交动作。
  • 动作行必须在 360px 下单行,且最多三个控件。
  • 暂缓类退出留 mini 条,关闭留时间线指引;两者都不会让这件事消失。
  • 跳过不是终点:摘要行指向设置页,再问一次也会重新引导。

4. 产品决策

保留在主路径

  • 停靠式引导卡:目标说明、缺失项、安装按钮、已装好按钮、跳过。
  • 依赖三态区分及各自的下一步动作。
  • 依赖就绪自动续跑,并把卡片塌缩成一行摘要。
  • 依赖就绪时的反向唤醒(限最近一次意图)。
  • 跳过后的降级方案或干净收尾。
  • 动作区从左到右按权重递增排列:Skip(弱)靠最左,次要动作居中,主按钮贴最右。手机上主按钮落在拇指热区,误触成本最高的「Skip」落在最难碰到的一侧。
  • 动作行最多三个控件,且必须在 360px 视口下保持单行。卡片上不放永久性动作——那是另一类决定,属于设置页;塞进来还会挤爆这一行并把主按钮甩到左下角。
  • 非交互 run 的能力状态位与通知。

从主路径隐藏

  • 工具名、内部请求 ID、决策枚举值等内部标识不出现在用户文案中。
  • 不展示审批剩余秒数倒计时,避免制造时间压力;到期直接换态。
  • 不展示「一直允许」这个决策——安装是一次性动作,不存在持续授权语义。
  • 不在首次引导里堆排障内容;排障只在第二次出现。
  • 不为引导单独开一个设置页;常驻入口就是扩展 options 页里的 Browser control 分组。

5. 功能需求

功能需求用来连接用户故事、字段映射、状态机和验收标准。开发拆分任务时应先确认用户故事,再从 FR 落到 S、OP 和 AC。

ID用户故事需求用户价值对应验收
FR-1US-1工具执行前探测依赖;缺失时抬起阻塞式引导,不先产生一次可见失败。用户看到的是「还差一步」,不是「出错了」。AC-1
FR-2US-1引导以停靠卡形式出现在输入框上方,事后塌缩为时间线上的一行摘要。提示不会被滚走,也不会挡住用户查看上文。AC-2
FR-3US-1、US-5依赖状态必须区分未安装与浏览器不匹配,并给出各自的下一步;第二次探测失败时进入内容不同的排障态。用户不会在一句 Not connected 这种笼统提示上反复卡住。AC-3、AC-10
FR-4US-2等待期间持续探测;依赖就绪时自动放行并继续原任务。用户装完回来任务已经在跑,不用再点一次。AC-4
FR-5US-3必须提供跳过出口;跳过后 agent 给出降级方案或干净收尾。不想装的用户有退路,且不会留下悬案。AC-6、AC-7
FR-6US-3、US-4退出分两类:Skip/发新消息/超时把卡片最小化成常驻可展开的 mini 条;× 彻底关闭并在时间线留一行指向设置页。「先收起来」和「拿走」是两种意图,各有各的出口,都不会把这件事弄丢。AC-8、AC-13、AC-19
FR-7US-4依赖事后就绪且被跳过的请求仍是最近一次用户意图时,询问是否继续;中间发生过别的事就静默更新,不打扰。该接上的时候接上,不该打扰的时候闭嘴。AC-14
FR-8US-5第二次及以后的引导内容必须与首次不同,进入排障态。重复同一张卡会让用户以为按钮坏了。AC-11
FR-9US-3抑制只有 run 与会话两层,且只作用于「要不要弹卡」,从不影响能力本身。产品侧没有关闭能力的开关——真正的开关在浏览器里。用户不会被同一件事反复打扰,也不可能误把一块能力关死。AC-13
FR-16US-7user scripts 权限缺失时复用同一套引导骨架,但主按钮指向扩展详情页、文案按 Chrome 版本切换、语气不带催促。用户用同一种心智处理两类前置条件,不用学两套交互。AC-20、AC-21
FR-17US-7权限就绪结果不得缓存;每次调用前重新探测,权限被关掉时进入专门的 perm-revoked 文案。用户中途关掉权限后不会看到系统「假装还能用」然后莫名失败。AC-22
FR-18US-7两道门的抑制标记相互独立:关闭安装引导不影响权限引导,反之亦然。用户拒绝其中一件事,不会连带失去另一个能力。AC-23
FR-19US-8扩展 options 页 › Claw 分区新增 Browser control 常驻分组,与既有分组并列并复用 Chat apps 的行式布局;两行显示各自的真实状态与说明,未就绪时给引导入口,就绪时也保留展示。用户可以主动配好,不必等到被对话拦下来才知道差什么。AC-24
FR-20US-8设置页只映射真实状态并提供引导入口,不拥有开关;引导入口不受任何抑制层影响,始终可用。用户随时能查状态、随时能被带到该去的地方。AC-24
FR-10US-6非交互 run 无法提示时,结果落到能力状态位并发出通知。定时任务不会静默地什么都没做。AC-12
FR-11US-2放行前必须重新探测;「Already installed」不得盲目放行。用户没真装完时得到的是解释,不是又一次失败。AC-5
FR-12US-4超时使用 plugin 提供的 超时话术 控制 agent 收尾话术,使其可续。用户回来时读到的是「装好告诉我」,不是道歉。AC-9
FR-13US-6工具本身必须有独立于引导的、可读的失败路径。引导不可用时用户仍能知道下一步做什么。AC-12
FR-14US-1、US-4恢复待处理引导前必须校验其背后的 run 仍然存活。不会出现点了没反应的僵尸按钮。AC-15
FR-15US-1同一引导在多端只保持一份;一端解决后其他端同步收起。用户不会在两个标签页各看到一张等待中的卡。AC-16

6. UI 字段映射

表格只列用户可见字段。映射类型分为直接字段、派生字段和现有动作。OpenClaw 侧不新增字段,引导所需的展示信息由 channel 依据 toolNamepluginId 在前端组装。

区域 UI 字段 映射 OpenClaw 字段或动作 开发说明
触发引导出现动作运行时推来的「待决请求」事件推荐走事件流而不是消息渲染:安装引导本质不是一条聊天消息。
卡片标题派生待决请求标题协议上限 80 字符。前端可按 toolName 覆写为更贴合场景的文案,原字段只作路由标识。
卡片说明文字派生description + 前端依赖状态协议上限 512 字符。安装步骤、截图、链接由前端组装,不塞进协议字段。
卡片缺失项与下一步派生plugin 依赖探测结果枚举:readyabsentwrong-browser。文案与主按钮由此派生。
卡片「Install」按钮动作无审批动作;新标签打开安装页只改变卡片本地状态为等待连接,不解决审批。
卡片「Already installed」按钮动作先探测;就绪才 放行本次调用探测失败进入排障态,不得直接放行。
卡片「Skip」按钮动作阻断本次调用模型侧收到 Denied by user;agent 转降级或收尾。
会话关闭提示行派生跳过后的塌缩摘要文案 Dismissed browser setup · finish any time in Settings。只有 × 关闭会产生这一行;暂缓类退出留的是 mini 条。
会话mini 条派生最小化后的卡片状态文字(Sider Operator not installed / User Scripts permission is off)+ Continue ›,右上角悬停显形的 ×,整条可点。由 Skip/发新消息/超时产生;同一时刻最多一条。依赖转为就绪时直接放行并移除。
卡片到期换态派生等待上限不展示倒计时;到点直接切「已暂停」。
卡片严重度样式直接severity本场景固定使用 info,不使用 warning/critical 的告警样式。
会话塌缩摘要行派生「请求已解决」事件answered/denied/expired 各有不同摘要文案,均留在时间线上。
Agent超时后的收尾话术超时话术写成给模型的指令而不是给用户的错误文案;设了它超时才是 veto 而不是 timed_out 失败。
Agent等待时限等待上限产品期望是一直等到用户处理或明确离开。运行时当前有固定上限,见第 13 节的缺口与降级方案;上限值不进用户文案。
设置页Browser control 分组动作扩展 options 页 › Claw与 Agent status、Dev tools、Chat apps 并列的第四个分组,建议排在 Chat apps 之后。复用 Chat apps 的行式布局(名称 + 说明 + 状态 + 右侧动作按钮),不发明新视觉。独立标签页,与聊天面板互不重叠;分组内不出现引导卡。
设置页Sider Operator 行派生Operator 依赖探测结果状态 Not installed / Installed;未装时动作按钮为 Install,跳转 Chrome Web Store。就绪时保留展示、不给按钮。
设置页User Scripts 行派生chrome.userScripts.getScripts() 探测结果状态 Off / On;未开时动作按钮为 Open Chrome settings,跳转扩展详情页。按钮是导航不是开关——真正的切换在 Chrome 里。权限可逆,每次进入分组和焦点回归时重新探测。
非交互依赖缺失记录直接「运行时无法提示」无人值守的运行 时核心直接拒绝,没有任何 UI,必须由此路径兜底。

7. 值字典

依赖状态

ready = 已安装且可用,不出现引导。

absent = 当前浏览器未安装插件。

wrong-browser = 在其他浏览器中检测到,但当前会话所在浏览器没有。

插件装完即可用,没有配对或授权步骤,因此不存在「已安装但连不上」这一类状态。

用户决策

继续 = 放行本次调用。按钮文案随状态变化:InstallAlready installedTry againContinue setupOpen settings

跳过 = 阻断本次调用,文案固定 Skip

卡片上没有第三种决策。

终态

answered = 依赖就绪并放行,任务继续。

denied = 用户跳过或隐式跳过。

expired = 超过 等待上限,核心 fail closed。

unavailable = 非交互 run,无法抬起引导。

抑制层级

只有两层,且只作用于「要不要弹卡」,从不影响能力本身。

run 级 = 同一轮内多个工具需要同一依赖,只引导一次。

会话级 = 任一脱身路径之后,本会话不再自动弹;下次新会话恢复。

没有账号级:产品侧不拥有开关,真正的开关在浏览器里。用户反复要求做浏览器的事,我们就反复告诉他还差什么——那是回答,不是骚扰。

渲染方式

引导卡由我们自己渲染,运行时只提供待决请求的结构化数据与放行/阻断通道。

推荐把它当成独立于聊天流的一层来画——安装引导本质不是一条聊天消息。

文案、布局、按钮全部由产品定义,不受运行时默认渲染约束。

8. 依赖状态与文案矩阵

这一节是本设计的核心差异点。把三种失败合并成一句 Not connected 是最常见的翻车方式:用户明明装了,界面还让他装。 文案栏是产品定稿口径,开发不得自行改写;主按钮栏决定卡片的唯一主动作。 卡片上只有 Skip 一个出口,表中不再逐行重复这一点。 产品文案为英文(面向英文客户),本文档其余部分为中文;文档正文引用按钮时一律使用真实英文串,方便开发和 QA 直接对照。

依赖状态出现时机标题说明文字主按钮次要动作
absent首次引导Claw needs Sider Operator for thisIt's a browser extension that lets Claw see and act on pages for you. Once it's installed, I'll pick up right where I left off.InstallAlready installed / Skip
absent点过安装后Waiting for Sider Operator…This will continue automatically once it is installed.(无,展示进行态 Checking connectionAlready installed / Skip
wrong-browser当前浏览器无插件Sider Operator isn't in this browserIt needs to be installed in the browser you're using right now.Install in this browserSkip
探测仍失败点过 Already installed 之后Still not seeing Sider OperatorIt may be installed in a different browser, or this page may need a refresh.
附排查清单两条:Check that it's installed in the browser you're using now / Refresh this page, then try again
Try againInstall / Skip
超时(未操作过)到达 等待上限Parked this for nowSider Operator isn't set up yet. Let me know once it is, or set it up any time in Settings.Continue setup
超时(点过安装)到达 等待上限Looks like setup didn't finishCome back and continue when it's ready — I'll resume from where I stopped.Continue setupTroubleshoot
暂缓Skip / 发新消息 / 超时(卡片折成 mini 条)mini 条文案:Sider Operator not installed + Continue ›
关闭× 之后Browser setup dismissedYou can set it up any time in Settings › Browser control. I won't bring this up again in this chat.Got itCancel
就绪探测到 ready(卡片塌缩为摘要行)Sider Operator connected(无)(无)
反向唤醒本会话脱身过且依赖转为就绪Sider Operator connectedWant me to pick up where we left off?ContinueNo thanks

权限门:user scripts

第二道门,和安装门平行:Operator 是独立扩展,我们调用它的能力;user scripts 权限是我们自己扩展这一侧的事。 两者互不为前置,也不共享抑制标记;交互骨架完全复用,但下表五处必须不同。

维度安装门权限门为什么不能照搬
主按钮跳商店,确定可行Open settings,指向 chrome://extensions/?id=<id>能否从扩展程序化打开 chrome:// 页面未经证实(见 OQ-6)。打不开就退化为 Copy link 加图文步骤。
探测wrong-browser 可靠性存疑官方写法:chrome.userScripts.getScripts() 放进 try/catch,抛错即未开启探测可靠,因此不需要「装错浏览器」那类模糊状态。
方向单向,装了就装了可逆,用户可以随时关回去多出一个「之前能用、现在不能了」的状态;就绪结果不得缓存,每次调用前重新探测。
语气「装完我接着做」,轻松陈述 Chrome 把这个开关交给用户自己,不催促Chrome 自己会对这个开关给出安全提示。用户拒绝是合理选择,文案不能显得在推销。
版本分叉Chrome 138+ 是每扩展的 Allow user scripts 开关;138 之前是全局开发者模式两个 Chrome 版本的操作步骤完全不同,文案必须按探测到的版本切换。
状态出现时机标题说明文字主按钮次要动作
perm-off首次引导Claw needs the User Scripts permissionChrome asks you to switch this on yourself. It lets Claw carry out steps on the page. Flip "Allow user scripts" and I'll continue from here.Open settingsAlready on / Skip
perm-off点过 Open settings 后Waiting for the permission…This will continue automatically once "Allow user scripts" is on.(无,展示进行态)Already on / Skip
perm-off(旧版 Chrome)探测到 Chrome < 138Claw needs Developer mode turned onOlder Chrome versions put this behind Developer mode. Switch it on at the top right of the extensions page.Open settingsAlready on / Skip
perm-revoked本会话内曾就绪,再次探测失败The User Scripts permission is offIt was on earlier — something turned it back off. Switching it on again picks up where we left off.Open settingsAlready on / Skip
超时 / 跳过 / 就绪同安装门完全复用安装门的骨架,只把「extension」换成「permission」。

文案原则

  • 先说用户的目标,再说缺什么;不要以系统的问题开头。
  • 禁用词:errorfailedunavailablerequiredblocked;不使用错误色。
  • 用第一人称的 agent 口吻(I'll pick up right where I left off),不用系统播报口吻。
  • 不暴露工具名、内部请求 ID、决策枚举值或 plugin id。
  • 首次引导必须承诺装完自动继续,因为这直接决定用户是否愿意离开去装。
  • 超时文案必须可续,不能读起来像结案。
  • 按钮用动词开头的祈使短语,最多两词;不用 OK / Yes / No 这类无信息量标签。
  • 不要把文案绑死在单一用途上。同一道门服务多个工具(读页面、点击、填表、抽取…),标题若写「要读取页面」,换个工具就成了错的。任务上下文由紧邻的 agent 消息提供,卡片只负责说清缺什么。
  • 跳转类动作要在标签上说清去哪儿。设置页两个按钮都会离开 Sider(去商店 / 去 chrome://extensions)。写 Enable 会读成「点一下就开了」,用户点完发现开了个新标签页,会觉得被骗了一下——所以写 Open Chrome settings
  • 用真实产品名,不用泛称。Sider Operator,不叫「browser extension」——用户点安装后落地的商店页写的就是这个名字,对不上会让他怀疑装错了东西。
  • 按钮文案有宽度预算:卡片在 360px 视口下内容区只有 306px,动作行三个控件合计不得超过它。标题已给出上下文时优先用单动词(Install 而不是 Install extension)。

超时话术写法

  • 它进入的是模型上下文,不是用户界面;写成给模型的指令,且与产品文案同为英文。
  • 参考:Sider Operator is not installed yet. Do not apologize and do not retry. Tell them you'll continue once they say it's set up, and that they can also set it up in Settings, then stop.
  • 超时也是一条脱身路径,所以这段话必须包含设置页指引——否则静置离开的用户是四条路径里唯一没被告知的。
  • 不设它时超时是 timed_out 失败,模型多半会道歉或反复重试。
  • 设了它超时会转成 veto,文本原样成为模型看到的原因。

9. 条件显示规则

规则条件显示隐藏/保留
引导卡依赖状态非 ready,且 有人在场的运行,且未命中任何抑制层停靠卡:标题、说明、主按钮、次要动作工具名、内部请求 ID、决策枚举值不显示。
不弹卡命中 run 或会话抑制什么都不显示不再主动打断当前对话;用户再问一次或去设置页仍可继续。
排查步骤已经历过一次探测失败排查清单与文档链接首次引导下隐藏,避免首屏信息过载。
关闭告知条× 之后、确认之前原位一条告知:标题 + 说明 + Cancel / Got it占据卡片或 mini 条刚腾出的同一位置。未确认前不产生任何实际效果。
设置页指引告知条被 Got it 确认后时间线一行:Dismissed browser setup · finish any time in Settings关闭之后用户手边什么都没剩下,留一条可回溯的线索。暂缓类退出不需要——mini 条就在手边。
mini 条暂缓类退出之后,直到本会话结束、依赖就绪或被关闭输入框上方一条 mini 条,右上角浮一个悬停显形的 × 徽标关闭后不再出现。它是被折起来的卡片,不是一条待办提醒——所以它也该能被拿走。
引导卡所在 surface任何情况只出现在聊天面板设置页永不渲染引导卡,只有状态与动作;两个 surface 职责不重叠。
倒计时任何状态不显示仅内部依据 等待上限 换态,不给用户制造时间压力。
塌缩摘要行审批到达任一终态时间线上一行摘要不做定时清除;answered/denied/expired 文案不同。
反向唤醒本会话脱身过、依赖转为 ready,且被跳过的请求仍是最近一次用户意图轻量询问条中间发生过别的事就静默更新、不打扰;用户拒绝后本会话不再问。
能力状态位始终设置页 Browser control 分组中常驻两行就绪时也保留展示,用户可以确认状态、也能主动关闭;不因就绪而隐藏。
无 UI 路径无人值守的运行,或初始面不支持审批能力状态位标记 + 通知不渲染引导卡;工具返回可读的失败文本。

10. 状态与操作逻辑

这一节是开发实现契约。原型中的每个按钮、过渡和塌缩都必须能映射到这里;如果实现中出现这里没有定义的新行为,需要先回到产品评审。

状态模型

下面四个状态只描述聊天面板。设置页是另一个 surface(独立标签页),不进这个状态机——它没有引导态,只是常驻映射真实状态并提供引导入口,见 US-8 与第 6 节。
聊天面板只有四个状态:无卡有卡最小化关闭告知。卡片长什么样不是状态,是「依赖状态 × 本次进展」两个维度决定的文案。 早期版本把这两个维度的取值当成十几个独立状态,评审时会淹死在状态表里而看不到设计。

状态进入条件可见内容允许操作退出
无卡依赖就绪,或本轮未触及相关工具,或本会话已 Close 过。普通对话与输入框。正常对话操作。工具执行前探测到缺失且本会话未 Close 过 → 有卡。
有卡探测到依赖缺失。停靠卡:右上角 ×、标题、说明、Skip、次要动作、主按钮。内容按下表两个维度决定。主按钮、次要动作、Skip×、发新消息。探测到就绪 → 放行回无卡;Skip/发新消息/超时 → 最小化;× → 关闭告知。
关闭告知在卡片或 mini 条上点了 ×原位一条告知 + Cancel / Got it确认或撤销;发新消息视同确认。Got it → 无卡且本会话不再出现任何形态;Cancel → 退回 × 之前的状态。
最小化Skip、发新消息或超时之后。输入框上方一条 mini 条:状态文字 + Continue ›,右上角浮一个悬停显形的 × 徽标,整条可点。点击整条展开;点 × 进入关闭告知。点击 → 有卡;× → 关闭告知;探测到就绪 → 直接放行并移除。

卡片内容矩阵

纵轴是探测结果,横轴是本次引导的进展。文案定稿见第 8 节,这里只定形态。

依赖状态 \ 进展首次等待中受阻
missing(未装 / 未开启)说明缺什么 + 主动作进行态 + 持续探测,主按钮让位换一套说法 + 排查清单
wrong-browser(仅安装门)说明该在哪个浏览器装同上同上
revoked(仅权限门)承认之前是开着的同上同上

两类退出:暂缓 vs 关闭

这两件事不是同一个动作,早期版本把它们合并过,结果是 × 变成一个多余的按钮,而「先收起来待会儿弄」这个最常见的意图无处表达。

类别触发用户在说什么系统行为留下什么
暂缓Skip、直接发新消息、等待超时「先不弄,但别丢掉」阻断本次调用,卡片最小化。本会话不再自动弹卡,但 mini 条一直在。mini 条 + Continue ›,随时展开
关闭卡片右上角 ×,或 mini 条右上角 ×「拿走」两步× 先在原位换成一条告知,说明去哪儿还能完成、且本会话不再提;用户点 Got it 才真正生效,点 Cancel 退回原样。未确认前什么都没发生。确认后:时间线一行 Dismissed browser setup · finish any time in Settings

超时归入暂缓而不是关闭:用户只是没顾上,不是拒绝,留个可恢复的入口比清场更合理。它今天之所以会发生,纯粹因为运行时有等待上限,属于降级产物,见第 13 节。 只有关闭这一条需要设置页指引——暂缓的用户手边就有 mini 条,不需要被再告知一遍。

操作矩阵

ID操作触发位置前置条件逻辑/结果字段或动作
OP-1依赖前置探测工具执行前。被调用工具声明了依赖。返回状态枚举之一;ready 直接放行,不产生任何 UI。我们自己的依赖探测。
OP-2抬起引导探测失败。有人在场的运行,且未命中抑制层。返回 引导请求,核心阻塞该次工具调用并广播请求事件。不得先让工具失败一次再补救。引导请求;「待决请求」事件。
OP-3点击安装卡片主按钮。状态为 absent新标签打开安装页;卡片进入「等待中」并开始轮询探测。不解决审批。UI state only。
OP-4自动探测就绪「等待中」或「受阻」的轮询。探测返回 ready直接放行,不要求用户点击;卡片塌缩为摘要行。安装行为本身即为同意。放行本次调用。
OP-5点击「Already installed」卡片次要动作。卡片处于「首次」或「等待中」。重新探测:就绪则同 OP-4;仍失败进入「受阻」。不得因为按钮被点就放行。plugin 依赖探测。
OP-6Skip(暂缓)动作行最左的 Skip卡片可见。阻断本次调用,卡片最小化成 mini 条;agent 给降级方案或干净收尾。本会话不再自动弹卡,但 mini 条常驻,随时可展开。不写时间线摘要——mini 条本身就是记录。阻断本次调用。
OP-6AClose(第一步:告知)卡片或 mini 条右上角 ×卡片或 mini 条可见。不立即生效。原位把卡片/mini 条换成一条告知:标题 Browser setup dismissed,正文说明可在设置页完成、且本会话不再提;动作行 Cancel 靠左、Got it 贴右。选原位是因为用户视线本来就在这里,比时间线上一行容易被看到。UI state only。
OP-6BClose(第二步:确认或撤销)告知条上的 Got it / Cancel告知条可见。Got it:阻断本次调用,本会话不再出现任何形态(含 mini 条),时间线留一行摘要。Cancel:完整退回 × 之前的状态——从卡片来的回卡片,从 mini 条来的回 mini 条。用户在告知条上发新消息视同 Got it阻断本次调用。
OP-7发送新消息(隐式暂缓)输入框。存在待处理引导。先阻断本次调用并最小化卡片,再放行消息进入正常对话。归入暂缓而非关闭——用户只是转去做别的事,没有拒绝。新消息不得被吞成对引导的回答。阻断本次调用。
OP-8到期系统。到达等待上限。归入暂缓:阻断本次调用并最小化卡片。agent 按超时话术输出可续收尾。到期不是独立状态,也不是拒绝。等待上限、超时话术。
OP-9最小化与展开系统 / mini 条。暂缓类退出之后。mini 条显示当前依赖状态文字 + Continue ›,整条可点,点击展开回卡片。右侧另有一个 ×:指针设备上悬停或聚焦才显形,触屏上常驻——触屏没有 hover,藏起来等于关不掉。× 的点击必须阻止冒泡,否则会被整条的展开行为吞掉。依赖转为就绪时直接放行并移除。同一时刻最多一条。UI state only。
OP-10反向唤醒系统。本会话脱身过一次,之后依赖转为就绪,且被跳过的那个请求仍是最近一次用户意图展示轻量询问条;确认则重新执行原任务,拒绝则本会话不再问。中间只要用户做过别的事就静默更新状态、不打扰——不用定「多久算过期」这种时间窗。依赖就绪信号。
OP-11多端同步系统。同一审批在多端渲染。一端解决后其他端收 「请求已解决」事件 并收起卡片,不各自保留一张等待中的卡。「请求已解决」事件。
OP-12恢复时校验页面重载或重连。存在待处理审批记录。审批记录持久化会存活,但其背后的 run 可能已随进程结束。恢复前必须校验 run 存活;不存活则显示「已过期,请重新提问」,不得渲染一个点了没反应的按钮审批记录 + run 存活校验。
OP-13非交互记录系统。无人值守的运行。核心直接以 「运行时无法提示」 拒绝;写入能力状态位并发通知;工具返回可读失败文本。拒绝原因。
OP-14run 级去重系统。同一轮内多个工具需要同一依赖。只抬起一次引导;后续调用直接走已知失败路径,不再弹卡。run 级抑制标记。

场景:装完自动继续

  • 用户点安装后注意力已经转移到商店标签页,此时再要求他回来点确认,会读起来像系统没记住他刚做过的事。
  • 探测到就绪即放行,卡片塌缩为一行摘要,agent 直接给出原任务结果。
  • agent 的下一条消息必须完成原任务,不能只说「好的,插件装好了」就停止。
  • 自动放行的安全前提:这是能力开通门,用户的安装动作即为同意。真正的敏感操作审批不适用本规则。

场景:用户一直没操作

  • 审批时限硬上限 10 分钟且 fail closed,这是协议常量,不通过修改核心来绕开。
  • 到期与 Skip 同一个出口,只是摘要措辞不同;agent 的收尾话术必须可续。
  • agent 收尾由 超时话术 驱动,读起来是「装完告诉我」,不是道歉或报错。
  • 用户之后随时装好,反向唤醒会把这件事重新提起来。

抑制与恢复规则

  • run 级:同一轮只引导一次。只作用于弹卡,不影响能力。
  • 会话级:任一脱身路径之后本会话不再自动弹;下次新会话恢复。
  • 没有账号级。产品侧没有关闭能力的开关,设置页只映射浏览器里的真实状态。
  • 依赖状态从就绪变为缺失是新原因,清除该门的会话抑制——用户本会话跳过过一次,不该导致他后来主动开了又被关掉时收不到提示。
  • 设置页始终显示两项的真实状态并提供引导入口,不受任何抑制层影响。
  • 不做定时暂停档。会话级已经覆盖「现在别烦我」;再加一档会让三个出口互相混淆,用户分不清自己刚才选了哪个。

预防优于拦截

  • 设置页 Browser control 分组常驻显示「Browser extension not installed」并提供主动安装入口。
  • 首次开启相关能力时就引导安装,而不是等到用了才拦。
  • 本 PRD 的引导卡是安全网,最好的结果是它一次都不出现。
  • 默认关闭的能力必须在同一次改动里给出具名的开启路径,这是仓库既有规则,不是本 PRD 的额外要求。

11. 评审清单

必须通过

  • 引导抬起前不产生任何可见的工具失败记录。
  • 卡片停靠在输入框上方,不使用聊天气泡,也不使用模态框。
  • 依赖状态在文案和主按钮上真正分开,不合并成一句 Not connected;卡片里不出现配对码、授权码之类插件不需要的步骤。
  • 探测到就绪时自动放行,不要求用户回来点第二次。
  • 「Install」和「Already installed」是两个按钮,点安装不等于放行。
  • 动作区从左到右为 Skip → 次要动作 → 主按钮;主按钮贴右,「Skip」贴左,且 DOM 顺序与视觉顺序一致。
  • 360px 视口下每个状态的动作行都是单行,主按钮始终贴右。
  • 点「Already installed」必须重新探测,不得盲目放行。
  • 第二次提示进入排障态,内容与首次不同。
  • 「Skip」和 × 结果不同:Skip 最小化,× 彻底关闭。mini 条上也有 ×,触屏上必须常驻可见。
  • 用户发新消息等同跳过,新消息不被吞成对引导的回答。
  • 超时不渲染为错误态,文案可续,并折成 mini 条。
  • 暂缓折成 mini 条,关闭需二次确认并留下指向设置页的一行;两者结果不同。
  • 依赖事后就绪且意图仍在时反向唤醒;意图已过期则静默。
  • Skip× 是两件事:前者最小化成可展开的 mini 条,后者彻底关闭并留下设置页指引。
  • 设置页两个按钮都是跳转(商店 / chrome://extensions),不是就地开关;两行在就绪时保留展示且不给按钮。
  • 非交互 run 落到能力状态位与通知,不静默吞掉。
  • 恢复待处理引导前校验背后 run 存活。
  • 同一引导多端只保持一份,一端解决后其他端收起。
  • 不展示倒计时,不展示工具名、内部请求 ID 或决策枚举值。

需要重点看代码

  • 依赖探测是否在工具执行前完成,而不是失败之后才补。
  • 超时是否走产品定义的可续话术,而不是运行时的默认失败文案。
  • 卡片是否只暴露「继续」和「跳过」两种决策,没有混入持续授权。
  • 自动放行前是否真的重新探测过,而不是复用上一次的探测结果。
  • 工具 execute 开头是否再探测一次——放行不代表依赖真的就绪。
  • 隐式暂缓是否先阻断本次调用再放行消息,避免两条线并行。
  • run / 会话两层抑制标记的写入与清除时机。
  • 恢复流程是否校验 run 存活,僵尸审批是否被正确标记为过期。
  • 多端场景下 「请求已解决」事件 是否被所有渲染端消费。
  • 非交互路径下工具返回的失败文本是否可读、是否指明下一步。
  • 无人值守的运行 的判定是否覆盖 cron、heartbeat 和非交互 CLI。

12. 沟通准备

沟通时先确认产品边界,再讨论实现。核心判断标准是:用户看到的是安装步骤而不是错误,装完能自动继续,不装也有干净的出口,走开之后还能回来接上。

必须当场对齐

  • 产品要的是「工具执行前拦住、阻塞到用户决定」。运行时已具备这个能力,细节和缺口见第 13 节。
  • 渲染端由自定义 channel 全权负责;OpenClaw 只提供视图模型和决策通道,按钮文案不构成约束。
  • 等待时长应由产品决定。运行时当前有固定上限,属于待补能力(第 13 节);在补齐前用可续的超时文案兜底,上限值不进用户文案。
  • 定时任务等非交互 run 完全无法弹卡,这是核心行为,必须由能力状态位和通知兜底。
  • 插件装完即可用,没有配对或授权步骤;探测只需回答装没装、装在哪个浏览器。
  • 状态区分是产品必须项,不是优化项;合并成一句 Not connected 会让用户卡死。
  • 自动续跑是本设计的关键,不是加分项;把它降级为「用户回来点一下」会显著劣化体验。

容易误解的点

  • 「继续」 不代表依赖真的就绪,它只是放行;工具 execute 必须自己再探测一次。
  • 「Skip」只是这一次不用。产品里没有「永久关闭」这个东西——用户真想停用,是去浏览器里卸载扩展或关掉权限。
  • 设置页不是控制面板,是状态镜子加指路牌——它不能开关任何东西。
  • 跳过不是终点:摘要行指向设置页,用户再问一次也会重新引导。
  • 审批记录持久化,但等待中的工具调用不持久化——记录活着不等于任务还能续上。
  • 超时不是错误;把它渲染成失败会让用户以为系统坏了。
  • 超时话术 进的是模型上下文,不是用户界面;写给模型看,不是写给用户看。
  • 引导卡的最佳状态是一次都不出现;设置页 Browser control 分组和 onboarding 的常驻入口和它同等重要。
视角主要关心需要确认的结论
用户为什么停下来、要我做什么、做完能不能接上。文案读起来是安装步骤;装完自动继续;不装也有出口。
产品异常路径是否都有终点,会不会反复打扰。暂缓与关闭是两个出口,各有各的归宿;两层抑制;任何退出后设置页都可回。
设计卡片位置、状态过渡、塌缩形态。停靠在输入框上方;终态塌缩为时间线一行;不留常驻元素。
前端待决请求订阅、探测轮询、抑制状态、恢复校验。自行渲染引导卡;等待态轮询探测;恢复前校验归属任务是否存活。
插件开发探测接口、超时文案、工具失败路径。探测返回四态枚举;设置 超时话术;execute 开头再探测一次。
运行时(OpenClaw)哪些能力已具备、哪些要补。见第 13 节:拦截、结构化推送、程序化放行、工具摘除已具备;等待时长、无人值守场景的可见结果、待决请求与任务的存活一致性需要新增。
QA不按剧本走的路径。用下方 AC 覆盖:不操作、拒绝、点安装后消失、假称装好、发新消息、刷新页面、多端、定时任务。
ID验收标准验证方式
AC-1依赖缺失时,引导卡在工具产生任何可见失败之前出现。卸载依赖后触发相关请求;检查时间线中没有先出现一条工具错误。
AC-2引导以停靠卡出现在输入框上方,终态后塌缩为时间线上一行摘要且不被定时清除。目视检查位置;滚动对话确认摘要行留存。
AC-3各依赖状态呈现不同的标题、说明和主按钮。分别构造未安装、装在其他浏览器两种环境。
AC-4安装并授权完成后,无需用户任何点击,任务自动继续。点安装后在另一标签完成安装授权,回到会话确认已在输出结果。
AC-5未真正安装时点击「Already installed」不会放行,而是进入排障态。不安装直接点该按钮;确认没有产生工具调用,且卡片内容已改变。
AC-6点击跳过后 agent 给出降级方案或干净收尾,不出现沉默或仅一句确认。点跳过后检查 agent 下一条消息内容。
AC-7无视卡片直接发新消息时,审批被解决,新消息按正常对话处理。发一条与引导无关的消息;确认它没有被当成对引导的回答。
AC-8超时归入暂缓,留下 mini 条而不是清场。抬起引导后静置到期,确认 mini 条存在且可展开,agent 收尾话术可续。
AC-9超时后 agent 的收尾话术可续,不含道歉或失败宣告。检查 agent 输出;确认 超时话术 已生效而非默认超时文案。
AC-10装在其他浏览器时说明应在哪个浏览器安装,而不是让用户以为要重装一遍。在浏览器 A 安装后,从浏览器 B 触发引导,检查标题、说明与主按钮。
AC-11同一会话内不出现两张内容完全相同的引导卡。连续两次触发失败探测;对比两次卡片内容。
AC-12定时任务因依赖缺失失败时,能力状态位被标记且发出通知。在依赖缺失状态下让定时任务触发相关工具;检查状态位与通知,确认没有静默。
AC-13跳过或超时后本会话不再主动弹卡,但下一次新会话恢复。跳过后在同一会话内再次触发同一工具,确认不再弹卡;开新会话后确认引导恢复。
AC-14反向唤醒只在被跳过的请求仍是最近一次用户意图时出现。跳过后立即完成安装,确认出现询问条;另一轮跳过后先问三个别的问题再完成安装,确认静默更新、不打扰。
AC-15刷新页面或重连后恢复的引导,其背后 run 不存活时显示为已过期而不是可点击按钮。抬起引导后重启 gateway 再刷新页面;确认不会出现点了没反应的按钮。
AC-16同一引导在两个标签页打开时,一端解决后另一端同步收起。双标签页打开同一会话;在一端点击 Skip,观察另一端。
AC-17360px 视口下每个状态的动作行都保持单行,主按钮贴右边缘。逐个状态在 360px 宽度下检查动作行高度与主按钮右边界;重点覆盖超时态(历史上会换行并把主按钮甩到左下角)。
AC-18卡片上只有 Skip 与前进类动作,没有任何永久性开关;设置页也没有开关。逐状态检查每张卡与设置页。
AC-19Skip 与 × 产生不同结果:前者留 mini 条且可展开,后者移除一切并留下指向设置页的时间线行。mini 条自身也能被关闭。两条路各走一遍;再验证发新消息与超时都归入暂缓;最后在 mini 条上点 ×,确认与卡片上的 × 结果一致。
AC-25mini 条的 × 在触屏设备上常驻可见,不依赖悬停。在触屏或 hover: none 模拟下打开最小化状态,确认 × 直接可见可点;点击它不会误触发展开。
AC-26× 是两步:先原位告知,Got it 才生效,Cancel 完整退回。在卡片上点 × 后点 Cancel,确认回到原卡片且未产生任何抑制;再点 × 后点 Got it,确认本会话不再出现任何形态且时间线留下摘要。在 mini 条上重复一遍,确认 Cancel 退回的是 mini 条而不是卡片。
AC-20user scripts 权限缺失时抬起的引导卡,交互骨架与安装门一致(停靠位置、动作行顺序、退出方式、自动续跑)。关闭该权限后触发需要它的工具;逐项对照安装门的行为。
AC-21文案按 Chrome 版本切换:138+ 指向每扩展的 Allow user scripts 开关,更早版本指向全局开发者模式。在 138+ 与更早版本各触发一次,对比标题与说明文字。
AC-22权限在会话中途被关掉时,下次调用进入 perm-revoked 文案,而不是首次引导文案,也不是静默失败。先开启权限成功跑一次,再关掉权限并重新触发;检查标题是否承认「之前是开着的」。
AC-23两道门的抑制标记相互独立。在设置页关闭安装那一项后,触发需要 user scripts 的工具,确认权限引导仍正常出现;反向再验一次。
AC-24设置页 Browser control 分组的两行实时反映真实状态,就绪时也保留展示,且页面本身不提供任何开关。分别在未装、已装、权限开、权限关四种组合下打开设置页;再在 chrome://extensions 里切换开关后切回窗口,确认状态自动刷新而不需手动重载。

建议开发拆分

  • Slice 1:依赖探测 + 工具执行前抬起引导 + 超时话术;工具真正执行前再探测一次。
  • Slice 2:订阅待决请求,渲染首次引导卡,接通「继续」与「跳过」。
  • Slice 3:等待态轮询探测与自动续跑,卡片塌缩与时间线摘要行。
  • Slice 4:排障态与文案矩阵。
  • Slice 5:反向唤醒(限最近一次意图)与两层抑制。
  • Slice 6:恢复校验、多端同步、非交互路径的状态位与通知。
  • Slice 7:QA 补齐,按 AC-1 到 AC-16 覆盖全部异常路径。

开放问题

  • OQ-1:等待态的探测轮询节奏,需要前端和扩展侧对齐,避免在长时间等待中产生过多请求。
  • OQ-4:wrong-browser 状态的可探测性依赖具体实现,需要确认能否稳定区分于 absent。配对状态已确认不存在后,它是仅剩的第二个状态;若它也探测不出来,首次引导就只有一种形态,状态区分完全落到「首次引导 vs 排障态」这一层,FR-3 需要相应收窄。
  • OQ-6:能否从扩展程序化打开 chrome://extensions/?id=<id>chrome.tabs.create)?官方文档没有明确说明。**需要扩展团队实测**——能打开则主按钮为 Open settings;打不开则退化为 Copy link 加两步图文说明,卡片会变高,需要重新量 360px。
  • OQ-7:user scripts 权限门的目标扩展是我们自己的扩展还是 Operator,需要在实现前确认,它决定深链里填哪个 extension id。
  • OQ-5:最小支持宽度定在 360px,所有卡片状态在此宽度下动作行单行。需要产品确认 320px 是否要一并支持。

13. 对 OpenClaw 的能力需求

前十二节是产品定义,不受任何现有实现限制。这一节把产品需要的运行时能力集中列出,并标注 OpenClaw 当前是否提供。 标为「待新增」的项不是产品让步的理由:它们是需要向 OpenClaw 提出的需求,在补齐之前可以先按降级方案上线,但降级方案要写清楚,不能默默改掉产品行为。

产品需要的能力用在哪现状缺口与降级方案
工具执行前拦截,并阻塞该次调用直到用户决定FR-1、FR-2已提供
把待决请求以结构化数据推给前端自行渲染FR-2、FR-19已提供前端完全掌握文案与布局,不受运行时默认渲染约束。
由前端在探测到依赖就绪时程序化放行FR-4已提供
等待时长由产品决定FR-6、FR-12当前运行时对等待有固定上限,且到点即判失败。产品期望的是「一直等到用户处理或明确离开」。
降级方案:到上限时走和 Skip 相同的出口,只把摘要措辞换成超时——用户体验上不是失败,只是这次没做成。上限值本身不进产品文案。
非交互场景也能留下可见结果FR-10、FR-13当前运行时在无人值守的运行中不会抬起用户提示。
降级方案:由我们自己写入能力状态位并发通知,不依赖运行时提示。
超时后 agent 的收尾话术可由产品指定FR-12部分提供可以传入一段给模型的说明。产品要求是它必须能让 agent 说出可续的话而不是道歉;当前形态够用,但属于约定而非契约,需要在 OpenClaw 侧固化。
待决请求与其归属任务的存活性绑定FR-14当前待决记录会比它归属的任务活得久,重启后可能出现「点了没反应」的僵尸入口。
降级方案:前端恢复前自行校验归属任务是否存活,不存活就显示为已过期。这是补丁,正解应由运行时保证一致性。
多端之间的待决状态同步FR-15已提供

由我们自己实现的部分

  • 两类依赖的探测,以及探测结果的状态枚举。
  • 引导卡、反向唤醒、设置页 Browser control 分组的全部渲染与交互。
  • run / 会话两层抑制标记的读写。
  • 等待态的轮询节奏与自动放行判定。
  • 设置页两行的状态映射与引导入口。

外部依据