reticle README

The project's README from github.com/reticlehq/reticle. As one markdown file: README.md.

Reticle

Your AI agent says "done." Reticle checks whether that's true.

It drives your real running app, reads what actually happened, and hands back pass · fail · couldn't tell with the file:line to fix.


npm downloads stars license OpenSSF Discord

Install · Use it · How it works · vs Playwright · Benchmarks · Limits · Docs


Watch: an agent drives a real app, reads the network and the store, and returns a verdict with the file:line to fix

▶ Two minutes. An agent finds a bug the screen was hiding, and proves the fix.


Install

Three steps. The first one is the whole install.

Before you run any of it. Reticle is a dev tool that edits your build config and registers an MCP server, so here is what it does, up front, rather than after you have run it:

1. Run the installer

macOS · Linux

curl -fsSL https://raw.githubusercontent.com/reticlehq/reticle/main/install/install.sh | sh

Windows (PowerShell)

irm https://raw.githubusercontent.com/reticlehq/reticle/main/install/install.ps1 | iex

It puts reticle on your PATH and registers the MCP server with every coding agent it can reach: Claude Code, Cursor, Windsurf, VS Code, Zed, Gemini CLI, Copilot CLI, OpenCode, Warp, Kiro, Amazon Q, Cline, Amp, Continue and Factory Droid. Nothing is written outside your agent configs and ~/.reticle. It is a shell script: curl -fsSL <url> | less reads it before you run it.

Codex CLI keeps a TOML config we don't rewrite, so the installer prints the four lines to paste and where they go. It tells you; it doesn't pretend.

2. Open your coding agent

That's it. The tools are already there, because the installer wrote the config before your agent started.

Run the installer first, in a terminal. A coding agent reads its MCP server list once at startup. Install while it's closed and there is nothing to restart. If it was already open, quit and reopen it once.

3. Wire your app

In your project, let your agent run:

RETICLE_INSTALL_SOURCE=readme npx @reticlehq/server init

Like npm init or git init, this is the per-project step. It installs the dev-only SDK, wires your build config, restarts your dev server, and then opens your app and proves a session connected. A config file is not an install, so init doesn't stop until it has seen your app.

Step 1 is once per machine. This step is once per project.

Check it worked

npx @reticlehq/server doctor

Or just ask your agent: "Is Reticle connected to my app?"

Manual install (no pipe to shell)
npm install -g @reticlehq/server   # 1. the CLI
npx @reticlehq/server setup mcp    # 2. register it with your agents

Step 2 registers the same agents as the installer, and writes the /reticle skill where the agent supports one. On Claude Code it also pre-approves the Reticle tools, so there is no Accept prompt on every call.

Any other MCP client: point it at npx @reticlehq/server mcp.

{ "mcpServers": { "reticle": { "command": "npx", "args": ["@reticlehq/server", "mcp"] } } }

Then continue at step 2 above: open your agent, and run npx @reticlehq/server init in your project.

The RETICLE_INSTALL_SOURCE prefix above is optional. It tells us which page somebody installed from, so we know which docs are working.

Requires Node 20.11+.

Claude Code plugin (skill + MCP in one step)
/plugin marketplace add reticlehq/reticle
/plugin install reticle@reticlehq

Registers the MCP server and installs the Reticle skill together. Reopen Claude Code once and the tools are there.

For other agents that support the skills CLI:

npx skills add reticlehq/reticle

Use it

You never write test syntax. You say what should be true, in plain English.

An agent driving a real app through Reticle: it clicks, reads what actually happened, and returns a verdict.

Verify what you just built

"I changed checkout. Verify it with Reticle before you tell me it's done."

Find what the screen is hiding

"The page looks fine but something's off. Use Reticle to check what's happening underneath."

Prove a bug is fixed

"Reproduce the bug with Reticle, fix it, then prove the fix with the same steps."

Lock a flow so it can't break

"Record the login flow with Reticle, then re-verify it after every change."

Sweep before you ship

"Walk the main routes with Reticle. Tell me anything broken."

Reticle answers with evidence: the request that fired, the state that changed, the console line, and the file to open.

Make it unavoidable in CI

npx @reticlehq/server gate --since HEAD~1

gate works out which saved flows your edits affect and exits non-zero unless a passing artifact covers each one. An agent that edits a covered file cannot call itself finished without re-verifying, and it is the one check nobody can satisfy by reasoning about their own diff. See docs/cli/gate.mdx.


Why not Playwright?

Playwright, DevTools and browser agents all stand outside the browser looking in. For a site you don't own, that's right. For the app you're building, the bugs that matter never reach the pixels.

Bug Looks fine on screen? Reticle reads
Pay button silently returns 500 yes the network response, tied to the click
Badge shows "12", the store holds 0 yes your app's state
The form fired the request twice yes request count
"Deploy succeeded", the deploy failed yes the store's real status
A console error slipped in yes the console since the action
Component re-renders 60×/sec yes the React commit stream

Use both. Playwright for sites you don't own, many browsers, real pixels. Reticle for the app you're building, inside your agent's loop.


The problem

Your agent writes code, assumes it worked, and moves on. It never opens the app.

So the broken modal, the silent 500, the "Deploy succeeded" over a failed deploy: they all ship, and you find them by clicking around afterwards. You've become your agent's QA.

The truth was in the running app the whole time. It just never reached the screen.

A page that looks shipped, hiding mock data, a dead click and a silent 500.

This isn't something your agent forgot. A coding agent is built to produce a change, and it's optimistic by construction. Verification is the opposite motion: going to find out, and being willing to come back with no.


How it works

You: "Verify login works."

Agent, via Reticle: clicks Sign in → POST /api/login → 200 (14 ms) → dashboard rendered → store holds auth: { email: "admin@…" } → PASS, evidence attached.

Reticle watches the app from the inside: a broken Pay button traced to onPay.tsx line 46, handed to the coding agent as a repair packet.

flowchart LR
    A["Your agent<br/>(Claude Code, Cursor…)"] -->|"look · act · observe · assert"| B(("Reticle"))
    B <-->|"structured events,<br/>not pixels"| C["Your running app<br/>DOM · network · console<br/>store · React fiber"]
    B -->|"verdict + evidence<br/>+ file:line"| A
    style B fill:#8b7bff,stroke:#5b4bd0,color:#fff
    style A fill:#15131f,stroke:#3a3550,color:#fff
    style C fill:#1c2433,stroke:#2f3d57,color:#fff

A failed verdict naming the exact source file and line to fix, rather than a screenshot to squint at.

A verdict points at the line that caused it. That pointer is the difference between "something broke" and a fix.

One call checks many things at once. Say "save that as a flow" and it replays on every later edit with no model in the loop, so today's fix can't quietly break last week's feature.

Re-driving a suite with an LLM burns tokens on every step, every run. Reticle records the flow once and replays it deterministically: no model, no flake, just a verdict.

What one call looks like underneath
// The agent clicked "Pay". Did the right things actually happen?
reticle_assert({
  predicate: { allOf: [
    { kind: "net",     method: "POST", urlContains: "/api/order", status: 200 },
    { kind: "element", query: { role: "dialog", name: "Order confirmed" }, state: "visible" },
    { kind: "signal",  name: "order:saved" },          // the charge actually committed
    { kind: "console", level: "error", absent: true }  // …and nothing errored
  ]}
})
// → { pass: false,
//     failureReason: "POST /api/order returned 500, expected 200",
//     source: { file: "src/checkout/PayButton.tsx", line: 42 } }

Benchmarks

88 real regressions injected into a controlled app, Reticle against a Playwright script. Every number comes from a committed harness. Reproduce it with pnpm bench.

Reticle catches 14x more bugs where the screen looks right: 28 versus 2 across the six categories the two tools disagree on, and 85/86 versus 59/86 overall.

Cumulative tokens to re-verify a four-flow suite over 100 runs: Reticle 128k, Playwright MCP 12.1M.

Re-verification has no model in the loop, so a recorded suite is a fixed, tiny read. Reticle is ahead from the second run even when charged a full LLM drive to author the suite.

Re-running a four-flow suite: Reticle replays it in 47 tokens with no model and no flake, against about 120,000 tokens to re-drive it with an LLM.

Wall-clock time to a verdict: a 2.6 second time-gated transition verified in 176 ms versus a 2,978 ms real wait, and a 16-flow batch in 5.2 seconds versus 31.7 seconds one at a time.

Faster for a structural reason rather than a browser-speed one: a time-gated transition is verified from the event stream instead of waited out, and a batch of flows runs as a batch.


Limits

A verification tool that oversells its reach is worse than none.

Strong silent failed requests, state that disagrees with the screen, stale caches, double-submits, a write that failed while the UI moved on
Partial races around a single action. It detects request-never-settled and duplicate-request; it is not a scheduler-level race analyser
Not the tool cross-browser rendering, visual regressions, sites you don't own. That's Playwright
Can't see yet IndexedDB, Web Workers, closed shadow roots, cross-origin iframes

When Reticle can't see something, it says so. A verdict is yes, no, or unknown, where unknown means the evidence couldn't decide. Never a quiet pass.

Cost: zero bytes in production. The SDK sits behind import.meta.env.DEV and is dead-code eliminated; a runtime guard refuses to connect under NODE_ENV=production. No app data leaves your machine.


Supported

Web Next.js (App + Pages), Vite + React, CRA, SvelteKit, Svelte, Astro, Vue 3, Preact, plain HTML
Desktop Electron, Tauri, including the IPC boundary a browser-only tool can't see
Agents anything that speaks MCP. Config written automatically for Claude Code, Cursor, Windsurf, VS Code, Zed, Gemini CLI, Copilot CLI, OpenCode, Warp, Kiro, Amazon Q, Cline, Amp, Continue, Factory Droid. Codex CLI is a printed four-line paste
Browsers Chrome, Edge, Arc, Brave, Opera, Firefox, Safari, plus Electron and Tauri webviews
State zustand and Redux need no adapter. Shipped: TanStack Query, Jotai, XState, Valtio, MobX, Recoil, Svelte stores, Pinia
OS macOS, Linux, Windows

On the roadmap

Routing verification flows with TypeSafe AI's Jev. A verification run makes a lot of small decisions — is this page settled, is this finding worth chasing, does this failure warrant a full capture — and today an LLM answers each one at LLM latency and LLM cost. Jev is a System One model: it returns a typed, probabilistic choice from a fixed set instead of prose, in 70–500ms. That is the exact shape of a routing decision inside Reticle's infra, so when we build that layer, Jev is what decides which flow a run takes. That layer is the roadmap item; it does not ship yet.

What DOES ship, since 3.2.0, is Jev driving the app rather than routing inside it: reticle_verify { action: "explore", driver: "jev" } explores a page by selecting from candidates Reticle enumerated off the DOM, so the model chooses and never composes. See docs/autodrive.md.

Docs

docs.reticle.sh — a page per tool, a page per command, every example captured from a real run.

Quickstart · Frameworks · Troubleshooting · Architecture · Contributing

Community

Join the Discord → Where the work happens in the open: what's being built, what's up for grabs, and design calls before they land.

Contributors

If Reticle proves useful, a ⭐ helps other developers find it.

License

SDK and adapters are Apache-2.0. The server is FSL (source-available, converts to Apache-2.0 after two years). See LICENSE.

dev-only · localhost-only · your app data stays local

reticle (reticlehq/reticle)

Searching Database…

1.2K ·GitHub
这是什么?Reticle 让编码 AI 智能体通过操控真实运行中的应用并读取实际发生的事情——网络请求、应用状态、控制台——来验证自己的工作,而不是想当然地认为代码没问题,最后给出通过、失败或“未知”的判定结果,并附上需要修复的确切 file:line。
它是 Playwright 的替代品,还是别的东西?它是一个 MCP 服务器加一个仅供开发用的 SDK,供你的编码智能体作为工具调用,并不是取代 Playwright 的浏览器自动化工具。Playwright 从浏览器外部操控像素,面向你不拥有的网站;Reticle 则从内部读取你自己应用的真实网络、状态和控制台。
怎么让它跑起来?运行一次性的机器级安装程序(macOS/Linux 用 shell 脚本,Windows 用 PowerShell),它会把 reticle 加入 PATH 并为你的编码智能体注册 MCP 服务器;然后在每个项目中让智能体运行 “npx @reticlehq/server init”,把开发 SDK 接入你的构建。
它支持哪些编码智能体,我还需要什么?任何支持 MCP 的智能体都能用:Claude Code、Cursor、Windsurf、VS Code、Zed、Gemini CLI、Copilot CLI、OpenCode、Warp、Kiro、Amazon Q、Cline、Amp、Continue 和 Factory Droid(Codex CLI 需要手动粘贴四行配置)。你只需要 Node 20.11+;本地判定不需要账号或 API 密钥。
Reticle 目前还看不到哪些东西?它目前还看不到 IndexedDB、Web Worker、闭合的 shadow root 和跨源 iframe,对单操作竞态也只能部分处理(并非完整的调度器级竞态分析器)。它明确不适合用于跨浏览器渲染或视觉回归检查——那仍然是 Playwright 的职责。
它支持哪些框架和平台?支持 Next.js、Vite+React、SvelteKit、Vue 3、Astro 等网页框架以及纯 HTML,还有用 Electron 或 Tauri 构建的桌面应用——包括纯浏览器工具看不到的原生 IPC 边界。CLI 本身可在 macOS、Linux 和 Windows 上运行。
我的应用数据会离开我的电脑吗?不会——每个判定都完全在本地计算,除非你明确运行 “reticle login” 和 “reticle link”,否则不会向任何地方发送数据。匿名使用遥测(只包含事件名称,不含代码或页面内容)可以关闭。
整个项目都开源吗?部分开源:SDK 和适配器采用 Apache-2.0,但服务器本身以 FSL 许可证发布——源码现在可见,并在每个版本发布两年后自动转为 Apache-2.0。
判定结果实际长什么样?判定结果是通过、失败或“无法判断”——绝不会默默放行——并附有证据,例如实际发出的请求、发生改变的状态、相关的控制台输出行,以及需要打开查看的 file:line。
我可以锁定一个已验证的流程,防止它日后悄悄失效吗?可以——让智能体“把它保存为流程”,Reticle 就会记录下来;重新验证时会原样重放,过程中不使用 LLM;“reticle gate” 还可以在代码修改后,某个已保存流程没有被一次通过的运行覆盖时让 CI 失败。
Jev 是什么?Reticle 已经在用它了吗?Jev 是一个快速的“系统一”模型(70-500 毫秒),返回结构化的选项而不是一段文字;从 v3.2.0 起,它可以通过 reticle_verify 驱动探索式的应用走查,不过让 Reticle 自身的内部决策也经由 Jev 处理仍在路线图上,尚未发布。
加入 Reticle 会让我的生产构建变臃肿或变慢吗?不会——SDK 藏在 import.meta.env.DEV 之后会被死代码消除,且运行时守卫在 NODE_ENV=production 下拒绝连接,因此对生产环境的体积开销为零字节。
Creator
reticlehq
Size
156.1 MB
Stars
1.2K
Age
4mo
Commits · 90 Days