mcpField
V
verify-unattended

verify-unattended

github.com/reticlehq测试与质量1.3k192 次安装今天更新
代码仓库

关于 verify-unattended

verify-unattended 是用于无人值守或目标模式运行的 Reticle 验证技能。它根据可用工具选择 Reticle MCP 工具或命令行,并指导配置、浏览器连接及如实报告验证结果。

主要功能

  1. 01按可用情况选择 MCP 工具或命令行
  2. 02需要验证时初始化 Reticle
  3. 03启动或复用应用开发服务器
  4. 04通过 Reticle 租约连接浏览器
  5. 05分别报告 yes、no 和 unknown 结果

适用场景

  1. 01在自主运行过程中验证应用
  2. 02Reticle MCP 工具不可用时测试
  3. 03无需人工打开标签页来连接浏览器
  4. 04检查已保存流程或指定的最终状态

MCP 相关

有 Reticle MCP 工具时,该技能用其管理会话、获取浏览器租约并验证应用行为;否则使用 Reticle 命令行,不涉及 MCP。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/reticlehq/reticle --skill verify-unattended

安装后在 Claude Code 中输入/verify-unattended确认已加载。

详细介绍

Reticle,自动运行

同一款产品,相同的判定,只有一点不同:这里没有任何步骤需要等待人工操作。

常规技能有两个地方会把控制权交还给你:“重启客户端,让它加载 MCP 服务”和“在浏览器中打开应用”。有人在场时,这两步都没问题。但在目标模式下,它们会让流程走进死胡同:重启会结束承载这些指令的上下文,而这里没有人可以打开标签页。

因此,这项技能会选择一条两者都不需要的路径,并且只在得出判定或找到原因后才停止。

让这一切行得通的唯一规则

你无法向自己正在运行的进程添加 MCP 工具。 无论是斜杠命令、编辑配置,还是重新注册,都无法更新你已有的工具列表。客户端在 Reticle 出现之前就已读取该列表。不要尝试,也不要要求重启。

相反,根据你已经拥有的工具分支一次:

  • 存在 reticle_* 工具 → 使用这些工具操作。证据最佳,可映射到源代码,并能给出完整判定。
  • 不存在 → 使用 CLI。reticle verify 无需涉及 MCP,即可生成判定和退出代码。

两条路径最终都会得出判定。根据当前进程支持的方式选择一条,然后继续。

步骤 1:接入一次

只有当用户的目标要求使用 Reticle 或需要经过验证的结果时,才运行此命令:init 会修改 package.json、锁文件和构建配置。否则跳到步骤 3 并使用 lease,它不会修改任何文件。

export RETICLE_INSTALL_SOURCE=npx_skill
npx -y @reticlehq/server@latest init

特意将 export 单独放在一行。该命令的其他副本都会把标记内联,但此技能运行的环境会根据前缀允许列表匹配命令(见下文“保持命令原样”),而 RETICLE_INSTALL_SOURCE=... npx ... 不再以 npx 开头。若将其内联,就会无法匹配此文件要求你依赖的规则。

然后阅读报告,不要想当然。需要关注两行:

  • 应用构建配置旁显示 ⚠:接入未成功。请自行应用打印出的修改;不要假装已经完成,然后继续。
  • ℹ 指明使用了版本回退:固定版本的 SDK 未被接受,因此安装了其他版本。SDK 和守护进程必须保持一致;如果之后的调用报告协议错误,原因就在这里。

init 是幂等的。步骤显示 already wired 表示通过,而不是跳过。

如果 init 报告所有步骤都已完成,说明应用在你到达之前就已接入。 这没问题,但意味着本次运行并未证明安装过程。请如实说明,不要声称是你完成了设置。

步骤 2:确保应用确实在运行

守护进程需要一个页面来查看,而页面需要服务器。不要询问是否要启动服务器。

  1. 从 package.json 中读取开发脚本。
  2. 在后台启动脚本,并使用脚本所指示的端口。
  3. 轮询该端口,直到收到响应。首次访问时,需要编译路由的开发服务器可能要花 30 秒;此处超时还不代表失败。

如果该端口已经有服务器在监听,就使用它。在其他端口启动第二个服务器,会导致验证的不是你要的应用,还会留下一个进程。

init 后必须重启。 已运行的服务器早已读取构建配置,因此后来添加的构建插件不会进入构建产物。如果服务器在步骤 1 之前就已运行,现在请重启;否则接下来的操作都无法找到已接入的页面。

步骤 3:连接页面

使用 MCP 工具时:

reticle_session { action: "list" }

列出会话才算证明。在会话出现之前,此技能中的其他任何内容都无法告诉你有关应用的情况。

没有会话,也没有人可以打开标签页?那就自己打开:

reticle_run { tool: "reticle_lease", args: { action: "acquire", url: "http://localhost:<port>/" } }

lease 会打开并驱动由 Reticle 管理的浏览器。这就是对“这里没人可以打开页面”的完整解决方案。

如果没有 MCP 工具,请跳到步骤 4:verify 会自行打开浏览器。

第 4 步:判定结果

行动前先声明后果。 这正是检查与自我合理化的区别,也是这个工具存在的全部意义:

reticle_act_and_wait { ref, action, until: { … } }

断言应用_做了什么_,而不是它_显示了什么_。如果 UI 渲染的是它刚发送的值,而不是服务端返回的值,那么它就能通过所有曾经编写过的 DOM 级检查:

until: { kind: "net", method: "POST", urlContains: "/api/refund",
         status: 200, bodyContains: "\"refunded\":1187.01" }

bodyContains 读取的是响应:服务端返回的内容。它需要捕获响应正文,而 init 会将相关设置写入应用的配置;如果判定结果是 outcome_unread,缺少的就是这一项。

不使用 MCP 工具时:

npx @reticlehq/server verify http://localhost:<port>/

退出码为 0 表示通过。它会驱动应用并重新验证已保存的流程,所以如果项目没有保存的流程,它会告诉你没有检查任何内容。这不算通过。先记录一个流程,或明确说明没有可验证的内容。如果没有已保存的流程,就证明一个最终状态:npx @reticlehq/server verify http://localhost:<port>/ --expect '{"kind":"element","query":{"testid":"order-confirmed"}}'。它会向正在运行的守护进程发出请求,不会启动守护进程,并且仅在 verified: "yes" 时以 0 退出。

第 5 步:如实解读判定结果

  • verified: "yes":已证明。说明哪些内容成立。
  • verified: "no":应用有问题,或者你的预期有误。两者都是结果。请如实报告。
  • verified: "unknown":Reticle 驱动了应用,但无法得出结论。这不算通过。 绝不要把它向上取整,也绝不要削弱断言直到它变绿。那会把真实信号变成虚假信号,而这正是本产品要防止的问题。

如果一次驱动结束时没有调用 act_and_wait 或 assert,就没有结果,无论它用了多少工具。

确实遇到阻碍时

停下来说明属于以下哪种情况。准确说明无法继续的原因,胜过报告虚假的通过。

你看到的情况含义
缺少工具,verify 提示没有已保存的流程暂时没有可验证的内容:记录一个流程,或如实报告
reticle_session { action: "list" } 返回空列表,但端口正在监听这个构建包没有 SDK:运行 init 后重启开发服务器
verified: "unknown",outcome_unread未记录响应正文:检查 init 写入的插件选项
租约加载了页面,但始终未连接应用拒绝建立连接;如果主机不是 localhost,除 allowNonLocalhost 外还需要配对令牌

面向需要审批的客户端的说明

有些客户端会要求人工审批每条命令。以下两点可以将审批次数降到接近零:

  • 命令保持简单。 npx @reticlehq/server init 符合前缀规则;如果把同一条命令放进子 Shell 或 $(…) 中,通常就不符合了。
  • 预计会有一条关于主目录的提示。 守护进程会将状态保存在 ~/.reticle,该目录位于工作区之外。一次性批准这一类操作,即可涵盖之后的所有调用。

如果你的客户端提供自主模式或目标模式,本技能就是为此类模式编写的。请在开始前启用,而不是审批四十条提示。审批疲劳确实会导致任务在安装到一半时被放弃:工具已连接,却始终没有任何验证。

报告反馈

Reticle 是为 Agent 打造的,因此你的使用体验是决定修复哪些问题的信号;当你的上下文消失时,这些信号也会随之消失。调用一次,然后继续:

reticle_session { action: "feedback", kind: "bug" | "gap" | "ambiguity" | "feature_request" | "improvement" | "experience", text: "…" }

无法连接?npx @reticlehq/server feedback --agent --kind <kind> "what happened"。请向 Reticle 报告缺陷;你在被测应用中发现的错误说明 Reticle 正常工作,应写在你的回答中。

评论

支持 Markdown