@reticlehq/server 3.4.0 → 3.6.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 (350) hide show
  1. package/README.md +1 -1
  2. package/SKILL.md +16 -8
  3. package/dist/chromium-launch-options.d.ts +3 -1
  4. package/dist/chromium-launch-options.js +2 -1
  5. package/dist/command/cli/adhoc-verdict.d.ts +1 -0
  6. package/dist/command/cli/adhoc-verdict.js +6 -3
  7. package/dist/command/cli/answers/open-note.d.ts +2 -0
  8. package/dist/command/cli/answers/open-note.js +22 -0
  9. package/dist/command/cli/auth/cloud-session.d.ts +4 -4
  10. package/dist/command/cli/auth/device-flow.d.ts +2 -2
  11. package/dist/command/cli/cli-flow-commands.js +4 -8
  12. package/dist/command/cli/cli-parse.d.ts +1 -1
  13. package/dist/command/cli/cli-parse.js +13 -11
  14. package/dist/command/cli/cli-verify.d.ts +1 -1
  15. package/dist/command/cli/cli-verify.js +35 -25
  16. package/dist/command/cli/cloud-cli.js +110 -12
  17. package/dist/command/cli/cloud-login.d.ts +9 -1
  18. package/dist/command/cli/cloud-login.js +43 -8
  19. package/dist/command/cli/demo/demo-page.js +11 -3
  20. package/dist/command/cli/doctor/browser/chromium-hint.d.ts +46 -0
  21. package/dist/command/cli/doctor/browser/chromium-hint.js +99 -1
  22. package/dist/command/cli/drive/drive-attach.d.ts +27 -2
  23. package/dist/command/cli/drive/drive-attach.js +71 -4
  24. package/dist/command/cli/drive/drive-command.d.ts +2 -1
  25. package/dist/command/cli/drive/drive-command.js +13 -7
  26. package/dist/command/cli/lifecycle/daemon-lifecycle.js +4 -1
  27. package/dist/command/cli/ports/port-holder.d.ts +10 -0
  28. package/dist/command/cli/ports/port-holder.js +24 -0
  29. package/dist/command/cli/setup-mcp-cli.js +15 -5
  30. package/dist/command/cli/tutorial.d.ts +2 -2
  31. package/dist/command/cli/tutorial.js +6 -9
  32. package/dist/command/cli.d.ts +6 -0
  33. package/dist/command/cli.js +45 -23
  34. package/dist/command/daemon/binding/daemon-status-probe.d.ts +2 -0
  35. package/dist/command/daemon/binding/daemon-status-probe.js +1 -0
  36. package/dist/command/daemon/daemon-resolve.d.ts +14 -0
  37. package/dist/command/daemon/daemon-resolve.js +33 -2
  38. package/dist/command/setup/agent-writer.d.ts +1 -1
  39. package/dist/command/setup/agent-writer.js +3 -2
  40. package/dist/command/setup/bringup/connect-lease.d.ts +1 -0
  41. package/dist/command/setup/bringup/connect-lease.js +1 -0
  42. package/dist/command/setup/bringup/dev-server-wait.d.ts +10 -0
  43. package/dist/command/setup/bringup/dev-server-wait.js +20 -1
  44. package/dist/command/setup/init/init-port.d.ts +4 -0
  45. package/dist/command/setup/init/init-port.js +10 -0
  46. package/dist/command/setup/init/init-runtime.d.ts +10 -0
  47. package/dist/command/setup/init/init-runtime.js +71 -9
  48. package/dist/command/setup/node-effects.js +8 -2
  49. package/dist/command/setup/remaining-steps.js +2 -1
  50. package/dist/command/setup/run-setup.d.ts +7 -0
  51. package/dist/command/setup/run-setup.js +38 -25
  52. package/dist/command/setup/setup-command.d.ts +2 -1
  53. package/dist/command/setup/setup-command.js +2 -0
  54. package/dist/command/setup/setup-mcp.d.ts +2 -0
  55. package/dist/command/setup/setup-mcp.js +14 -5
  56. package/dist/command/version/peer-announce.d.ts +6 -2
  57. package/dist/command/version/peer-announce.js +8 -6
  58. package/dist/command/version/version-nudge.d.ts +17 -3
  59. package/dist/command/version/version-nudge.js +25 -4
  60. package/dist/command/version/version-skew.js +11 -2
  61. package/dist/features/crawl/crawl-tools.js +4 -0
  62. package/dist/features/crawl/crawl.d.ts +6 -0
  63. package/dist/features/crawl/crawl.js +9 -1
  64. package/dist/features/exhaust/ledger.d.ts +7 -0
  65. package/dist/features/exhaust/ledger.js +35 -9
  66. package/dist/features/harness/app-findings.d.ts +2 -0
  67. package/dist/features/harness/app-findings.js +52 -0
  68. package/dist/features/harness/drive-report.d.ts +27 -1
  69. package/dist/features/harness/drive-report.js +162 -11
  70. package/dist/features/harness/drivers.d.ts +10 -14
  71. package/dist/features/harness/drivers.js +10 -14
  72. package/dist/features/harness/fill-values.d.ts +3 -69
  73. package/dist/features/harness/fill-values.js +3 -133
  74. package/dist/features/harness/goals.d.ts +21 -0
  75. package/dist/features/harness/goals.js +77 -0
  76. package/dist/features/harness/harness.d.ts +21 -0
  77. package/dist/features/harness/harness.js +69 -2
  78. package/dist/features/harness/platform/drive-target.d.ts +30 -0
  79. package/dist/features/harness/platform/drive-target.js +81 -0
  80. package/dist/features/harness/platform/local-apps.d.ts +94 -0
  81. package/dist/features/harness/platform/local-apps.js +204 -0
  82. package/dist/features/harness/platform/remote-drive.d.ts +180 -0
  83. package/dist/features/harness/platform/remote-drive.js +365 -0
  84. package/dist/features/harness/platform/script.d.ts +48 -0
  85. package/dist/features/harness/platform/script.js +128 -0
  86. package/dist/features/harness/platform/server-driver.d.ts +41 -0
  87. package/dist/features/harness/platform/server-driver.js +179 -0
  88. package/dist/features/harness/platform-config.d.ts +7 -0
  89. package/dist/features/harness/platform-config.js +14 -2
  90. package/dist/features/harness/script/app-controls.d.ts +5 -0
  91. package/dist/features/harness/script/app-controls.js +40 -0
  92. package/dist/features/harness/script/lane-ids.d.ts +14 -0
  93. package/dist/features/harness/script/lane-ids.js +16 -0
  94. package/dist/features/harness/script/script-run.d.ts +41 -0
  95. package/dist/features/harness/script/script-run.js +299 -0
  96. package/dist/features/license/license.d.ts +2 -2
  97. package/dist/features/visual/visual-tools.d.ts +10 -1
  98. package/dist/features/visual/visual-tools.js +40 -3
  99. package/dist/hooks/driven-by.d.ts +4 -0
  100. package/dist/hooks/driven-by.js +16 -0
  101. package/dist/hooks/hook-commands.js +15 -4
  102. package/dist/hooks/tool-log.d.ts +9 -0
  103. package/dist/hooks/tool-log.js +29 -0
  104. package/dist/index.d.ts +1 -0
  105. package/dist/index.js +91 -89
  106. package/dist/judgement/capsule/capsule-store.d.ts +4 -4
  107. package/dist/judgement/runs/artifact/build-verification-run.js +6 -0
  108. package/dist/judgement/runs/artifact/replay-mapping.d.ts +1 -1
  109. package/dist/judgement/runs/artifact/replay-mapping.js +16 -6
  110. package/dist/judgement/runs/artifact/run-store.d.ts +1 -1
  111. package/dist/judgement/runs/artifact/run-store.js +26 -1
  112. package/dist/judgement/runs/drive-run.d.ts +22 -0
  113. package/dist/judgement/runs/drive-run.js +99 -1
  114. package/dist/judgement/runs/repair-prompt.js +1 -1
  115. package/dist/judgement/runs/reticle-runner.js +8 -1
  116. package/dist/judgement/runs/verification-sync.d.ts +3 -2
  117. package/dist/judgement/runs/verification-sync.js +4 -3
  118. package/dist/language/flows/change/gate.d.ts +10 -0
  119. package/dist/language/flows/change/gate.js +22 -0
  120. package/dist/language/flows/decision.js +34 -0
  121. package/dist/language/flows/flow-anchor.d.ts +54 -8
  122. package/dist/language/flows/flow-anchor.js +88 -3
  123. package/dist/language/flows/flow-cross-step.d.ts +15 -0
  124. package/dist/language/flows/flow-cross-step.js +21 -0
  125. package/dist/language/flows/flow-learning.js +8 -11
  126. package/dist/language/flows/flow-mutate-tools.js +5 -3
  127. package/dist/language/flows/flow-replay-run.d.ts +23 -9
  128. package/dist/language/flows/flow-replay-run.js +101 -94
  129. package/dist/language/flows/flow-replay.d.ts +23 -1
  130. package/dist/language/flows/flow-replay.js +92 -19
  131. package/dist/language/flows/flow-scope.js +5 -1
  132. package/dist/language/flows/flow-step-runners.d.ts +20 -2
  133. package/dist/language/flows/flow-step-runners.js +236 -42
  134. package/dist/language/flows/flow-store-for-session.d.ts +2 -2
  135. package/dist/language/flows/flow-store-for-session.js +2 -2
  136. package/dist/language/flows/flow-tools.js +58 -34
  137. package/dist/language/flows/flows.js +5 -2
  138. package/dist/language/flows/heal-run.js +6 -4
  139. package/dist/language/flows/recording/flake.d.ts +2 -2
  140. package/dist/language/flows/recording/tape/recordings.d.ts +30 -4
  141. package/dist/language/flows/recording/tape/recordings.js +40 -8
  142. package/dist/language/flows/replay-from-hud.d.ts +20 -0
  143. package/dist/language/flows/replay-from-hud.js +51 -0
  144. package/dist/language/flows/replay.d.ts +9 -5
  145. package/dist/language/flows/replay.js +27 -9
  146. package/dist/language/flows/suite/suite-flakes.js +2 -0
  147. package/dist/language/flows/suite-selection.d.ts +2 -15
  148. package/dist/language/flows/suite-selection.js +4 -3
  149. package/dist/language/flows/verify-change-tools.js +8 -4
  150. package/dist/launch-chromium.d.ts +27 -5
  151. package/dist/launch-chromium.js +38 -8
  152. package/dist/memory/cloud/cloud-config.d.ts +12 -0
  153. package/dist/memory/cloud/cloud-config.js +15 -0
  154. package/dist/memory/cloud/cloud-sync.d.ts +17 -14
  155. package/dist/memory/cloud/cloud-sync.js +12 -1
  156. package/dist/memory/cloud/harness-config.d.ts +26 -1
  157. package/dist/memory/cloud/harness-config.js +99 -4
  158. package/dist/memory/cloud/hud-notices-source.d.ts +21 -0
  159. package/dist/memory/cloud/hud-notices-source.js +128 -0
  160. package/dist/memory/cloud/memory-scope.d.ts +144 -0
  161. package/dist/memory/cloud/memory-scope.js +205 -0
  162. package/dist/memory/cloud/sync-cycle.d.ts +21 -3
  163. package/dist/memory/cloud/sync-cycle.js +45 -5
  164. package/dist/memory/cloud/sync-daemon.js +7 -5
  165. package/dist/memory/cloud/sync-disk.d.ts +1 -1
  166. package/dist/memory/cloud/sync-disk.js +5 -8
  167. package/dist/memory/impact/account-watch.d.ts +19 -0
  168. package/dist/memory/impact/account-watch.js +34 -0
  169. package/dist/memory/impact/impact-recorder.d.ts +8 -0
  170. package/dist/memory/impact/impact-recorder.js +12 -2
  171. package/dist/memory/impact/impact-store.d.ts +16 -0
  172. package/dist/memory/impact/impact-store.js +142 -26
  173. package/dist/memory/intent/intent-shard.d.ts +2 -2
  174. package/dist/memory/intent/intent-tools.js +88 -5
  175. package/dist/memory/journal/envelope.d.ts +16 -16
  176. package/dist/memory/journal/journal-query.d.ts +14 -0
  177. package/dist/memory/journal/journal-query.js +15 -0
  178. package/dist/memory/journal/journal-recorder.js +7 -1
  179. package/dist/memory/journal/on-disk/retention.d.ts +3 -0
  180. package/dist/memory/journal/on-disk/retention.js +5 -0
  181. package/dist/memory/journal/on-disk/startup-maintenance.js +3 -1
  182. package/dist/memory/journal/on-disk/workspace-tiers.js +7 -4
  183. package/dist/memory/journal/session-end.js +6 -4
  184. package/dist/memory/project/artifact-root-resolver.d.ts +36 -1
  185. package/dist/memory/project/artifact-root-resolver.js +134 -26
  186. package/dist/memory/project/artifact-root.d.ts +42 -5
  187. package/dist/memory/project/artifact-root.js +87 -8
  188. package/dist/memory/project/dir/reticle-dir.d.ts +4 -2
  189. package/dist/memory/project/dir/reticle-dir.js +3 -1
  190. package/dist/memory/project/project-tools.js +22 -3
  191. package/dist/memory/project/session-root.d.ts +24 -1
  192. package/dist/memory/project/session-root.js +41 -5
  193. package/dist/memory/project/sync-status.d.ts +39 -0
  194. package/dist/memory/project/sync-status.js +90 -0
  195. package/dist/memory/recall/memory-tools.js +2 -0
  196. package/dist/memory/recall/project-memory.d.ts +19 -0
  197. package/dist/memory/recall/project-memory.js +45 -6
  198. package/dist/portal/bridge/bridge.d.ts +7 -4
  199. package/dist/portal/bridge/bridge.js +25 -3
  200. package/dist/portal/bridge/pairing-token.d.ts +9 -0
  201. package/dist/portal/bridge/pairing-token.js +17 -0
  202. package/dist/portal/input/real-input.d.ts +81 -10
  203. package/dist/portal/input/real-input.js +207 -22
  204. package/dist/portal/input/viewport-tools.js +19 -9
  205. package/dist/portal/pool/browser-pool.d.ts +22 -9
  206. package/dist/portal/pool/browser-pool.js +70 -35
  207. package/dist/portal/pool/playwright-launcher.d.ts +13 -0
  208. package/dist/portal/pool/playwright-launcher.js +17 -1
  209. package/dist/portal/pool/pool-contract.d.ts +7 -4
  210. package/dist/portal/session/command-payload.d.ts +8 -0
  211. package/dist/portal/session/command-payload.js +19 -0
  212. package/dist/portal/session/dev-server/dev-command.d.ts +12 -0
  213. package/dist/portal/session/dev-server/dev-command.js +61 -12
  214. package/dist/portal/session/facts/departure-note.d.ts +22 -0
  215. package/dist/portal/session/facts/departure-note.js +47 -0
  216. package/dist/portal/session/facts/session-replaced.d.ts +5 -0
  217. package/dist/portal/session/facts/session-replaced.js +5 -0
  218. package/dist/portal/session/first-run-wiring.d.ts +42 -0
  219. package/dist/portal/session/first-run-wiring.js +132 -0
  220. package/dist/portal/session/human/notes-ledger.d.ts +20 -0
  221. package/dist/portal/session/human/notes-ledger.js +55 -0
  222. package/dist/portal/session/human/review-store.d.ts +12 -0
  223. package/dist/portal/session/human/review-store.js +18 -10
  224. package/dist/portal/session/live-control-tools.d.ts +0 -13
  225. package/dist/portal/session/live-control-tools.js +28 -3
  226. package/dist/portal/session/no-session-diagnosis.d.ts +7 -0
  227. package/dist/portal/session/no-session-diagnosis.js +15 -0
  228. package/dist/portal/session/no-session-next-action.d.ts +11 -0
  229. package/dist/portal/session/no-session-next-action.js +31 -5
  230. package/dist/portal/session/no-session-watch.d.ts +14 -1
  231. package/dist/portal/session/no-session-watch.js +63 -10
  232. package/dist/portal/session/presence/session-mirror.js +3 -0
  233. package/dist/portal/session/serving-directory.d.ts +27 -0
  234. package/dist/portal/session/serving-directory.js +45 -0
  235. package/dist/portal/session/session-health.d.ts +7 -0
  236. package/dist/portal/session/session-health.js +6 -0
  237. package/dist/portal/session/session-info.d.ts +8 -1
  238. package/dist/portal/session/session-info.js +6 -0
  239. package/dist/portal/session/session-manager.d.ts +21 -0
  240. package/dist/portal/session/session-manager.js +44 -8
  241. package/dist/portal/session/session-reaper.js +4 -1
  242. package/dist/portal/session/session-successor.d.ts +5 -0
  243. package/dist/portal/session/session-tools.js +26 -3
  244. package/dist/portal/session/session.d.ts +12 -10
  245. package/dist/portal/session/session.js +30 -31
  246. package/dist/start-options.d.ts +6 -0
  247. package/dist/status-payload.d.ts +10 -0
  248. package/dist/status-payload.js +23 -0
  249. package/dist/surface/http-server.d.ts +1 -1
  250. package/dist/surface/http-server.js +15 -4
  251. package/dist/surface/mcp/mcp-proxy.d.ts +5 -0
  252. package/dist/surface/mcp/mcp-proxy.js +36 -5
  253. package/dist/surface/mcp/mcp.d.ts +11 -6
  254. package/dist/surface/mcp/mcp.js +28 -14
  255. package/dist/surface/mcp/proxy/proxy-log.js +3 -5
  256. package/dist/surface/mcp/server-instructions.d.ts +4 -2
  257. package/dist/surface/mcp/server-instructions.js +14 -4
  258. package/dist/surface/mcp/shared-params.js +2 -2
  259. package/dist/surface/tools/act/navigation/navigate-arrival.d.ts +8 -0
  260. package/dist/surface/tools/act/navigation/navigate-arrival.js +56 -2
  261. package/dist/surface/tools/act/settle-in-flight.js +25 -3
  262. package/dist/surface/tools/act-sequence-tool.js +2 -2
  263. package/dist/surface/tools/act-tools.js +25 -9
  264. package/dist/surface/tools/assert/assert-verdict.d.ts +1 -1
  265. package/dist/surface/tools/assert/assert-verdict.js +17 -2
  266. package/dist/surface/tools/browser-tools.js +8 -1
  267. package/dist/surface/tools/chat-drives.d.ts +26 -0
  268. package/dist/surface/tools/chat-drives.js +165 -0
  269. package/dist/surface/tools/dynamic-tools.js +29 -2
  270. package/dist/surface/tools/empty-session-list.d.ts +41 -0
  271. package/dist/surface/tools/empty-session-list.js +80 -0
  272. package/dist/surface/tools/error-recovery.d.ts +6 -0
  273. package/dist/surface/tools/error-recovery.js +38 -6
  274. package/dist/surface/tools/explore-tools.d.ts +10 -1
  275. package/dist/surface/tools/explore-tools.js +82 -13
  276. package/dist/surface/tools/feedback-tools.js +14 -0
  277. package/dist/surface/tools/harness-explore.d.ts +96 -14
  278. package/dist/surface/tools/harness-explore.js +227 -202
  279. package/dist/surface/tools/harness-plan.d.ts +12 -0
  280. package/dist/surface/tools/harness-plan.js +31 -0
  281. package/dist/surface/tools/harness-script.d.ts +8 -0
  282. package/dist/surface/tools/harness-script.js +342 -0
  283. package/dist/surface/tools/harness-toolset.d.ts +14 -1
  284. package/dist/surface/tools/harness-toolset.js +77 -6
  285. package/dist/surface/tools/invoke-tool.js +64 -9
  286. package/dist/surface/tools/lease-seed.d.ts +29 -0
  287. package/dist/surface/tools/lease-seed.js +123 -0
  288. package/dist/surface/tools/lease-tools.d.ts +3 -23
  289. package/dist/surface/tools/lease-tools.js +30 -131
  290. package/dist/surface/tools/live-call-text.js +2 -2
  291. package/dist/surface/tools/next-step.d.ts +19 -0
  292. package/dist/surface/tools/next-step.js +159 -0
  293. package/dist/surface/tools/observe-tools.js +2 -4
  294. package/dist/surface/tools/platform-moment.d.ts +12 -0
  295. package/dist/surface/tools/platform-moment.js +168 -0
  296. package/dist/surface/tools/query-hint-schema.d.ts +7 -0
  297. package/dist/surface/tools/query-hint-schema.js +10 -0
  298. package/dist/surface/tools/read-tools.js +8 -2
  299. package/dist/surface/tools/real-input-attempt.js +96 -13
  300. package/dist/surface/tools/tool-kit.d.ts +25 -1
  301. package/dist/surface/tools/tool-kit.js +4 -6
  302. package/dist/surface/tools/tools.js +20 -48
  303. package/dist/telemetry/argument-shape.js +1 -1
  304. package/dist/telemetry/hud-metrics.d.ts +2 -0
  305. package/dist/telemetry/hud-metrics.js +17 -0
  306. package/dist/telemetry/onboarding-firsts.d.ts +2 -2
  307. package/dist/telemetry/onboarding-firsts.js +2 -2
  308. package/dist/telemetry/telemetry.d.ts +12 -0
  309. package/dist/telemetry/telemetry.js +43 -14
  310. package/dist/telemetry/verification-of.js +1 -0
  311. package/dist/wire-journal.js +4 -1
  312. package/docs/README.md +1 -1
  313. package/docs/actions.mdx +1 -2
  314. package/docs/agent-cheatsheet.md +1 -1
  315. package/docs/autodrive.md +29 -25
  316. package/docs/cli/cloud.mdx +6 -4
  317. package/docs/cli/doctor.mdx +6 -0
  318. package/docs/cli/drive.mdx +8 -2
  319. package/docs/cli/init.mdx +11 -13
  320. package/docs/cli/status.mdx +5 -1
  321. package/docs/cli/version.mdx +3 -3
  322. package/docs/cli.mdx +14 -8
  323. package/docs/desktop.mdx +5 -1
  324. package/docs/environment.mdx +3 -7
  325. package/docs/getting-started.md +14 -2
  326. package/docs/human-control.md +1 -2
  327. package/docs/index.mdx +4 -3
  328. package/docs/install-agentic.mdx +1 -1
  329. package/docs/install-manual.mdx +2 -2
  330. package/docs/packages/next.mdx +3 -0
  331. package/docs/packages/tauri.mdx +2 -2
  332. package/docs/packages/vite-plugin.mdx +24 -1
  333. package/docs/packages.mdx +1 -1
  334. package/docs/quickstart.mdx +23 -11
  335. package/docs/telemetry.md +1 -1
  336. package/docs/tools/act.mdx +1 -1
  337. package/docs/tools/session-and-feedback.mdx +9 -9
  338. package/docs/usage.md +5 -3
  339. package/docs/what-is-recorded.md +13 -3
  340. package/docs/what-is-reticle.mdx +3 -1
  341. package/package.json +8 -12
  342. package/dist/features/harness/driver.d.ts +0 -50
  343. package/dist/features/harness/driver.js +0 -236
  344. package/dist/features/harness/jev-driver.d.ts +0 -188
  345. package/dist/features/harness/jev-driver.js +0 -678
  346. package/dist/features/harness/openai-driver.d.ts +0 -46
  347. package/dist/features/harness/openai-driver.js +0 -194
  348. package/dist/memory/project/dir/fill-value-store.d.ts +0 -32
  349. package/dist/memory/project/dir/fill-value-store.js +0 -88
  350. package/docs/local-registry.md +0 -143
@@ -4,7 +4,7 @@ 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 the installer, open your coding agent, then run `npx @reticlehq/server init` in your project root.** Getting started is three stages. **Installation** is one command in a terminal, `curl -fsSL https://raw.githubusercontent.com/reticlehq/reticle/main/install/install.sh | sh` (or `irm https://raw.githubusercontent.com/reticlehq/reticle/main/install/install.ps1 | iex` on Windows): it puts the CLI on the machine and registers the MCP server with every agent it can reach, so the tools are there the next time you open your agent. **Onboarding** is `init`: it wires your project, starts your dev server, opens the app and waits for it to connect. **The first run** is what proves anything: `reticle_verify { action: "explore", persona: "<the journey worth proving>" }`, or from a terminal `npx @reticlehq/server verify <url> --explore --persona "<the journey worth proving>"`. A connected app is not a verified one. 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.
7
+ **To get started: run the installer, then `reticle init` in your app directory before opening your coding agent.** The installer puts the CLI on the machine and registers its MCP tools with supported agents. `init` wires your app and checks that a browser session connected; without it the agent has the tools and nothing to point them at. For a cloud dashboard, use `reticle connect --project "My App"`, which does the same and also links a cloud project and syncs history. The first run is what proves anything: ask your agent to verify one journey in your app, or use `reticle_verify { action: "explore", persona: "<the journey worth proving>" }`. A connected app is not a verified one. You need Node 20.11 or newer, an app you run locally, and an agent that speaks MCP.
8
8
 
9
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.
10
10
  >
@@ -58,7 +58,9 @@ Everything is **dev-only** and **localhost-only**. It's tree-shaken out of produ
58
58
 
59
59
  ---
60
60
 
61
- ## Fastest path: `reticle init`
61
+ ## Wire your app: on the first run, or `reticle init`
62
+
63
+ Installing Reticle changes nothing in your project. The first time your agent uses Reticle in a project that has never connected (its first `reticle_session { action: "list" }`), Reticle runs `init` there itself and returns the files it changed under `wired`, so you can skip straight to asking your agent to verify a flow. Run `init` yourself to wire a project ahead of time, to preview the changes, or when the agent's MCP server was started outside the project (the call then answers `run_init` with this same command).
62
64
 
63
65
  From your project root:
64
66
 
@@ -94,6 +96,16 @@ If you ran `--files-only` with a dev server already running, restart it, then sk
94
96
 
95
97
  ---
96
98
 
99
+ ## Add a cloud dashboard: `reticle connect`
100
+
101
+ Optional. Instead of, or after, `init`, run this in your app directory:
102
+
103
+ ```bash
104
+ npx @reticlehq/server connect --project "My App"
105
+ ```
106
+
107
+ Approve the short browser code if Reticle asks you to sign in. The command then links this folder and sends any history already on the machine. Open or restart your coding agent and ask it to verify one real journey. For a new project, the dashboard has no result until that first run is recorded.
108
+
97
109
  ## Step 1: Connect your coding agent (MCP), once
98
110
 
99
111
  You don't start the server manually; your agent starts it via MCP. Register Reticle **once, at the user (global) scope** so every project picks it up. There's nothing to add per project.
@@ -25,10 +25,9 @@ MCP is **pull-based**: the agent only receives data when it calls a tool. Reticl
25
25
  The floating panel (bottom-center, `present: true`) gives you:
26
26
 
27
27
  - **Pause / Resume**: one toggle. Paused turns the panel + page border **amber** with a `PAUSED` badge.
28
- - **Message box + send.** Type a correction ("check the error state first"), hit Send (or Enter). Your message shows as a `🧑 you:` bubble in the transcript **and** is delivered to the agent.
29
28
  - **End** ends the session: panel turns **emerald**, shows `Session ended · <summary>`, then fades away.
30
29
  - **Minimise (▾)** collapses the panel to a bar that streams only the live line; click the bar to restore.
31
- - **Flag a bug**, the button in the corner. Toggle it on, click the element that looks wrong, type what's wrong (⌘/Ctrl+Enter to send, Esc to back out). Reticle pins a numbered marker, logs your flag in the panel, and hands the agent a structured mark.
30
+ - **Flag a bug**, the button in the corner. Toggle it on, click the element that looks wrong, type what's wrong (⌘/Ctrl+Enter to send, Esc to back out). Reticle pins a numbered marker, logs your flag in the panel, and hands the agent a structured mark. Notes are kept in `.reticle/notes.json` (pending and resolved), so a reload or a daemon restart does not lose them, and a linked project syncs them to the dashboard.
32
31
 
33
32
  ## Flag a bug: annotate the mistake where you see it
34
33
 
package/docs/index.mdx CHANGED
@@ -28,7 +28,7 @@ irm https://raw.githubusercontent.com/reticlehq/reticle/main/install/install.ps1
28
28
 
29
29
  </CodeGroup>
30
30
 
31
- That registers the MCP server with every coding agent it can reach, so the `reticle_*` tools are there the next time you open one. Then, in your project, `npx @reticlehq/server init` wires the app. The [quickstart](/quickstart) walks both.
31
+ That registers the MCP server with every coding agent it can reach, so the `reticle_*` tools are there the next time you open one. Then ask your agent to verify something in your app: its first Reticle call wires the app and lists the files it changed (`npx @reticlehq/server init` does the same by hand). The [quickstart](/quickstart) walks both.
32
32
 
33
33
  ### Or hand the whole thing to your agent
34
34
 
@@ -54,8 +54,9 @@ That one command wires the project, starts the dev server, opens the app and
54
54
  waits for it to connect. Do not walk it by hand: read what it prints, do anything
55
55
  it says is outstanding, and re-run it, which is safe. It exits non-zero until the
56
56
  app connects, and that connection, not a config file, is what "installed" means.
57
- Then prove a flow, which is a separate call:
58
- reticle_verify { action: "explore", persona: "<who does what>" }. Only if it could not run at all, follow
57
+ Then prove a flow, which is a separate call: drive the journey with
58
+ reticle_act_and_wait and an `until` on its last step (or, with a linked project,
59
+ reticle_verify { action: "explore", persona: "<who does what>" }). Only if it could not run at all, follow
59
60
  https://docs.reticle.sh/install-manual.md.
60
61
 
61
62
  Afterwards, use it whenever you change any user-facing behaviour.
@@ -248,7 +248,7 @@ Three of these are answers only the caller has. `init` reads your repository; it
248
248
  | `--env KEY=VALUE` | What the app needs to reach a usable state: the key from `.env.example`, the mock backend, the variable that skips an auth wall. Repeatable, and a value may contain spaces and equals signs. Without it a real app sits on a login screen and there is no flow to drive. |
249
249
  | `--app <dir>` | Monorepos. `init` can find the apps that are servable; only your request says which one you are working in. |
250
250
  | `--license <key>` | Writes `RETICLE_LICENSE_KEY` to `.env` and keeps `.env` out of git. Do not do those two by hand. |
251
- | `--json` | One object on stdout: what was wired, what connected, the verdict, and an `agentTodo` array. For agents. |
251
+ | `--json` | One result object on stdout; progress and package-manager output go to stderr. Default init reports runtime setup and connection. `--files-only` and `--dry-run` report the wiring result. Init does not drive a flow or produce a verification verdict. |
252
252
  | `--files-only` | Write the files, register the MCP server with every agent on the machine, pre-approve Reticle's tools, and stop: no dev server, no drive. What `init` did before it learned to boot the app, and the upgrade path for a machine that installed Reticle on an earlier version. |
253
253
  | `--no-open` | Do not open a browser: CI, a container, an SSH session, or a tab you already have. |
254
254
  | `--dry-run` | See the plan before anything is written. |
@@ -7,7 +7,7 @@ icon: screwdriver-wrench
7
7
 
8
8
  **Installing Reticle by hand is two independent halves: register the MCP server so your agent gets the `reticle_*` tools, then add the SDK to your app so there is something for those tools to talk to.** You need both, in that order.
9
9
 
10
- Do only the first half and the tools appear but every call reports no session. Do only the second and your app connects to a daemon nobody is asking questions.
10
+ Do only the first half and the tools appear but every call reports no session. Do only the second and your app connects to a daemon nobody is asking questions. Stop after the first half and your agent's first Reticle call wires the app itself when you ask it to verify something, and offers to otherwise.
11
11
 
12
12
  <Warning>
13
13
  **You probably do not need this page.** Two commands do all of it:
@@ -175,7 +175,7 @@ Screenshots and headless mode need the Rust crate, which is versioned independen
175
175
 
176
176
  ```toml
177
177
  [dependencies]
178
- reticle-tauri = "3.4"
178
+ reticle-tauri = "3.6"
179
179
  ```
180
180
 
181
181
  ```rust
@@ -44,10 +44,13 @@ Returns the config unchanged when `NODE_ENV === 'production'`. Otherwise it merg
44
44
  | --- | --- |
45
45
  | `webpack` | Pushes an `enforce: 'pre'` rule for `/\.(t\|j)sx$/`, excluding `node_modules`, using this package's loader. Your own `webpack` function still runs afterwards |
46
46
  | `turbopack` | On Next 15.3 and above only: rules for `*.tsx` and `*.jsx` pointing at `@reticlehq/next/loader` |
47
+ | `env.NEXT_PUBLIC_RETICLE_URL` | The bridge URL: a valid `RETICLE_PORT` override, otherwise project daemon discovery and `.reticle.json` |
47
48
  | `env.NEXT_PUBLIC_RETICLE_TOKEN` | The pairing token, when one exists on disk |
48
49
  | `env.NEXT_PUBLIC_RETICLE_ROOT` | `process.cwd()`, so source paths come back repository-relative |
49
50
  | `env.NEXT_PUBLIC_RETICLE_SDK_VERSION` | The version of the app's installed `@reticlehq/react` |
50
51
 
52
+ Daemon discovery reads `RETICLE_STATE_DIR` (default `~/.reticle`). Pairing tokens use `RETICLE_PAIRING_TOKEN_DIR` independently. The generated `ReticleDev` component reads `NEXT_PUBLIC_RETICLE_URL`; restart the dev server after changing these settings.
53
+
51
54
  `readPairingToken()` is also exported at runtime. It is not declared in `index.d.ts`, so TypeScript will not see it.
52
55
 
53
56
  ### `./loader`
@@ -21,10 +21,10 @@ Tauri IPC observation needs nothing on the Rust side. An `invoke('load_todos')`
21
21
 
22
22
  ```toml
23
23
  [dependencies]
24
- reticle-tauri = "3.4"
24
+ reticle-tauri = "3.6"
25
25
  ```
26
26
 
27
- Its own dependencies are `tauri = "2"` plus the per-platform capture backends: `objc2` and friends on macOS, `webview2-com` and `windows` on Windows, `webkit2gtk` and `cairo-rs` on Linux and the BSDs.
27
+ Its own dependencies are `tauri = "2.12"` (the Windows backend must use the same `webview2-com` and `windows` versions Tauri does, so it follows Tauri's minor version) plus the per-platform capture backends: `objc2` and friends on macOS, `webview2-com` and `windows` on Windows, `webkit2gtk` and `cairo-rs` on Linux and the BSDs.
28
28
 
29
29
  ## Wiring
30
30
 
@@ -31,6 +31,8 @@ export default defineConfig({
31
31
  [`@reticlehq/server`](/packages/server).
32
32
  </Warning>
33
33
 
34
+ Set `RETICLE_PORT` in the dev server or desktop build environment to use the same custom bridge port as the CLI. A valid value overrides discovery and `.reticle.json`; invalid values are ignored.
35
+
34
36
  ## Why it exists
35
37
 
36
38
  `apply: 'serve'` means it never reaches a production build. That is the guarantee that lets you leave it in the config permanently: there is no way to ship Reticle to your users by forgetting to remove a line.
@@ -59,18 +61,39 @@ Plus a dynamic import of your dev module if one exists. It looks for `src/reticl
59
61
  | `session` | `string` | Omitted, so the SDK generates one |
60
62
  | `projectId` | `string` | Derived from the package name plus the root path |
61
63
  | `token` | `string` | `readPairingToken()`, from `~/.reticle/pairing-token` |
64
+ | `present` | `boolean` | `true`. Set `false` to hide Reticle's presenter while keeping the agent connection active |
62
65
  | `sourceMapping` | `boolean` | `true`. Set `false` to skip the Babel pass |
63
66
  | `inject` | `boolean` | `true`. Set `false` to call `connect()` yourself |
64
67
  | `desktop` | `boolean` | `false`. When `true` the connect passes `allowInProduction: true`, which an Electron or Tauri renderer needs, and a `vite build` in a non-production mode (`--mode development`) is instrumented too. A production-mode build is stubbed like a web build |
65
68
  | `captureNetworkBodies` | `boolean` | `false`. Also enabled by `VITE_RETICLE_CAPTURE_BODIES=1` |
66
69
  | `onWarn` | `(message: string) => void` | `console.warn` |
67
70
 
71
+ `reticle({ present: false })` still lets the plugin create and configure the connection; it only hides Reticle's visible presenter. `reticle({ inject: false })` disables that generated connection, so your application must call `connect()` itself. In that manual call, pass the pairing token explicitly:
72
+
73
+ ```ts
74
+ reticle.connect({
75
+ token: __RETICLE_TOKEN__,
76
+ root: __RETICLE_ROOT__,
77
+ sdkVersion: __RETICLE_SDK_VERSION__,
78
+ });
79
+ ```
80
+
81
+ Add ambient declarations for these identifiers to `src/vite-env.d.ts` (or another included `.d.ts`) in a TypeScript app:
82
+
83
+ ```ts
84
+ declare const __RETICLE_TOKEN__: string;
85
+ declare const __RETICLE_ROOT__: string;
86
+ declare const __RETICLE_SDK_VERSION__: string;
87
+ ```
88
+
89
+ Vite replaces these `define` identifiers in application source at build time; the declarations let TypeScript typecheck them and do not create runtime globals. The SDK does not discover the pairing token, so pass it explicitly in a hand-written connection:
90
+
68
91
  ## Other exports
69
92
 
70
93
  | Export | Type | What it is |
71
94
  | --- | --- | --- |
72
95
  | `RETICLE_VITE_PLUGIN_NAME` | `'reticle'` | The plugin name |
73
- | `RETICLE_TOKEN_GLOBAL` | `'__RETICLE_TOKEN__'` | The global the token is stamped onto |
96
+ | `RETICLE_TOKEN_GLOBAL` | `'__RETICLE_TOKEN__'` | The Vite `define` identifier replaced with the pairing token |
74
97
  | `RETICLE_CONNECT_MODULE` | `'/@reticle-connect'` | The virtual module id |
75
98
  | `RENDER_PREHOOK_SOURCE` | `string` | The inline render prehook snippet |
76
99
  | `RETICLE_DEV_MODULE_CANDIDATES` | readonly tuple | The four dev-module paths it looks for |
package/docs/packages.mdx CHANGED
@@ -239,7 +239,7 @@ A lint rule makes the signal layer self-enforcing, which is the only way a conve
239
239
 
240
240
  ```toml
241
241
  [dependencies]
242
- reticle-tauri = "3.4"
242
+ reticle-tauri = "3.6"
243
243
  ```
244
244
 
245
245
  <Warning>
@@ -5,7 +5,7 @@ description: Install Reticle, connect your coding agent, and get a real verdict
5
5
  icon: rocket
6
6
  ---
7
7
 
8
- **Run the installer in a terminal, open your coding agent, then run `init` in your project.** Reticle is a verification layer for AI coding agents: it embeds a dev-only SDK in your running web app so an agent can prove a change works instead of guessing.
8
+ **Run the installer once, then ask your agent to verify something in your app; its first Reticle call wires the app (the same thing `reticle init` does, which you can also run yourself).** Reticle embeds a dev-only SDK in your running app and proves a browser session connected. No account needed. Add `reticle connect` later if you want a cloud dashboard.
9
9
 
10
10
  By the end of this page your agent will click a button in your app and prove what happened: the request that fired, the state that changed, and the file to open if it didn't.
11
11
 
@@ -53,17 +53,26 @@ npm install -g @reticlehq/server
53
53
  npx @reticlehq/server setup mcp
54
54
  ```
55
55
 
56
- ## Step 2. Open your coding agent, and wire the project
56
+ ## Step 2. Wire this project
57
57
 
58
- The `reticle_*` tools are already there. In your project directory:
58
+ In your project directory, before opening your coding agent:
59
59
 
60
60
  ```bash
61
- npx @reticlehq/server init
61
+ RETICLE_INSTALL_SOURCE=docs_site npx @reticlehq/server init
62
62
  ```
63
63
 
64
- Like `npm init` or `git init`, this is the per-project step: it installs the SDK, wires it into your app's entry point, starts your dev server and then opens your app to prove a session connected. It is idempotent. Run it twice and the second run reports what was already done rather than doing it again.
64
+ This installs the dev-only SDK, wires your build config, starts the dev server, and checks that a browser session connected. Nothing from your project leaves your machine. Open your coding agent once this command finishes; if it was already open during installation, restart it to load the new tools. The `RETICLE_INSTALL_SOURCE` prefix is optional and only tells us which page you installed from. It is idempotent: run it twice and the second run reports what was already done rather than doing it again.
65
65
 
66
- Step 1 is once per machine. This step is once per project.
66
+ Step 1 is once per machine. This step is once per project. **Skipping it is the most common reason Reticle "does nothing":** the agent has the tools, but there is no app on the other end for them to see.
67
+
68
+ Want a cloud dashboard too? Run `npx @reticlehq/server connect --project "My App"` instead of, or after, `init`. It does everything `init` does, then opens browser sign-in approval, links this folder to the named cloud project, and sends existing local history. Approve the short code shown in the browser and terminal; the command resumes by itself.
69
+
70
+ <Note>
71
+ **Skipped this step?** Ask your agent to verify something in the app. Its first `reticle_session`
72
+ call finds a project that has never connected, runs `init` there itself, and lists every file it
73
+ changed under `wired`. Asked about something unrelated, it offers to wire the app instead of doing
74
+ it. This works in Claude Code, Codex, Cursor and other MCP agents.
75
+ </Note>
67
76
 
68
77
  Prefer to install the skill and let the agent run setup itself? On Claude Code the plugin registers the MCP server and the skill in one step:
69
78
 
@@ -80,7 +89,7 @@ npx skills add reticlehq/reticle
80
89
 
81
90
  Then type `/reticle` and the agent runs the install from the skill.
82
91
 
83
- Useful flags, from `reticle init` itself:
92
+ Useful flags for the local-only `reticle init` path:
84
93
 
85
94
  ```
86
95
  reticle init [--dry-run] [--port N] [--no-mcp] [--no-install] [--app <dir>]
@@ -90,7 +99,7 @@ reticle init [--dry-run] [--port N] [--no-mcp] [--no-install] [--app <dir>]
90
99
  only make sense once the tools are reachable.
91
100
  ```
92
101
 
93
- Start with `--dry-run` if you want to see the plan before anything is written.
102
+ Start with `reticle init --dry-run` if you want to see the app changes before anything is written.
94
103
 
95
104
  <Tip>
96
105
  In a monorepo, `init` will find several apps and ask which one you mean. `--app packages/web`
@@ -107,9 +116,9 @@ npx @reticlehq/server doctor
107
116
 
108
117
  `doctor` diagnoses the whole setup in one command: Chromium, the daemon, the port. If something is wrong this is the page you want before you start debugging your app instead.
109
118
 
110
- ## Step 4. Start your app and open it
119
+ ## Step 4. Open your app again when you need it
111
120
 
112
- Start your dev server as usual, then:
121
+ `connect` already started the dev server and opened the app. On a later day, start your dev server as usual, then:
113
122
 
114
123
  ```bash
115
124
  npx @reticlehq/server open
@@ -216,7 +225,7 @@ Read what that actually proves:
216
225
 
217
226
  ## What "verified" can say
218
227
 
219
- <CardGroup cols={3}>
228
+ <CardGroup cols={2}>
220
229
  <Card title="yes" icon="circle-check">
221
230
  The consequence you named actually happened, and the evidence is attached.
222
231
  </Card>
@@ -226,6 +235,9 @@ Read what that actually proves:
226
235
  <Card title="unknown" icon="circle-question">
227
236
  Reticle drove the app and could not tell. **This is not a pass.** Report it as unknown.
228
237
  </Card>
238
+ <Card title="no-fault" icon="circle-minus">
239
+ Nothing was declared to prove, so nothing was checked. **Not a pass either:** add an `until`.
240
+ </Card>
229
241
  </CardGroup>
230
242
 
231
243
  That third state is the one that matters. Most tools have two outcomes and quietly file "I couldn't tell" under "fine". A verification layer that cannot admit uncertainty is just a very confident random number generator.
package/docs/telemetry.md CHANGED
@@ -48,7 +48,7 @@ Eighteen kinds of events, each a single small JSON object. This is the whole lis
48
48
 
49
49
  **Parameter and flag NAMES are collected; their VALUES are not.** We record that `reticle_act` was called with `ref` and `action`, and that you ran `reticle serve --headed --port`. We do not record what you set them to. This distinction is the whole safety property, and it is absolute for CLI flags: `--http-token` holds a secret, `--drive` holds a URL, `--storage-state` holds a file path, so no flag value is ever sent. For tool parameters there is one narrow exception: a short, explicit allowlist of parameters whose values are enums _we_ defined (`action: "click"`), listed in [`argument-shape.ts`](https://github.com/reticlehq/reticle/blob/main/server/src/telemetry/argument-shape.ts). A value outside that allowlist reports as `other`, so a future schema change cannot quietly start forwarding free text. `reticle_act`'s `args` (the text being typed into your app, which on a login form is a password) is **never** in that allowlist.
50
50
 
51
- `daemon_stopped` carries: how long the session ran, how many tool calls and of which tools, how long each tool took (total and worst case), how many failed, how many verifications ran, browser/lease connection attempts with their failure causes, and which MCP clients connected (`claude-code`, `cursor`).
51
+ `daemon_stopped` carries: how long the session ran, how many tool calls and of which tools, how long each tool took (total and worst case), how many failed, how many verifications ran, browser/lease connection attempts with their failure causes, and which MCP clients connected (`claude-code`, `cursor`). It also carries how the in-page HUD was used: presses per control (`hudControls`, by the control's name from a closed list Reticle defines, a toggle as `name:on` / `name:off`), how long the HUD sat as a bubble, collapsed or open and on which page (`hudViewMs`, `hudPanelMs`), which rail slides were shown (`hudSlides`), and the order of those presses and views, cut at 60 (`hudJourney`). Control names, never anything typed or shown on the page.
52
52
 
53
53
  It also carries a snapshot of the **machine's** state (our own process's memory, free and total system RAM, load average and CPU count), taken at shutdown and again on any crash. This is what separates "your machine ran out of memory" from "Reticle has a bug", which otherwise produce identical-looking failures. No hostname, no username, no paths, no process list.
54
54
 
@@ -59,7 +59,7 @@ Real response:
59
59
 
60
60
  ## Actions
61
61
 
62
- `click` · `dblclick` · `hover` · `focus` · `blur` · `fill` · `type` · `clear` · `select` · `check` · `uncheck` · `submit` · `press` · `upload` · `scrollIntoView` · `drag` · `webmcp`
62
+ `click` · `dblclick` · `hover` · `focus` · `blur` · `fill` · `type` · `clear` · `select` · `check` · `uncheck` · `submit` · `press` · `upload` · `scrollIntoView` · `drag`
63
63
 
64
64
  | Action | Arguments |
65
65
  | ---------------- | --------------------------------------------------------------- |
@@ -10,15 +10,15 @@ icon: comments
10
10
 
11
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
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` |
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: `idleEndMs`, the idle-end window, or `hud`: `hidden`, `shown`, `removed` (until reload), or a corner (`top-left`, `top-right`, `bottom-left`, `bottom-right`) when the HUD covers a control you must test |
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
22
 
23
23
  ```json
24
24
  { "action": "yield", "mode": "waiting" }
package/docs/usage.md CHANGED
@@ -415,11 +415,10 @@ A `state` assertion is graded as a **consequence** (a wrong element or stale ren
415
415
  | `select` | `{ value }` | `<select>` option |
416
416
  | `check` / `uncheck` | n/a | checkbox/radio |
417
417
  | `submit` | n/a | submits the element's `<form>` |
418
- | `press` | `{ key, modifiers? }` | keydown/up (default `Enter`); `modifiers`: an array of `Meta` / `Control` / `Shift` / `Alt` for Cmd+K-style shortcuts |
418
+ | `press` | `{ key, modifiers?, holdMs?, keys?, code? }` | keydown/up (default `Enter`); `modifiers`: an array of `Meta` / `Control` / `Shift` / `Alt` for Cmd+K-style shortcuts. With a `ref` the key is dispatched AT that element; with NO ref it is a document key (Escape, Tab, a shortcut) and goes through the real keyboard, so it can actually move focus. `holdMs` keeps the key DOWN for that long (hold-to-confirm, hold-to-reveal). `keys` holds several keys together, pressed in order and released in reverse, and `code` names the physical key: both stay on the in-page dispatcher, which is the only path that can express them |
419
419
  | `scrollIntoView` | n/a | |
420
420
  | `upload` | `{ name, content?, type? }` | sets a file on `<input type=file>` |
421
421
  | `drag` | `{ toRef }` | pointer-based drag (dnd-kit / rbd) + HTML5 DnD |
422
- | `webmcp` | `{ tool, params }` | calls a `navigator.modelContext` tool if the site exposes one |
423
422
 
424
423
  ---
425
424
 
@@ -817,7 +816,7 @@ A session starts on the agent's first activity and must reliably end even when t
817
816
  - **Agent kills the Reticle server process** (so no push can arrive) → the SDK self-ends the session after it can't reach the bridge for `BRIDGE_LOST_MS` (~15s), showing "lost connection to Reticle."
818
817
  - **Slow-but-alive agent** → if it goes quiet long enough to auto-end and then acts again, the session **revives** automatically (an explicit `reticle_session {action:"end"}` stays terminal).
819
818
 
820
- Tune the idle window with `reticle_session({ action: "tune", idleEndMs })`; it updates both the browser timer and the server reaper. The human keeps the panel (with Copy/Export of the run) after any end.
819
+ Tune the idle window with `reticle_session({ action: "tune", idleEndMs })`; it updates both the browser timer and the server reaper. When the HUD covers a control you have to test, `reticle_session({ action: "tune", hud: "top-left" })` moves it (any corner), and `hud: "hidden"`, `"shown"` or `"removed"` (until the page reloads) take it out of the way; the call fails rather than pretending if the page could not apply it. The human keeps the panel (with Copy/Export of the run) after any end.
821
820
 
822
821
  ### `reticle_session {action:"narrate"}`: show the agent's intent
823
822
 
@@ -1054,6 +1053,9 @@ When `inputMode` is `"synthetic"` and the target has hover/enter handlers, the r
1054
1053
  | `provider-declined` / `provider-error` | the CDP provider declined or threw (the latter also sets `warning`) |
1055
1054
  | `not-a-pointer-action` | `fill`/`type`/etc. are always synthetic by design |
1056
1055
  | `synthetic-click-preferred` | a `click`/`dblclick` ran the occlusion-honest synthetic path by default; pass `args:{ native:true }` to force a trusted native click |
1056
+ | `synthetic-element-press-preferred` | the `press` named a `ref`/`target`, so it stayed synthetic on purpose: dispatching AT that element reaches it exactly, while a real keyboard sends the key to whatever holds focus. A `press` with NO ref is a document key (Escape, Tab, a modifier shortcut) and does run through the real keyboard when one is configured |
1057
+ | `synthetic-multi-key-press-preferred` | the `press` named `keys`: several keys held down **together**, pressed in order and released in reverse. Only the in-page dispatcher implements that sequence; a real keyboard chord cannot express it |
1058
+ | `synthetic-key-code-press-preferred` | the `press` named an explicit `code`, which the real driver cannot send: it presses by KEY name, so `{ text: "z", code: "KeyY" }` would strike a different key than the one asked for |
1057
1059
 
1058
1060
  (No `inputModeReason` is set when real input simply isn't configured; synthetic is the expected default there.)
1059
1061
 
@@ -15,7 +15,7 @@ Everything lands in `.reticle/` in your project, and it is yours. Three kinds of
15
15
  | --- | --- | --- |
16
16
  | **runs** | a verdict and its evidence | what was claimed, whether it held, the request or state change that decided it, and the `file:line` of the element driven |
17
17
  | **flows** | a journey you drove, saved so it can be replayed | the steps, the anchors they resolve by, and the values that were typed |
18
- | **memory** | what this project has learned across sessions | intents you declared, envelopes of normal behaviour, notes about anchors that drift |
18
+ | **memory** | what this project has learned across sessions | intents you declared, envelopes of normal behaviour, notes about anchors that drift, the coverage ledger (`coverage.json`), the notes people pinned in the HUD (`notes.json`), and the user's latest request as the agent relayed it (`request.json`, local only) |
19
19
 
20
20
  `.reticle/` splits into a part meant for git and a part meant to stay local. Flows are the part worth committing: a saved flow is a regression test. Evidence is the part that is not.
21
21
 
@@ -27,7 +27,7 @@ Everything lands in `.reticle/` in your project, and it is yours. Three kinds of
27
27
 
28
28
  So: **drive staging.** Not because the risk is large, but because it is real and avoiding it is free.
29
29
 
30
- Network bodies are **not** captured by default. Page content that reaches a verdict is the element text and attributes the assertion needed, not a copy of the DOM.
30
+ Network bodies are **not** captured by default. When you turn body capture on (`captureNetworkBodies: true`, or `VITE_RETICLE_CAPTURE_BODIES=1`), redaction runs **before each body is kept**. Built-in rules mask keys such as `password`, `apiKey` and `authorization`, selected token keys, and high-confidence secret shapes such as JWTs and `sk_live_…` keys. Other credential values can remain under names or in formats those rules do not recognize; add app-specific field names with `redact.keys` and use staging. Page content that reaches a verdict is the element text and attributes the assertion needed, not a copy of the DOM.
31
31
 
32
32
  ## What leaves, only if you ask
33
33
 
@@ -39,6 +39,14 @@ Once linked, you choose what syncs:
39
39
  npx @reticlehq/server config --runs on|off --flows on|off --memory on|off
40
40
  ```
41
41
 
42
+ `--memory` covers the coverage ledger and the HUD notes as well, and the notes are the words people typed. The user's request (`request.json`, the prompt the agent relayed, redacted) goes to the platform with the runs from a linked project, so the dashboard can show what each run was for; `"shareRequests": false` in `.reticle.json` keeps it on the machine. An unlinked project sends it nowhere, and it is kept out of git either way.
43
+
44
+ The Harness runs on the platform, so the platform sees what it drives: each step's result goes there so it can choose the next one. A secret field is sent by name only; its value is typed in on your machine.
45
+
46
+ **Your apps, for the platform's chat.** While a project is linked, the daemon tells the platform every ten seconds, with or without an app open, which apps on this machine have Reticle connected, so the chat can list them and you can pick one instead of typing an address. For each app it sends: a key made from a hash of this machine and the project's folder (the folder path itself never leaves), the project's name (its package name, else its folder's name), the address the app is open at with Reticle's own query parameters removed, the page title, what it is built with (`react`, `vite`, `electron`, …), this machine's name, the Reticle version, and what this daemon can do for the platform. The platform keeps the last report for each app until the project is deleted. Its answer can ask this machine to open one of those apps again, or show you a short notice (for example, to update Reticle), which appears in the daemon's log and on the HUD.
47
+
48
+ **Drives asked for from the platform's chat.** When someone in your workspace asks the chat to drive one of your apps, the daemon drives it here, on your machine: in the tab you have open, or in a browser of its own, headless or in a window, as the chat asked. It only opens addresses on this machine or apps already open here. On a recent platform, the platform decides each step: it sends Reticle tool calls from a fixed list (reading the page, acting on it, asserting, recording and replaying flows), the daemon runs them in that one tab, and sends back what each returned, which includes what the page showed. On an older platform, the daemon drives and sends back each step's result and how the drive ended. Either way the platform keeps the drive as a check you can open in Runs. Unless the request said not to record, the daemon also sends a picture of the tab it is driving, a JPEG about once a second, so the chat can show the drive live and replay it afterwards. Pictures are kept with that check (at most a few minutes' worth per drive) and deleted with the project. A tab the daemon opened, headless or in a window, can be pictured, with Reticle's own panel left out; so can the window `reticle drive` opened, which is pictured as you see it, panel included. A tab in your own browser sends steps only. Unlinking the project stops all of it.
49
+
42
50
  ## Telemetry, which is separate from all of the above
43
51
 
44
52
  The CLI sends anonymous usage events: event names and a random installation id. No code, no page content, no URLs from your app. It is how we know which parts of the product are reached at all.
@@ -49,7 +57,9 @@ DO_NOT_TRACK=1 # the convention, honoured
49
57
  npx @reticlehq/server telemetry disable # this machine, permanently
50
58
  ```
51
59
 
52
- Feedback is the only free text that ever leaves, it is never collected passively, and `RETICLE_FEEDBACK=0` disables it.
60
+ Telemetry carries no free text. Free text leaves in three ways, each one something you chose: a feedback report (never collected passively; `RETICLE_FEEDBACK=0` disables it), HUD notes on a linked project with `--memory on`, and the user's request from a linked project unless `"shareRequests": false`.
61
+
62
+ The daemon also fetches a small public file, `https://reticle.sh/hud/notices.v1.json`, for the notices in the HUD's rail. The request carries nothing about you or your project. `RETICLE_TELEMETRY=0` or `DO_NOT_TRACK=1` stops it, and `RETICLE_HUD_NOTICES_URL` points it elsewhere.
53
63
 
54
64
  ## What `init` writes to your project
55
65
 
@@ -31,7 +31,9 @@ Reticle sits next to several familiar categories, and it works alongside each of
31
31
 
32
32
  **Monitoring.** Reticle runs against environments you control (a dev server, a staging or preview deployment) and replays saved flows in CI. The SDK refuses to connect in a production build, so it complements an APM or error tracker rather than watching live traffic.
33
33
 
34
- **Your agent.** Reticle has no model of its own for the verify loop. It gives the agent you already use a way to see the running app. Your agent, your model, your keys. (`explore` can drive a journey for you with a model inside the daemon; see [Autodrive](/autodrive).)
34
+ **Not an accessibility auditor.** `reticle_look { action: "page" }` addresses elements by role and name, which is not the same as auditing contrast, focus order, or screen reader behaviour. Use a dedicated accessibility tool for that.
35
+
36
+ **Your agent.** Reticle has no model of its own for the verify loop. It gives the agent you already use a way to see the running app. Your agent, your model, your keys. (On a linked project, `explore` has the Reticle Harness drive a journey for you on the Reticle platform; see [Autodrive](/autodrive).)
35
37
 
36
38
  **The verdict.** A verdict of `unknown` means Reticle drove the app and could not tell. It is deliberately not rounded up to a pass.
37
39
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reticlehq/server",
3
- "version": "3.4.0",
3
+ "version": "3.6.0",
4
4
  "description": "Reticle CLI, bridge and MCP server: a coding agent drives your running web app from the inside and gets a verdict with evidence, for change verification, access control, accessibility, performance and SEO checks.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -19,15 +19,15 @@
19
19
  }
20
20
  },
21
21
  "dependencies": {
22
- "@modelcontextprotocol/sdk": "^1.30.1",
22
+ "@modelcontextprotocol/sdk": "^1.31.0",
23
23
  "ws": "^8.21.3",
24
24
  "zod": "^3.24.1",
25
25
  "zod-to-json-schema": "^3.24.0",
26
- "@reticlehq/browser": "3.4.0",
27
- "@reticlehq/init": "3.4.0",
28
- "@reticlehq/engine": "3.4.0",
26
+ "@reticlehq/browser": "3.6.0",
27
+ "@reticlehq/core": "3.6.0",
28
+ "@reticlehq/engine": "3.6.0",
29
29
  "open-verification": "1.0.0",
30
- "@reticlehq/core": "3.4.0"
30
+ "@reticlehq/init": "3.6.0"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@types/pngjs": "^6.0.5",
@@ -64,13 +64,9 @@
64
64
  "cli"
65
65
  ],
66
66
  "reticle": {
67
- "changelog": "Reticle writes and tightens your regression flows for you: every drive is recorded automatically and replays with no model in the loop. The agent now sees nine tools instead of seventeen, `init` stops at a connected app and proving a flow is a separate first run, and Windows is supported. Upgrading from 2.x: see MIGRATION.md.",
67
+ "changelog": "Drive your localhost app from the Reticle platform's chat: the daemon of a linked project drives it on your machine, the chat shows it live and keeps it as a check with a replay. The Harness now runs only on the platform, on every plan, and plans, replays and learns each app. A page on SDK 3.1-3.4 is no longer version-skewed, a pressed key sends its keyCode, and a screenshot never carries another tab's pixels. Upgrading from 3.5: see MIGRATION.md.",
68
68
  "breakingChanges": [
69
- "The default MCP surface is the merged nine. reticle_snapshot/query/inspect/state -> reticle_look { action }, reticle_network/console -> reticle_observe { action }, reticle_sessions/feedback -> reticle_session { action }, reticle_wait_for -> reticle_assert { action: \"wait\" }, reticle_act_sequence -> reticle_act { steps }. Old names redirect when CALLED, but an allowedTools allowlist or an MCP permission rule naming one refuses first -- update those by hand.",
70
- "Twelve tools are unreachable on the default surface and have NO redirect: reticle_capabilities, reticle_clock, reticle_context, reticle_flow_replay, reticle_flow_save, reticle_intent, reticle_network_mock, reticle_record, reticle_run, reticle_screenshot, reticle_storage, reticle_visual_diff. The default surface ships no reticle_run hatch. Start the daemon with RETICLE_ADVERTISE_ALL_TOOLS=1 (read once at startup) and call them by name. Saved flows still replay via reticle_verify { action: \"flows\" }.",
71
- "`reticle init` no longer drives: it ends at a connected session. --flow, --no-drive and --drive-model now exit non-zero, each naming its replacement. Prove a flow with reticle_verify { action: \"explore\", persona: \"<who does what>\" }, or npx @reticlehq/server verify <url> --explore --persona \"...\". init's exit code now means \"nothing connected\" rather than \"no verdict\". --files-only is unchanged.",
72
- "@reticlehq/server now requires Node >=20.11 (was >=20.0.0).",
73
- "@reticlehq/server, @reticlehq/init and @reticlehq/test declare license FSL-1.1-ALv2 instead of \"SEE LICENSE IN LICENSE\". The terms are identical; add the SPDX id to a licence allowlist."
69
+ "reticle_verify { action: \"explore\" } and reticle verify --explore no longer drive on a model key of your own. The Harness decides on the Reticle platform and needs a linked project (npx @reticlehq/server connect); every plan includes Harness credits. ANTHROPIC_API_KEY, OPENAI_API_KEY and JEV_API_KEY are no longer read for driving, RETICLE_HARNESS_DRIVER and RETICLE_HARNESS_MODEL are ignored, and the explore tool's `driver` argument is removed. A secret field's value comes from RETICLE_SECRET_<FIELD> on your machine."
74
70
  ]
75
71
  },
76
72
  "publishConfig": {
@@ -1,50 +0,0 @@
1
- /**
2
- * The model binding: the one file in the harness that knows there is a network.
3
- *
4
- * Everything about the loop lives in harness.ts against the `ModelDriver` interface, so this file is
5
- * a translation layer and nothing else. That split is not tidiness — it is what lets the loop be
6
- * tested against a scripted model with no API key, on every run of the unit gate.
7
- *
8
- * It speaks the Messages API over `fetch` rather than through a vendor SDK. The loop is ours (the
9
- * harness owns the step budget and has to record every call even when a run is cut short), so an SDK
10
- * would contribute one HTTP POST and a dependency — and this package's dependency list is short on
11
- * purpose.
12
- */
13
- import type { ModelDriver } from './harness.js';
14
- /**
15
- * The default driver model.
16
- *
17
- * Deliberately not the largest model available. The harness is not reasoning about business logic; it
18
- * is exploring an interface and stating consequences, and the verdict is produced by the engine
19
- * reading what it drove. If finding defects required a frontier model HERE, the engine would not be
20
- * doing its job — so the model tier is also a standing test of the design.
21
- */
22
- export declare const DEFAULT_HARNESS_MODEL = "claude-sonnet-5";
23
- export declare const DEFAULT_HARNESS_BASE_URL = "https://api.anthropic.com";
24
- /** The one call this file makes. Injected so a test can drive the translation with no network. */
25
- export type HarnessFetch = (url: string, init: {
26
- method: string;
27
- headers: Record<string, string>;
28
- body: string;
29
- }) => Promise<{
30
- ok: boolean;
31
- status: number;
32
- text(): Promise<string>;
33
- }>;
34
- export interface HarnessDriverOptions {
35
- apiKey: string;
36
- model?: string;
37
- baseUrl?: string;
38
- /** Injected for tests. Defaults to the platform `fetch`. */
39
- fetch?: HarnessFetch;
40
- }
41
- /**
42
- * Read the harness's configuration out of the environment.
43
- *
44
- * Returns `undefined` when there is no key, which is the ONLY thing that decides whether the harness
45
- * is available. Stated as a read rather than a throw because "you have not configured this" is a
46
- * routine answer a caller offers a way out of, not a failure.
47
- */
48
- export declare function harnessOptionsFromEnv(env: Record<string, string | undefined>): HarnessDriverOptions | undefined;
49
- /** Build a driver backed by the Messages API. */
50
- export declare function harnessDriver(options: HarnessDriverOptions): ModelDriver;