@reticlehq/server 2.8.0 → 2.10.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 (318) hide show
  1. package/SKILL.md +130 -813
  2. package/dist/bridge/bridge.d.ts +23 -0
  3. package/dist/bridge/bridge.js +80 -2
  4. package/dist/bridge/bridge.test-harness.d.ts +5 -0
  5. package/dist/bridge/bridge.test-harness.js +6 -4
  6. package/dist/capsule/capsule-store.d.ts +2 -2
  7. package/dist/capsule/causal-summary.d.ts +16 -1
  8. package/dist/capsule/causal-summary.js +2 -1
  9. package/dist/cli/cli-doctor.js +41 -13
  10. package/dist/cli/cli-flow-commands.js +8 -8
  11. package/dist/cli/cli-launch.d.ts +0 -17
  12. package/dist/cli/cli-launch.js +0 -28
  13. package/dist/cli/cli-parse.d.ts +1 -1
  14. package/dist/cli/cli-parse.js +1 -1
  15. package/dist/cli/cli-port.d.ts +24 -0
  16. package/dist/cli/cli-port.js +66 -35
  17. package/dist/cli/cli-verify.d.ts +21 -0
  18. package/dist/cli/cli-verify.js +45 -1
  19. package/dist/cli/config-discovery.d.ts +35 -0
  20. package/dist/cli/config-discovery.js +163 -0
  21. package/dist/cli/doctor-daemon-line.js +4 -1
  22. package/dist/cli/doctor-project-line.d.ts +37 -0
  23. package/dist/cli/doctor-project-line.js +35 -0
  24. package/dist/cli/doctor-rows.d.ts +51 -0
  25. package/dist/cli/doctor-rows.js +54 -0
  26. package/dist/cli/doctor-sessions-line.js +6 -3
  27. package/dist/cli/drive-attach.d.ts +99 -0
  28. package/dist/cli/drive-attach.js +203 -0
  29. package/dist/cli/drive-command.d.ts +13 -0
  30. package/dist/cli/drive-command.js +103 -0
  31. package/dist/cli/open-note.d.ts +20 -0
  32. package/dist/cli/open-note.js +37 -0
  33. package/dist/cli/status-next-action.d.ts +37 -0
  34. package/dist/cli/status-next-action.js +61 -0
  35. package/dist/cli.js +65 -70
  36. package/dist/crawl/crawl.d.ts +7 -2
  37. package/dist/crawl/crawl.js +52 -9
  38. package/dist/ee/audit-log.js +2 -2
  39. package/dist/events/body-failures.d.ts +2 -2
  40. package/dist/events/contradiction-folds.d.ts +45 -0
  41. package/dist/events/contradiction-folds.js +42 -0
  42. package/dist/events/contradictions.d.ts +51 -1
  43. package/dist/events/contradictions.js +26 -7
  44. package/dist/events/declared.d.ts +45 -0
  45. package/dist/events/declared.js +73 -0
  46. package/dist/events/echo-mismatch.d.ts +9 -3
  47. package/dist/events/echo-mismatch.js +33 -5
  48. package/dist/events/event-filters.d.ts +1 -1
  49. package/dist/events/event-filters.js +7 -4
  50. package/dist/events/predicate-eval.d.ts +17 -91
  51. package/dist/events/predicate-eval.js +85 -326
  52. package/dist/events/predicate-parse.js +31 -3
  53. package/dist/events/predicate-route.d.ts +32 -0
  54. package/dist/events/predicate-route.js +102 -0
  55. package/dist/events/predicate-schema.d.ts +99 -0
  56. package/dist/events/predicate-schema.js +309 -0
  57. package/dist/events/predicate.d.ts +8 -0
  58. package/dist/events/predicate.js +127 -5
  59. package/dist/events/stale-response.d.ts +2 -3
  60. package/dist/events/stale-response.js +49 -2
  61. package/dist/events/unit-mismatch.d.ts +2 -2
  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-replay-run.js +8 -1
  69. package/dist/flows/flow-tools.js +9 -1
  70. package/dist/flows/replay.js +3 -0
  71. package/dist/flows/verify-change-tools.js +1 -1
  72. package/dist/honesty/accepted-write.d.ts +3 -0
  73. package/dist/honesty/accepted-write.js +8 -3
  74. package/dist/honesty/already-true.js +15 -0
  75. package/dist/honesty/blind-spots.js +4 -0
  76. package/dist/honesty/honesty.d.ts +11 -0
  77. package/dist/honesty/honesty.js +1 -0
  78. package/dist/honesty/uncaptured-bodies.d.ts +4 -2
  79. package/dist/honesty/uncaptured-bodies.js +9 -2
  80. package/dist/honesty/unread-outcome.d.ts +8 -0
  81. package/dist/honesty/unread-outcome.js +36 -9
  82. package/dist/honesty/unsettled.d.ts +9 -0
  83. package/dist/honesty/unsettled.js +7 -3
  84. package/dist/honesty/verified.d.ts +29 -3
  85. package/dist/honesty/verified.js +67 -8
  86. package/dist/http-server.d.ts +19 -0
  87. package/dist/http-server.js +202 -4
  88. package/dist/impact/impact-recorder.d.ts +23 -0
  89. package/dist/impact/impact-recorder.js +76 -0
  90. package/dist/impact/impact-store.d.ts +47 -0
  91. package/dist/impact/impact-store.js +171 -0
  92. package/dist/index.d.ts +25 -0
  93. package/dist/index.js +60 -10
  94. package/dist/init/agent-rules.d.ts +20 -0
  95. package/dist/init/agent-rules.js +36 -0
  96. package/dist/init/astro-patch.js +27 -1
  97. package/dist/init/confirm.d.ts +21 -3
  98. package/dist/init/confirm.js +32 -5
  99. package/dist/init/connect-steps.d.ts +2 -0
  100. package/dist/init/connect-steps.js +50 -0
  101. package/dist/init/csp-check.d.ts +38 -0
  102. package/dist/init/csp-check.js +92 -0
  103. package/dist/init/csp-doctor.d.ts +25 -0
  104. package/dist/init/csp-doctor.js +49 -0
  105. package/dist/init/cursor.js +6 -9
  106. package/dist/init/detect.d.ts +8 -0
  107. package/dist/init/detect.js +33 -3
  108. package/dist/init/mcp-clients.d.ts +1 -0
  109. package/dist/init/mcp-clients.js +51 -7
  110. package/dist/init/mcp.d.ts +16 -2
  111. package/dist/init/mcp.js +23 -1
  112. package/dist/init/plan-framework.d.ts +10 -0
  113. package/dist/init/plan-framework.js +25 -1
  114. package/dist/init/plan.d.ts +7 -2
  115. package/dist/init/plan.js +66 -30
  116. package/dist/init/run.js +11 -5
  117. package/dist/init/slash-command.d.ts +1 -1
  118. package/dist/init/slash-command.js +12 -4
  119. package/dist/init/snippets.d.ts +1 -1
  120. package/dist/init/snippets.js +35 -7
  121. package/dist/init/vite-config.js +24 -2
  122. package/dist/input/network-mock-tools.js +8 -1
  123. package/dist/input/scroll-find.d.ts +6 -0
  124. package/dist/input/scroll-find.js +17 -2
  125. package/dist/input/scroll-tools.js +4 -0
  126. package/dist/journal/attach-journal.d.ts +9 -1
  127. package/dist/journal/attach-journal.js +13 -2
  128. package/dist/journal/journal-query.d.ts +13 -0
  129. package/dist/journal/journal-query.js +28 -3
  130. package/dist/journal/workspace-gitignore.d.ts +10 -0
  131. package/dist/journal/workspace-gitignore.js +59 -0
  132. package/dist/license/license.d.ts +69 -4
  133. package/dist/license/license.js +84 -15
  134. package/dist/mcp/mcp-proxy.d.ts +7 -93
  135. package/dist/mcp/mcp-proxy.js +183 -250
  136. package/dist/mcp/mcp.d.ts +27 -2
  137. package/dist/mcp/mcp.js +77 -36
  138. package/dist/mcp/proxy-daemon-probe.d.ts +8 -0
  139. package/dist/mcp/proxy-daemon-probe.js +48 -0
  140. package/dist/mcp/proxy-handshake.d.ts +82 -1
  141. package/dist/mcp/proxy-handshake.js +110 -3
  142. package/dist/mcp/proxy-lifecycle.d.ts +10 -1
  143. package/dist/mcp/proxy-lifecycle.js +11 -2
  144. package/dist/mcp/proxy-log.d.ts +63 -0
  145. package/dist/mcp/proxy-log.js +132 -0
  146. package/dist/mcp/server-instructions.d.ts +17 -0
  147. package/dist/mcp/server-instructions.js +56 -0
  148. package/dist/mcp/shared-params.d.ts +27 -0
  149. package/dist/mcp/shared-params.js +36 -0
  150. package/dist/mcp/sse-frame-parser.d.ts +19 -0
  151. package/dist/mcp/sse-frame-parser.js +41 -0
  152. package/dist/project/reticle-dir.d.ts +2 -0
  153. package/dist/project/reticle-dir.js +1 -0
  154. package/dist/session/connection-memory.d.ts +59 -0
  155. package/dist/session/connection-memory.js +108 -0
  156. package/dist/session/dev-command.d.ts +26 -0
  157. package/dist/session/dev-command.js +89 -0
  158. package/dist/session/dev-server-probe.d.ts +68 -0
  159. package/dist/session/dev-server-probe.js +102 -7
  160. package/dist/session/last-act.d.ts +26 -0
  161. package/dist/session/last-act.js +35 -1
  162. package/dist/session/live-control-tools.js +42 -5
  163. package/dist/session/no-session-diagnosis.d.ts +55 -2
  164. package/dist/session/no-session-diagnosis.js +199 -22
  165. package/dist/session/no-session-next-action.d.ts +46 -0
  166. package/dist/session/no-session-next-action.js +85 -0
  167. package/dist/session/no-session-watch.d.ts +40 -1
  168. package/dist/session/no-session-watch.js +172 -11
  169. package/dist/session/pending-commands.d.ts +12 -0
  170. package/dist/session/pending-commands.js +13 -1
  171. package/dist/session/session-manager.d.ts +4 -0
  172. package/dist/session/session-manager.js +35 -5
  173. package/dist/session/session-readiness.js +1 -1
  174. package/dist/session/session.d.ts +10 -1
  175. package/dist/session/session.js +146 -5
  176. package/dist/telemetry/app-instrumented.d.ts +8 -0
  177. package/dist/telemetry/app-instrumented.js +10 -0
  178. package/dist/telemetry/bug-found.d.ts +18 -0
  179. package/dist/telemetry/bug-found.js +14 -0
  180. package/dist/telemetry/daemon-telemetry.js +29 -0
  181. package/dist/telemetry/install-source.d.ts +20 -0
  182. package/dist/telemetry/install-source.js +34 -0
  183. package/dist/telemetry/instrumentation-stall.d.ts +57 -0
  184. package/dist/telemetry/instrumentation-stall.js +103 -0
  185. package/dist/telemetry/license-activation.d.ts +48 -0
  186. package/dist/telemetry/license-activation.js +57 -0
  187. package/dist/telemetry/session-metrics.d.ts +8 -0
  188. package/dist/telemetry/session-metrics.js +10 -0
  189. package/dist/telemetry/telemetry.d.ts +3 -1
  190. package/dist/telemetry/telemetry.js +23 -3
  191. package/dist/tools/act-tools.js +166 -29
  192. package/dist/tools/assert-verdict.js +32 -7
  193. package/dist/tools/browser-tools.js +10 -0
  194. package/dist/tools/dynamic-tools.js +17 -8
  195. package/dist/tools/error-recovery.js +10 -6
  196. package/dist/tools/feedback-tools.js +31 -6
  197. package/dist/tools/invoke-tool.d.ts +1 -1
  198. package/dist/tools/invoke-tool.js +30 -8
  199. package/dist/tools/lease-hint.d.ts +30 -8
  200. package/dist/tools/lease-hint.js +65 -14
  201. package/dist/tools/lease-tools.d.ts +11 -0
  202. package/dist/tools/lease-tools.js +141 -96
  203. package/dist/tools/observe-tools.js +9 -3
  204. package/dist/tools/react-grace.d.ts +4 -0
  205. package/dist/tools/react-grace.js +6 -3
  206. package/dist/tools/read-tools.js +47 -1
  207. package/dist/tools/resolve-target.d.ts +33 -0
  208. package/dist/tools/resolve-target.js +53 -0
  209. package/dist/tools/settle-in-flight.d.ts +15 -0
  210. package/dist/tools/settle-in-flight.js +42 -2
  211. package/dist/tools/snapshot-delta.d.ts +3 -0
  212. package/dist/tools/snapshot-delta.js +67 -6
  213. package/dist/tools/tool-kit.d.ts +38 -3
  214. package/dist/tools/tool-names.d.ts +2 -0
  215. package/dist/tools/tool-names.js +2 -0
  216. package/dist/tools/tool-surface.d.ts +60 -0
  217. package/dist/tools/tool-surface.js +84 -19
  218. package/dist/tools/tools.js +61 -5
  219. package/dist/tools/unadvertised-help.js +9 -6
  220. package/docs/README.md +1 -2
  221. package/docs/actions.mdx +41 -8
  222. package/docs/agent-cheatsheet.md +6 -4
  223. package/docs/architecture.md +6 -0
  224. package/docs/benchmarks.md +60 -12
  225. package/docs/best-practices.mdx +11 -6
  226. package/docs/capabilities.mdx +204 -57
  227. package/docs/cli/affected.mdx +6 -4
  228. package/docs/cli/capsules.mdx +9 -8
  229. package/docs/cli/cloud.mdx +30 -4
  230. package/docs/cli/doctor.mdx +41 -8
  231. package/docs/cli/drive.mdx +34 -15
  232. package/docs/cli/gate.mdx +6 -6
  233. package/docs/cli/help.mdx +8 -6
  234. package/docs/cli/hunt.mdx +20 -4
  235. package/docs/cli/identify.mdx +16 -2
  236. package/docs/cli/init.mdx +35 -8
  237. package/docs/cli/kill.mdx +5 -5
  238. package/docs/cli/license.mdx +1 -1
  239. package/docs/cli/open.mdx +6 -0
  240. package/docs/cli/restart.mdx +6 -6
  241. package/docs/cli/serve.mdx +10 -3
  242. package/docs/cli/status.mdx +29 -5
  243. package/docs/cli/stop.mdx +8 -0
  244. package/docs/cli/verify.mdx +20 -1
  245. package/docs/cli/version.mdx +1 -1
  246. package/docs/cli/watch.mdx +9 -2
  247. package/docs/cli.mdx +44 -22
  248. package/docs/debugging.md +3 -1
  249. package/docs/deploy-checks.md +31 -2
  250. package/docs/desktop.mdx +276 -80
  251. package/docs/docs.json +13 -12
  252. package/docs/enterprise.md +9 -3
  253. package/docs/faq.mdx +49 -35
  254. package/docs/fixtures.md +2 -0
  255. package/docs/flows.md +7 -5
  256. package/docs/for-agents.md +3 -3
  257. package/docs/frameworks.mdx +46 -7
  258. package/docs/gate-plan.md +4 -2
  259. package/docs/gates.md +8 -6
  260. package/docs/getting-started.md +53 -12
  261. package/docs/human-control.md +2 -0
  262. package/docs/index.mdx +43 -1
  263. package/docs/install-agentic.mdx +13 -4
  264. package/docs/install-manual.mdx +6 -4
  265. package/docs/instrumentation.mdx +7 -1
  266. package/docs/integration-patterns.md +3 -1
  267. package/docs/local-registry.md +4 -2
  268. package/docs/multi-agent-testing.md +3 -1
  269. package/docs/packages/babel-plugin.mdx +15 -6
  270. package/docs/packages/browser.mdx +2 -2
  271. package/docs/packages/core.mdx +26 -16
  272. package/docs/packages/electron.mdx +5 -7
  273. package/docs/packages/eslint-plugin.mdx +5 -3
  274. package/docs/packages/next.mdx +3 -5
  275. package/docs/packages/react.mdx +3 -3
  276. package/docs/packages/server.mdx +2 -2
  277. package/docs/packages/tauri.mdx +6 -6
  278. package/docs/packages/test.mdx +18 -7
  279. package/docs/packages/vite-plugin.mdx +4 -6
  280. package/docs/packages.mdx +14 -13
  281. package/docs/platform-integration.md +2 -0
  282. package/docs/predicates.mdx +76 -7
  283. package/docs/quickstart.mdx +51 -5
  284. package/docs/recipes.mdx +63 -23
  285. package/docs/skill-file.mdx +3 -1
  286. package/docs/state-management.mdx +2 -0
  287. package/docs/system-map.md +3 -1
  288. package/docs/telemetry-contract.md +33 -5
  289. package/docs/telemetry-events.mdx +63 -18
  290. package/docs/telemetry.md +8 -5
  291. package/docs/testing.md +35 -1
  292. package/docs/token-efficiency.md +8 -2
  293. package/docs/tools-act-and-wait.mdx +64 -14
  294. package/docs/tools-act-sequence.mdx +34 -17
  295. package/docs/tools-act.mdx +24 -11
  296. package/docs/tools-assert.mdx +69 -10
  297. package/docs/tools-console.mdx +11 -7
  298. package/docs/tools-inspect.mdx +11 -8
  299. package/docs/tools-navigate.mdx +41 -5
  300. package/docs/tools-network.mdx +42 -9
  301. package/docs/tools-observe.mdx +66 -10
  302. package/docs/tools-overview.mdx +26 -23
  303. package/docs/tools-query.mdx +52 -8
  304. package/docs/tools-session-and-feedback.mdx +35 -9
  305. package/docs/tools-sessions.mdx +39 -10
  306. package/docs/tools-snapshot.mdx +57 -3
  307. package/docs/tools-state.mdx +24 -1
  308. package/docs/tools-tools-and-run.mdx +55 -24
  309. package/docs/tools-wait-for.mdx +34 -15
  310. package/docs/troubleshooting.mdx +80 -10
  311. package/docs/usage.md +46 -24
  312. package/docs/vs-chrome-devtools-mcp.mdx +41 -0
  313. package/docs/vs-playwright-mcp.mdx +42 -2
  314. package/docs/vs-screenshots.mdx +42 -1
  315. package/docs/what-is-reticle.mdx +1 -1
  316. package/docs/why-reticle.mdx +3 -1
  317. package/package.json +5 -5
  318. package/docs/desktop-apps.md +0 -265
package/docs/faq.mdx CHANGED
@@ -1,23 +1,29 @@
1
1
  ---
2
- title: FAQ: frequently asserted questions
2
+ title: 'FAQ: frequently asserted questions'
3
3
  sidebarTitle: FAQ
4
4
  description: Does it run in production, does it need React, does it replace Playwright, and the other questions people actually ask.
5
5
  icon: circle-question
6
6
  ---
7
7
 
8
- ## Does this run in production?
8
+ Reticle is a dev-only, localhost-only verification layer an AI coding agent uses to prove a change actually worked in your running app. It does not run in production, it does not need React, and it does not replace Playwright. The rest of the questions people actually ask are below.
9
9
 
10
- No, and it is built so that it cannot easily be made to. Keep `reticle.connect()` behind a dev guard; the SDK is side-effect-free and tree-shakes out of production builds. The Vite plugin uses `apply: 'serve'`, which means it is not part of a production build at all.
10
+ <AccordionGroup>
11
11
 
12
- ## Do I have to change my components?
12
+ <Accordion title="Does this run in production?">
13
+ No, and it is built so that it cannot easily be made to. Keep `reticle.connect()` behind a dev
14
+ guard; the SDK is side-effect-free and tree-shakes out of production builds. The Vite plugin uses
15
+ `apply: 'serve'`, which means it is not part of a production build at all.
16
+ </Accordion>
13
17
 
14
- No, for look, act and observe. You get DOM, network, console and routing with zero changes.
18
+ <Accordion title="Do I have to change my components?">
19
+ No, for look, act and observe. You get DOM, network, console and routing with zero changes.
15
20
 
16
21
  You get considerably better results by adding `data-testid` attributes and by [emitting signals](/instrumentation). That is the difference between a verdict that says "something appeared" and one that says "the app declared success".
17
22
 
18
- ## Does it work without React?
23
+ </Accordion>
19
24
 
20
- The core is framework-agnostic: DOM, network, routing, console, animations, snapshots and actions are gated against a vanilla TypeScript app.
25
+ <Accordion title="Does it work without React?">
26
+ The core is framework-agnostic: DOM, network, routing, console, animations, snapshots and actions are gated against a vanilla TypeScript app.
21
27
 
22
28
  Support beyond that is uneven, and we would rather say so than let you find out:
23
29
 
@@ -27,62 +33,70 @@ Support beyond that is uneven, and we would rather say so than let you find out:
27
33
  | SvelteKit | Wired end to end. `init` writes the client hook, the plugin stamps `.svelte` source. But **no CI gate**, so unverified rather than supported |
28
34
  | Vue | A Pinia store adapter and nothing else. No detection, no `.vue` stamping, no gate |
29
35
 
30
- ## Can it tell me whether my UI looks good?
36
+ </Accordion>
31
37
 
32
- No. Reticle verifies behaviour, not aesthetics. Visual correctness and "does this feel right" remain a human job, or a visual-diff tool's.
38
+ <Accordion title="Can it tell me whether my UI looks good?">
39
+ No. Reticle verifies behaviour, not aesthetics. Visual correctness and "does this feel right" remain a human job, or a visual-diff tool's.
33
40
 
34
41
  It does read design tokens. [`reticle_inspect`](/tools-inspect) reports whether a colour came from your theme or from someone's clipboard. But that is a consistency check, not taste.
35
42
 
36
- ## Does it replace Playwright or Cypress?
43
+ </Accordion>
37
44
 
38
- No. Those are your scripted CI suite. Reticle is for in-loop verification while an agent is coding, and for the flows you never got round to automating. They compose.
45
+ <Accordion title="Does it replace Playwright or Cypress?">
46
+ No. Those are your scripted CI suite. Reticle is for in-loop verification while an agent is coding, and for the flows you never got round to automating. They compose.
39
47
 
40
- <Card title="The full comparison" icon="masks-theater" href="/vs-playwright-mcp">
41
- Where Playwright is the right choice, stated plainly.
42
- </Card>
48
+ <Card title="The full comparison" icon="masks-theater" href="/vs-playwright-mcp">
49
+ Where Playwright is the right choice, stated plainly.
50
+ </Card>
51
+ </Accordion>
43
52
 
44
- ## How does it compare to Playwright MCP or Chrome DevTools MCP?
45
-
46
- Those drive a **separate** browser from the outside. Reticle verifies your **own running app** from the inside, with your real session and auth, and with assertions and regression as first-class.
53
+ <Accordion title="How does it compare to Playwright MCP or Chrome DevTools MCP?">
54
+ Those drive a **separate** browser from the outside. Reticle verifies your **own running app** from the inside, with your real session and auth, and with assertions and regression as first-class.
47
55
 
48
56
  Measured on the same app: Reticle caught 10 of 10 injected bugs, Playwright MCP 9, Chrome DevTools MCP 8. DevTools MCP is about 7% cheaper per look on a simple page, and more expensive on a real one.
49
57
 
50
- ## Can I run several apps or tabs at once?
58
+ </Accordion>
51
59
 
52
- Yes. Each is a session. Pass `sessionId` to any tool when more than one is connected, and [`reticle_sessions`](/tools-sessions) lists them.
60
+ <Accordion title="Can I run several apps or tabs at once?">
61
+ Yes. Each is a session. Pass `sessionId` to any tool when more than one is connected, and [`reticle_sessions`](/tools-sessions) lists them.
53
62
 
54
63
  Reticle scopes to your project and prefers the active tab, and it **refuses rather than guesses** when the choice is ambiguous. A refusal you can act on beats a silent pick of the wrong tab.
55
64
 
56
- ## Why did I get `verified: "unknown"` on something that clearly worked?
65
+ </Accordion>
57
66
 
58
- Because Reticle could not confirm it saw the whole story, and it will not call that a pass.
67
+ <Accordion title="Why did I get `verified: \"unknown\"` on something that clearly worked?">
68
+ Because Reticle could not confirm it saw the whole story, and it will not call that a pass.
59
69
 
60
70
  The most common cause is a **throttled tab**: a backgrounded browser tab has its timers suppressed, which suppresses the quiescence detection used to decide the page has settled. Focus the tab, or drive a dedicated context.
61
71
 
62
72
  If you believe an `unknown` is wrong, report it. Reticle's own response says as much: "an unknown verdict is our defect, not yours".
63
73
 
64
- ## Does my data leave the machine?
74
+ </Accordion>
65
75
 
66
- Your app's data, no. Reticle is dev-only, localhost-only and offline. Credential-shaped values are redacted before they leave the page. You will see `[REDACTED]` in request bodies without configuring anything.
76
+ <Accordion title="Does my data leave the machine?">
77
+ Your app's data, no. Reticle is dev-only, localhost-only and offline. Credential-shaped values are redacted before they leave the page. You will see `[REDACTED]` in request bodies without configuring anything.
67
78
 
68
79
  Anonymous usage telemetry is sent separately and can be turned off with `reticle telemetry disable`.
69
80
 
70
- <Card title="Exactly what is collected" icon="chart-line" href="/telemetry">
71
- The complete list. If it is not on that page, it is not sent.
72
- </Card>
73
-
74
- ## Is Reticle proven to make agents fix more bugs?
81
+ <Card title="Exactly what is collected" icon="chart-line" href="/telemetry">
82
+ The complete list. If it is not on that page, it is not sent.
83
+ </Card>
84
+ </Accordion>
75
85
 
76
- No, and we are not going to claim it. A controlled test of fix-rate did **not** show an improvement. The benchmark was confounded in ways we can point at, and we consider the question open.
86
+ <Accordion title="Is Reticle proven to make agents fix more bugs?">
87
+ No, and we are not going to claim it. A controlled test of fix-rate did **not** show an improvement. The benchmark was confounded in ways we can point at, and we consider the question open.
77
88
 
78
89
  What is measured is detection: 10 of 10 injected regressions caught, with zero false alarms on a known-good control, against 9 and 8 for the alternatives.
79
90
 
80
- ## Why are there 48 tools but only 18 in my agent?
91
+ </Accordion>
81
92
 
82
- MCP re-sends every advertised tool definition on every turn, so the tool list is rent rather than a one-time cost. Measured: 18 tools is about 5,400 tokens per turn; all 48 is about 33,600.
93
+ <Accordion title="Why does my agent only see some of Reticle's tools?">
94
+ Because MCP re-sends every advertised tool definition on **every turn**, so the tool list is rent, not a one-time cost. Reticle advertises the verify loop directly and keeps the cold tail one call away.
83
95
 
84
- The other 30 are one call away via `reticle_tools` and `reticle_run`.
96
+ Nothing is unreachable. `reticle_tools` lists every tool (pass `names: [...]` for full parameters) and `reticle_run({ tool, args })` invokes any of them by name. If you want the whole surface advertised directly, set `RETICLE_ADVERTISE_ALL_TOOLS=1` in the **daemon's** environment and restart it, which costs roughly seven times the per-turn schema tax and is meant for suites that call by name rather than for running agents.
85
97
 
86
- <Card title="The surface, explained" icon="wrench" href="/tools-overview">
87
- Which 18, and why each earned its slot.
88
- </Card>
98
+ <Card title="The surface, explained" icon="wrench" href="/tools-overview">
99
+ Which tools are advertised directly, and why each earned its slot.
100
+ </Card>
101
+ </Accordion>
102
+ </AccordionGroup>
package/docs/fixtures.md CHANGED
@@ -4,6 +4,8 @@ description: 'Why the apps in apps/ cannot answer the one question that matters
4
4
  icon: cubes
5
5
  ---
6
6
 
7
+ The apps in `apps/` cannot tell you whether the install still works, because every one of them is already wired to Reticle. That question is answered in a separate repo, **[`reticle-fixtures`](https://github.com/reticlehq/reticle-fixtures)**, which keeps a pristine `clean` branch of real third-party apps and runs `node scripts/verify.mjs` to install into each one and assert a session actually connects.
8
+
7
9
  The apps in `apps/` are ours. We chose their defects, so passing against them says less than it looks like, and they are all wired to Reticle already, which makes them useless for the one question that matters before a release: **does the install still work on an app that has never seen Reticle?**
8
10
 
9
11
  That question is answered in a separate repo: **[`reticle-fixtures`](https://github.com/reticlehq/reticle-fixtures)**.
package/docs/flows.md CHANGED
@@ -4,6 +4,8 @@ description: 'Record an interactive run once and replay it forever as a git-chec
4
4
  icon: repeat
5
5
  ---
6
6
 
7
+ A **flow** is a recorded interactive run that Reticle stores as JSON under `.reticle/flows/` and replays forever with no AI model in the loop. Steps are anchored on **meaning** (a testid, a signal, or an auto-derived component + source location), never on a `eXX` ref or a coordinate, so they survive refactors; when an anchor does drift, `reticle_flow_replay` names what changed and `reticle_flow_heal` can rebind it.
8
+
7
9
  Reticle turns an interactive run into a **git-checked, replayable program** stored under `.reticle/`. Flows are anchored on **meaning** (testid + signal), not volatile element refs or coordinates, so they survive refactors, and when an anchor does drift, Reticle tells you _why_ and can repair it. This is what makes Reticle "the project's living test suite a human seeds and an agent maintains."
8
10
 
9
11
  > All of this is on-disk and human-readable, so flows are reviewed in PRs and diffed like code.
@@ -113,17 +115,17 @@ This is the feedback a human reviewer used to give, made machine-actionable, so
113
115
 
114
116
  ## Verify the whole suite in one call
115
117
 
116
- `reticle_flow_verify` replays **every** saved flow (or a named subset) deterministically, with no LLM per flow, and returns one consolidated verdict. This is the regression check to run after any change:
118
+ `reticle_verify {action:"flows"}` replays **every** saved flow (or a named subset) deterministically, with no LLM per flow, and returns one consolidated verdict. This is the regression check to run after any change:
117
119
 
118
120
  ```jsonc
119
- reticle_flow_verify()
121
+ reticle_verify({ action: "flows" })
120
122
  // → { status: "fail", total: 4, passed: 3, failed: 1,
121
- // summary: "3/4 flows pass — 1 needs attention: ship-deploy",
123
+ // summary: "3/4 flows pass, 1 needs attention: ship-deploy",
122
124
  // failures: [{ flow: "ship-deploy", verdict: "drift",
123
125
  // whatChanged: "...", whereInSource: "src/...:NN", nextAction: "..." }] }
124
126
  ```
125
127
 
126
- Passing flows are counted; only failures carry detail (token-cheap). Build → `reticle_flow_verify` → fix from each failure's `nextAction` → repeat: the autonomous regression loop.
128
+ Passing flows are counted; only failures carry detail (token-cheap). Build → `reticle_verify {action:"flows"}` → fix from each failure's `nextAction` → repeat: the autonomous regression loop.
127
129
 
128
130
  ## Self-healing: the agent maintains the flow
129
131
 
@@ -163,7 +165,7 @@ With `apply: false` the flow file is **never modified**; you get the proposed di
163
165
  | `reticle_flow {action:"list"}` | `{}` | flows on disk |
164
166
  | `reticle_flow {action:"load"}` | `{ flowName }` | the flow JSON |
165
167
  | `reticle_flow_replay` | `{ flowName }` | `{ status, steps, decision? }` (decision on drift/fail) |
166
- | `reticle_flow_verify` | `{ names?, sessionId? }` | suite verdict `{ status, passed, failed, failures[] }` |
168
+ | `reticle_verify {action:"flows"}` | `{ names?, sessionId? }` | suite verdict `{ status, passed, failed, failures[] }` |
167
169
  | `reticle_flow_heal` | `{ flowName, apply? }` | propose / apply nearest-match rebind |
168
170
  | `reticle_annotate` | `{ kind, … }` | compile a structured annotation into the flow |
169
171
 
@@ -4,9 +4,9 @@ description: Fetch any page as plain Markdown, pull the whole site as one file,
4
4
  icon: robot
5
5
  ---
6
6
 
7
- These docs are built to be read by a program, not just a person. Nothing here needs an API key, a scraper, or an HTML parser. Every page has a plain-text form at a predictable URL.
7
+ Append `.md` to any Reticle docs URL to get that page as plain Markdown, or fetch [`https://docs.reticle.sh/llms.txt`](https://docs.reticle.sh/llms.txt) for the index of every page. No API key, no scraper, no HTML parser.
8
8
 
9
- The site lives at **`https://docs.reticle.sh`**.
9
+ The site lives at **`https://docs.reticle.sh`**. Everything below is a plain HTTP GET.
10
10
 
11
11
  ## Fetch one page
12
12
 
@@ -66,6 +66,6 @@ You rarely need more than one.
66
66
  | Get fluent in one screen | [Agent cheat sheet](/agent-cheatsheet) |
67
67
  | Look up a specific tool, flag, or workflow | [Complete usage guide](/usage) |
68
68
  | Understand what Reticle is doing under the hood | [Architecture](/architecture) |
69
- | Wire it into a desktop app | [Desktop apps](/desktop-apps) |
69
+ | Wire it into a desktop app | [Desktop apps](/desktop) |
70
70
  | Make the checks repeatable in CI | [Specs for CI](/testing) |
71
71
  | Work on Reticle itself | [Gates](/gates), then [System map](/system-map) |
@@ -1,10 +1,13 @@
1
1
  ---
2
- title: Frameworks
3
- description: Which frameworks Reticle supports, which are wired but unverified, and the exact wiring for each one.
2
+ title: 'Frameworks: proven, wired, and the difference'
3
+ sidebarTitle: Frameworks
4
+ description: Which frameworks Reticle supports, which are wired but unverified, and the exact wiring for each one. React, Next.js, Remix, Astro, SvelteKit, Nuxt, Vue and plain HTML.
4
5
  icon: layer-group
5
6
  ---
6
7
 
7
- The core of Reticle is framework-neutral. DOM, network, console, routing, animations and source mapping work anywhere JavaScript runs.
8
+ **React + Vite, Next.js, Remix and Astro are fully supported, each with an example app driven to a verdict in CI. SvelteKit, Nuxt, Vue, Preact, Create React App and plain HTML are wired and documented but not gated, so treat them as plausible rather than proven.** The exact wiring for each is below.
9
+
10
+ Reticle is a verification layer that embeds a dev-only SDK in your running web app so an AI coding agent can prove a change works. Its core is framework-neutral: DOM, network, console, routing, animations and source mapping work anywhere JavaScript runs.
8
11
 
9
12
  What varies is two things: how `connect()` gets into your app, and whether you get component identity on top.
10
13
 
@@ -14,7 +17,7 @@ What varies is two things: how `connect()` gets into your app, and whether you g
14
17
 
15
18
  We separate "we tested this" from "this should work". Four frameworks have an example app and a CI gate. The rest are wired and documented but nothing proves they still work.
16
19
 
17
- Two columns say different things and it is worth keeping them apart. **CI gate** `yes` means an example app is driven to a verdict on every change. **install only** means the install gate scaffolds that stack from scratch, runs `init`, boots it and waits for a session, so the setup is proven and the drive is not. Vue is there because 2.8.0 nearly shipped an installer that left a Vue app connecting 0% of the time, and the gate that exists for exactly that had only React scaffolds.
20
+ Two columns say different things and it is worth keeping them apart. **CI gate** `yes` means an example app is driven to a verdict on every change. **install only** means the install gate scaffolds that stack from scratch, runs `init`, boots it and waits for a session, so the setup is proven and the drive is not. Vue is there because a release once nearly shipped an installer that left a Vue app connecting 0% of the time, and the gate that exists for exactly that had only React scaffolds.
18
21
 
19
22
  **Source pointer** is the `file:line` on a verdict. It needs the build plugin to stamp the source, which it does for JSX and, separately, for Svelte components. Vue single-file components are neither, so a Vue app gets every other signal and no `source` field. Measured, not assumed: a Svelte counter returns `src/lib/Counter.svelte:5` and the same drive on Vue returns none.
20
23
 
@@ -70,9 +73,7 @@ npm i -D @reticlehq/react @reticlehq/next
70
73
  ```js
71
74
  const { withReticle } = require('@reticlehq/next');
72
75
 
73
- module.exports = withReticle({
74
- /* your config */
75
- });
76
+ module.exports = withReticle({/* your config */});
76
77
  ```
77
78
 
78
79
  <Note>
@@ -194,6 +195,44 @@ Electron and Tauri invert the direction: your app dials the daemon, and there is
194
195
 
195
196
  Angular and Solid appear in dependency detection but have no wiring, no adapter and no gate. The sensor may work if you call `connect()` yourself. Nothing proves it, so we are not going to list them as supported.
196
197
 
198
+ ## Frequently asked questions
199
+
200
+ <AccordionGroup>
201
+ <Accordion title="Does Reticle work with Next.js?">
202
+ Yes, and it keeps SWC. Install `@reticlehq/react` and `@reticlehq/next`, then wrap your config
203
+ with `withReticle`. There is no Babel migration. Next.js has an example app and a CI gate, so it
204
+ is supported rather than merely wired, and you get component identity and `file:line` source
205
+ pointers.
206
+ </Accordion>
207
+
208
+ <Accordion title="Does Reticle work with Vue?">
209
+ Partly, and the limit is specific. Install `@reticlehq/browser` rather than the React kit, and you
210
+ get DOM, network, console, routing, actions and Pinia state. What you do not get is a `source`
211
+ field: source stamping covers JSX and Svelte components, and a Vue single-file component is
212
+ neither. The install path is covered by a gate; the drive is not.
213
+ </Accordion>
214
+
215
+ <Accordion title="Which framework should I pick if I want the strongest verdicts?">
216
+ React on Vite. It is the shortest install, and it is the only combination that gives you all three
217
+ of component identity, `file:line` source pointers and a CI-gated example app. If you are already
218
+ on Next.js, Remix or Astro, you get the same guarantees.
219
+ </Accordion>
220
+
221
+ <Accordion title="My framework is not listed at all. Will it work?">
222
+ Probably, with one line. `@reticlehq/browser` is the framework-neutral sensor: call
223
+ `reticle.connect()` behind a dev guard anywhere your app boots, and you get DOM, network, console
224
+ and routing. What you lose is component identity and, unless a build plugin stamps your source,
225
+ the `file:line` pointer. If it does not register a session, that is a bug worth reporting.
226
+ </Accordion>
227
+
228
+ <Accordion title="What does 'wired, unverified' actually mean for me?">
229
+ The recipe on this page was written from a real integration and is expected to work, but no app
230
+ in CI exercises it, so nothing will tell us when it breaks. If you depend on one of these, the
231
+ useful thing you can do is report it when it stops working, since that is the only signal there
232
+ is.
233
+ </Accordion>
234
+ </AccordionGroup>
235
+
197
236
  <Card title="Something missing?" icon="comments" href="/tools-session-and-feedback">
198
237
  A framework you need is a `gap` report. It is the signal that decides what gets built.
199
238
  </Card>
package/docs/gate-plan.md CHANGED
@@ -4,6 +4,8 @@ description: 'What has to be true before a PR merges and before a release ships,
4
4
  icon: list-check
5
5
  ---
6
6
 
7
+ Two gates, not one: a **merge gate** that answers "does this PR break anything" and runs on every PR in minutes, and a **release gate** that answers "does this version work in the clients people use" and runs on a release candidate over hours. Phases 0, 1, 2 and 4 are built; Phase 3 (the client matrix) is blocked on `init` learning each client, and Tier 2 is blocked on a token that cannot be created from inside this repo.
8
+
7
9
  > What has to be true before a PR merges and before a release ships, why each piece exists, and what is built so far. Derived from [`system-map.md`](./system-map.md); the harness rules every tier obeys are in [`harness-rules.md`](../apps/e2e/harness-rules.md).
8
10
 
9
11
  ## Two gates, not one
@@ -76,12 +78,12 @@ Nothing below is trustworthy until a gate result can be distinguished from a gat
76
78
 
77
79
  ### Phase 3: the client matrix
78
80
 
79
- **Blocked on `init` learning each client.** Today only Claude Code (`claude mcp add`) and Cursor (`~/.cursor/mcp.json`) are first-class; everything else gets a printed JSON snippet, so a `v2.5.0-<client>` artifact would measure the contributor's copy-paste rather than the product.
81
+ **Blocked on `init` learning each client.** Today only Claude Code (`claude mcp add`) and Cursor (`~/.cursor/mcp.json`) are first-class; everything else gets a printed JSON snippet, so a per-client release artifact would measure the contributor's copy-paste rather than the product.
80
82
 
81
83
  - [x] **`init` support per client**: `init/mcp-clients.ts` registers Reticle with **seven** clients, not two. Every path and shape was read from that client's own documentation rather than recalled: Cursor/Windsurf/Gemini share `mcpServers`, VS Code uses `servers`, OpenCode uses `mcp` with the command as an **array**, Codex is TOML. A single "write mcp.json" assuming the Cursor shape produces a file three of them ignore: an install that reports success and registers nothing.
82
84
  - Detection is conservative and one-directional: we write into a config a client **already has**, never creating `~/.gemini` or `~/.codeium` for somebody who does not use them.
83
85
  - Codex is deliberately not auto-written. Editing TOML without a parser risks every _other_ server in the user's file; it returns MANUAL with an exact block.
84
- - [x] **Per-client compat script**: `apps/e2e/client-compat.mjs`. Extracts the command from the config **exactly the way that client would**, runs it, and speaks MCP to it. 7/7 clients, 23 assertions, each advertising 18 tools.
86
+ - [x] **Per-client compat script**: `apps/e2e/client-compat.mjs`. Extracts the command from the config **exactly the way that client would**, runs it, and speaks MCP to it. 7/7 clients, 23 assertions, each advertising the default surface (the count is asserted in `surface-sizes.test.ts`, never restated here).
85
87
  - It proves only the half a machine can prove, and the verdict is named `runnable-unverified` so the distinction survives into the matrix. Whether the client _reads_ that path needs the real client, which is the submitted half.
86
88
  - [x] **Submission flow**: `apps/e2e/matrix.mjs --validate`, run by CI's `matrix-records` job on every PR. The validator refuses what cannot be acted on: `works` without `checks.toolsVisible` (the self-report the flow exists to replace), `broken` without the client's verbatim error, or any record with no host or version. Its self-check runs first, because a validator that has never refused anything is not a validator. Contributor guide in [`docs/matrix/README.md`](./matrix/README.md).
87
89
  - [x] **Generated `MATRIX.md`**: built from submitted records, prettier-ignored because a generated file that fails `format:check` teaches people to skip the gate. **The current honest state is seven clients and ZERO ticks**: `◐` means a runnable entry was written where the client documents it and _nobody has run that client_, and the generated legend says so rather than rounding `◐` up to `✅`.
package/docs/gates.md CHANGED
@@ -4,6 +4,8 @@ description: 'I changed some files. Which command do I run before I push?'
4
4
  icon: shield-check
5
5
  ---
6
6
 
7
+ If you changed anything at all, run `pnpm format:check && pnpm lint && pnpm typecheck && pnpm test:unit` (about two minutes). If you also touched the tool surface, install, desktop or Rust, section 1 below names the one extra command your change needs. CI runs everything regardless, so routing costs you a slower red, never a missed one.
8
+
7
9
  > **One question this file answers:** _I changed some files. Which command do I run?_
8
10
  >
9
11
  > The _why_ behind the gate design (tiers, the merge-gate/release-gate split, what is still unbuilt) lives in [`gate-plan.md`](./gate-plan.md). This file is the routing table.
@@ -19,17 +21,17 @@ Every gate below was executed end to end against `main` on **2026-08-12** (macOS
19
21
  | `pnpm build` | ✅ | ~40s |
20
22
  | `pnpm lint` (+ both guard self-tests) | ✅ | ~15s |
21
23
  | `pnpm typecheck` | ✅ | ~10s |
22
- | `pnpm test:unit` | ✅ 4,315 tests / 461 files across 8 packages | ~45s |
24
+ | `pnpm test:unit` | ✅ 5,725 tests / 613 files across 8 packages | ~45s |
23
25
  | `pnpm format:check` | ✅ | ~10s |
24
26
  | `pnpm test:integration` | ✅ 12/12 | 17s |
25
- | `pnpm test:e2e` | ✅ 32/32 specs + soak 60/60 answered | **490s** |
26
- | `pnpm test:e2e:desktop` | ✅ 2/2 (Electron 20, Tauri 14) | 58s |
27
+ | `pnpm test:e2e` | ✅ 33/33 specs + soak 60/60 answered | **490s** |
28
+ | `pnpm test:e2e:desktop` | ✅ 2/2 (Electron 20, Tauri 17) | 58s |
27
29
  | `node apps/e2e/soak.mjs --self-check` | ✅ | `<1s` |
28
30
  | `node apps/e2e/matrix.mjs --self-check` | ✅ | `<1s` |
29
31
  | `pnpm matrix:compat --only cursor` | ✅ 4/4 | ~10s |
30
32
  | `pnpm bench` | ✅ 10/10 (**was failing before this sweep**, see below) | 279s |
31
33
 
32
- **`pnpm bench` was broken and nobody knew.** `suite-rre.mjs` recorded four flows that asserted no observable consequence and then demanded a `pass` verdict from `reticle_flow_verify`, which correctly grades an assertion-free suite `unverifiable`. The product got more honest about false greens; the benchmark measuring it did not follow, so the whole run aborted at script 9 of 10 and `replay-determinism` never ran at all. Each flow now carries a success oracle. This is the failure mode `bench/` is most exposed to: **nothing in CI runs it**, so it can only rot silently.
34
+ **`pnpm bench` was broken and nobody knew.** `suite-rre.mjs` recorded four flows that asserted no observable consequence and then demanded a `pass` verdict from whole-suite replay, which correctly grades an assertion-free suite `unverifiable`. The product got more honest about false greens; the benchmark measuring it did not follow, so the whole run aborted at script 9 of 10 and `replay-determinism` never ran at all. Each flow now carries a success oracle. This is the failure mode `bench/` is most exposed to: **nothing in CI runs it**, so it can only rot silently.
33
35
 
34
36
  `pnpm gate:install` (~15 min) and the Windows / Rust jobs were **not** run in this sweep; they are CI-only or network-bound. They are green on `main` per the last CI run, which is a weaker claim than every row above, and is stated that way on purpose.
35
37
 
@@ -41,7 +43,7 @@ Find the row that matches what you changed. Run its commands. That is the whole
41
43
 
42
44
  | You changed | Run | Cost |
43
45
  | --- | --- | --- |
44
- | **Anything at all** | `pnpm lint && pnpm typecheck && pnpm test:unit` | ~2 min |
46
+ | **Anything at all** | `pnpm format:check && pnpm lint && pnpm typecheck && pnpm test:unit` | ~2 min |
45
47
  | The tool surface, the wire contract (`packages/core`), or an observer | ↑ **and** `pnpm test:e2e` | +~8 min |
46
48
  | `reticle init`, `@reticlehq/vite-plugin`, `@reticlehq/next`, `@reticlehq/babel-plugin`, anything a user runs before their first session | ↑ **and** `pnpm gate:install` | +~15 min |
47
49
  | `@reticlehq/electron`, `packages/tauri`, the IPC observer, desktop capture | ↑ **and** `pnpm test:e2e:desktop` | +~3 min |
@@ -65,7 +67,7 @@ Each gate exists because the ones above it are blind to something. That blindnes
65
67
  | **Unit** | `pnpm test:unit` | 4,315 tests, per-package, no browser | anything crossing a package boundary at runtime | `verify` |
66
68
  | **Format** | `pnpm format:check` | Prettier | n/a | `verify` |
67
69
  | **Integration** | `pnpm test:integration` | real headless Chromium: browser pool, crash isolation, framework adapters, `withReticle` | the MCP surface, the daemon | `e2e` |
68
- | **Web e2e battery** | `pnpm test:e2e` | 30 specs against 3 booted servers and a real browser (the tool surface, the daemon lifecycle, transport faults, telemetry, trace shape), plus the soak | desktop runtimes; the install | `e2e` |
70
+ | **Web e2e battery** | `pnpm test:e2e` | 32 specs against 3 booted servers and a real browser (the tool surface, the daemon lifecycle, transport faults, telemetry, trace shape), plus the soak | desktop runtimes; the install | `e2e` |
69
71
  | **Desktop battery** | `pnpm test:e2e:desktop` | a real Electron main process and a **packaged** Tauri binary, driven headless | web-only paths | `desktop-e2e` |
70
72
  | **Install gate** | `pnpm gate:install` | scaffolds 3 pristine apps, publishes this checkout to a local Verdaccio, lets `init` install itself, boots each app in a real browser, polls for a session | install _complexity_; see [`fixtures.md`](./fixtures.md) | `install-gate` |
71
73
  | **Matrix records** | `pnpm matrix:validate` | every submitted client-compat record is well-formed | whether the client actually works | `matrix-records` |
@@ -4,6 +4,8 @@ description: 'Zero to your agent verifying your real app, step by step, with wor
4
4
  icon: rocket
5
5
  ---
6
6
 
7
+ **To get started with Reticle: run `npx @reticlehq/server init` in your project root, restart your dev server, restart your coding agent, then open your app in a browser and ask the agent to drive a flow.** Reticle is a verification layer that embeds a dev-only SDK in your running web app so an AI coding agent can prove a change works instead of guessing. It needs Node 20 or newer, an app you run locally, and an agent that speaks MCP.
8
+
7
9
  > **Looking for the fast path?** [Quickstart](/quickstart) gets you to a real verdict in five minutes, and every response on it was captured live. [Agentic install](/install-agentic) and [Manual install](/install-manual) cover setup in detail, per agent and per framework.
8
10
  >
9
11
  > This page is the long-form walkthrough: the same ground, more slowly, plus per-framework wiring, multi-app setups and prerelease notes. Start here if you want the whole picture in one file rather than the fast route.
@@ -50,7 +52,7 @@ Everything is **dev-only** and **localhost-only**. It's tree-shaken out of produ
50
52
 
51
53
  ## Prerequisites
52
54
 
53
- - Node 18+ and a package manager (npm/pnpm/yarn).
55
+ - Node 20 or newer, and a package manager (npm/pnpm/yarn).
54
56
  - A coding agent that speaks MCP: Claude Code, Cursor, Windsurf, Claude Desktop, etc.
55
57
  - A web app you run locally in dev (any framework; React gets the richest features).
56
58
 
@@ -74,7 +76,7 @@ It detects your framework, package manager, and React version, then:
74
76
 
75
77
  The bridge + MCP server is a single process that serves all your projects, so it's registered at **user scope**, not in a per-project `.mcp.json`. Only the SDK (the `reticle()` plugin / connect call) is added per project.
76
78
 
77
- Re-running is safe (already-registered/already-patched steps are skipped). Preview without writing via `npx @reticlehq/server init --dry-run`. Flags: `--port N`, `--no-mcp`, `--no-install`, `--yes`.
79
+ Re-running is safe (already-registered/already-patched steps are skipped). Preview without writing via `npx @reticlehq/server init --dry-run`. Flags: `--dry-run`, `--port N`, `--no-mcp`, `--no-install`, `--app <dir>`.
78
80
 
79
81
  Then restart your dev server and skip to [Step 4](#step-4-run-it-and-verify-the-connection). The manual steps below explain what `init` sets up, if you prefer to wire it yourself.
80
82
 
@@ -129,7 +131,7 @@ import react from '@vitejs/plugin-react';
129
131
  import { reticle } from '@reticlehq/vite-plugin';
130
132
 
131
133
  export default defineConfig({
132
- plugins: [react(), reticle()],
134
+ plugins: [reticle(), react()],
133
135
  });
134
136
  ```
135
137
 
@@ -140,7 +142,7 @@ This injects `reticle.connect()` for you _and_ handles React 19 source mapping (
140
142
 
141
143
  In your entry file (`src/main.tsx`), call `connect()` in dev only:
142
144
 
143
- ```ts
145
+ ```tsx
144
146
  import { StrictMode } from 'react';
145
147
  import { createRoot } from 'react-dom/client';
146
148
  import { reticle, SESSION_AUTO } from '@reticlehq/react';
@@ -259,7 +261,7 @@ reticle.connect({ session: SESSION_AUTO, url: 'ws://localhost:4401/reticle' });
259
261
 
260
262
  ```ts
261
263
  // project-b/vite.config.ts
262
- plugins: [react(), reticle({ port: 4401 })],
264
+ plugins: [reticle({ port: 4401 }), react()],
263
265
  ```
264
266
 
265
267
  Either way, the rule is the same: **the app's bridge port must equal the daemon's `RETICLE_PORT`**, and it's the Reticle bridge port, never your dev-server port. Project A stays on the default `4400`, project B on `4401`; they never touch each other. (A port that is already in use now fails fast with a clear error instead of hanging, so a misconfiguration is obvious.)
@@ -291,14 +293,17 @@ export default defineConfig({
291
293
 
292
294
  > **Next.js:** verified on **Next.js 15 / React 19 (app router, SWC)**. For source-file mapping, use `@reticlehq/next` instead of the Babel plugin. It adds a **dev-only webpack pre-loader that keeps SWC** and stamps `data-reticle-source` so `reticle_inspect` returns `file:line` (e.g. `app/page.tsx:30`):
293
295
  >
294
- > ```js
295
- > // next.config.mjs
296
- > import reticleNext from '@reticlehq/next';
297
- > /** @type {import('next').NextConfig} */
298
- > const nextConfig = {};
299
- > export default reticleNext.withReticle(nextConfig); // no-op in production
296
+ > ```ts
297
+ > // next.config.ts
298
+ > import { withReticle } from '@reticlehq/next';
299
+ > import type { NextConfig } from 'next';
300
+ >
301
+ > const nextConfig: NextConfig = {};
302
+ > export default withReticle(nextConfig); // no-op in production
300
303
  > ```
301
304
  >
305
+ > This is exactly what `reticle init` writes. `@reticlehq/next` is CommonJS, so a default import (`import reticleNext from '@reticlehq/next'` then `reticleNext.withReticle(...)`) and a CJS `const { withReticle } = require('@reticlehq/next')` both work too, if your config is `.mjs` or `.js`.
306
+ >
302
307
  > Component identity works with or without it (Next's internal wrappers are filtered out so you see your components, e.g. just `Page`).
303
308
 
304
309
  ---
@@ -430,7 +435,7 @@ Everything below comes from the `@reticlehq/react` kit plus your framework's bui
430
435
 
431
436
  **It is still unverified.** There is no SvelteKit app in `apps/` and no CI gate for one, so nothing would tell us when this breaks; `reticle init` says so out loud in its plan. React, Next.js, Remix and Astro each have an app and a gate. Treat SvelteKit as wired and plausible, not as supported.
432
437
 
433
- **Vue is not supported.** The SDK is framework-agnostic so `connect()` may work, and `piniaStore` will read a Pinia store, but there is no detection, no `.vue` source stamping and no CI gate.
438
+ **Vue is install-gated, drive-unverified.** `init` detects a Vue app (as a Vite app with Vue as the UI library) and the install gate scaffolds one from scratch, runs `init`, boots it and waits for a session, so the setup is proven. What is not proven is the drive: there is no Vue example app in CI. `piniaStore` reads a Pinia store, and everything the framework-neutral core provides works. What you do not get is a `source` field, because source stamping covers JSX and Svelte components and a `.vue` single-file component is neither. See [Frameworks](/frameworks) for the full status table.
434
439
 
435
440
  ---
436
441
 
@@ -478,3 +483,39 @@ npm install @reticlehq/next --legacy-peer-deps
478
483
  # or use pnpm, whose peer resolution does not hard-fail here
479
484
  pnpm add @reticlehq/next
480
485
  ```
486
+
487
+ ---
488
+
489
+ ## Frequently asked questions
490
+
491
+ ### What exactly does `reticle init` change in my project?
492
+
493
+ Four things, and none of them are mysterious: a `.reticle.json` project config, your build config (the `reticle()` Vite plugin, or `withReticle` in `next.config`), a dev-only capabilities file at `src/reticle-dev.ts` (or `app/reticle-dev.tsx` on Next.js), and your agent's rule files. It also registers the MCP server globally, which is a once-per-machine step rather than a per-project one. Run `npx @reticlehq/server init --dry-run` first to see the exact plan before anything is written.
494
+
495
+ ### Do I have to re-register the MCP server for every project?
496
+
497
+ No. The bridge and MCP server are a single process serving all your projects, so `init` registers it at user scope. Every later project starts with the tools already there. Only the SDK wiring is per project.
498
+
499
+ ### Why do the Reticle tools not appear after installing?
500
+
501
+ Because your agent read its MCP server list at startup, before Reticle existed, and no slash command re-reads it. Restart the agent process: quit and reopen Claude Code, reload the window in Cursor, or press Start in `.vscode/mcp.json` in VS Code. `/mcp` only manages servers that are already loaded, so it cannot discover a new one.
502
+
503
+ ### Which Node version do I need?
504
+
505
+ Node 20 or newer.
506
+
507
+ ### Do I need the React adapter?
508
+
509
+ No, it is optional enrichment and the core works without it. What it adds is component identity, meaning `reticle_inspect` can say which React component rendered an element. Combined with a build plugin that stamps source, that is what turns a DOM node into `src/components/Login.tsx:81`, which is the difference between an agent knowing something failed and knowing which file to open.
510
+
511
+ ### Can I run several apps against Reticle at once?
512
+
513
+ Yes, as long as each connection has a unique session id, which `SESSION_AUTO` gives you automatically. Tool calls target the focused or most recently active app, or you can pass an explicit `sessionId`. If you want two projects fully isolated, give each its own bridge port and set the same port in both the MCP server config and the app's connection.
514
+
515
+ ### Will Reticle end up in my production bundle?
516
+
517
+ No. Keep `connect()` behind a dev guard (`import.meta.env.DEV` or a `NODE_ENV` check); the packages are side-effect free and tree-shake out when unused. The Vite plugin uses `apply: 'serve'`, so it is dropped from `vite build` entirely. As a backstop, `connect()` also self-disables when the build reports `NODE_ENV=production`.
518
+
519
+ ### Why is my install failing with `ERESOLVE`?
520
+
521
+ You are almost certainly on a Next.js canary or a React RC. That is npm's semver rule for prereleases, not a Reticle restriction. Install with `--legacy-peer-deps`, or use pnpm, whose peer resolution does not hard-fail here. See [Installing alongside a Next.js or React prerelease](#installing-alongside-a-nextjs-or-react-prerelease) above.
@@ -4,6 +4,8 @@ description: 'Watch the agent’s live transcript, steer it mid-run, or end the
4
4
  icon: hand
5
5
  ---
6
6
 
7
+ With the presenter on (`reticle.connect({ present: true })`), the floating panel in your page lets you watch the agent's live transcript and steer it: **pause** it (its next action tool refuses and returns your guidance), **send** it a correction that rides back on its next tool result, or **end** the session. You can also point at a broken element with **Flag a bug** and hand the agent the element plus its source `file:line`.
8
+
7
9
  When you run with the presenter on (`reticle.connect({ present: true })`), the floating panel is a **two-way control surface**. You watch the agent's live transcript _and_ can steer it (pause it, send it a correction, or end the session) without leaving the page. There's also a clean, unmistakable "session ended" signal for both you and the agent.
8
10
 
9
11
  ## Watch the testing score climb (the live verdict tally)
package/docs/index.mdx CHANGED
@@ -12,6 +12,44 @@ Reticle reads the program from **inside** your running app. Network, state, cons
12
12
 
13
13
  It answers the only question that matters: did the change actually work? On React it also tells your agent which file to open.
14
14
 
15
+ ## Install it: paste this into your coding agent
16
+
17
+ You do not install Reticle by hand. Copy the block below into Claude Code, Cursor, Copilot, Codex, Windsurf, OpenCode, or any MCP agent, and let the agent wire its own workspace. It ends with the only definition of "installed" that counts: one real flow driven, one real verdict returned.
18
+
19
+ ```text
20
+ Reticle is the proof layer for AI coding agents. It runs a dev-only SDK inside my
21
+ running web app, so instead of guessing whether your change worked, you can drive
22
+ the real app and read what actually happened: the network calls, the store, the
23
+ console, the routes, the DOM. You get back pass, fail, or "couldn't tell", with
24
+ the file:line to fix. No screenshots, no vision model, no test syntax.
25
+
26
+ Use it because you cannot otherwise tell whether your own code works. Reading the
27
+ diff proves nothing, and unit tests do not run the app. Reticle is how you check
28
+ your work before telling me it is done, and how you stop reporting "fixed" over a
29
+ silent 500.
30
+
31
+ Install it now:
32
+
33
+ RETICLE_INSTALL_SOURCE=docs_site npx @reticlehq/server@latest init
34
+
35
+ Then follow https://docs.reticle.sh/install-agentic.md and, if anything needs a
36
+ manual edit, https://docs.reticle.sh/install-manual.md. Do not stop until you have
37
+ driven one real flow in my app and produced a verdict. That, not a config file, is
38
+ what "installed" means.
39
+
40
+ Afterwards, use it whenever you change any user-facing behaviour.
41
+ ```
42
+
43
+ <Tip>
44
+ On Claude Code the plugin is shorter still: `/plugin marketplace add reticlehq/reticle` then
45
+ `/plugin install reticle@reticlehq`, which registers the MCP server and the skills in one step. On
46
+ most other agents, `npx skills add reticlehq/reticle`.
47
+ </Tip>
48
+
49
+ <Card title="What that command actually changes" icon="wand-magic-sparkles" href="/install-agentic">
50
+ The four files it writes, the marks it prints, and how to read its report.
51
+ </Card>
52
+
15
53
  <CardGroup cols={2}>
16
54
  <Card title="Quickstart" icon="rocket" href="/quickstart">
17
55
  Install, connect your agent, and get a real verdict. Five minutes.
@@ -41,7 +79,11 @@ It answers the only question that matters: did the change actually work? On Reac
41
79
  Your agent names the expected consequence _before_ it acts. That ordering is the whole trick. It is the difference between a check and a rationalisation.
42
80
 
43
81
  ```json
44
- { "ref": "e4", "action": "click", "until": { "network": "POST /api/todos" } }
82
+ {
83
+ "ref": "e4",
84
+ "action": "click",
85
+ "until": { "kind": "net", "method": "POST", "urlContains": "/api/todos" }
86
+ }
45
87
  ```
46
88
 
47
89
  Reticle clicks, watches, and reports what actually happened. A verdict of `unknown` is not a pass; it means Reticle drove the app and could not tell. It says so rather than guessing, which is a rarer quality in software than it should be.
@@ -1,16 +1,25 @@
1
1
  ---
2
- title: Agentic install: let the agent do it
2
+ title: 'Agentic install: let the agent do it'
3
3
  sidebarTitle: Agentic install
4
4
  description: Run npx @reticlehq/server init and let your coding agent wire Reticle into the project. What it changes, what it asks, and how to read its report.
5
5
  icon: wand-magic-sparkles
6
6
  ---
7
7
 
8
- The install is one command, and it's designed for the agent to run rather than you. The agent is about to be the primary user of this tool, so it may as well set up its own workspace.
8
+ **Run `npx @reticlehq/server init` in your project root.** It registers the MCP server for every agent it finds, installs the SDK, wires your build config, writes the agent rule files, and prints a plan you can read. It is idempotent, so running it twice is safe.
9
9
 
10
10
  ```bash
11
11
  npx @reticlehq/server init
12
12
  ```
13
13
 
14
+ The install is designed for the agent to run rather than you. The agent is about to be the primary user of this tool, so it may as well set up its own workspace.
15
+
16
+ <Warning>
17
+ Always write the package scope: `npx @reticlehq/server <command>` is the CLI. Dropping the scope
18
+ and npx-ing the bare, unscoped `reticle` name fetches a different package published by somebody
19
+ else, which will not give you Reticle. Once `@reticlehq/server` is installed, `reticle` works as a
20
+ bin name on your PATH, which is the only context where the unscoped name is ours.
21
+ </Warning>
22
+
14
23
  ## What do I paste into my coding agent to install Reticle?
15
24
 
16
25
  Copy this whole block into Claude Code, Cursor, Copilot, Codex, Windsurf, OpenCode, or any MCP agent. It tells the agent what Reticle is, why it should want it, and what counts as finished. That last part is the one that matters.
@@ -82,7 +91,7 @@ reticle init (dry run, no files written)
82
91
  [✓] The /reticle command → .claude/commands/reticle.md
83
92
  type /reticle to verify one flow in the browser
84
93
  [✓] Install dependencies → package.json
85
- npm i -D @reticlehq/react@2.8.0 @reticlehq/vite-plugin@2.8.0
94
+ npm i -D @reticlehq/react@<version> @reticlehq/vite-plugin@<version>
86
95
  [✓] Reticle config → .reticle.json
87
96
  write project config (framework + port)
88
97
  [✓] Vite plugin → vite.config.ts
@@ -93,7 +102,7 @@ reticle init (dry run, no files written)
93
102
 
94
103
  ## Reading the marks
95
104
 
96
- There are four, and they mean different things. This is the part worth understanding, because a run full of green ticks can still leave you with a broken install.
105
+ There are five, and they mean different things. This is the part worth understanding, because a run full of green ticks can still leave you with a broken install. Two of the five ask something of you.
97
106
 
98
107
  | Mark | Meaning | Do you need to act? |
99
108
  | ---- | ----------------------------------------------------------- | ------------------- |