@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,126 @@
1
+ ---
2
+ title: reticle_query
3
+ description: Find elements by Testing-Library semantics. Role, text, label, placeholder, testid, alt, or React component, including inside open shadow roots.
4
+ icon: magnifying-glass
5
+ ---
6
+
7
+ `reticle_query` answers "where is the thing I mean?" without dumping the whole page into your context window. It queries the way a testing library does. By role, label, text, testid. So your agent binds to meaning rather than to DOM structure that a refactor will move.
8
+
9
+ ## Example
10
+
11
+ ```json
12
+ { "by": "role", "value": "button", "limit": 6 }
13
+ ```
14
+
15
+ Real response from a running app, with four of the six elements trimmed out for length:
16
+
17
+ ```json
18
+ {
19
+ "count": 7,
20
+ "elements": [
21
+ {
22
+ "ref": "e118",
23
+ "role": "button",
24
+ "name": "Overview",
25
+ "visible": true,
26
+ "source": "src/components/Sidebar.tsx:41",
27
+ "states": ["present", "visible", "enabled"]
28
+ },
29
+ {
30
+ "ref": "e120",
31
+ "role": "button",
32
+ "name": "Compose",
33
+ "visible": true,
34
+ "source": "src/components/Sidebar.tsx:41",
35
+ "states": ["present", "visible", "enabled"]
36
+ }
37
+ ],
38
+ "total": 7,
39
+ "truncated": true,
40
+ "cost": { "bytes": 944, "tokens": 236 }
41
+ }
42
+ ```
43
+
44
+ Seven buttons, each with a `ref` to act on and a source file to open, for 236 tokens.
45
+
46
+ ## Arguments
47
+
48
+ | Argument | What it does |
49
+ | ------------ | -------------------------------------------------------------------------- |
50
+ | `by` | `role` · `text` · `label` · `placeholder` · `testid` · `alt` · `component` |
51
+ | `value` | The query value for that strategy |
52
+ | `name` | Accessible-name filter. Narrows a broad `role` query |
53
+ | `scope` | CSS selector or ref, to search inside a subtree |
54
+ | `limit` | Cap the descriptors returned. Cuts tokens hard on broad queries |
55
+ | `count_only` | Return just `{ count }`, around 30x smaller |
56
+ | `attrs` | Extra attributes per match, e.g. `['href']` to inventory links |
57
+ | `self` | Return the `scope` element itself instead of searching inside it |
58
+
59
+ Every argument also has a predicate spelling, so `{ "role": "button" }` works as shorthand for `{ "by": "role", "value": "button" }`.
60
+
61
+ ## Use `count_only` when you only need a number
62
+
63
+ "Are there still three rows?" does not require three row descriptors:
64
+
65
+ ```json
66
+ { "by": "testid", "value": "login-submit", "count_only": true }
67
+ ```
68
+
69
+ ```json
70
+ { "count": 1, "cost": { "bytes": 11, "tokens": 3 } }
71
+ ```
72
+
73
+ Three tokens. Note that `total` is not emitted on this path, because `count` already is the total.
74
+
75
+ ## A zero-match result tells you what _is_ there
76
+
77
+ ```json
78
+ { "by": "testid", "value": "compose-prompt" }
79
+ ```
80
+
81
+ ```json
82
+ {
83
+ "count": 0,
84
+ "elements": [],
85
+ "hint": {
86
+ "route": "/hostile",
87
+ "knownEmptyState": true,
88
+ "presentTestids": [
89
+ "brand",
90
+ "nav-overview",
91
+ "nav-deployments",
92
+ "nav-compose",
93
+ "nav-diagnostics",
94
+ "nav-hostile",
95
+ "session-pill",
96
+ "cmdk-open",
97
+ "sign-out",
98
+ "hostile-view",
99
+ "hostile-ticker",
100
+ "hostile-feed-count"
101
+ ],
102
+ "presentRegions": [
103
+ { "role": "list", "childCount": 0, "name": "hostile-feed", "sample": [] },
104
+ { "role": "banner", "childCount": 0, "sample": [] }
105
+ ]
106
+ },
107
+ "cost": { "bytes": 402, "tokens": 101 }
108
+ }
109
+ ```
110
+
111
+ The testid existed, on another route. `hint.route` says where you actually are, `presentTestids` says what is on this page instead, and `presentRegions` distinguishes an empty list from a missing one. All of it without paying for a snapshot.
112
+
113
+ ## Reading the response
114
+
115
+ `ref` is the handle for every other tool: `act`, `inspect`, `state`. It stays valid until the element leaves the DOM, so you do not need to re-snapshot between actions on the same element.
116
+
117
+ `source` appears when `@reticlehq/react` is installed. Note that both sidebar buttons above report `Sidebar.tsx:41`, and so do the three trimmed out of the example. That is the line where the component renders all five in a loop, which is exactly the line you want to edit.
118
+
119
+ `truncated: true` with `total: 7` means `limit` cut the list, not that Reticle ran out of room. Neither field is emitted when nothing was cut, so their absence is itself the signal that you are looking at every match.
120
+
121
+ `states` distinguishes `present` from `visible` from `enabled`. An element can be all three and still be covered by a modal. [`reticle_inspect`](/tools-inspect) reports `occluded` for that.
122
+
123
+ <Tip>
124
+ Query by `testid` when you can. Role and text queries survive refactors well; testids survive
125
+ redesigns, translations, and the day someone rewrites your button labels for the marketing team.
126
+ </Tip>
@@ -0,0 +1,112 @@
1
+ ---
2
+ title: reticle_session and reticle_feedback
3
+ description: Hand the session back to the human, end it cleanly, and tell the maintainers when Reticle got something wrong.
4
+ icon: comments
5
+ ---
6
+
7
+ `reticle_session` manages the boundary between the agent and the human watching: hand control back, end the session, narrate what you are doing, and drain the bugs they pinned on elements. `reticle_feedback` is how you tell the Reticle maintainers that Reticle itself got something wrong. Neither tool touches your app, and neither produces a verdict.
8
+
9
+ ## reticle_session
10
+
11
+ The presenter panel in your app shows a live transcript of what the agent is doing. It reads "live" until the agent says otherwise. So an agent that wanders off without a word leaves a panel claiming work is in progress forever.
12
+
13
+ | Action | What it does |
14
+ | ---------- | ------------------------------------------------------------------------ |
15
+ | `yield` | Hand control back between turns. `mode: "waiting"` or `"ask"`. Revivable |
16
+ | `end` | The task is done. Frees the session; revives on the next action |
17
+ | `tune` | Adjust session behaviour, such as `idleEndMs`, the idle-end window |
18
+ | `resume` | Clear a pause the human applied |
19
+ | `messages` | Drain the human-to-agent inbox |
20
+ | `review` | List, and with `resolve`, retire the mistakes a human pinned to elements |
21
+ | `narrate` | State your intent on the presenter panel, with an optional `level` |
22
+
23
+ ```json
24
+ { "action": "yield", "mode": "waiting" }
25
+ ```
26
+
27
+ `review` returns a real reading rather than a silent empty:
28
+
29
+ ```json
30
+ { "marks": [], "pendingCount": 0 }
31
+ ```
32
+
33
+ Reticle nudges you about all of this. Every response on a long-running session carries a reminder:
34
+
35
+ ```json
36
+ "session_age_warning": "Session s223e0fad-e012-43f9-a23d-6d585470c90d has been open for 21 minutes. If your task is complete, call reticle_session{action:\"end\"} now."
37
+ ```
38
+
39
+ And each lease carries the rule in the payload itself:
40
+
41
+ ```json
42
+ "session_lease": {
43
+ "IMPORTANT": "When you stop driving, call reticle_session {action:\"yield\", mode:\"waiting\"|\"ask\"}. The panel reads \"live\" until you do."
44
+ }
45
+ ```
46
+
47
+ <Tip>
48
+ `yield` when you are pausing and might come back. `end` when you are finished. Both revive on your
49
+ next action, so neither is destructive. The difference is what the human watching the panel is
50
+ told.
51
+ </Tip>
52
+
53
+ ## reticle_feedback
54
+
55
+ Reticle is built for agents, which creates an unusual problem: the primary user's experience vanishes the moment its context does. If an agent hits a gap and works around it silently, nobody ever learns the gap existed.
56
+
57
+ ```json
58
+ {
59
+ "kind": "bug",
60
+ "text": "What I called, what I expected, what I got, and why Reticle is at fault.",
61
+ "currentApproach": "How I am working around it today.",
62
+ "impact": "What measurably improves if this is fixed."
63
+ }
64
+ ```
65
+
66
+ | `kind` | Use it when |
67
+ | ----------------- | ---------------------------------------------------------- |
68
+ | `bug` | A tool returned a wrong or broken result |
69
+ | `gap` | Reticle could not observe something you needed at all |
70
+ | `ambiguity` | The check ran but you could not tell what the answer meant |
71
+ | `feature_request` | You wished a capability existed |
72
+ | `improvement` | It works, but costs too many calls |
73
+
74
+ ### It will tell you when it cannot send
75
+
76
+ Feedback is not fire-and-forget, and it does not pretend to succeed:
77
+
78
+ ```json
79
+ {
80
+ "sent": false,
81
+ "accepted": false,
82
+ "reason": "this is a Reticle source checkout, where telemetry is disabled by design, so feedback has nowhere to go. Open an issue at https://github.com/reticlehq/reticle/issues instead, or run from the app you are verifying.",
83
+ "redacted": [],
84
+ "context": {
85
+ "stack": "react",
86
+ "client": "claude-code",
87
+ "runtime": "web",
88
+ "engine": "blink",
89
+ "driver": "cdp",
90
+ "mcpScope": "user"
91
+ },
92
+ "note": "NOT accepted (see reason). Tell the human what you found so it is not lost."
93
+ }
94
+ ```
95
+
96
+ `redacted` names anything stripped from your report before it left the machine, so you can see what was and was not sent. `context` is the environment attached automatically, which is why a useful report costs one call and no boilerplate.
97
+
98
+ That is a real response, captured while writing these docs. The instruction in `note` is the important part: when the report cannot be delivered, say so in your answer to the human rather than letting the finding evaporate.
99
+
100
+ ### From the shell, when the tools are unreachable
101
+
102
+ The setup that failed to finish is exactly the setup that most needs reporting, and in that state the MCP tools do not exist:
103
+
104
+ ```bash
105
+ npx @reticlehq/server feedback --agent --kind gap "reticle init finished but no session ever connected"
106
+ ```
107
+
108
+ <Note>
109
+ Report defects in **Reticle**. A bug you find in the app under test is Reticle working correctly,
110
+ and belongs in your answer to the user. Not in a bug report to us. We get a surprising number of
111
+ those, and each one is quietly a compliment.
112
+ </Note>
@@ -0,0 +1,94 @@
1
+ ---
2
+ title: reticle_sessions
3
+ description: List every connected browser tab, with the health fields that tell you whether it can actually be driven.
4
+ icon: list-check
5
+ ---
6
+
7
+ `reticle_sessions` lists every browser tab currently connected to the Reticle daemon, with the health fields that decide whether it can actually be driven. Reach for it first when a tool says no session is connected, and after every [`reticle_navigate`](/tools-navigate) that came back `confirmed: false`.
8
+
9
+ ```json
10
+ {}
11
+ ```
12
+
13
+ Real response from a healthy session:
14
+
15
+ ```json
16
+ {
17
+ "sessions": [
18
+ {
19
+ "sessionId": "sba6117a6-24ec-494d-8c2c-e2958cff2e7f",
20
+ "url": "http://localhost:4310/",
21
+ "title": "Reticle · Mission Control",
22
+ "adapters": ["react"],
23
+ "hasCapabilities": true,
24
+ "hidden": false,
25
+ "lastSeenMs": 155,
26
+ "throttled": false,
27
+ "focused": true,
28
+ "attachment": { "connectedSinceMs": 18654, "outages": 0 },
29
+ "realInputAvailable": false,
30
+ "leased": false
31
+ }
32
+ ]
33
+ }
34
+ ```
35
+
36
+ A backgrounded tab adds a `recommendation` telling you what to do about it, and `attachment` grows a `lastOutage` once the connection has dropped at least once:
37
+
38
+ ```json
39
+ {
40
+ "hidden": false,
41
+ "throttled": true,
42
+ "attachment": {
43
+ "connectedSinceMs": 1217047,
44
+ "outages": 3,
45
+ "lastOutage": { "startedMs": 1786818483776, "durationMs": 967 }
46
+ },
47
+ "recommendation": "tab hidden/throttled and may be un-focusable from here; refocus it, or run `reticle drive <url>` for a guaranteed scriptable context"
48
+ }
49
+ ```
50
+
51
+ ## When nothing is connected
52
+
53
+ An empty list is not silent. It comes back with a `why` that separates the two causes, and refuses to guess between them:
54
+
55
+ ```json
56
+ {
57
+ "sessions": [],
58
+ "why": "no browser session connected. Two things to weigh, and neither of them is proof. (1) Nothing is listening on the ports Reticle scans, so the dev server may not be running. That scan is narrow though: a server on any other port is invisible to it, so if the app IS running, ask for its URL rather than assuming it is down, and open it with `reticle open <url>`. (2) There is no `.reticle.json` in the directory this daemon is running in. That is the file `reticle init` writes, so the app may carry no Reticle SDK."
59
+ }
60
+ ```
61
+
62
+ That string is trimmed. The full text also lists the exact ports it scanned and warns that in a monorepo the daemon often runs at the root while the app lives in a subdirectory, so you should check the app's own directory before re-running `init`.
63
+
64
+ ## The fields that decide whether driving will work
65
+
66
+ | Field | Why it matters |
67
+ | --- | --- |
68
+ | `throttled` | The browser is deprioritising a background tab. Synthetic timers and pointer gestures may silently no-op |
69
+ | `hidden` / `focused` | Why it's throttled, and what to do about it |
70
+ | `hasCapabilities` | Whether the app registered testids, signals and stores. `false` means [`reticle_state`](/tools-state) has nothing to read |
71
+ | `adapters` | `["react"]` means you get component names and source pointers |
72
+ | `realInputAvailable` | `true` when native CDP input is available, under `reticle drive` |
73
+ | `outages` | How often the connection has dropped. Non-zero is worth investigating |
74
+
75
+ <Warning>
76
+ `throttled: true` is the most common cause of "the click did nothing". Focus the tab, or drive a
77
+ dedicated context. It is not your app being broken. It is the browser saving battery on a tab
78
+ nobody is looking at.
79
+ </Warning>
80
+
81
+ ## Confirm after navigating
82
+
83
+ [`reticle_navigate`](/tools-navigate) can only report that a navigation was dispatched. `sessions` is how you confirm one arrived: a session at the new URL means the page loaded **and** is instrumented. No session means one of those two is false, and you find out now rather than after three confusing failures.
84
+
85
+ ## Scoping
86
+
87
+ You rarely need to pass `sessionId` to other tools. Reticle scopes to your project, prefers the active tab, and refuses rather than guesses when the choice is ambiguous. A refusal you can act on beats a silent pick of the wrong tab.
88
+
89
+ Pass it explicitly when you genuinely mean one specific tab, such as when testing two apps at once.
90
+
91
+ <Note>
92
+ Sessions accumulate. A stale entry pointing at a dev server you have since restarted will sit there
93
+ looking plausible. `reticle_session { action: "end" }` clears one out.
94
+ </Note>
@@ -0,0 +1,129 @@
1
+ ---
2
+ title: reticle_snapshot
3
+ description: A semantic accessibility snapshot of the page or a subtree, in three sizes. From the full tree down to a 25-token route check.
4
+ icon: camera
5
+ ---
6
+
7
+ `reticle_snapshot` is how an agent gets its bearings. It returns the page as semantic structure, not pixels and not raw HTML, and it comes in three sizes so you can pay for only what you need.
8
+
9
+ ## Three modes, three prices
10
+
11
+ | Mode | Returns | Real cost on one page |
12
+ | ------------- | ------------------------------------- | --------------------- |
13
+ | `status` | Route and title only | **25 tokens** |
14
+ | `interactive` | Only clickable and focusable elements | **65 tokens** |
15
+ | `full` | Every element | Depends on the page |
16
+
17
+ ### `status`. the cheapest possible check
18
+
19
+ ```json
20
+ { "mode": "status" }
21
+ ```
22
+
23
+ ```json
24
+ {
25
+ "tree": "",
26
+ "nodes": 0,
27
+ "truncated": false,
28
+ "status": { "route": "/", "title": "Reticle · Mission Control" },
29
+ "cost": { "bytes": 98, "tokens": 25 }
30
+ }
31
+ ```
32
+
33
+ Ninety-eight bytes to answer "where am I?". Use it after a navigation instead of re-reading the page.
34
+
35
+ ### `interactive`. the default working view
36
+
37
+ ```json
38
+ { "mode": "interactive" }
39
+ ```
40
+
41
+ ```json
42
+ {
43
+ "tree": "- textbox \"Email\" (ref=e303) [value=\"admin@reticle.dev\"]\n- textbox \"Password\" (ref=e304) [value=\"[REDACTED]\"]\n- button \"Sign in\" (ref=e305)",
44
+ "nodes": 3,
45
+ "truncated": false,
46
+ "status": { "route": "/deployments", "title": "Reticle · Mission Control" },
47
+ "cost": { "bytes": 260, "tokens": 65 }
48
+ }
49
+ ```
50
+
51
+ Everything you can act on, with a `ref` for each, for 65 tokens. Note the password arrives `[REDACTED]` without anyone configuring it.
52
+
53
+ ## Arguments
54
+
55
+ | Argument | What it does |
56
+ | -------- | ---------------------------------------------------------------------------- |
57
+ | `mode` | `full` · `interactive` · `status` |
58
+ | `scope` | CSS selector or ref, to snapshot one subtree |
59
+ | `diff` | Return only what changed since your last snapshot of the same scope and mode |
60
+
61
+ ## `diff` is how you keep a long session cheap
62
+
63
+ ```json
64
+ { "mode": "interactive", "diff": true }
65
+ ```
66
+
67
+ When nothing moved since your last look of the same scope and mode, that costs 20 tokens and says so:
68
+
69
+ ```json
70
+ {
71
+ "mode": "unchanged",
72
+ "status": { "route": "/", "title": "Reticle · Mission Control" },
73
+ "cost": { "bytes": 79, "tokens": 20 }
74
+ }
75
+ ```
76
+
77
+ When something did move, you get only what changed. This is the same call after a login replaced the form with the app shell:
78
+
79
+ ```json
80
+ {
81
+ "mode": "delta",
82
+ "delta": {
83
+ "added": [
84
+ "- button \"Overview\" (ref=e17)",
85
+ "- button \"Deployments40\" (ref=e18)",
86
+ "- button \"Compose\" (ref=e19)",
87
+ "- button \"Diagnostics\" (ref=e20)",
88
+ "- button \"Hostile\" (ref=e21)",
89
+ "- button \"Search or jump to…⌘K\" (ref=e22)",
90
+ "- button \"Sign out\" (ref=e23)"
91
+ ],
92
+ "removed": [
93
+ "- textbox \"Email\" (ref=e4) [value=\"admin@reticle.dev\"]",
94
+ "- textbox \"Password\" (ref=e5) [value=\"[REDACTED]\"]",
95
+ "- button \"Sign in\" (ref=e3)"
96
+ ],
97
+ "addedCount": 7,
98
+ "removedCount": 3
99
+ },
100
+ "status": { "route": "/", "title": "Reticle · Mission Control" },
101
+ "cost": { "bytes": 545, "tokens": 137 }
102
+ }
103
+ ```
104
+
105
+ A route change resets it: the next call after one returns a full snapshot rather than a delta against a page that no longer exists.
106
+
107
+ <Tip>
108
+ Reach for [`reticle_query`](/tools-query) instead when you already know what you're looking for.
109
+ Snapshot is for orientation; query is for retrieval, and it's almost always cheaper.
110
+ </Tip>
111
+
112
+ ## Refs change across documents
113
+
114
+ Refs are stable while the element is in the DOM. A full navigation builds a new document, so refs are re-issued. Across the captures on this page the same "Sign in" button was `e105`, then `e305`, then `e3`, because each reload built a new document. Snapshot after navigating; don't reuse refs across one.
115
+
116
+ Reticle refuses a stale ref rather than clicking whatever now occupies that slot:
117
+
118
+ ```json
119
+ {
120
+ "error": "ref 'e303' no longer resolves to an element",
121
+ "recovery": "That ref is stale: refs are invalidated whenever the DOM re-renders, so any action that navigated, opened a modal, re-sorted a list or changed the page invalidates every ref taken before it. Call reticle_query again for a fresh ref and retry the action."
122
+ }
123
+ ```
124
+
125
+ <Note>
126
+ That `recovery` string is trimmed. The full text also recommends
127
+ [`reticle_act_and_wait`](/tools-act-and-wait) with `until`, so the next ref is taken after the
128
+ page settles.
129
+ </Note>
@@ -0,0 +1,104 @@
1
+ ---
2
+ title: reticle_state
3
+ description: Read live framework state directly from the running app. What it believes, not just what it rendered, without the app broadcasting anything.
4
+ icon: database
5
+ ---
6
+
7
+ `reticle_state` reads live framework state straight out of the running app, without the app broadcasting anything. Reach for it when the DOM looks right and you want to know whether the application actually accepted the change, which is where false greens live.
8
+
9
+ The DOM tells you what the app _drew_. `reticle_state` tells you what it _believes_. The gap between those two is where false greens live: a row appears in the table, the store never changed, and a reload makes the row vanish.
10
+
11
+ ## Example
12
+
13
+ ```json
14
+ { "depth": 2 }
15
+ ```
16
+
17
+ Real response:
18
+
19
+ ```json
20
+ {
21
+ "found": true,
22
+ "value": {
23
+ "stores": {
24
+ "__reticle_renders": "{…1 keys}",
25
+ "app": "{…30 keys}",
26
+ "queries": "{…0 keys}"
27
+ },
28
+ "storeNames": ["__reticle_renders", "app", "queries"]
29
+ },
30
+ "storeNames": ["__reticle_renders", "app", "queries"]
31
+ }
32
+ ```
33
+
34
+ `depth: 2` collapsed the contents to size markers: `{…30 keys}` rather than thirty keys of JSON. On a large store this is the difference between a cheap look and a very expensive one.
35
+
36
+ ## Arguments
37
+
38
+ | Argument | What it does |
39
+ | -------- | ------------------------------------------------------------ |
40
+ | `store` | A registered store name, e.g. `app` |
41
+ | `path` | Dot-path into a store, e.g. `cart.items.0.qty` |
42
+ | `depth` | Collapse anything deeper than N levels to a size marker |
43
+ | `ref` | Best-effort read of the nearest React component's hook state |
44
+
45
+ Drill in once you know what you want:
46
+
47
+ ```json
48
+ { "store": "app", "path": "auth" }
49
+ ```
50
+
51
+ ```json
52
+ {
53
+ "store": "app",
54
+ "path": "auth",
55
+ "found": true,
56
+ "value": { "email": "admin@reticle.dev" },
57
+ "storeNames": ["__reticle_renders", "app", "queries"]
58
+ }
59
+ ```
60
+
61
+ A wrong `path` comes back `{ "found": false, "availableKeys": [...] }` rather than an empty value, so a typo is diagnosable instead of looking like an empty store.
62
+
63
+ <Warning>
64
+ `reticle_state` asks the page and waits. On a backgrounded tab the page may never answer, and you
65
+ get `"command 'state_read' timed out after 8000ms"` with a recovery note pointing at
66
+ [`reticle_sessions`](/tools-sessions). That is a fact about the tab, not a Reticle failure. Bring
67
+ it to the front, or drive your own browser.
68
+ </Warning>
69
+
70
+ ## You have to register stores first
71
+
72
+ `reticle_state` reads what your app registered in `src/reticle-dev.ts`. With nothing registered, `storeNames` comes back empty and this tool has nothing to say.
73
+
74
+ ```ts
75
+ registerCapabilities({
76
+ stores: [{ name: 'app', store: appStore }],
77
+ });
78
+ ```
79
+
80
+ <Warning>
81
+ Pass the **store**, not `() => store.getState()`. The store form wires `subscribe` too, so every
82
+ mutation emits a state diff. The getter form is read-only and silently produces empty diffs, which
83
+ looks like "nothing changed" and is really "I was never watching".
84
+ </Warning>
85
+
86
+ That distinction is the single most common instrumentation mistake, and its failure mode is a verdict that passes when it should not.
87
+
88
+ ## Why this is the strongest evidence you have
89
+
90
+ A `POST` returning `200` proves the server was reachable. A row in the DOM proves React rendered something. Neither proves your application accepted the change.
91
+
92
+ State does. When [`reticle_act_and_wait`](/quickstart) reports
93
+
94
+ ```json
95
+ "stateDiffs": [
96
+ { "path": "auth", "from": null, "to": "{\"email\":\"admin@reticle.dev\"}", "atMs": 44403 }
97
+ ]
98
+ ```
99
+
100
+ that is the app itself saying the login took. A mock that returns `200` without touching state gets caught right there, and nowhere else.
101
+
102
+ <Card title="Instrument your app" icon="wrench" href="/instrumentation">
103
+ Registering one store for your most important flow is the highest-value line you can write.
104
+ </Card>