reticle
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseReticle
Reticle
Reticle embeds a dev-only SDK in the running app and exposes it to you as MCP tools. You look, act, observe, and assert against the real app. No screenshots.
reticle_*Reticle 会将一个仅限开发环境使用的 SDK 嵌入运行中的应用,并以 MCP 工具的形式提供给你。你可以对真实应用执行查看、操作、观察和断言。无需截图。
reticle_*Finish the setup steps
完成设置步骤
The plugin already registered the MCP server, so this file runs with no client restart. Finish the setup steps; ask the user only when a step needs their decision. Running , fixing wiring it could not, starting the dev server and opening the browser are setup steps, not decisions.
initThe repo already answers which framework, package manager and port, so work those out rather than asking. Say what you did in one line.
Two places always need the user:
- No recognisable dev script in . Say so; do not invent one.
package.json - Your host asks the human to approve a command. That prompt belongs to the host. Never bypass or suppress it, and take a refusal as the answer. writing a pre-approval rule for the
initserver is not that: it is a scoped, announced config change the human asked for by running the command, and it covers only Reticle's own tools.reticle
插件已经注册 MCP 服务器,因此执行此文件时无需重启客户端。 完成设置步骤;只有当某一步需要用户决策时才询问用户。运行 、修复其未能完成的接线、启动开发服务器并打开浏览器都属于设置步骤,而不是需要用户决策的事项。
init仓库中已经能确定使用什么框架、包管理器和端口,因此应自行查明,而不要询问。用一行说明你所做的工作。
以下两处始终需要用户介入:
- 中没有可识别的开发脚本。 说明这一点;不要自行编造。
package.json - 你的 host 要求人工批准命令。 该提示由 host 发出。绝不绕过或抑制;如果用户拒绝,就将其视为最终答案。为 server 写入预批准规则并不属于上述情况:这是用户通过运行命令主动要求的、范围受限且已明确说明的配置变更,并且仅涵盖 Reticle 自身的工具。
reticle
Run this branch first
先运行此分支
bash
cat .reticle.json 2>/dev/null || echo NOT_FOUND- → ONBOARD, then VERIFY.
NOT_FOUND - File exists → VERIFY.
Either way you are finished only when a verdict exists: from , , or where a step declares . Config files are not an install, and a listed session is not a result.
reticle_act_and_waitreticle_assertreticle_act { steps }expectbash
cat .reticle.json 2>/dev/null || echo NOT_FOUND- → ONBOARD,然后 VERIFY。
NOT_FOUND - 文件存在 → VERIFY。
无论哪种情况,只有产生结论后才算完成:结论必须来自 、,或某个 step 声明了 的 。仅生成配置文件不代表安装成功,列出会话也不代表得到了结果。
reticle_act_and_waitreticle_assertexpectreticle_act { steps }ONBOARD
ONBOARD(接入)
One command wires the project. A second one proves a flow.
bash
npx @reticlehq/server@latest initIt detects the framework and package manager, wires the build config, installs the SDK, registers the MCP server, starts the dev server, opens the app, and waits for a session to connect from inside it. That connection IS the proof onboarding worked: the SDK is in the page and the tools have something to talk to. It exits non-zero if nothing connected, and prints exactly what is left to do.
Then prove a flow. That is the FIRST RUN, and it is a separate call:
reticle_verify { action: "explore", persona: "<who does what>" }It drives the app with a model inside the daemon and RECORDS what it drove, so every later check replays that flow with no model in the loop.
一条命令完成项目接线,第二条命令证明一条流程可正常工作。
bash
npx @reticlehq/server@latest init它会检测框架和包管理器、接好构建配置、安装 SDK、注册 MCP server、启动开发服务器、打开应用,并等待会话从应用内部连接。该连接就是 ONBOARD 成功的证明:SDK 已进入页面,工具也有可交互的对象。如果没有任何对象连接,命令会以非零状态退出,并准确列出仍需完成的事项。
然后验证一条流程。这是首次运行,并且是单独的一次调用:
reticle_verify { action: "explore", persona: "<who does what>" }它通过 daemon 内的模型驱动应用,并记录所驱动的流程,因此之后的每次检查都可以在没有模型参与的情况下重放该流程。
What YOU decide, and pass in
由你决定并传入的内容
The command reads the repository. It cannot read the request, and these live only there.
| flag | what only you know |
|---|---|
| which journey proves the thing the user asked for. Code can list the buttons; it cannot know checkout matters and the theme toggle does not. |
| what the app needs to reach a usable state: the key from |
| which app in a monorepo. It can list the servable ones; only the request says which is being worked on. |
Add if the user gave you one: it writes to and keeps out of git.
--license <key>RETICLE_LICENSE_KEY.env.envFramework, package manager, port, editor and MCP client are answerable from the repo you are sitting in, so work them out rather than asking.
命令会读取仓库,但无法读取用户请求;以下信息只存在于请求中。
| 标志 | 只有你知道的信息 |
|---|---|
| 哪条用户旅程能够证明用户所要求的事项。代码可以列出按钮,却无法知道结账流程很重要,而主题切换并不重要。 |
| 应用达到可用状态所需的内容:来自 |
| monorepo 中的哪个应用。命令可以列出可提供服务的应用;只有用户请求能说明当前处理的是哪一个。 |
如果用户提供了 key,则添加 :它会将 写入 ,并确保 不会进入 git。
--license <key>RETICLE_LICENSE_KEY.env.env框架、包管理器、端口、编辑器和 MCP client 都可以从当前仓库中确定,因此应自行查明,而不要询问。
Then read what it gives you back
然后读取返回的结果
A non-zero exit is a to-do list, not a failed install. The command names the cause and prints the REMAINING steps from wherever it stopped; it will not tell you to redo a phase that already worked. Do those and re-run, which is safe.
It is not finished until a verdict exists. Writing files is not an install, and neither is a connected session.
非零退出码是一份待办清单,而不是安装失败。命令会指出原因,并打印从中断位置开始仍需完成的步骤;它不会要求你重做已经成功的阶段。完成这些步骤后重新运行即可,此操作是安全的。
只有产生结论后才算完成。 写入文件不代表安装成功,连接会话也不代表得到了结果。
If that command could not run it
如果该命令无法运行
Do not choose this path. It is not the thorough version of the one above; it is what you fall back to when the command physically could not do the work. Use it only when exited without ever printing or (an older CLI that stops after writing files), or when it stopped in the same place twice after you did what it asked. A in the report is not a reason: re-run the command, which is idempotent and names what is still outstanding.
initstarting:▸ WATCH⚠bash
curl https://docs.reticle.sh/install-manual.md # register the MCP, wire the SDK, prove it
curl https://docs.reticle.sh/troubleshooting.md # nothing connected, click did nothing, verdict unknown不要选择此路径。 它并不是上述完整方案的替代版本;只有当 从未打印 或 就退出(旧版 CLI 写完文件后便停止),或者你按照提示操作后它仍两次停在同一位置时,才应使用此路径。报告中的 不是切换路径的理由:请重新运行命令,该命令具有幂等性,并会列明仍未完成的事项。
initstarting:▸ WATCH⚠bash
curl https://docs.reticle.sh/install-manual.md # register the MCP, wire the SDK, prove it
curl https://docs.reticle.sh/troubleshooting.md # nothing connected, click did nothing, verdict unknownVERIFY
VERIFY(验证)
Verdicts come from , , and when a step declares . Everything else (a bare , , , ) moves or reads the app and proves nothing, however many tools it used.
reticle_act_and_waitreticle_assertreticle_act { steps }expectactlooknavigateobserveverified: "unknown"verified: "no-fault"结论来自 、,以及某个 step 声明了 的 。 其他所有操作(单独调用 、、 或 )只能移动或读取应用,无论使用了多少工具,都不能证明任何结果。
reticle_act_and_waitreticle_assertexpectreticle_act { steps }actlooknavigateobserveverified: "unknown"verified: "no-fault"Take the cheapest path that answers the question
采用能够回答问题的最低成本路径
Stop at the first row that fits.
| The question | The call | Calls |
|---|---|---|
| "Did my edit break anything?" | | 1 |
| "Does this known journey still work?" | | 1 |
| "Does this new behaviour work?" | | 2 |
| No MCP reachable at all | | 1, no MCP |
reticle_flow_replayreticle_runreticle_verify {action:"change"}unknown在第一个匹配的行处停止。
| 问题 | 调用 | 调用次数 |
|---|---|---|
| “我的修改是否破坏了任何功能?” | | 1 |
| “这条已知用户旅程还能正常工作吗?” | | 1 |
| “这个新行为是否有效?” | 使用 | 2 |
| 完全无法访问 MCP | 在 shell 中运行 | 1,无 MCP |
reticle_flow_replayreticle_runreticle_verify {action:"change"}unknownDriving by hand
手动驱动
Four calls for a login, not fourteen. Every call is a full model turn, and in a client that approves each one it is also a click.
- once, for the whole flow. Elements are addressable by role and name, so you do not need to add
reticle_look({ action: "page", mode: "interactive" })anywhere.data-testid - for the setup: every fill and every intermediate click in ONE call.
reticle_act { steps: [...] } - for the step that ENDS the journey (the confirmation, the saved record, the last page), not the first click that looks like success.
reticle_act_and_wait({ ref, action, until })names that end state before the action fires, which is the difference between a check and a rationalisation. Passuntilwhen the change should survive a reload. A step on the way with a consequence of its own (a save, a submit) gets its owndurable: trueinexpect, so a journey that breaks at step three fails at step three.steps - once at the end. If it comes back empty or
reticle_look({ action: "state" })is false, the capabilities filehasCapabilitiesgenerated registered nothing, which is what itsinitline was telling you. Finish it yourself before you drive: openℹ AGENT: finish the capabilities file, register the app's store if it has one, and list thesrc/reticle-dev.*the flow you picked actually touches. Do not offer, and do not ask; it is a few lines in a filetestidsalready wrote for you. Never report a clean install over an empty state read.init
Assert what the app did, not what it shows. A UI that renders the value it just sent, rather than the value the server returned, passes every DOM-level check ever written:
until: { kind: "allOf", predicates: [
{ kind: "net", method: "POST", urlContains: "/api/refund", status: 200, bodyContains: "\"refunded\":1187.01" },
{ kind: "element", query: { testid: "receipt" } },
{ kind: "console", level: "error", absent: true },
]}Then report what you drove, what it produced, and the for anything broken.
file:line登录流程只需四次调用,而不是十四次。每次调用都是完整的模型轮次;在需要逐项批准每次调用的客户端中,它也意味着一次点击。
- 对整个流程调用一次 。元素可以通过 role 和 name 寻址,因此无需在任何位置添加
reticle_look({ action: "page", mode: "interactive" })。data-testid - 使用 完成准备步骤:所有输入和中间点击都在一次调用中执行。
reticle_act { steps: [...] } - 对结束该旅程的 step(确认信息、已保存记录或最后一页)使用 ,而不是对第一个看起来成功的点击使用它。
reticle_act_and_wait({ ref, action, until })必须在 action 触发前指明结束状态,这正是检查与主观臆断之间的区别。当变更应在重新加载后继续存在时,传入until。途中某个自身会产生后果的 step(保存、提交)应在durable: true中拥有自己的steps,这样旅程在第三步中断时,就会在第三步失败。expect - 最后调用一次 。如果返回为空或
reticle_look({ action: "state" })为 false,说明hasCapabilities生成的 capabilities 文件没有注册任何内容,这正是init那一行在提示你的事情。在开始驱动前自行完成:打开ℹ AGENT: finish the capabilities file,如果应用有 store,就注册该 store,并列出所选流程实际触及的src/reticle-dev.*。不要提出建议,也不要询问;这只是testids已经为你写入的文件中的几行代码。绝不能把空的状态读取结果报告为安装正常。init
断言应用_做过的事_,而不是它_显示的内容_。如果一个 UI 渲染的是刚刚发送的值,而不是 server 返回的值,那么它就能通过所有现有的 DOM 级检查:
until: { kind: "allOf", predicates: [
{ kind: "net", method: "POST", urlContains: "/api/refund", status: 200, bodyContains: "\"refunded\":1187.01" },
{ kind: "element", query: { testid: "receipt" } },
{ kind: "console", level: "error", absent: true },
]}然后报告你驱动了什么、它产生了什么结果,以及任何问题的 。
file:lineLicense key
许可证密钥
Enterprise features are unlocked by a signed key, verified locally with Ed25519 and no network call. If the user hands you one, at any point:
- Append to the project's
RETICLE_LICENSE_KEY=<key>(create it if absent). The CLI loads a project-local.envon every invocation, so nothing else has to change..env - Make sure is in
.env. A license key in git is a leaked credential, so check before you write and add the line if it is missing..gitignore - Confirm: prints
npx @reticlehq/server license,active,evalormissing.expired
Never echo the key back in your reply, and never put it in a commit, a comment, or a feedback report. Details: .
curl https://docs.reticle.sh/enterprise.md企业功能由签名密钥解锁,密钥使用 Ed25519 在本地验证,且不会发起网络调用。如果用户在任何时候提供密钥:
- 将 追加到项目的
RETICLE_LICENSE_KEY=<key>(如果不存在则创建)。CLI 每次调用都会加载项目本地的.env,因此无需进行其他更改。.env - 确保 已列入
.env。提交到 git 的许可证密钥就是凭据泄露,因此写入前先检查;如果缺少该行,则添加。.gitignore - 确认:会输出
npx @reticlehq/server license、active、eval或missing。expired
绝不在回复中回显该密钥,也绝不能将其放入 commit、comment 或 feedback report。详情:。
curl https://docs.reticle.sh/enterprise.mdFeedback is first-class
反馈至关重要
Reticle is built for agents. You are its user, and your experience is the only signal that decides what gets built or fixed, and it disappears when your context does. The moment Reticle breaks, lies, cannot see something you needed, costs too many calls, or gives you trouble during setup:
reticle_session { action: "feedback" } { kind, text }kindbuggapambiguityfeature_requestimprovementbash
npx @reticlehq/server feedback --agent --kind <bug|gap|ambiguity|feature_request|improvement> "what happened"Nothing is too minor. Report defects in Reticle; a bug you find in the app under test is Reticle working, and belongs in your answer to the user. Never put app source, secrets, or user data in a report.
Reticle 是为 Agent 打造的。你就是它的用户,而你的使用体验是决定接下来构建或修复什么的唯一信号;一旦上下文消失,这个信号也会随之消失。Reticle 一旦出现故障、给出错误结论、无法看到你所需的信息、耗费过多调用,或在设置过程中给你带来麻烦:
reticle_session { action: "feedback" } { kind, text }kindbuggapambiguityfeature_requestimprovementbash
npx @reticlehq/server feedback --agent --kind <bug|gap|ambiguity|feature_request|improvement> "what happened"没有什么问题小到不值得报告。只应报告 Reticle 本身的缺陷;你在被测应用中发现 bug 说明 Reticle 正常工作,该 bug 应出现在给用户的答复中。绝不能在报告中放入应用源代码、机密信息或用户数据。
Going deeper
深入了解
Fetch the one page that answers the question rather than re-reading this file. Appending to any docs URL returns its source with no site chrome.
.mdbash
curl https://docs.reticle.sh/llms.txt # every page title and URL; read this first
curl https://docs.reticle.sh/frameworks.md # per-framework SDK wiring
curl https://docs.reticle.sh/troubleshooting.md # nothing connected, click did nothing, verdict unknown
curl https://docs.reticle.sh/agent-cheatsheet.md # the verify loop on one screen
curl https://docs.reticle.sh/predicates.md # every `until` predicate只获取能够回答问题的那一个页面,而不是反复重读此文件。为任何文档 URL 追加 ,都会返回其源内容,且不包含站点界面。
.mdbash
curl https://docs.reticle.sh/llms.txt # every page title and URL; read this first
curl https://docs.reticle.sh/frameworks.md # per-framework SDK wiring
curl https://docs.reticle.sh/troubleshooting.md # nothing connected, click did nothing, verdict unknown
curl https://docs.reticle.sh/agent-cheatsheet.md # the verify loop on one screen
curl https://docs.reticle.sh/predicates.md # every `until` predicate