@reticlehq/server 2.7.0 → 2.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (357) hide show
  1. package/README.md +14 -5
  2. package/SKILL.md +130 -778
  3. package/dist/bridge/bridge.d.ts +23 -0
  4. package/dist/bridge/bridge.js +80 -2
  5. package/dist/bridge/bridge.test-harness.d.ts +5 -0
  6. package/dist/bridge/bridge.test-harness.js +6 -4
  7. package/dist/capsule/causal-summary.d.ts +36 -1
  8. package/dist/capsule/causal-summary.js +33 -7
  9. package/dist/capsule/divergence.js +7 -1
  10. package/dist/cli/chromium-hint.d.ts +33 -5
  11. package/dist/cli/chromium-hint.js +82 -12
  12. package/dist/cli/cli-doctor.js +65 -34
  13. package/dist/cli/cli-flow-commands.js +8 -8
  14. package/dist/cli/cli-kill.d.ts +58 -0
  15. package/dist/cli/cli-kill.js +162 -0
  16. package/dist/cli/cli-parse.d.ts +16 -1
  17. package/dist/cli/cli-parse.js +32 -9
  18. package/dist/cli/cli-port.d.ts +32 -0
  19. package/dist/cli/cli-port.js +82 -35
  20. package/dist/cli/cli-verify.d.ts +21 -0
  21. package/dist/cli/cli-verify.js +47 -3
  22. package/dist/cli/config-discovery.d.ts +35 -0
  23. package/dist/cli/config-discovery.js +163 -0
  24. package/dist/cli/doctor-daemon-line.js +4 -1
  25. package/dist/cli/doctor-project-line.d.ts +37 -0
  26. package/dist/cli/doctor-project-line.js +35 -0
  27. package/dist/cli/doctor-rows.d.ts +51 -0
  28. package/dist/cli/doctor-rows.js +54 -0
  29. package/dist/cli/doctor-sessions-line.d.ts +12 -0
  30. package/dist/cli/doctor-sessions-line.js +69 -0
  31. package/dist/cli/drive-attach.d.ts +99 -0
  32. package/dist/cli/drive-attach.js +203 -0
  33. package/dist/cli/drive-command.d.ts +13 -0
  34. package/dist/cli/drive-command.js +103 -0
  35. package/dist/cli/open-note.d.ts +20 -0
  36. package/dist/cli/open-note.js +37 -0
  37. package/dist/cli/port-holder.d.ts +10 -0
  38. package/dist/cli/port-holder.js +26 -2
  39. package/dist/cli/status-next-action.d.ts +37 -0
  40. package/dist/cli/status-next-action.js +61 -0
  41. package/dist/cli.js +119 -39
  42. package/dist/crawl/crawl-tools.js +12 -2
  43. package/dist/crawl/crawl.d.ts +13 -0
  44. package/dist/crawl/crawl.js +50 -2
  45. package/dist/events/contradictions.d.ts +46 -0
  46. package/dist/events/contradictions.js +35 -22
  47. package/dist/events/declared.d.ts +45 -0
  48. package/dist/events/declared.js +73 -0
  49. package/dist/events/echo-mismatch.d.ts +8 -2
  50. package/dist/events/echo-mismatch.js +33 -5
  51. package/dist/events/event-filters.d.ts +1 -1
  52. package/dist/events/event-filters.js +7 -4
  53. package/dist/events/predicate-eval.d.ts +17 -72
  54. package/dist/events/predicate-eval.js +117 -236
  55. package/dist/events/predicate-parse.js +31 -3
  56. package/dist/events/predicate-route.d.ts +32 -0
  57. package/dist/events/predicate-route.js +102 -0
  58. package/dist/events/predicate-schema.d.ts +99 -0
  59. package/dist/events/predicate-schema.js +309 -0
  60. package/dist/events/predicate.d.ts +8 -0
  61. package/dist/events/predicate.js +296 -22
  62. package/dist/flows/annotate-tools.js +3 -0
  63. package/dist/flows/annotate.js +18 -4
  64. package/dist/flows/coverage.d.ts +38 -5
  65. package/dist/flows/coverage.js +30 -4
  66. package/dist/flows/decision.d.ts +15 -0
  67. package/dist/flows/decision.js +1 -1
  68. package/dist/flows/flow-classify.js +1 -1
  69. package/dist/flows/flow-replay-run.js +8 -1
  70. package/dist/flows/flow-tools.js +21 -5
  71. package/dist/flows/heal-run.js +1 -1
  72. package/dist/flows/replay.js +3 -0
  73. package/dist/honesty/accepted-write.d.ts +3 -0
  74. package/dist/honesty/accepted-write.js +8 -3
  75. package/dist/honesty/already-true.js +15 -0
  76. package/dist/honesty/blind-spots.js +10 -2
  77. package/dist/honesty/honesty.d.ts +11 -0
  78. package/dist/honesty/honesty.js +1 -0
  79. package/dist/honesty/uncaptured-bodies.d.ts +4 -2
  80. package/dist/honesty/uncaptured-bodies.js +9 -2
  81. package/dist/honesty/unread-outcome.d.ts +8 -0
  82. package/dist/honesty/unread-outcome.js +36 -9
  83. package/dist/honesty/unsettled.d.ts +49 -0
  84. package/dist/honesty/unsettled.js +82 -0
  85. package/dist/honesty/verified.d.ts +36 -3
  86. package/dist/honesty/verified.js +54 -11
  87. package/dist/http-server.d.ts +19 -0
  88. package/dist/http-server.js +202 -4
  89. package/dist/impact/impact-recorder.d.ts +23 -0
  90. package/dist/impact/impact-recorder.js +76 -0
  91. package/dist/impact/impact-store.d.ts +47 -0
  92. package/dist/impact/impact-store.js +171 -0
  93. package/dist/index.d.ts +7 -0
  94. package/dist/index.js +47 -10
  95. package/dist/init/agent-rules.d.ts +36 -0
  96. package/dist/init/agent-rules.js +132 -22
  97. package/dist/init/astro-patch.d.ts +2 -1
  98. package/dist/init/astro-patch.js +38 -6
  99. package/dist/init/capabilities.d.ts +22 -0
  100. package/dist/init/capabilities.js +76 -0
  101. package/dist/init/confirm.d.ts +114 -0
  102. package/dist/init/confirm.js +165 -0
  103. package/dist/init/connect-steps.d.ts +2 -0
  104. package/dist/init/connect-steps.js +50 -0
  105. package/dist/init/cra.js +3 -2
  106. package/dist/init/csp-check.d.ts +38 -0
  107. package/dist/init/csp-check.js +92 -0
  108. package/dist/init/csp-doctor.d.ts +25 -0
  109. package/dist/init/csp-doctor.js +49 -0
  110. package/dist/init/cursor.js +6 -9
  111. package/dist/init/detect.d.ts +8 -0
  112. package/dist/init/detect.js +33 -3
  113. package/dist/init/mcp-clients.d.ts +1 -0
  114. package/dist/init/mcp-clients.js +51 -7
  115. package/dist/init/mcp.d.ts +15 -0
  116. package/dist/init/mcp.js +19 -0
  117. package/dist/init/non-js-project.js +29 -5
  118. package/dist/init/plan-framework.d.ts +10 -0
  119. package/dist/init/plan-framework.js +78 -16
  120. package/dist/init/plan.d.ts +47 -6
  121. package/dist/init/plan.js +228 -69
  122. package/dist/init/run.d.ts +24 -2
  123. package/dist/init/run.js +157 -45
  124. package/dist/init/slash-command.d.ts +1 -1
  125. package/dist/init/slash-command.js +54 -6
  126. package/dist/init/snippets.d.ts +45 -5
  127. package/dist/init/snippets.js +194 -42
  128. package/dist/init/vite-config.js +53 -5
  129. package/dist/input/network-mock-tools.d.ts +19 -0
  130. package/dist/input/network-mock-tools.js +37 -5
  131. package/dist/input/scroll-find.d.ts +6 -0
  132. package/dist/input/scroll-find.js +17 -2
  133. package/dist/input/scroll-tools.js +4 -0
  134. package/dist/journal/attach-journal.d.ts +9 -1
  135. package/dist/journal/attach-journal.js +13 -2
  136. package/dist/journal/journal-query.d.ts +13 -0
  137. package/dist/journal/journal-query.js +28 -3
  138. package/dist/journal/workspace-gitignore.d.ts +10 -0
  139. package/dist/journal/workspace-gitignore.js +59 -0
  140. package/dist/license/license.js +1 -1
  141. package/dist/mcp/mcp-proxy.d.ts +35 -30
  142. package/dist/mcp/mcp-proxy.js +306 -104
  143. package/dist/mcp/mcp.d.ts +10 -1
  144. package/dist/mcp/mcp.js +70 -34
  145. package/dist/mcp/proxy-handshake.d.ts +82 -1
  146. package/dist/mcp/proxy-handshake.js +109 -2
  147. package/dist/mcp/proxy-lifecycle.d.ts +11 -2
  148. package/dist/mcp/proxy-lifecycle.js +12 -3
  149. package/dist/mcp/proxy-log.d.ts +63 -0
  150. package/dist/mcp/proxy-log.js +132 -0
  151. package/dist/mcp/server-instructions.d.ts +17 -0
  152. package/dist/mcp/server-instructions.js +56 -0
  153. package/dist/mcp/shared-params.d.ts +27 -0
  154. package/dist/mcp/shared-params.js +36 -0
  155. package/dist/pool/browser-pool.d.ts +22 -2
  156. package/dist/pool/browser-pool.js +44 -4
  157. package/dist/project/learned-routes.d.ts +24 -0
  158. package/dist/project/learned-routes.js +63 -0
  159. package/dist/project/project-store.d.ts +6 -0
  160. package/dist/project/project-store.js +25 -1
  161. package/dist/project/reticle-dir.d.ts +2 -0
  162. package/dist/project/reticle-dir.js +1 -0
  163. package/dist/session/connection-memory.d.ts +59 -0
  164. package/dist/session/connection-memory.js +108 -0
  165. package/dist/session/dev-command.d.ts +26 -0
  166. package/dist/session/dev-command.js +89 -0
  167. package/dist/session/dev-server-probe.d.ts +68 -0
  168. package/dist/session/dev-server-probe.js +102 -7
  169. package/dist/session/last-act.d.ts +26 -0
  170. package/dist/session/last-act.js +35 -1
  171. package/dist/session/live-control-tools.js +42 -5
  172. package/dist/session/no-session-diagnosis.d.ts +67 -2
  173. package/dist/session/no-session-diagnosis.js +236 -27
  174. package/dist/session/no-session-next-action.d.ts +46 -0
  175. package/dist/session/no-session-next-action.js +85 -0
  176. package/dist/session/no-session-watch.d.ts +40 -1
  177. package/dist/session/no-session-watch.js +174 -8
  178. package/dist/session/pending-commands.d.ts +12 -0
  179. package/dist/session/pending-commands.js +13 -1
  180. package/dist/session/ref-provenance.d.ts +54 -0
  181. package/dist/session/ref-provenance.js +61 -0
  182. package/dist/session/session-lease.js +1 -1
  183. package/dist/session/session-manager.d.ts +4 -0
  184. package/dist/session/session-manager.js +35 -5
  185. package/dist/session/session.d.ts +10 -1
  186. package/dist/session/session.js +146 -5
  187. package/dist/telemetry/app-instrumented.d.ts +8 -0
  188. package/dist/telemetry/app-instrumented.js +10 -0
  189. package/dist/telemetry/automation-hint.d.ts +17 -0
  190. package/dist/telemetry/automation-hint.js +71 -0
  191. package/dist/telemetry/bug-found.d.ts +15 -17
  192. package/dist/telemetry/bug-found.js +52 -21
  193. package/dist/telemetry/cli-telemetry.js +7 -1
  194. package/dist/telemetry/daemon-telemetry.js +24 -0
  195. package/dist/telemetry/feedback.js +1 -1
  196. package/dist/telemetry/init-telemetry.js +9 -1
  197. package/dist/telemetry/install-source.d.ts +56 -0
  198. package/dist/telemetry/install-source.js +74 -0
  199. package/dist/telemetry/instrumentation-stall.d.ts +50 -0
  200. package/dist/telemetry/instrumentation-stall.js +90 -0
  201. package/dist/telemetry/run-telemetry.js +4 -1
  202. package/dist/telemetry/session-metrics.d.ts +8 -0
  203. package/dist/telemetry/session-metrics.js +15 -0
  204. package/dist/telemetry/telemetry.d.ts +7 -1
  205. package/dist/telemetry/telemetry.js +26 -2
  206. package/dist/telemetry/tool-refused.d.ts +19 -0
  207. package/dist/telemetry/tool-refused.js +55 -0
  208. package/dist/telemetry/verification-of.js +46 -7
  209. package/dist/temp-dir.d.ts +27 -0
  210. package/dist/temp-dir.js +46 -0
  211. package/dist/tools/act-tools.js +209 -28
  212. package/dist/tools/assert-grade.d.ts +1 -1
  213. package/dist/tools/assert-grade.js +27 -5
  214. package/dist/tools/assert-verdict.js +49 -7
  215. package/dist/tools/browser-tools.js +10 -0
  216. package/dist/tools/contract-tools.js +4 -0
  217. package/dist/tools/dynamic-tools.js +16 -7
  218. package/dist/tools/error-recovery.d.ts +10 -0
  219. package/dist/tools/error-recovery.js +73 -9
  220. package/dist/tools/feedback-invite.js +1 -1
  221. package/dist/tools/invoke-tool.js +159 -26
  222. package/dist/tools/lease-hint.d.ts +30 -8
  223. package/dist/tools/lease-hint.js +65 -14
  224. package/dist/tools/lease-tools.d.ts +40 -1
  225. package/dist/tools/lease-tools.js +181 -83
  226. package/dist/tools/navigate-result.js +1 -1
  227. package/dist/tools/observe-tools.js +10 -4
  228. package/dist/tools/observed-nothing.js +1 -1
  229. package/dist/tools/react-grace.d.ts +52 -0
  230. package/dist/tools/react-grace.js +90 -0
  231. package/dist/tools/read-tools.js +67 -5
  232. package/dist/tools/resolve-target.d.ts +33 -0
  233. package/dist/tools/resolve-target.js +53 -0
  234. package/dist/tools/settle-in-flight.d.ts +94 -0
  235. package/dist/tools/settle-in-flight.js +146 -0
  236. package/dist/tools/snapshot-delta.d.ts +10 -0
  237. package/dist/tools/snapshot-delta.js +194 -9
  238. package/dist/tools/tool-kit.d.ts +8 -0
  239. package/dist/tools/tool-surface.d.ts +60 -0
  240. package/dist/tools/tool-surface.js +86 -1
  241. package/dist/tools/tools.js +61 -8
  242. package/dist/tools/unadvertised-help.js +9 -6
  243. package/docs/README.md +55 -11
  244. package/docs/actions.mdx +120 -0
  245. package/docs/agent-cheatsheet.md +95 -29
  246. package/docs/architecture.md +52 -35
  247. package/docs/benchmarks.md +127 -75
  248. package/docs/best-practices.mdx +216 -0
  249. package/docs/capabilities.mdx +534 -0
  250. package/docs/cli/affected.mdx +53 -0
  251. package/docs/cli/capsules.mdx +70 -0
  252. package/docs/cli/cloud.mdx +153 -0
  253. package/docs/cli/doctor.mdx +109 -0
  254. package/docs/cli/drive.mdx +74 -0
  255. package/docs/cli/feedback.mdx +67 -0
  256. package/docs/cli/gate.mdx +64 -0
  257. package/docs/cli/help.mdx +94 -0
  258. package/docs/cli/hunt.mdx +73 -0
  259. package/docs/cli/identify.mdx +76 -0
  260. package/docs/cli/init.mdx +121 -0
  261. package/docs/cli/kill.mdx +91 -0
  262. package/docs/cli/license.mdx +48 -0
  263. package/docs/cli/mcp.mdx +61 -0
  264. package/docs/cli/open.mdx +74 -0
  265. package/docs/cli/restart.mdx +60 -0
  266. package/docs/cli/rollback.mdx +35 -0
  267. package/docs/cli/serve.mdx +69 -0
  268. package/docs/cli/status.mdx +88 -0
  269. package/docs/cli/stop.mdx +64 -0
  270. package/docs/cli/telemetry.mdx +57 -0
  271. package/docs/cli/update.mdx +52 -0
  272. package/docs/cli/verify.mdx +76 -0
  273. package/docs/cli/version.mdx +39 -0
  274. package/docs/cli/watch.mdx +62 -0
  275. package/docs/cli.mdx +241 -0
  276. package/docs/debugging.md +16 -10
  277. package/docs/deploy-checks.md +45 -12
  278. package/docs/desktop.mdx +384 -0
  279. package/docs/docs.json +364 -0
  280. package/docs/enterprise.md +22 -16
  281. package/docs/faq.mdx +102 -0
  282. package/docs/fixtures.md +13 -7
  283. package/docs/flows.md +29 -23
  284. package/docs/for-agents.md +71 -0
  285. package/docs/frameworks.mdx +238 -0
  286. package/docs/gate-plan.md +48 -42
  287. package/docs/gates.md +28 -22
  288. package/docs/getting-started.md +129 -77
  289. package/docs/human-control.md +24 -18
  290. package/docs/index.mdx +143 -0
  291. package/docs/install-agentic.mdx +224 -0
  292. package/docs/install-manual.mdx +196 -0
  293. package/docs/instrumentation.mdx +238 -0
  294. package/docs/integration-patterns.md +41 -35
  295. package/docs/local-registry.md +19 -13
  296. package/docs/multi-agent-testing.md +19 -13
  297. package/docs/packages/babel-plugin.mdx +79 -0
  298. package/docs/packages/browser.mdx +111 -0
  299. package/docs/packages/core.mdx +116 -0
  300. package/docs/packages/electron.mdx +85 -0
  301. package/docs/packages/eslint-plugin.mdx +86 -0
  302. package/docs/packages/next.mdx +89 -0
  303. package/docs/packages/react.mdx +91 -0
  304. package/docs/packages/server.mdx +98 -0
  305. package/docs/packages/tauri.mdx +63 -0
  306. package/docs/packages/test.mdx +119 -0
  307. package/docs/packages/vite-plugin.mdx +94 -0
  308. package/docs/packages.mdx +218 -0
  309. package/docs/platform-integration.md +35 -26
  310. package/docs/predicates.mdx +248 -0
  311. package/docs/quickstart.mdx +257 -0
  312. package/docs/recipes.mdx +282 -0
  313. package/docs/skill-file.mdx +107 -0
  314. package/docs/state-management.mdx +199 -0
  315. package/docs/style.css +14 -0
  316. package/docs/system-map.md +50 -33
  317. package/docs/telemetry-contract.md +106 -52
  318. package/docs/telemetry-events.mdx +475 -0
  319. package/docs/telemetry.md +63 -55
  320. package/docs/testing.md +44 -6
  321. package/docs/token-efficiency.md +37 -27
  322. package/docs/tools-act-and-wait.mdx +173 -0
  323. package/docs/tools-act-sequence.mdx +137 -0
  324. package/docs/tools-act.mdx +95 -0
  325. package/docs/tools-assert.mdx +129 -0
  326. package/docs/tools-console.mdx +63 -0
  327. package/docs/tools-inspect.mdx +88 -0
  328. package/docs/tools-navigate.mdx +99 -0
  329. package/docs/tools-network.mdx +119 -0
  330. package/docs/tools-observe.mdx +145 -0
  331. package/docs/tools-overview.mdx +160 -0
  332. package/docs/tools-query.mdx +126 -0
  333. package/docs/tools-session-and-feedback.mdx +112 -0
  334. package/docs/tools-sessions.mdx +94 -0
  335. package/docs/tools-snapshot.mdx +129 -0
  336. package/docs/tools-state.mdx +104 -0
  337. package/docs/tools-tools-and-run.mdx +156 -0
  338. package/docs/tools-wait-for.mdx +85 -0
  339. package/docs/troubleshooting.mdx +263 -0
  340. package/docs/usage.md +209 -165
  341. package/docs/vs-chrome-devtools-mcp.mdx +123 -0
  342. package/docs/vs-playwright-mcp.mdx +125 -0
  343. package/docs/vs-screenshots.mdx +137 -0
  344. package/docs/what-is-reticle.mdx +63 -0
  345. package/docs/why-reticle.mdx +109 -0
  346. package/package.json +5 -5
  347. package/docs/desktop-apps.md +0 -256
  348. package/docs/matrix/2.5.0/claude-code-machine.json +0 -19
  349. package/docs/matrix/2.5.0/codex-machine.json +0 -20
  350. package/docs/matrix/2.5.0/cursor-machine.json +0 -22
  351. package/docs/matrix/2.5.0/gemini-machine.json +0 -22
  352. package/docs/matrix/2.5.0/opencode-machine.json +0 -22
  353. package/docs/matrix/2.5.0/vscode-machine.json +0 -22
  354. package/docs/matrix/2.5.0/windsurf-machine.json +0 -22
  355. package/docs/matrix/MATRIX.md +0 -26
  356. package/docs/matrix/README.md +0 -59
  357. package/docs/mint.json +0 -61
@@ -0,0 +1,123 @@
1
+ ---
2
+ title: Reticle vs Chrome DevTools MCP
3
+ description: Chrome DevTools MCP is slightly cheaper per look. Reticle caught every bug it missed. Here is the trade, measured.
4
+ icon: chrome
5
+ ---
6
+
7
+ **Short answer:** Chrome DevTools MCP is a few percent cheaper per observation. It also caught 8 of 10 bugs where Reticle caught 10. If your tool is cheap because it looks at less, the savings are not savings.
8
+
9
+ ## The measurement
10
+
11
+ Same app, same bugs, same moment:
12
+
13
+ | | Reticle | Chrome DevTools MCP |
14
+ | ----------------------- | --------- | ------------------- |
15
+ | Bugs caught (of 10) | **10** | 8 |
16
+ | Detection accuracy | **1.00** | 0.82 |
17
+ | Avg tokens per look | 815 | **758** |
18
+ | Verification efficiency | **12.27** | 10.55 |
19
+
20
+ DevTools MCP genuinely wins the cost column. We are not going to bury that. 758 against 815 is a real 7% advantage per observation, and if you are making a very large number of trivial looks it adds up.
21
+
22
+ But cost per look is only half a metric. Verification efficiency combines both. Regressions caught per 1,000 tokens spent, gated on catching **all** of them with zero false alarms on a known-good control. On that measure Reticle leads 12.27 to 10.55.
23
+
24
+ <Card title="Why efficiency is gated on the catch rate" icon="chart-column" href="/benchmarks">
25
+ A tool can look cheap by not looking. The floor exists to stop that counting as a win.
26
+ </Card>
27
+
28
+ On a real production dashboard, one observation:
29
+
30
+ | | Snapshot | Network | Total |
31
+ | ------------------- | -------- | ------- | --------- |
32
+ | Reticle | 678 | 345 | **1,023** |
33
+ | Chrome DevTools MCP | 1,105 | 252 | 1,357 |
34
+
35
+ Note the flip. DevTools is cheaper on a small page and more expensive on a large one. Its snapshot is 1,105 tokens against Reticle's 678. The cost advantage does not survive contact with a real app.
36
+
37
+ ## What DevTools MCP does better
38
+
39
+ - **Cheaper on simple pages**, as above.
40
+ - **It is Chrome's own tooling**, which means the performance and tracing surface is deep and authoritative in a way third-party instrumentation is not.
41
+ - **Nothing to install in your app.** No SDK, no plugin, no build-time step. If instrumenting is off the table, this matters a lot.
42
+ - **Real pixels.** Actual rendered frames, with everything that implies.
43
+
44
+ ## The two bugs
45
+
46
+ DevTools MCP is DOM-and-network only. It can describe what a page looks like and what it requested; it cannot ask the application what it believes.
47
+
48
+ That is why the misses cluster where they do. The scenarios that separate the tools are the ones where the page is fine and the program is not. A mutation that never reached the store, a success handler that fired for the wrong reason. There is nothing in the DOM or the network log that distinguishes those from working code.
49
+
50
+ Reticle can require the app's own signal:
51
+
52
+ ```json
53
+ { "ref": "e5", "action": "click", "until": { "kind": "signal", "name": "deploy:created" } }
54
+ ```
55
+
56
+ That predicate cannot be satisfied by a `200`, by a rendered row, or by a hopeful agent. Either the app declared success or it did not.
57
+
58
+ ## The other difference: where to fix it
59
+
60
+ DevTools MCP can tell you a request failed. Reticle tells you a request failed **and** that the button which sent it lives at `src/components/Login.tsx:81`.
61
+
62
+ For a human, that is a convenience. For an agent, it is most of the value. Finding the bug is half the job, and the other half is knowing which file to open.
63
+
64
+ ## They compose
65
+
66
+ Neither tool forbids the other. A reasonable setup:
67
+
68
+ - **DevTools MCP** for performance traces, deep Chrome internals, and real screenshots.
69
+ - **Reticle** for the verify loop: did the change work, and where do I fix it.
70
+
71
+ ## Choosing
72
+
73
+ <CardGroup cols={2}>
74
+ <Card title="Pick Chrome DevTools MCP" icon="gauge">
75
+ You cannot instrument the app, you are chasing a performance or rendering problem, or you need
76
+ Chrome's own tracing.
77
+ </Card>
78
+ <Card title="Pick Reticle" icon="crosshairs">
79
+ You own the app and the failures you care about are the non-visual ones, mock data, dead
80
+ handlers, double submits, silent validation.
81
+ </Card>
82
+ </CardGroup>
83
+
84
+ ## FAQ
85
+
86
+ <AccordionGroup>
87
+
88
+ <Accordion title="Which two bugs did Chrome DevTools MCP miss?">
89
+ The ones where the page is fine and the program is not: a mutation that never reached the store,
90
+ and a success handler that fired for the wrong reason. DevTools MCP is DOM-and-network only, so it
91
+ can describe what the page looks like and what it requested, but it cannot ask the application
92
+ what it believes. There is nothing in the DOM or the network log that separates those cases from
93
+ working code.
94
+ </Accordion>
95
+
96
+ <Accordion title="If DevTools MCP is cheaper, why not just use it?">
97
+ Because it is cheaper partly by looking at less. Cost per look is half a metric; the other half is
98
+ whether the look catches the bug. Verification Efficiency combines them and gates on catching
99
+ every bug with zero false alarms, and on that measure Reticle leads 12.27 to 10.55. The 7%
100
+ per-look advantage also inverts on a real app: on the production dashboard measured here DevTools'
101
+ snapshot was 1,105 tokens against Reticle's 678.
102
+ </Accordion>
103
+
104
+ <Accordion title="Can I run both MCP servers at once?">
105
+ Yes. They are independent servers with distinct tool names. A reasonable split is DevTools MCP for
106
+ performance traces, deep Chrome internals and real screenshots, and Reticle for the verify loop
107
+ and the source pointer.
108
+ </Accordion>
109
+
110
+ <Accordion title="Do I have to instrument my app to use Reticle?">
111
+ You have to add the dev-only SDK, which is what `npx @reticlehq/server init` does. Beyond that,
112
+ look, act and observe work with zero component changes. Signals and registered stores are
113
+ optional, and they are what buys the assertions DevTools MCP structurally cannot make. If
114
+ instrumenting is off the table entirely, DevTools MCP is the correct choice.
115
+ </Accordion>
116
+
117
+ <Accordion title="Does Reticle give me performance traces?">
118
+ Not in the way Chrome's own tooling does, and it does not pretend to. It can tell you a React
119
+ render storm is happening (commit rate climbing with no DOM mutation), which DevTools MCP does not
120
+ surface. For flame charts and deep tracing, use Chrome's.
121
+ </Accordion>
122
+
123
+ </AccordionGroup>
@@ -0,0 +1,125 @@
1
+ ---
2
+ title: 'Reticle vs Playwright MCP: outside in, inside out'
3
+ sidebarTitle: vs Playwright MCP
4
+ description: Playwright MCP drives any website from the outside. Reticle verifies an app you own from the inside. They solve different problems, and they compose.
5
+ icon: masks-theater
6
+ ---
7
+
8
+ **Short answer:** if you need to drive a website you do not control, use Playwright MCP. If you need to prove that a change to _your_ app actually worked, use Reticle. They are not really competitors, and the best setup often runs both.
9
+
10
+ ## The one-line difference
11
+
12
+ Playwright MCP drives a browser **from the outside**. Reticle runs **inside** your app.
13
+
14
+ That single architectural choice explains every difference below. An outside-in tool can go anywhere and see anything rendered. An inside-out tool needs to be installed, and in exchange it can read things that were never rendered at all. Application state, emitted signals, the exact requests that fired.
15
+
16
+ ## Measured, on the same app at the same moment
17
+
18
+ | | Reticle | Playwright MCP |
19
+ | ----------------------- | --------- | -------------- |
20
+ | Bugs caught (of 10) | **10** | 9 |
21
+ | Detection accuracy | **1.00** | 0.91 |
22
+ | Avg tokens per look | **815** | 1,292 |
23
+ | Verification efficiency | **12.27** | 6.97 |
24
+
25
+ On a real production dashboard, observing once:
26
+
27
+ | | Snapshot | Network | Total |
28
+ | -------------- | -------- | ------- | --------- |
29
+ | Reticle | 678 | 345 | **1,023** |
30
+ | Playwright MCP | 1,522 | 671 | 2,193 |
31
+
32
+ Reticle is about 2.1x leaner on a large page. The gap comes from what each tool sends: Playwright MCP returns the accessibility tree, and on a complex app that tree is enormous. Reticle asks narrower questions: `mode: "interactive"` returns only controls, `count_only` returns a number.
33
+
34
+ <Card title="How these were measured" icon="chart-column" href="/benchmarks">
35
+ The method, the scenarios, and the control where a false positive would count against us.
36
+ </Card>
37
+
38
+ ## What Playwright MCP does better
39
+
40
+ This is not a courtesy section. There are real cases where Playwright is the correct choice and Reticle is not.
41
+
42
+ - **Sites you do not own.** Reticle needs a dev-only SDK in the app. No SDK, no Reticle. Playwright drives anything with a URL, which is the entire point of it.
43
+ - **Cross-browser.** Firefox and WebKit are first-class in Playwright. Reticle's real-input and screenshot paths are Chromium-oriented.
44
+ - **True pixels.** A screenshot is the actual rendered frame. A font that failed to load or a compositing glitch shows up there and can be missed by structural reads.
45
+ - **Maturity and ecosystem.** Playwright is a large, battle-tested project with an enormous community. We are not going to pretend otherwise.
46
+
47
+ ## What Reticle does that Playwright cannot
48
+
49
+ - **Assert on the app's own success signal.** When your app emits `auth:granted`, Reticle can require that exact signal. Playwright can check that a DOM element appeared, which a mock also does.
50
+ - **Read application state.** `stateDiffs` shows `auth` moving from `null` to a real user. A POST that returns `200` without touching state is caught here and nowhere else.
51
+ - **Map a DOM node to source.** `src/components/Login.tsx:81`, via the React fiber tree. Playwright can tell you the selector; it cannot tell you the file.
52
+ - **Grade its own evidence.** Every verdict reports `honesty.grade`: `presence`, `state`, `net` or `signal`, weakest to strongest. Plus whether the capture was clean and complete.
53
+ - **Say "unknown".** Reticle distinguishes "did not happen" from "I could not tell". That third state is the difference between a check and a coin flip.
54
+
55
+ ## The false-green case
56
+
57
+ Here is the failure both tools face, and only one catches reliably.
58
+
59
+ Your agent adds a "save" button. It calls an API. The API returns `200`. A row appears in the table. Reload the page and the row is gone, nothing was ever persisted.
60
+
61
+ Playwright MCP sees the row appear. That is a pass by every DOM-based check you could write.
62
+
63
+ Reticle sees `stateDiffs: []`. The store never changed. And fails the assertion, with the file and line of the button that lied.
64
+
65
+ ## Use both
66
+
67
+ They compose cleanly, and the combination is better than either alone:
68
+
69
+ - **Drive with Playwright** when you need a browser context it is better at. A third-party OAuth flow, a cross-browser check, a genuine pixel diff.
70
+ - **Assert with Reticle** when the question is "did my app actually do the thing".
71
+
72
+ Reticle also has a driven mode (`reticle drive`) that provides real CDP input and screenshots, so a lot of teams do not need both. Start with whichever matches the question you ask most often.
73
+
74
+ ## Choosing
75
+
76
+ <CardGroup cols={2}>
77
+ <Card title="Pick Playwright MCP" icon="globe">
78
+ You are testing a site you do not own, you need Firefox or WebKit, or you need real pixel
79
+ comparison as the primary signal.
80
+ </Card>
81
+ <Card title="Pick Reticle" icon="crosshairs">
82
+ You own the app, an agent is editing it, and you want proof it worked rather than a screenshot
83
+ that looks fine.
84
+ </Card>
85
+ </CardGroup>
86
+
87
+ ## FAQ
88
+
89
+ <AccordionGroup>
90
+
91
+ <Accordion title="Can I use Reticle and Playwright MCP at the same time?">
92
+ Yes, and it is a common setup. They are separate MCP servers with separate tool namespaces, so
93
+ nothing collides. Drive with Playwright where it is stronger (a third-party OAuth hop, a
94
+ cross-browser pass, a genuine pixel diff) and assert with Reticle where the question is "did my
95
+ app actually do the thing".
96
+ </Accordion>
97
+
98
+ <Accordion title="Does Reticle work on a site I do not own?">
99
+ No. Reticle reads the program from inside the page, which requires a dev-only SDK in the app. No
100
+ SDK, no Reticle. That is the single hardest boundary between these two tools, and it is why
101
+ Playwright MCP is the right answer for anything you cannot instrument.
102
+ </Accordion>
103
+
104
+ <Accordion title="Is Reticle actually cheaper, or only on the pages you chose?">
105
+ On a full-tree-vs-full-tree comparison the gap is modest, roughly 1.8x. The large gap comes from
106
+ not needing the full tree: Playwright MCP's primary perception primitive returns the accessibility
107
+ tree, Reticle's answers a specific question. On a small page both are cheap. On the real
108
+ production dashboard measured here Reticle was about 2.1x leaner. Force Reticle to dump the whole
109
+ page every step and you save very little.
110
+ </Accordion>
111
+
112
+ <Accordion title="Does Reticle support Firefox or WebKit?">
113
+ Not meaningfully. The always-on in-page SDK is browser-agnostic, but the driven paths that provide
114
+ real pointer input and screenshots go through CDP and are Chromium-oriented. If cross-browser is a
115
+ requirement, that is a Playwright job.
116
+ </Accordion>
117
+
118
+ <Accordion title="Do I have to give up my existing Playwright suite?">
119
+ No, and you should not. A scripted Playwright or Cypress suite is what gates your releases.
120
+ Reticle is the in-loop check while an agent is coding and the safety net for the flows nobody ever
121
+ got round to automating. Your existing `data-testid` attributes work in Reticle unchanged, so the
122
+ two share the same anchors.
123
+ </Accordion>
124
+
125
+ </AccordionGroup>
@@ -0,0 +1,137 @@
1
+ ---
2
+ title: 'Screenshots lie: why pixels cannot verify AI-generated code'
3
+ sidebarTitle: vs screenshots
4
+ description: The failures that AI coding agents actually produce are invisible in a rendered frame. Here is why a better vision model does not fix that.
5
+ icon: image
6
+ ---
7
+
8
+ **Short answer:** the information is not in the picture. Whether a request fired, what it returned, whether state changed, whether one click sent two requests. None of that is visible in a rendered frame, at any resolution, to any model.
9
+
10
+ ## The four failures a screenshot approves
11
+
12
+ <CardGroup cols={2}>
13
+ <Card title="Mock data" icon="ghost">
14
+ POST returns `200`, the row appears, nothing persisted. Reload and it's gone. The screenshot
15
+ during the demo is perfect.
16
+ </Card>
17
+ <Card title="Dead handler" icon="plug-circle-xmark">
18
+ Button has an `onClick`, the `onClick` calls a function, the function was never wired to the
19
+ store. Looks connected all the way down.
20
+ </Card>
21
+ <Card title="Double submit" icon="clone">
22
+ One click, two POSTs, customer charged twice. Zero pixels differ.
23
+ </Card>
24
+ <Card title="Silent validation" icon="triangle-exclamation">
25
+ The form accepts `"abc"` as a quantity and sends it to your database. Renders beautifully.
26
+ </Card>
27
+ </CardGroup>
28
+
29
+ Every one of these renders as a correct-looking page. Ask a vision model whether the feature works and it will say yes, because the only evidence available says yes.
30
+
31
+ ## "Just use a better model"
32
+
33
+ This is the intuition worth killing, because it sounds reasonable and costs teams months.
34
+
35
+ Model quality is not the constraint. **You cannot see a network call.** You cannot photograph a state mutation. A screenshot of a page whose bug is non-visual contains no signal about that bug, so asking a stronger model to look harder produces a more confident version of the same wrong answer.
36
+
37
+ Improving the model improves the reading of the evidence. It does not create evidence that was never captured.
38
+
39
+ ## What "reading the program" means instead
40
+
41
+ Reticle runs inside the app and reads what actually happened:
42
+
43
+ ```json
44
+ {
45
+ "verified": "yes",
46
+ "verdict": {
47
+ "evidence": { "method": "POST", "url": "/api/login", "status": 200, "durationMs": 67 }
48
+ },
49
+ "summary": {
50
+ "net": { "total": 1, "errors": 0 },
51
+ "consoleErrors": 0,
52
+ "stateDiffs": [{ "path": "auth", "from": null, "to": "{\"email\":\"admin@reticle.dev\"}" }],
53
+ "signals": ["auth:granted"]
54
+ }
55
+ }
56
+ ```
57
+
58
+ Read what that rules out. `net.total: 1` kills double-submit. `stateDiffs` kills mock data, the store genuinely changed. `signals` is the app declaring success in its own words. `consoleErrors: 0` kills "it worked but threw".
59
+
60
+ No pixel in the world carries that.
61
+
62
+ ## A real one, caught on the first run
63
+
64
+ On the first drive of a real production dashboard, before any instrumentation, Reticle's network observation flagged two endpoints returning `500`. A database migration that had not been applied.
65
+
66
+ **The page rendered fine.** The sidebar loaded. Nothing looked broken. A screenshot agent would have called it done and moved on.
67
+
68
+ That is the thesis in one incident: "looks done" and "is done" are different properties, and the difference is usually non-visual.
69
+
70
+ ## When a screenshot is the right tool
71
+
72
+ Screenshots are not useless. They are the correct instrument for a specific class of bug, and this page would be dishonest without saying so:
73
+
74
+ - A font that failed to load
75
+ - A GPU or compositing glitch
76
+ - Layout that breaks only at a particular viewport
77
+ - Anything where the actual rendered frame _is_ the thing under test
78
+
79
+ Those are real bugs and structural reads can miss them. Reticle has `reticle_screenshot` and `reticle_visual_diff` for exactly this, and if pixel regression is your primary concern, a dedicated visual tool will serve you better.
80
+
81
+ The argument is not "screenshots are bad". It is that a screenshot cannot answer "did the code work", and that is the question an AI coding agent needs answered on every change.
82
+
83
+ ## The honest limits
84
+
85
+ We have not proven that Reticle makes agents _fix_ more bugs. A controlled test did not show a fix-rate improvement; the benchmark was confounded and we are still working on measuring it properly.
86
+
87
+ What is measured is detection: 10 of 10 injected regressions caught with zero false alarms, against 9 and 8 for the alternatives.
88
+
89
+ ## FAQ
90
+
91
+ <AccordionGroup>
92
+
93
+ <Accordion title="Would a better vision model fix this?">
94
+ No, and this is the single most expensive misconception on the page. Model quality improves the
95
+ _reading_ of evidence; it cannot create evidence that was never captured. A screenshot of a page
96
+ whose bug is non-visual contains no signal about that bug at any resolution, so a stronger model
97
+ produces a more confident version of the same wrong answer.
98
+ </Accordion>
99
+
100
+ <Accordion title="So screenshots are useless?">
101
+ No. They are the correct instrument for a specific class of bug: a font that failed to load, a GPU
102
+ or compositing glitch, layout that breaks only at one viewport, and anything where the rendered
103
+ frame _is_ the thing under test. Reticle ships `reticle_screenshot` and `reticle_visual_diff` for
104
+ exactly those. If pixel regression is your primary concern, a dedicated visual tool will serve you
105
+ better.
106
+ </Accordion>
107
+
108
+ <Accordion title="What does Reticle read instead of pixels?">
109
+ The program: the network log (did the request fire, how many times, what did it return), the
110
+ console, client-side routing, registered store state, and any signal the app itself emits. A
111
+ response carrying `net.total: 1` rules out a double submit; a non-empty `stateDiffs` rules out
112
+ mock data; `consoleErrors: 0` rules out "it worked but threw".
113
+ </Accordion>
114
+
115
+ <Accordion title="Does that mean Reticle catches every bug?">
116
+ No. It has not been shown to make agents _fix_ more bugs; a controlled fix-rate test did not show
117
+ an improvement and we consider that question open. What is measured is detection: 10 of 10
118
+ injected regressions caught with zero false alarms, against 9 and 8 for the alternatives. And a
119
+ purely visual regression still needs the opt-in visual diff.
120
+ </Accordion>
121
+
122
+ <Accordion title="Can I keep using screenshots alongside Reticle?">
123
+ Yes, and for a visual product you probably should. The argument here is not that screenshots are
124
+ bad, it is that a screenshot cannot answer "did the code work", which is the question an AI coding
125
+ agent needs answered on every change.
126
+ </Accordion>
127
+
128
+ </AccordionGroup>
129
+
130
+ <CardGroup cols={2}>
131
+ <Card title="See a real verdict" icon="rocket" href="/quickstart">
132
+ Five minutes, and the output on that page was captured live.
133
+ </Card>
134
+ <Card title="The full benchmark" icon="chart-column" href="/benchmarks">
135
+ Method, raw numbers, and where Reticle comes second.
136
+ </Card>
137
+ </CardGroup>
@@ -0,0 +1,63 @@
1
+ ---
2
+ title: What is Reticle?
3
+ sidebarTitle: What is Reticle
4
+ description: Reticle is a verification layer for AI coding agents. It runs a dev-only SDK inside your running web app so an agent can prove a change works, instead of guessing. What it is, what it is not, and what it needs.
5
+ icon: circle-question
6
+ ---
7
+
8
+ **Reticle is a verification layer for AI coding agents.** It embeds a dev-only SDK inside your running web application and exposes what that application is actually doing, its DOM, network calls, routing, console, and framework state, as structured tools an agent can call over MCP. The agent names the consequence it expects, performs an action, and gets back a verdict: pass, fail, or an honest "couldn't tell", with the evidence and the `file:line` to open.
9
+
10
+ It exists because an agent that writes code cannot otherwise tell whether that code works. Reading the diff proves nothing. Unit tests do not run the application. A screenshot shows a page that renders perfectly over a failed request.
11
+
12
+ ## How it works, in three parts
13
+
14
+ 1. **An SDK inside the app.** Dev-only, stripped from production builds, added by a build plugin. It instruments the DOM, network, routing, console, animations, and your state library.
15
+ 2. **A local bridge.** The SDK connects over a WebSocket to a daemon on your machine. The daemon never starts or manages your dev server. It attaches to the app that is running. If none is, the agent is the one told to start it, using your project's own dev script, in the background, and saying so.
16
+ 3. **An MCP server.** The daemon exposes the app to your agent as tools. `reticle_snapshot` to look, `reticle_act_and_wait` to act and prove in one call, `reticle_state` and `reticle_network` to observe, `reticle_assert` to check.
17
+
18
+ Everything stays on your machine. No application code, DOM, network traffic, or console output leaves it.
19
+
20
+ ## What Reticle is not
21
+
22
+ This is the section most people need, because Reticle sits next to several familiar categories without being any of them.
23
+
24
+ **Not a browser automation framework.** Playwright, Cypress and Selenium drive a browser from the outside and are excellent at it. Reticle runs inside the page you already have open. If you want to script a browser, use Playwright. Reticle is what an agent uses to answer "did the thing I just changed actually work?"
25
+
26
+ **Not a replacement for your test suite.** Unit and integration tests still do their job. Reticle covers the layer they structurally cannot reach: behaviour that only exists when the whole application runs. Many teams use both, and Reticle is often the thing that catches a suite passing over a broken app.
27
+
28
+ **Not a screenshot or visual regression tool.** It can take screenshots, but the point is that it does not need to. Verdicts come from predicates over real events, a request with a status, a state path, a signal your code fired, so they do not break when a button moves four pixels. If pixel-perfect visual diffing is your goal, a dedicated visual testing service fits better.
29
+
30
+ **Not a monitoring or observability product.** Reticle is a development-time tool aimed at localhost. It is not an APM, not error tracking, and it does not watch production.
31
+
32
+ **Not an accessibility auditor.** `reticle_snapshot` addresses elements by role and name, which is not the same as auditing contrast, focus order, or screen reader behaviour. Use a dedicated accessibility tool for that.
33
+
34
+ **Not an AI model, and not an agent.** Reticle has no model of its own and makes no decisions. It gives an agent you already use a way to see the running app. Your agent, your model, your keys.
35
+
36
+ **Not a hosted service that receives your application data.** The daemon runs on your machine and the SDK runs in your browser. Anonymous product analytics are sent unless you opt out, and they never include your code or your application's data. See the [Telemetry Policy](https://www.reticle.sh/legal/telemetry).
37
+
38
+ **Not a way to make a failing check pass.** A verdict of `unknown` means Reticle drove the app and could not tell. It is deliberately not rounded up to a pass, because a verification tool that flatters you is worse than none.
39
+
40
+ ## What Reticle needs
41
+
42
+ Honest constraints, so you can tell in a minute whether it fits:
43
+
44
+ - **A web application you can run locally**, with its dev server. Reticle attaches; it does not start one.
45
+ - **A build step it can hook**, or two lines added by hand. Vite, Next.js, Remix and Astro are proven by gates in the repository. The SDK is framework agnostic and usually connects elsewhere, with reduced source mapping.
46
+ - **An agent that speaks MCP.** Claude Code, Cursor, Codex, Copilot, Windsurf, OpenCode and others.
47
+ - **Node 20 or newer.**
48
+
49
+ Electron and Tauri desktop applications are supported, including the IPC boundary a browser-based tool cannot observe at all.
50
+
51
+ ## How it compares
52
+
53
+ Side by side with the tools people ask about most:
54
+
55
+ - [Reticle vs Playwright MCP](/vs-playwright-mcp)
56
+ - [Reticle vs Chrome DevTools MCP](/vs-chrome-devtools-mcp)
57
+ - [Reticle vs screenshots](/vs-screenshots)
58
+
59
+ ## Where to go next
60
+
61
+ - [Quickstart](/quickstart) gets a real verdict out of your own app in about five minutes.
62
+ - [Why Reticle](/why-reticle) is the argument, with the evidence and the cases where it loses.
63
+ - [For agents](/for-agents) is written for the agent rather than for you.
@@ -0,0 +1,109 @@
1
+ ---
2
+ title: 'Why Reticle: seeing is not believing'
3
+ sidebarTitle: Why Reticle
4
+ description: AI-written code fails by looking correct. Reticle reads the running program instead of the pixels, so a silent failure stops being invisible.
5
+ icon: lightbulb
6
+ ---
7
+
8
+ **Use Reticle because AI-written code fails by looking correct.** A screenshot cannot show you whether a request fired, what status it returned, whether application state changed, or whether one click sent one request or two. Reticle reads the running program instead of the pixels, so those silent failures stop being invisible.
9
+
10
+ Software has always had bugs. What changed is the _kind_ of bug that reaches you.
11
+
12
+ A human writing code by hand produces errors that announce themselves: a stack trace, a red screen, a test that goes red. An agent writing code produces something more dangerous: a change that looks completely correct, renders beautifully, and does nothing. The page is fine. The data never saved.
13
+
14
+ We call it a **false green**, and it is the defining failure mode of the AI-coding era.
15
+
16
+ ## What a false green actually looks like
17
+
18
+ <CardGroup cols={2}>
19
+ <Card title="Mock data" icon="ghost">
20
+ The POST returns `200`. The row appears in the table. Reload the page and it's gone. Nothing was
21
+ ever persisted.
22
+ </Card>
23
+ <Card title="Dead handler" icon="plug-circle-xmark">
24
+ The button has an `onClick`. The `onClick` calls a function. The function was never wired to the
25
+ store. It looks connected all the way down.
26
+ </Card>
27
+ <Card title="Double submit" icon="clone">
28
+ One click, two POSTs. The user gets charged twice. Nothing on screen is wrong.
29
+ </Card>
30
+ <Card title="Silent validation" icon="triangle-exclamation">
31
+ The form accepts `"abc"` as a quantity and cheerfully sends it to your database.
32
+ </Card>
33
+ </CardGroup>
34
+
35
+ Every one of these renders as a perfectly nice page. A screenshot approves them all. So does an agent that just took the screenshot, and the agent is the one telling you it's done.
36
+
37
+ ## Why looking harder doesn't fix it
38
+
39
+ The instinct is to give the agent better eyes: a screenshot, a vision model, a full accessibility tree. This does not work, for a reason that has nothing to do with model quality.
40
+
41
+ **The information is not in the picture.** Whether a request fired, what status it returned, whether application state changed, whether the console logged an error, whether one click sent one request or two, none of that is visible. You cannot see a network call. You cannot photograph a state mutation. Asking a better model to look more carefully at a screenshot of a page whose bug is non-visual is asking it to hallucinate more confidently.
42
+
43
+ Reticle takes the other route. It runs **inside** your app and reads the program: network, state, console, routing, framework internals, and the app's own success signals. The answer is not interpreted from pixels. It is read from the running program, which means it is deterministic and the same every time.
44
+
45
+ ## The evidence
46
+
47
+ We built eleven scenarios: ten bugs, plus a control where nothing is wrong, so anything flagged on the control counts as a false positive. Each tool got the same app, the same moment, the same task.
48
+
49
+ | Tool | Bugs caught | Detection accuracy | Avg tokens per look | Verification efficiency |
50
+ | --- | --- | --- | --- | --- |
51
+ | **Reticle** | **10 / 10** | **1.00** | **815** | **12.27** |
52
+ | Playwright MCP | 9 / 10 | 0.91 | 1,292 | 6.97 |
53
+ | Chrome DevTools MCP | 8 / 10 | 0.82 | 758 | 10.55 |
54
+
55
+ Observing one real dashboard once, with no bug involved:
56
+
57
+ | Tool | Snapshot | Network | Observe total | Can it assert success? |
58
+ | --- | --- | --- | --- | --- |
59
+ | **Reticle** | 678 | 345 | **1,023** | Yes, via the app's own signal. 46 tokens, un-fakeable |
60
+ | Chrome DevTools MCP | 1,105 | 252 | 1,357 | No. DOM and network only |
61
+ | Playwright MCP | 1,522 | 671 | 2,193 | No. DOM and network only |
62
+
63
+ That last column is the one that matters more than the token counts. The other tools can _describe_ what a page looks like. Only Reticle can check whether the thing the app itself considers success actually happened.
64
+
65
+ <Card title="How every number was measured" icon="chart-column" href="/benchmarks">
66
+ The full method, the raw data, and the scenarios where Reticle comes second.
67
+ </Card>
68
+
69
+ ## Where Reticle loses
70
+
71
+ A benchmark that only shows you the wins is an advertisement wearing a lab coat. Ours doesn't.
72
+
73
+ - **Sites you don't own.** Reticle needs a dev-only SDK inside the app. If you're driving a third party's website, use Playwright. That is what it's for, and it's excellent at it.
74
+ - **Pixels.** Reticle reads the program, not the screen. If your bug is "the button is three pixels too far left", Reticle is the wrong instrument.
75
+ - **Chrome DevTools MCP is cheaper per look.** 758 tokens against our 815. It catches fewer bugs, so the efficiency works out in our favour, but on raw cost per glance it wins.
76
+
77
+ ## What we have not proven
78
+
79
+ Being honest here costs us something, and we'd rather pay it than have you find out later.
80
+
81
+ We ran a controlled test of whether an agent equipped with Reticle _fixes_ more bugs than one without it. **It did not show a fix-rate improvement.** The benchmark was confounded in ways we can point at, and we don't consider the question settled. But we are not going to claim a number we didn't measure.
82
+
83
+ What Reticle demonstrably does is catch failures that are invisible to the alternatives, and hand back the file and line to go fix. Whether that translates into a better fix rate is a separate question, and we're still working on measuring it properly.
84
+
85
+ ## When you should use it
86
+
87
+ <CardGroup cols={2}>
88
+ <Card title="A good fit" icon="circle-check">
89
+ You own the app. An agent edits it. You want the agent to prove its work rather than assure you
90
+ of it. React gets you source pointers on top.
91
+ </Card>
92
+ <Card title="A bad fit" icon="circle-xmark">
93
+ You're testing a site you don't control, you need pixel-level visual regression, or your app has
94
+ no dev build to instrument.
95
+ </Card>
96
+ </CardGroup>
97
+
98
+ ## The one-sentence version
99
+
100
+ Your agent already tells you it works. Reticle is the part that checks. And, more usefully, the part that says "I couldn't tell" instead of guessing.
101
+
102
+ <CardGroup cols={2}>
103
+ <Card title="Quickstart" icon="rocket" href="/quickstart">
104
+ Five minutes to your first real verdict.
105
+ </Card>
106
+ <Card title="Architecture" icon="sitemap" href="/architecture">
107
+ How it reads the program without slowing your app down.
108
+ </Card>
109
+ </CardGroup>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reticlehq/server",
3
- "version": "2.7.0",
3
+ "version": "2.9.0",
4
4
  "description": "Reticle bridge + MCP server. Hosts the browser WS endpoint and exposes MCP tools to the coding agent.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -19,10 +19,10 @@
19
19
  }
20
20
  },
21
21
  "dependencies": {
22
- "@modelcontextprotocol/sdk": "^1.13.0",
23
- "ws": "^8.18.0",
22
+ "@modelcontextprotocol/sdk": "^1.30.0",
23
+ "ws": "^8.21.3",
24
24
  "zod": "^3.24.1",
25
- "@reticlehq/core": "2.7.0"
25
+ "@reticlehq/core": "2.9.0"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@types/pngjs": "^6.0.5",
@@ -30,7 +30,7 @@
30
30
  },
31
31
  "optionalDependencies": {
32
32
  "pixelmatch": "^7.2.0",
33
- "playwright": "^1.48.0",
33
+ "playwright": "^1.62.1",
34
34
  "pngjs": "^7.0.0"
35
35
  },
36
36
  "license": "SEE LICENSE IN LICENSE",