@reticlehq/server 3.2.0 → 3.4.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 (437) hide show
  1. package/LICENSE-ENTERPRISE +1 -1
  2. package/README.md +3 -3
  3. package/SKILL.md +23 -22
  4. package/dist/chromium-launch-options.d.ts +4 -3
  5. package/dist/chromium-launch-options.js +6 -2
  6. package/dist/command/cli/adhoc-suite.d.ts +41 -0
  7. package/dist/command/cli/adhoc-suite.js +159 -0
  8. package/dist/command/cli/adhoc-verdict.d.ts +58 -2
  9. package/dist/command/cli/adhoc-verdict.js +108 -13
  10. package/dist/command/cli/answers/gate-hook-message.d.ts +6 -0
  11. package/dist/command/cli/answers/gate-hook-message.js +6 -0
  12. package/dist/command/cli/auth/cloud-keystore.d.ts +0 -2
  13. package/dist/command/cli/auth/cloud-keystore.js +0 -3
  14. package/dist/command/cli/auth/cloud-session.d.ts +4 -0
  15. package/dist/command/cli/auth/cloud-session.js +2 -0
  16. package/dist/command/cli/cli-doctor.js +30 -8
  17. package/dist/command/cli/cli-flow-commands.d.ts +3 -6
  18. package/dist/command/cli/cli-flow-commands.js +67 -4
  19. package/dist/command/cli/cli-parse-grammar.d.ts +7 -0
  20. package/dist/command/cli/cli-parse-grammar.js +7 -0
  21. package/dist/command/cli/cli-parse-verify.d.ts +2 -5
  22. package/dist/command/cli/cli-parse-verify.js +86 -13
  23. package/dist/command/cli/cli-parse.d.ts +14 -1
  24. package/dist/command/cli/cli-parse.js +54 -8
  25. package/dist/command/cli/cli-update-commands.js +8 -1
  26. package/dist/command/cli/cli-verify.d.ts +80 -0
  27. package/dist/command/cli/cli-verify.js +181 -26
  28. package/dist/command/cli/cloud-cli.js +5 -2
  29. package/dist/command/cli/cloud-kit.d.ts +0 -2
  30. package/dist/command/cli/cloud-kit.js +3 -5
  31. package/dist/command/cli/cloud-login.js +21 -3
  32. package/dist/command/cli/demo/demo-page.js +6 -3
  33. package/dist/command/cli/doctor/browser/chromium-hint.d.ts +5 -0
  34. package/dist/command/cli/doctor/browser/chromium-hint.js +5 -0
  35. package/dist/command/cli/doctor/doctor-sessions-line.d.ts +2 -1
  36. package/dist/command/cli/launch/cli-launch.d.ts +9 -29
  37. package/dist/command/cli/launch/cli-launch.js +27 -49
  38. package/dist/command/cli/launch/sdk-version-match.d.ts +84 -0
  39. package/dist/command/cli/launch/sdk-version-match.js +206 -0
  40. package/dist/command/cli/lifecycle/daemon-lifecycle.js +2 -16
  41. package/dist/command/cli/ports/resolve/cli-port.d.ts +38 -0
  42. package/dist/command/cli/ports/resolve/cli-port.js +169 -15
  43. package/dist/command/cli/report-command.d.ts +16 -0
  44. package/dist/command/cli/report-command.js +97 -0
  45. package/dist/command/cli/setup-mcp-cli.js +13 -13
  46. package/dist/command/cli/tutorial.d.ts +2 -2
  47. package/dist/command/cli/tutorial.js +21 -7
  48. package/dist/command/cli.js +67 -10
  49. package/dist/command/daemon/binding/daemon-status-probe.d.ts +44 -2
  50. package/dist/command/daemon/binding/daemon-status-probe.js +79 -6
  51. package/dist/command/daemon/binding/port-presence.d.ts +1 -1
  52. package/dist/command/daemon/daemon-resolve.d.ts +9 -0
  53. package/dist/command/daemon/daemon-resolve.js +1 -1
  54. package/dist/command/daemon/idle-shutdown.d.ts +2 -1
  55. package/dist/command/daemon/lifetime/daemon-usefulness.d.ts +7 -1
  56. package/dist/command/daemon/lifetime/daemon-usefulness.js +30 -7
  57. package/dist/command/dev/stale-issue-guard.d.ts +3 -4
  58. package/dist/command/dev/stale-issue-guard.js +8 -8
  59. package/dist/command/setup/bringup/connect-lease.d.ts +17 -0
  60. package/dist/command/setup/bringup/connect-lease.js +38 -0
  61. package/dist/command/setup/bringup/dev-server-files.d.ts +68 -0
  62. package/dist/command/setup/bringup/dev-server-files.js +131 -0
  63. package/dist/command/setup/bringup/dev-server-log-cap.d.ts +35 -0
  64. package/dist/command/setup/bringup/dev-server-log-cap.js +121 -0
  65. package/dist/command/setup/bringup/ensure-daemon.d.ts +65 -4
  66. package/dist/command/setup/bringup/ensure-daemon.js +135 -16
  67. package/dist/command/setup/bringup/static-page-server.d.ts +35 -0
  68. package/dist/command/setup/bringup/static-page-server.js +151 -0
  69. package/dist/command/setup/desktop-shape.d.ts +4 -0
  70. package/dist/command/setup/desktop-shape.js +18 -2
  71. package/dist/command/setup/init/init-host.js +8 -0
  72. package/dist/command/setup/init/init-port.d.ts +15 -0
  73. package/dist/command/setup/init/init-port.js +44 -0
  74. package/dist/command/setup/init/init-runtime.d.ts +1 -1
  75. package/dist/command/setup/init/init-runtime.js +39 -2
  76. package/dist/command/setup/node-effects.d.ts +27 -14
  77. package/dist/command/setup/node-effects.js +80 -44
  78. package/dist/command/setup/probe/loopback-probe-urls.d.ts +7 -0
  79. package/dist/command/setup/probe/loopback-probe-urls.js +40 -0
  80. package/dist/command/setup/probe/page-probe.d.ts +13 -2
  81. package/dist/command/setup/probe/page-probe.js +18 -3
  82. package/dist/command/setup/run-setup.d.ts +26 -1
  83. package/dist/command/setup/run-setup.js +96 -13
  84. package/dist/command/setup/session-pick.d.ts +13 -0
  85. package/dist/command/setup/session-pick.js +20 -0
  86. package/dist/command/setup/setup-command.d.ts +2 -14
  87. package/dist/command/setup/setup-command.js +105 -31
  88. package/dist/command/setup/setup-mcp.js +3 -3
  89. package/dist/command/setup/terminal/wait-progress.d.ts +8 -0
  90. package/dist/command/setup/terminal/wait-progress.js +17 -0
  91. package/dist/features/crawl/crawl-empty.js +1 -1
  92. package/dist/features/crawl/crawl-tools.d.ts +6 -0
  93. package/dist/features/crawl/crawl-tools.js +57 -0
  94. package/dist/features/crawl/crawl.d.ts +2 -0
  95. package/dist/features/crawl/crawl.js +171 -156
  96. package/dist/features/exhaust/app-coverage.d.ts +33 -0
  97. package/dist/features/exhaust/app-coverage.js +31 -0
  98. package/dist/features/exhaust/code-coverage.d.ts +47 -0
  99. package/dist/features/exhaust/code-coverage.js +77 -0
  100. package/dist/features/exhaust/exhaust-run.d.ts +33 -0
  101. package/dist/features/exhaust/exhaust-run.js +82 -0
  102. package/dist/features/exhaust/explorer.d.ts +103 -0
  103. package/dist/features/exhaust/explorer.js +195 -0
  104. package/dist/features/exhaust/failure-branches.d.ts +33 -0
  105. package/dist/features/exhaust/failure-branches.js +92 -0
  106. package/dist/features/exhaust/ledger.d.ts +202 -0
  107. package/dist/features/exhaust/ledger.js +252 -0
  108. package/dist/features/exhaust/session-fold.d.ts +31 -0
  109. package/dist/features/exhaust/session-fold.js +79 -0
  110. package/dist/features/exhaust/session-port.d.ts +36 -0
  111. package/dist/features/exhaust/session-port.js +102 -0
  112. package/dist/features/harness/drive-report.d.ts +0 -9
  113. package/dist/features/harness/drive-report.js +18 -0
  114. package/dist/features/harness/driver.js +4 -7
  115. package/dist/features/harness/fill-values.d.ts +6 -0
  116. package/dist/features/harness/fill-values.js +3 -0
  117. package/dist/features/harness/jev-driver.js +36 -22
  118. package/dist/features/harness/openai-driver.js +4 -7
  119. package/dist/features/harness/platform-config.d.ts +10 -0
  120. package/dist/features/harness/platform-config.js +13 -6
  121. package/dist/index.d.ts +10 -1
  122. package/dist/index.js +78 -104
  123. package/dist/judgement/capsule/capsule-store.d.ts +31 -2
  124. package/dist/judgement/capsule/capsule-store.js +58 -6
  125. package/dist/judgement/capsule/capsule.js +5 -0
  126. package/dist/judgement/capsule/causal-summary.d.ts +13 -1
  127. package/dist/judgement/capsule/causal-summary.js +7 -0
  128. package/dist/judgement/domain/domain-model.js +40 -9
  129. package/dist/judgement/oracles/self-instrument.js +4 -2
  130. package/dist/judgement/outcome/assertion-integrity.d.ts +3 -3
  131. package/dist/judgement/runs/artifact/gap-report.d.ts +17 -0
  132. package/dist/judgement/runs/artifact/gap-report.js +46 -0
  133. package/dist/judgement/runs/artifact/gap-summary.d.ts +58 -0
  134. package/dist/judgement/runs/artifact/gap-summary.js +85 -0
  135. package/dist/judgement/runs/artifact/render-report.js +4 -1
  136. package/dist/judgement/runs/artifact/replay-mapping.d.ts +2 -2
  137. package/dist/judgement/runs/artifact/replay-mapping.js +44 -9
  138. package/dist/judgement/runs/artifact/to-artifact.d.ts +7 -2
  139. package/dist/judgement/runs/artifact/to-artifact.js +1 -1
  140. package/dist/judgement/runs/context-tools.js +21 -3
  141. package/dist/judgement/runs/drive-run.js +7 -2
  142. package/dist/judgement/runs/verification-sync.d.ts +3 -1
  143. package/dist/judgement/runs/verification-sync.js +1 -1
  144. package/dist/language/flows/annotate-notes/annotate.d.ts +0 -15
  145. package/dist/language/flows/annotate-notes/annotate.js +66 -18
  146. package/dist/language/flows/change/affected.d.ts +9 -0
  147. package/dist/language/flows/change/affected.js +35 -0
  148. package/dist/language/flows/change/gate.d.ts +20 -0
  149. package/dist/language/flows/change/gate.js +12 -1
  150. package/dist/language/flows/flow-anchor.d.ts +12 -0
  151. package/dist/language/flows/flow-anchor.js +20 -0
  152. package/dist/language/flows/flow-author.d.ts +7 -0
  153. package/dist/language/flows/flow-author.js +19 -0
  154. package/dist/language/flows/flow-expect-grammar.d.ts +2 -2
  155. package/dist/language/flows/flow-expect-grammar.js +92 -11
  156. package/dist/language/flows/flow-intent.js +1 -1
  157. package/dist/language/flows/flow-journey.d.ts +54 -0
  158. package/dist/language/flows/flow-journey.js +119 -0
  159. package/dist/language/flows/flow-learning.d.ts +3 -0
  160. package/dist/language/flows/flow-learning.js +39 -8
  161. package/dist/language/flows/flow-replay-run.d.ts +33 -12
  162. package/dist/language/flows/flow-replay-run.js +131 -52
  163. package/dist/language/flows/flow-replay-types.d.ts +9 -0
  164. package/dist/language/flows/flow-replay.d.ts +27 -12
  165. package/dist/language/flows/flow-replay.js +127 -111
  166. package/dist/language/flows/flow-result.d.ts +2 -0
  167. package/dist/language/flows/flow-result.js +25 -0
  168. package/dist/language/flows/flow-step-runners.d.ts +26 -10
  169. package/dist/language/flows/flow-step-runners.js +20 -4
  170. package/dist/language/flows/flow-success.d.ts +21 -6
  171. package/dist/language/flows/flow-success.js +50 -138
  172. package/dist/language/flows/flow-tools.js +17 -5
  173. package/dist/language/flows/flows.d.ts +18 -5
  174. package/dist/language/flows/flows.js +101 -16
  175. package/dist/language/flows/heal.d.ts +9 -1
  176. package/dist/language/flows/heal.js +24 -2
  177. package/dist/language/flows/learned-sources.d.ts +21 -0
  178. package/dist/language/flows/learned-sources.js +84 -0
  179. package/dist/language/flows/recording/recording-backtrack.d.ts +0 -7
  180. package/dist/language/flows/recording/recording-backtrack.js +1 -1
  181. package/dist/language/flows/recording/replay-halt.d.ts +2 -1
  182. package/dist/language/flows/recording/replay-halt.js +3 -1
  183. package/dist/language/flows/recording/tape/recordings.d.ts +31 -2
  184. package/dist/language/flows/recording/tape/recordings.js +55 -1
  185. package/dist/language/flows/replay.d.ts +19 -0
  186. package/dist/language/flows/replay.js +53 -13
  187. package/dist/language/flows/stores/annotation-store.d.ts +5 -5
  188. package/dist/language/flows/stores/assertion-tiers-store.js +2 -3
  189. package/dist/language/flows/stores/flake-store.js +2 -3
  190. package/dist/language/flows/suite/coverage.d.ts +1 -1
  191. package/dist/language/flows/suite/parallel-suite.d.ts +2 -1
  192. package/dist/language/flows/verify-change-tools.js +19 -2
  193. package/dist/launch-chromium.d.ts +80 -0
  194. package/dist/launch-chromium.js +218 -0
  195. package/dist/memory/cloud/cloud-config.d.ts +11 -2
  196. package/dist/memory/cloud/cloud-config.js +47 -7
  197. package/dist/memory/cloud/cloud-sync.d.ts +4 -3
  198. package/dist/memory/cloud/cloud-sync.js +7 -10
  199. package/dist/memory/cloud/harness-config.d.ts +2 -0
  200. package/dist/memory/cloud/harness-offer.js +5 -6
  201. package/dist/memory/cloud/harness-switch.js +5 -6
  202. package/dist/memory/cloud/sync-cycle.d.ts +78 -1
  203. package/dist/memory/cloud/sync-cycle.js +321 -53
  204. package/dist/memory/cloud/sync-daemon.d.ts +13 -0
  205. package/dist/memory/cloud/sync-daemon.js +45 -20
  206. package/dist/memory/cloud/sync-disk.js +27 -8
  207. package/dist/memory/impact/impact-store.js +6 -0
  208. package/dist/memory/intent/inline-intent.js +8 -3
  209. package/dist/memory/intent/intent-shard-store.d.ts +33 -47
  210. package/dist/memory/intent/intent-shard-store.js +252 -140
  211. package/dist/memory/intent/intent-shard.d.ts +0 -23
  212. package/dist/memory/intent/intent-shard.js +1 -11
  213. package/dist/memory/intent/intent-store.d.ts +13 -8
  214. package/dist/memory/intent/intent-store.js +46 -90
  215. package/dist/memory/intent/intent-tools.js +34 -23
  216. package/dist/memory/journal/ambient-store.js +2 -3
  217. package/dist/memory/journal/deviation-report.js +4 -1
  218. package/dist/memory/journal/deviation-service.js +10 -2
  219. package/dist/memory/journal/drive-flow.d.ts +19 -14
  220. package/dist/memory/journal/drive-flow.js +65 -48
  221. package/dist/memory/journal/envelope-store.js +2 -3
  222. package/dist/memory/journal/journal-recorder.d.ts +21 -0
  223. package/dist/memory/journal/on-disk/retain-policy.d.ts +34 -0
  224. package/dist/memory/journal/on-disk/retain-policy.js +44 -0
  225. package/dist/memory/journal/on-disk/retention.d.ts +14 -10
  226. package/dist/memory/journal/on-disk/retention.js +13 -12
  227. package/dist/memory/journal/on-disk/startup-maintenance.d.ts +42 -0
  228. package/dist/memory/journal/on-disk/startup-maintenance.js +14 -0
  229. package/dist/memory/journal/on-disk/workspace-gitignore.d.ts +0 -11
  230. package/dist/memory/journal/on-disk/workspace-gitignore.js +6 -45
  231. package/dist/memory/journal/on-disk/workspace-tiers.d.ts +52 -0
  232. package/dist/memory/journal/on-disk/workspace-tiers.js +90 -0
  233. package/dist/memory/journal/route-template.d.ts +22 -0
  234. package/dist/memory/journal/route-template.js +44 -0
  235. package/dist/memory/journal/session-end.d.ts +13 -2
  236. package/dist/memory/journal/session-end.js +88 -18
  237. package/dist/memory/journal/session-journal.d.ts +8 -1
  238. package/dist/memory/journal/session-journal.js +10 -0
  239. package/dist/memory/project/baselines.d.ts +1 -1
  240. package/dist/memory/project/dir/reticle-dir.d.ts +3 -1
  241. package/dist/memory/project/dir/reticle-dir.js +1 -0
  242. package/dist/memory/project/fs/fs-port.js +44 -5
  243. package/dist/memory/project/fs/write-atomic.d.ts +26 -0
  244. package/dist/memory/project/fs/write-atomic.js +48 -0
  245. package/dist/memory/project/project-tools.js +3 -1
  246. package/dist/memory/recall/prior/connection-memory.d.ts +6 -0
  247. package/dist/memory/recall/prior/connection-memory.js +8 -0
  248. package/dist/memory/recall/registered-projects.d.ts +2 -1
  249. package/dist/portal/bridge/auth-failure-reason.d.ts +1 -1
  250. package/dist/portal/bridge/auth-failure-reason.js +9 -4
  251. package/dist/portal/bridge/bridge.d.ts +8 -0
  252. package/dist/portal/bridge/bridge.js +43 -2
  253. package/dist/portal/input/js-coverage.d.ts +25 -0
  254. package/dist/portal/input/js-coverage.js +30 -0
  255. package/dist/portal/input/real-input.d.ts +11 -0
  256. package/dist/portal/input/real-input.js +31 -5
  257. package/dist/portal/pool/browser-pool.d.ts +10 -0
  258. package/dist/portal/pool/browser-pool.js +10 -0
  259. package/dist/portal/pool/playwright-launcher.d.ts +6 -0
  260. package/dist/portal/pool/playwright-launcher.js +21 -13
  261. package/dist/portal/pool/pool-contract.d.ts +2 -0
  262. package/dist/portal/pool/storage-seed.d.ts +2 -1
  263. package/dist/portal/pool/zero-install.d.ts +27 -0
  264. package/dist/portal/pool/zero-install.js +54 -0
  265. package/dist/portal/realm/web-realm.js +6 -0
  266. package/dist/portal/session/dev-server/dev-command.d.ts +2 -2
  267. package/dist/portal/session/dev-server/dev-command.js +30 -12
  268. package/dist/portal/session/dev-server/dev-server-probe.d.ts +2 -1
  269. package/dist/portal/session/dev-server/dev-server-probe.js +17 -1
  270. package/dist/portal/session/dev-server/route-status-probe.d.ts +24 -0
  271. package/dist/portal/session/dev-server/route-status-probe.js +57 -0
  272. package/dist/portal/session/dev-server/served-document.d.ts +21 -0
  273. package/dist/portal/session/dev-server/served-document.js +57 -0
  274. package/dist/portal/session/facts/background-traffic.d.ts +9 -0
  275. package/dist/portal/session/facts/background-traffic.js +25 -0
  276. package/dist/portal/session/facts/observed-state.d.ts +11 -0
  277. package/dist/portal/session/facts/observed-state.js +34 -0
  278. package/dist/portal/session/live-control-tools.js +48 -3
  279. package/dist/portal/session/no-session-diagnosis.d.ts +29 -0
  280. package/dist/portal/session/no-session-diagnosis.js +62 -5
  281. package/dist/portal/session/no-session-next-action.d.ts +13 -0
  282. package/dist/portal/session/no-session-next-action.js +48 -9
  283. package/dist/portal/session/no-session-watch.d.ts +18 -0
  284. package/dist/portal/session/no-session-watch.js +88 -2
  285. package/dist/portal/session/presence/attachment-history.d.ts +13 -2
  286. package/dist/portal/session/session-health.d.ts +61 -0
  287. package/dist/portal/session/session-health.js +43 -3
  288. package/dist/portal/session/session-info.d.ts +6 -0
  289. package/dist/portal/session/session-manager.d.ts +29 -6
  290. package/dist/portal/session/session-manager.js +42 -5
  291. package/dist/portal/session/session-reaper.d.ts +28 -0
  292. package/dist/portal/session/session-reaper.js +49 -1
  293. package/dist/portal/session/session-successor.d.ts +11 -0
  294. package/dist/portal/session/session-successor.js +14 -1
  295. package/dist/portal/session/session-verdict-facts.d.ts +28 -0
  296. package/dist/portal/session/session-verdict-facts.js +15 -0
  297. package/dist/portal/session/session.d.ts +10 -0
  298. package/dist/portal/session/session.js +34 -26
  299. package/dist/surface/http-server.d.ts +2 -1
  300. package/dist/surface/http-server.js +4 -2
  301. package/dist/surface/mcp/mcp-proxy.d.ts +2 -2
  302. package/dist/surface/mcp/mcp-proxy.js +5 -5
  303. package/dist/surface/mcp/mcp.js +4 -2
  304. package/dist/surface/mcp/proxy/proxy-daemon-probe.d.ts +13 -1
  305. package/dist/surface/mcp/proxy/proxy-daemon-probe.js +27 -2
  306. package/dist/surface/mcp/proxy-idle-exit.d.ts +2 -1
  307. package/dist/surface/mcp/server-instructions.js +21 -8
  308. package/dist/surface/tools/act/after-match.d.ts +17 -0
  309. package/dist/surface/tools/act/after-match.js +30 -0
  310. package/dist/surface/tools/act/already-true.d.ts +40 -0
  311. package/dist/surface/tools/act/already-true.js +36 -0
  312. package/dist/surface/tools/act/durable.d.ts +69 -0
  313. package/dist/surface/tools/act/durable.js +139 -0
  314. package/dist/surface/tools/act/navigation/navigate-arrival.d.ts +19 -6
  315. package/dist/surface/tools/act/navigation/navigate-arrival.js +60 -10
  316. package/dist/surface/tools/act/navigation/navigate-result.d.ts +1 -12
  317. package/dist/surface/tools/act/navigation/navigate-result.js +21 -3
  318. package/dist/surface/tools/act/proved-controls.d.ts +9 -0
  319. package/dist/surface/tools/act/proved-controls.js +11 -0
  320. package/dist/surface/tools/act/sequence-grade.d.ts +5 -0
  321. package/dist/surface/tools/act/sequence-grade.js +32 -1
  322. package/dist/surface/tools/act/settle-in-flight.d.ts +6 -2
  323. package/dist/surface/tools/act/settle-in-flight.js +29 -6
  324. package/dist/surface/tools/act-capsule.d.ts +7 -0
  325. package/dist/surface/tools/act-capsule.js +68 -8
  326. package/dist/surface/tools/act-sequence-tool.js +25 -8
  327. package/dist/surface/tools/act-tools.js +51 -74
  328. package/dist/surface/tools/args/numeric-bounds.d.ts +15 -2
  329. package/dist/surface/tools/args/numeric-bounds.js +30 -3
  330. package/dist/surface/tools/assert/assert-grade.js +26 -3
  331. package/dist/surface/tools/assert/assert-verdict.js +32 -6
  332. package/dist/surface/tools/browser-tools.js +17 -4
  333. package/dist/surface/tools/coverage-tools.js +27 -1
  334. package/dist/surface/tools/dynamic-tools.js +6 -0
  335. package/dist/surface/tools/error-recovery.js +4 -4
  336. package/dist/surface/tools/feedback-invite.js +6 -4
  337. package/dist/surface/tools/feedback-tools.d.ts +2 -1
  338. package/dist/surface/tools/feedback-tools.js +1 -1
  339. package/dist/surface/tools/harness-explore.d.ts +3 -2
  340. package/dist/surface/tools/harness-explore.js +7 -6
  341. package/dist/surface/tools/invoke-tool.js +17 -4
  342. package/dist/surface/tools/lease-hint.d.ts +8 -0
  343. package/dist/surface/tools/lease-hint.js +10 -0
  344. package/dist/surface/tools/lease-tools.d.ts +16 -28
  345. package/dist/surface/tools/lease-tools.js +68 -11
  346. package/dist/surface/tools/lineage-tools.js +1 -1
  347. package/dist/surface/tools/live-call-text.js +4 -1
  348. package/dist/surface/tools/observe-tools.js +23 -7
  349. package/dist/surface/tools/real-input-attempt.d.ts +0 -5
  350. package/dist/surface/tools/real-input-attempt.js +1 -1
  351. package/dist/surface/tools/tool-kit.d.ts +5 -0
  352. package/dist/surface/tools/tool-kit.js +6 -1
  353. package/dist/surface/tools/tool-surface.js +17 -5
  354. package/dist/surface/tools/tools.js +68 -29
  355. package/dist/telemetry/argument-shape.d.ts +0 -2
  356. package/dist/telemetry/argument-shape.js +0 -4
  357. package/dist/telemetry/error-class.d.ts +2 -3
  358. package/dist/telemetry/error-class.js +2 -3
  359. package/dist/telemetry/feedback-local.d.ts +1 -0
  360. package/dist/telemetry/feedback-local.js +1 -3
  361. package/dist/telemetry/feedback.d.ts +1 -1
  362. package/dist/telemetry/harness-drive.d.ts +0 -2
  363. package/dist/telemetry/harness-drive.js +0 -4
  364. package/dist/telemetry/hud-metrics.d.ts +32 -0
  365. package/dist/telemetry/hud-metrics.js +95 -0
  366. package/dist/telemetry/session-metrics.d.ts +5 -0
  367. package/dist/telemetry/session-metrics.js +15 -1
  368. package/dist/wire-journal.d.ts +34 -0
  369. package/dist/wire-journal.js +104 -0
  370. package/dist/workspace-packages.d.ts +0 -2
  371. package/dist/workspace-packages.js +1 -9
  372. package/docs/README.md +5 -2
  373. package/docs/actions.mdx +3 -3
  374. package/docs/agent-cheatsheet.md +4 -4
  375. package/docs/architecture.md +6 -6
  376. package/docs/best-practices.mdx +1 -1
  377. package/docs/capabilities.mdx +32 -1
  378. package/docs/cli/cloud.mdx +21 -9
  379. package/docs/cli/doctor.mdx +4 -0
  380. package/docs/cli/feedback.mdx +2 -2
  381. package/docs/cli/gate.mdx +9 -4
  382. package/docs/cli/init.mdx +1 -0
  383. package/docs/cli/report.mdx +44 -0
  384. package/docs/cli/update.mdx +10 -0
  385. package/docs/cli.mdx +9 -0
  386. package/docs/desktop.mdx +14 -10
  387. package/docs/environment.mdx +87 -0
  388. package/docs/faq.mdx +18 -16
  389. package/docs/first-drive.md +5 -13
  390. package/docs/flows.md +32 -2
  391. package/docs/frameworks.mdx +140 -9
  392. package/docs/getting-started.md +3 -3
  393. package/docs/http-transport.md +6 -3
  394. package/docs/human-control.md +2 -2
  395. package/docs/index.mdx +16 -6
  396. package/docs/install-agentic.mdx +37 -1
  397. package/docs/install-manual.mdx +1 -1
  398. package/docs/integration-patterns.md +3 -3
  399. package/docs/multi-agent-testing.md +1 -1
  400. package/docs/packages/babel-plugin.mdx +1 -1
  401. package/docs/packages/browser.mdx +2 -2
  402. package/docs/packages/react.mdx +2 -2
  403. package/docs/packages/tauri.mdx +1 -1
  404. package/docs/packages/vite-plugin.mdx +2 -2
  405. package/docs/packages.mdx +9 -9
  406. package/docs/predicates.mdx +176 -7
  407. package/docs/quickstart.mdx +2 -2
  408. package/docs/recipes.mdx +2 -2
  409. package/docs/state-management.mdx +2 -2
  410. package/docs/system-map.md +1 -1
  411. package/docs/telemetry.md +1 -1
  412. package/docs/token-efficiency.md +3 -3
  413. package/docs/tools/act-and-wait.mdx +1 -0
  414. package/docs/tools/act-sequence.mdx +1 -1
  415. package/docs/tools/console.mdx +1 -1
  416. package/docs/tools/inspect.mdx +1 -1
  417. package/docs/tools/network.mdx +1 -1
  418. package/docs/tools/query.mdx +11 -11
  419. package/docs/tools/sessions.mdx +1 -1
  420. package/docs/tools/snapshot.mdx +1 -1
  421. package/docs/tools/state.mdx +1 -1
  422. package/docs/tools/wait-for.mdx +1 -1
  423. package/docs/usage.md +8 -7
  424. package/docs/use-cases.mdx +157 -0
  425. package/docs/vs-screenshots.mdx +3 -3
  426. package/docs/what-is-recorded.md +62 -0
  427. package/docs/what-is-reticle.mdx +17 -20
  428. package/docs/why-reticle.mdx +14 -21
  429. package/package.json +11 -10
  430. package/dist/judgement/capsule/minimize.d.ts +0 -12
  431. package/dist/judgement/capsule/minimize.js +0 -22
  432. package/dist/judgement/outcome/predicate-to-expect.d.ts +0 -44
  433. package/dist/judgement/outcome/predicate-to-expect.js +0 -148
  434. package/dist/judgement/phenomena/phenomena.d.ts +0 -26
  435. package/dist/judgement/phenomena/phenomena.js +0 -101
  436. package/dist/language/flows/flow-report.d.ts +0 -22
  437. package/dist/language/flows/flow-report.js +0 -106
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  title: 'Frameworks: proven, wired, and the difference'
3
3
  sidebarTitle: Frameworks
4
- description: Which frameworks Reticle supports, which are wired but unverified, and the exact wiring for each one. React, Next.js, Remix, Astro, SvelteKit, TanStack Start, Nuxt, Vue and plain HTML.
4
+ description: Which frameworks Reticle supports, which are wired but unverified, and the exact wiring for each one. React, Next.js, Remix, Astro, SvelteKit, TanStack Start, Nuxt, Vue, Angular and plain HTML.
5
5
  icon: layer-group
6
6
  ---
7
7
 
8
- **React + Vite, Next.js, Remix and Astro are fully supported, each with an example app driven to a verdict in CI. Astro, SvelteKit, Nuxt, React Router framework mode, Create React App and Vue have their INSTALL gated: the install gate scaffolds each from scratch on every change and requires a real session, but no gate drives them to a verdict. TanStack Start, Preact and plain HTML are wired and documented but not gated at all, so treat them as plausible rather than proven.** The exact wiring for each is below.
8
+ **React + Vite, Next.js, Remix and Astro are fully supported, each with an example app driven to a verdict in CI. Astro, SvelteKit, Nuxt, React Router framework mode, Create React App, Vue and Angular have their INSTALL gated: the install gate scaffolds each from scratch on every change and requires a real session, but no gate drives them to a verdict. TanStack Start, Preact and plain HTML are wired by `init` and documented but not gated at all, so treat them as plausible rather than proven.** The exact wiring for each is below.
9
9
 
10
10
  Reticle is a verification layer that embeds a dev-only SDK in your running web app so an AI coding agent can prove a change works. Its core is framework-neutral: DOM, network, console, routing, animations and source mapping work anywhere JavaScript runs.
11
11
 
@@ -32,9 +32,11 @@ Two columns say different things and it is worth keeping them apart. **CI gate**
32
32
  | **Nuxt** | yes | no | install only | unproven | Install gated, drive unverified |
33
33
  | **React Router (framework mode)** | yes | no | install only | yes | Install gated, drive unverified |
34
34
  | **Create React App** | yes | no | install only | unproven | Install gated, drive unverified |
35
+ | **Angular 17+** | yes | no | install only | no | Install gated, drive unverified |
35
36
  | **Plain HTML** | yes | no | no | no | Wired, unverified |
36
37
  | **Vue (non-Nuxt)** | as Vite | no | install only | no | Install gated, drive unverified |
37
- | **Preact** | as Vite | no | no | unproven | Sensor, React adapter via `preact/compat` |
38
+ | **Preact** | as Vite | no | no | transform-tested; drive unproven | Sensor, React adapter via `preact/compat` |
39
+ | **Server-rendered (Django, Flask, FastAPI, Streamlit, Rails)** | yes | no | no | no | Wired, unverified |
38
40
 
39
41
  <Warning>
40
42
  "Wired, unverified" means exactly that. The recipe exists and was written from a real integration,
@@ -85,7 +87,41 @@ module.exports = withReticle({/* your config */});
85
87
 
86
88
  ## Remix and Astro
87
89
 
88
- Both run on Vite, so both use the Vite plugin exactly as React does. Astro needs the React integration if you want component identity in `.jsx` islands. Static `.astro` markup gets DOM, network and routing without it.
90
+ Remix v2 on Vite is its own framework to `init`, not plain Vite. Remix SSRs its own HTML, so the plugin's `index.html` injection never reaches the page and the connect comes from `app/entry.client.tsx` instead, the same way as React Router framework mode. `init` adds the dev-only connect line to that entry, or writes the file when the app has none: `app/entry.client.tsx` only exists after `remix reveal`, so the written file is Remix's own default entry (`RemixBrowser`, `hydrateRoot`) with the one line added. The Vite plugin, `reticle()` in the `vite.config` that carries `vitePlugin`, stamps `file:line` and serves the connect module the entry imports. The classic Remix compiler (no `vite.config`) gets a manual step rather than a green plan, because there is no plugin to serve that module.
91
+
92
+ Astro uses the Vite plugin (wire it with `inject: false` if you want source pointers on JSX islands) and uses a different channel for the pairing token. `vite.define` does not reach Astro's client pipeline on 7.2+, so the identifier stays literal and the bridge refuses the dial. `init` reads the token in frontmatter and puts it on a `<meta name="reticle-pairing-token">`. Reading it per request also means a token written after the dev server started is picked up on the next load, with no restart.
93
+
94
+ Use a processed page `<script>` with a static SDK import. Vite owns that module graph from the first transform:
95
+
96
+ ```astro
97
+ ---
98
+ import { readFileSync } from 'node:fs';
99
+ import { homedir } from 'node:os';
100
+ import { join } from 'node:path';
101
+ const pairingToken = (() => {
102
+ if (!import.meta.env.DEV) return '';
103
+ const dir = process.env['RETICLE_PAIRING_TOKEN_DIR'] || join(homedir(), '.reticle');
104
+ try { return readFileSync(join(dir, 'pairing-token'), 'utf8').trim(); } catch { return ''; }
105
+ })();
106
+ const pairingRoot = import.meta.env.DEV ? process.cwd() : '';
107
+ ---
108
+ <meta name="reticle-pairing-token" content={pairingToken} />
109
+ <meta name="reticle-pairing-root" content={pairingRoot} />
110
+ <script>
111
+ import { reticle, install } from '@reticlehq/react';
112
+ if (import.meta.env.DEV) {
113
+ const token = document.querySelector('meta[name="reticle-pairing-token"]')?.getAttribute('content') ?? '';
114
+ const root = document.querySelector('meta[name="reticle-pairing-root"]')?.getAttribute('content') ?? '';
115
+ install();
116
+ reticle.connect({
117
+ ...(0 < token.length ? { token } : {}),
118
+ ...(0 < root.length ? { root } : {}),
119
+ });
120
+ }
121
+ </script>
122
+ ```
123
+
124
+ The `<script>` tag must not sit inside a conditional. Astro hoists them statically, so `{isDev && (<script />)}` is never hoisted. `init` writes the same `<meta>` tags and a local `src/components/ReticleDev.ts` that the script statically imports. It also raises `vite.build.target` to `es2022` (Astro's default down-levels the SDK), declares the SDK in `optimizeDeps.include`, and keeps `.reticle/` out of the watcher. Static `.astro` markup still gets DOM, network and routing without the React integration.
89
125
 
90
126
  ## SvelteKit
91
127
 
@@ -120,7 +156,7 @@ useEffect(() => {
120
156
  }, []);
121
157
  ```
122
158
 
123
- `init` detects Start and prints this recipe. There is no example app and no CI gate, so treat a connected session as the proof, not the plan.
159
+ `init` writes this for you: a `src/reticle-connect.tsx` client effect that connects, declares `__RETICLE_TOKEN__` so `tsc` passes, and loads `src/reticle-dev.ts`, plus `<ReticleConnect />` rendered before `<Scripts />` in `src/routes/__root.tsx`. When the root route is not a shape it can patch, it prints a recipe naming the real parts (`shellComponent`, `<Scripts />`) instead. There is no example app and no CI gate, so treat a connected session as the proof, not the plan.
124
160
 
125
161
  ## Nuxt
126
162
 
@@ -182,6 +218,10 @@ Detected as its own UI library, because a Preact app using `preact/compat` alias
182
218
 
183
219
  The sensor works. If you use `preact/compat`, the React adapter can attach through the alias, but that path is not gated.
184
220
 
221
+ **The source-pointer transform works on Preact code, and that is measured rather than assumed.** The stamper is JSX-syntactic: it tags a host element by its tag name and reads nothing about React, so a Preact `.jsx` or `.tsx` file is stamped exactly as a React one is. `class` instead of `className`, a `@jsxImportSource preact` pragma and a `@preact/signals` value in the tree all leave it unmoved. There are tests for each of those in `adapters/build/babel-plugin`. They prove the Babel transform, not the `@preact/preset-vite` pipeline end to end: nobody has yet driven a Preact app and seen a verdict name a `file:line`, so the drive stays unproven until someone does.
222
+
223
+ What is still missing on Preact is the enrichment above the DOM: `reticle_inspect` returns no `component`/`componentStack`, `@preact/signals` has no `reticle_state` adapter, and the render meter counts React commits only. Tracked in [#129](https://github.com/reticlehq/reticle/issues/129).
224
+
185
225
  ## Create React App and plain bundlers
186
226
 
187
227
  No config file to patch, so `connect()` goes in your entry module.
@@ -196,14 +236,105 @@ The same shape works for webpack, Parcel, and the Vue and Svelte CLIs.
196
236
 
197
237
  ## Plain HTML
198
238
 
239
+ A directory with an `index.html` and no `package.json` is wired by `init` itself: it writes the connect snippet into `index.html`, before `</body>`, writes `.reticle.json`, and hands over to setup. The block is marked, so a re-run finds it and never writes a second one, and a re-run with a new `--port` rewrites the port inside it. It loads the SDK from a CDN and runs only when the page is opened on `localhost`, `127.0.0.1` or `[::1]`: a static file has no development build to strip it, so the host is the only line between the snippet and a published page. The page carries no pairing token: `init` writes it into `reticle.local.js` beside the page, which the snippet imports, and adds that file to `.gitignore`. Keep it out of anything you publish, and let each teammate run `reticle init` for their own. Several pages and no `index.html` is a choice `init` does not make for you: it prints the snippet, filled in with your project id and token, for you to paste:
240
+
199
241
  ```html
200
242
  <script type="module">
201
- import { reticle } from '/node_modules/@reticlehq/browser/dist/index.js';
202
- reticle.connect();
243
+ import { reticle } from 'https://cdn.jsdelivr.net/npm/@reticlehq/browser@<version>/+esm';
244
+ reticle.connect({ projectId: '<your-project-id>', token: '<pairing token>' });
203
245
  </script>
204
246
  ```
205
247
 
206
- Keep it out of your production template. Reticle self-disables when the build reports `NODE_ENV=production`, but a second lock on a door leading to your users is a reasonable number.
248
+ A bare `/node_modules/...` import does not work here: the SDK's own `dist` imports bare specifiers, which a browser cannot resolve without a bundler. A page with a `package.json` and a bundler takes the entry-module path above instead.
249
+
250
+ ## Angular
251
+
252
+ Angular 17 and later, on the Vite-based `@angular/build` dev server. `init` installs only `@reticlehq/browser`, the framework-neutral sensor, and makes three edits:
253
+
254
+ - **The browser entry** (`src/main.ts`, or whatever `angular.json` names) gets a connect guarded on Angular's `ngDevMode` global (`typeof ngDevMode === 'undefined' || ngDevMode`), through a dynamic `import('@reticlehq/browser')` appended after the bootstrap. A production `ng build` defines `ngDevMode` as `false`, so the build drops the block and the chunk with it. The output carries no Reticle code at all, and the app never waits on Reticle. `isDevMode()` is not used because the build cannot fold a function call; an entry wired that way by an older `init` is rewritten in place on the next run.
255
+ - **`reticle.proxy.mjs`**, beside `angular.json`, answers one same-origin route, `/__reticle/pairing-token`, with this machine's pairing token, read from `~/.reticle/pairing-token` at request time. It refuses a request that did not arrive over loopback or came from another origin.
256
+ - **`angular.json`** gets the serve target's `proxyConfig` pointed at that file. `ng serve` loads it; `ng build` never reads a proxy config, so a production bundle has no route to the token and the token is never written into the project.
257
+
258
+ The token takes that route because the Angular CLI has no config file that runs code: a literal in `angular.json` commits a per-machine secret, and a gitignored module imported from `main.ts` is bundled into `ng build` whether or not anything can reach it. An existing `proxyConfig` is yours and is never replaced: the step goes manual and names the entry to add to it. A workspace with several served applications is also manual, because which one is the app is not `init`'s to guess.
259
+
260
+ You get DOM, network, console, routing and state tools. You do not get component identity (that is the React adapter) or a `source` field (the stamper covers JSX and Svelte). The install gate scaffolds an Angular app (no SSR) on every change and requires a session; SSR was proven by hand, and nothing drives an Angular app to a verdict.
261
+
262
+ ## Server-rendered apps (Django, Flask, FastAPI, Rails)
263
+
264
+ There is no JS build to import the SDK from, and no single template to paste a script tag into: an app has many templates and may not have a base one. The SDK loads from a URL instead, so a page with no build step is not a blocker.
265
+
266
+ `reticle init` detects these and prints the right thing for the stack it found, writing `.reticle.json` as it goes. What follows is the same wiring, written down so you can read it before running anything, or wire it by hand.
267
+
268
+ ### Django
269
+
270
+ Middleware is the Django-shaped answer: one place, runs for every page, no template to find.
271
+
272
+ ```python
273
+ # reticle_dev.py: add to MIDDLEWARE while DEBUG is on:
274
+ # MIDDLEWARE = [..., "reticle_dev.ReticleDevMiddleware"]
275
+ from django.conf import settings
276
+
277
+ _SNIPPET = """<script type="module">
278
+ import { reticle } from 'https://cdn.jsdelivr.net/npm/@reticlehq/browser@<version>/+esm';
279
+ reticle.connect({ projectId: '<your-project-id>', token: '<pairing token>' });
280
+ </script>"""
281
+
282
+
283
+ class ReticleDevMiddleware:
284
+ """Inject the Reticle SDK into HTML responses during development only."""
285
+
286
+ def __init__(self, get_response):
287
+ self.get_response = get_response
288
+
289
+ def __call__(self, request):
290
+ response = self.get_response(request)
291
+ if not settings.DEBUG:
292
+ return response
293
+ if "text/html" not in response.get("Content-Type", ""):
294
+ return response
295
+ # Streaming responses have no .content to rewrite; leave them alone.
296
+ if getattr(response, "streaming", False):
297
+ return response
298
+ body = response.content.decode(response.charset)
299
+ if "</body>" not in body:
300
+ return response
301
+ response.content = body.replace("</body>", _SNIPPET + "</body>", 1).encode(
302
+ response.charset
303
+ )
304
+ if response.has_header("Content-Length"):
305
+ response["Content-Length"] = str(len(response.content))
306
+ return response
307
+ ```
308
+
309
+ `reticle init` emits this with your real version, project id and pairing token filled in. Copy it from there rather than from this page: the placeholders above are the three things that have to be right.
310
+
311
+ Four details in that middleware are load-bearing, and each is there because the obvious version is wrong:
312
+
313
+ - **`settings.DEBUG`** is the guard. Reticle is dev-only, and this is the lock that cannot be forgotten at deploy time.
314
+ - **the `text/html` check** keeps it from corrupting a JSON API response or a file download.
315
+ - **the `streaming` check** exists because a `StreamingHttpResponse` has no `.content` to rewrite, and touching it raises.
316
+ - **`</body>`, not `<head>`** so the SDK sees a parsed document.
317
+
318
+ Re-setting `Content-Length` matters for the same reason: the body grew, and a stale length truncates the page in the browser rather than failing loudly.
319
+
320
+ ### Flask and FastAPI with Jinja
321
+
322
+ Same shape, one hook instead of a middleware class: an `@app.after_request` in Flask, or a middleware in FastAPI, with the same four guards: a debug flag, `text/html` only, not streaming, and injected before `</body>`.
323
+
324
+ ### Streamlit
325
+
326
+ Different again: Streamlit owns the top-level document, so there is no served template, and scripts passed to `st.markdown` do not run. Use `st.html` on Streamlit 1.63 or newer. `reticle init` prints the helper, which also guards against connecting twice across reruns.
327
+
328
+ ### What you get, and what you do not
329
+
330
+ Everything that comes from reading the live page works: queries, snapshots, actions, network and console channels, verdicts.
331
+
332
+ What is missing is the **source pointer**. `file:line` on a verdict comes from the build plugin stamping `data-reticle-source`, and there is no build step here to stamp it. You get every other signal and no `source` field, the same way a Vue single-file component does.
333
+
334
+ <Warning>
335
+ Wired, unverified. No app in CI drives one of these to a verdict, so nothing will tell us if it
336
+ breaks. If a page does not register a session, that is worth reporting.
337
+ </Warning>
207
338
 
208
339
  ## Desktop is a different shape
209
340
 
@@ -215,7 +346,7 @@ Electron and Tauri invert the direction: your app dials the daemon, and there is
215
346
 
216
347
  ## Not supported
217
348
 
218
- Angular and Solid appear in dependency detection but have no wiring, no adapter and no gate. The sensor may work if you call `connect()` yourself. Nothing proves it, so we are not going to list them as supported.
349
+ Solid appears in dependency detection but has no wiring, no adapter and no gate. The sensor may work if you call `connect()` yourself. Nothing proves it, so we are not going to list them as supported.
219
350
 
220
351
  ## Frequently asked questions
221
352
 
@@ -78,7 +78,7 @@ The bridge + MCP server is a single process that serves all your projects, so it
78
78
 
79
79
  Re-running is safe: already-registered and already-patched steps are skipped, and on a wired project it goes straight to proving the app still works. Preview without writing via `npx @reticlehq/server init --dry-run`.
80
80
 
81
- `init` does not stop at writing files. It starts your dev server (restarting one whose bundle predates the config edit), opens the app, and waits for a session to connect from inside it. That connection is the whole proof that onboarding worked. It exits non-zero if nothing connected and prints what is left to do. It does NOT drive. Then prove a flow. That is the FIRST RUN, and it is a separate call: `reticle_verify { action: "explore", persona: "<who does what>" }`. It drives with a model inside the daemon and records what it drove, so later checks replay it with no model in the loop.
81
+ `init` does not stop at writing files. It starts your dev server, opens the app, and waits for a session to connect from inside it. That connection is the whole proof that onboarding worked. If a dev server was already running without Reticle, restart it once: it read the build config before `init` edited it. It exits non-zero if nothing connected and prints what is left to do. It does NOT drive. Then prove a flow. That is the FIRST RUN, and it is a separate call: `reticle_verify { action: "explore", persona: "<who does what>" }`. It drives with a model inside the daemon and records what it drove, so later checks replay it with no model in the loop.
82
82
 
83
83
  These carry what the command cannot work out for itself:
84
84
 
@@ -90,7 +90,7 @@ These carry what the command cannot work out for itself:
90
90
 
91
91
  The rest are dials: `--license <key>` (writes it to `.env` and keeps `.env` out of git), `--json` (one object for an agent to read), `--files-only` (write, register, pre-approve, and stop, which is what `init` did before it learned to boot the app, and what an existing install re-runs to pick up new wiring), `--relaunch` (prints the command that restarts the conversation you are in, with the tools loaded: the restart step most installs stall on, and it composes with `--files-only`), `--no-open`, `--dry-run`, `--port N`, `--no-mcp`, `--no-install`.
92
92
 
93
- Then restart your dev server and skip to [Step 4](#step-4-run-it-and-verify-the-connection). The manual steps below explain what `init` sets up, if you prefer to wire it yourself.
93
+ If you ran `--files-only` with a dev server already running, restart it, then skip to [Step 4](#step-4-run-it-and-verify-the-connection). The manual steps below explain what `init` sets up, if you prefer to wire it yourself.
94
94
 
95
95
  ---
96
96
 
@@ -464,7 +464,7 @@ Everything below comes from the `@reticlehq/react` kit plus your framework's bui
464
464
 
465
465
  **You do not get** component identity. `@reticlehq/react` walks the fiber tree to answer "which component rendered this element"; there is no Svelte equivalent, so snapshots carry the file and line but no component name. Stamping targets Svelte 5's compiler AST and also accepts Svelte 4's; `.svelte.ts` runes modules are code rather than markup and are not stamped.
466
466
 
467
- **It is still unverified.** There is no SvelteKit app in `apps/` and no CI gate for one, so nothing would tell us when this breaks; `reticle init` says so out loud in its plan. React, Next.js, Remix and Astro each have an app and a gate. Treat SvelteKit as wired and plausible, not as supported.
467
+ **It is install-gated, drive-unverified.** The install gate scaffolds a SvelteKit app from scratch, runs `init`, boots it and waits for a session, so the setup is proven. There is no SvelteKit example app that CI drives to a verdict, so the drive is not. [Frameworks](/frameworks) has the full status table.
468
468
 
469
469
  **Vue is install-gated, drive-unverified.** `init` detects a Vue app (as a Vite app with Vue as the UI library) and the install gate scaffolds one from scratch, runs `init`, boots it and waits for a session, so the setup is proven. What is not proven is the drive: there is no Vue example app in CI. `piniaStore` reads a Pinia store, and everything the framework-neutral core provides works. What you do not get is a `source` field, because source stamping covers JSX and Svelte components and a `.vue` single-file component is neither. See [Frameworks](/frameworks) for the full status table.
470
470
 
@@ -8,7 +8,7 @@ Most clients reach Reticle over stdio: they spawn `reticle mcp`, and the tools a
8
8
 
9
9
  The daemon also speaks MCP over HTTP, on the same port as everything else. Nothing has to reload for a client to reach it, so this is the transport for scripted runs, CI, a language with no MCP client library, and any editor that will not pick up tools mid-session.
10
10
 
11
- It is the same tool surface. Not a subset, not a simplified one. `reticle_snapshot`, `reticle_act_and_wait`, `reticle_assert` and the rest behave exactly as they do over stdio, because they are the same server behind a different transport.
11
+ It is the same tool surface. Not a subset, not a simplified one. `reticle_look { action: "page" }`, `reticle_act_and_wait`, `reticle_assert` and the rest behave exactly as they do over stdio, because they are the same server behind a different transport.
12
12
 
13
13
  ## The two endpoints
14
14
 
@@ -136,7 +136,10 @@ async function start() {
136
136
  const listed = await send('tools/list', {});
137
137
  console.log(listed.result.tools.map((t) => t.name).join(', '));
138
138
 
139
- const snapshot = await send('tools/call', { name: 'reticle_snapshot', arguments: {} });
139
+ const snapshot = await send('tools/call', {
140
+ name: 'reticle_look',
141
+ arguments: { action: 'page' },
142
+ });
140
143
  console.log(snapshot.result.content[0].text);
141
144
  }
142
145
  ```
@@ -159,6 +162,6 @@ The `202` comes back here; the tool list appears in the first shell.
159
162
 
160
163
  ## What this does not change
161
164
 
162
- The transport carries the tools. It does not replace the rest of the setup. The app still has to be instrumented and connected, and `reticle_sessions` is still what tells you whether a session is there to drive. A verdict reached over HTTP is a verdict reached the usual way: only `verified: "yes"` is a pass.
165
+ The transport carries the tools. It does not replace the rest of the setup. The app still has to be instrumented and connected, and `reticle_session { action: "list" }` is still what tells you whether a session is there to drive. A verdict reached over HTTP is a verdict reached the usual way: only `verified: "yes"` is a pass.
163
166
 
164
167
  The endpoints, the handshake, the three status codes and the `202`-then-SSE shape are pinned by `server/src/mcp-http-transport.test.ts`, which drives them over raw HTTP with no client library, so the contract this page describes fails the build if it changes.
@@ -17,7 +17,7 @@ The panel header shows a running **✓N ✗M** tally: the verdict score, live. I
17
17
  MCP is **pull-based**: the agent only receives data when it calls a tool. Reticle can't freeze the model mid-thought, but it **intercepts the agent's next tool call**, which is exactly when the agent would touch the page. That makes steering reliable:
18
18
 
19
19
  - **Nudge** (a message, no pause). Your text is queued and rides back on the agent's **next** tool result as `guidance` (delivered once). The agent reads it and adjusts.
20
- - **Pause.** The agent's next `reticle_act` / `reticle_act_and_wait` / `reticle_act_sequence` **refuses to execute** and returns `{ paused: true, guidance: ["<your message>"], hint: "…" }`. The page is untouched until resume. _Read-only tools (snapshot/query/observe) still work_, so the agent can look while paused.
20
+ - **Pause.** The agent's next `reticle_act` (single or `steps`) / `reticle_act_and_wait` **refuses to execute** and returns `{ paused: true, guidance: ["<your message>"], hint: "…" }`. The page is untouched until resume. _Read-only tools (snapshot/query/observe) still work_, so the agent can look while paused.
21
21
  - **End.** The session is over; the panel shows "Session ended" and clears.
22
22
 
23
23
  ## From the panel (the human)
@@ -35,7 +35,7 @@ The floating panel (bottom-center, `present: true`) gives you:
35
35
  You don't have to describe a bug in prose. **Point at it.** The flag captures the element's re-resolvable anchor _and_ the source `file:line` (when the framework stamped one), so the agent fixes the exact element and code, not a guess. The loop:
36
36
 
37
37
  1. **You** flag the element and type the problem → Reticle emits a `HUMAN_MARK`.
38
- 2. **The agent** drains it with `reticle_session {action:"review"}`, getting note + element label + `source: { file, line }` + a ready-to-act `fix` hint. `reticle_sessions` also reports `pendingMarks` so the agent notices flags.
38
+ 2. **The agent** drains it with `reticle_session {action:"review"}`, getting note + element label + `source: { file, line }` + a ready-to-act `fix` hint. `reticle_session { action: "list" }` also reports `pendingMarks` so the agent notices flags.
39
39
  3. **The agent** opens the file, fixes it, and calls `reticle_session {action:"review"}({ resolve: "m1" })`.
40
40
  4. **You** see **"✓ fixed: \<your note\>"** land in the panel. Flag → fix → confirmation.
41
41
 
package/docs/index.mdx CHANGED
@@ -73,13 +73,16 @@ Afterwards, use it whenever you change any user-facing behaviour.
73
73
  The four files it writes, the marks it prints, and how to read its report.
74
74
  </Card>
75
75
 
76
- <CardGroup cols={2}>
76
+ <CardGroup cols={3}>
77
77
  <Card title="Quickstart" icon="rocket" href="/quickstart">
78
78
  Install, connect your agent, and get a real verdict. Five minutes.
79
79
  </Card>
80
80
  <Card title="Why Reticle" icon="lightbulb" href="/why-reticle">
81
81
  The false-green problem, and the evidence that this fixes it.
82
82
  </Card>
83
+ <Card title="Use cases" icon="list-check" href="/use-cases">
84
+ Agent-built changes, security behaviour, accessibility, performance, SEO basics and personas.
85
+ </Card>
83
86
  </CardGroup>
84
87
 
85
88
  <CardGroup cols={3}>
@@ -127,18 +130,25 @@ Reticle clicks, watches, and reports what actually happened. A verdict of `unkno
127
130
  single step.
128
131
  </Card>
129
132
  <Card title="Yours, locally" icon="lock">
130
- Dev-only, localhost-only, offline. Your app's data never leaves the machine.
133
+ Dev-only and localhost-only. Your app's data stays on your machine; anonymous usage counts are
134
+ sent unless you [turn them off](/telemetry).
131
135
  </Card>
132
136
  </CardGroup>
133
137
 
138
+ ## What people use it for
139
+
140
+ Beyond proving an agent's change, people use Reticle to check security behaviour (access control by role, calls that must never fire, CSP violations), accessibility and UX (roles, names, focus, keyboard), performance (request counts, long tasks, layout shift), SEO basics (titles, headings, links, redirects), and to drive the app as different users. [Use cases](/use-cases) has what each one checks and a call to run.
141
+
142
+ It pairs well with a visual testing tool for pixel diffs, Playwright for sites you don't own, axe for full WCAG audits and a security scanner for vulnerability discovery.
143
+
134
144
  ## The evidence
135
145
 
136
- We publish the losses too. Reticle is not the right tool for driving a site you don't own, and it does not see pixels.
146
+ Every number is measured by a committed harness, including the ties.
137
147
 
138
148
  ![One honest test, two apps: Reticle has the highest Verification Efficiency on the controlled app and the lowest observation cost on the real dashboard](/images/bench-two-apps.png)
139
149
 
140
150
  <Card title="Read the full benchmark" icon="chart-column" href="/benchmarks">
141
- How every number was measured, what it means, and where Reticle comes second.
151
+ How every number was measured, what it means, and where the tools tie.
142
152
  </Card>
143
153
 
144
154
  ## Built for agents, readable by humans
@@ -151,7 +161,7 @@ Reticle is used by a coding agent far more often than by a person, so these docs
151
161
 
152
162
  ## Build with us
153
163
 
154
- Reticle is early, and the sharp edges get filed down fastest when someone tells us where they are.
164
+ The roadmap moves on what people actually hit, so tell us.
155
165
 
156
166
  <CardGroup cols={2}>
157
167
  <Card title="Join the Discord" icon="discord" href="https://discord.gg/BwAbzv9ZRz">
@@ -163,4 +173,4 @@ Reticle is early, and the sharp edges get filed down fastest when someone tells
163
173
  </Card>
164
174
  </CardGroup>
165
175
 
166
- Found a bug, or something you wished existed? `reticle_feedback` sends it in one call, from wherever you are. If Reticle could not tell you what happened, that is our defect and we want to know.
176
+ Found a bug, or something you wished existed? `reticle_session { action: "feedback" }` sends it in one call from your agent, and `npx @reticlehq/server feedback "…"` from a terminal. If Reticle could not tell you what happened, that is our defect and we want to know.
@@ -131,7 +131,7 @@ That `ℹ` line is the one people skim past, so here it is in full:
131
131
  ```
132
132
  [ℹ] AGENT: finish the capabilities file → src/reticle-dev.ts
133
133
  src/reticle-dev.ts was written but registers nothing, so `hasCapabilities` stays false
134
- and reticle_state has nothing to read.
134
+ and reticle_look { action: "state" } has nothing to read.
135
135
  ```
136
136
 
137
137
  `init` wrote the file, but a brand-new Vite template has no testids and no state library, so there was nothing to register. Reticle tells you this instead of counting it as a win. See [Instrument your app](/instrumentation) for what to put in it.
@@ -150,6 +150,42 @@ Four files in your project, none of them mysterious.
150
150
  ```
151
151
  The `projectId` is how Reticle scopes sessions to this project, so two apps running at once
152
152
  don't get confused for each other.
153
+
154
+ **Keeping `.reticle/` small.** Reticle bounds the directory for you, by count and by total size.
155
+ Add a `retain` block to change what it keeps:
156
+
157
+ ```json
158
+ {
159
+ "retain": { "sessions": 20, "visual": 10, "feedback": 20, "budgetMb": 512 }
160
+ }
161
+ ```
162
+
163
+ Those are the defaults, and every field is optional. `sessions` is how many session journals
164
+ survive, `visual` how many overlay diffs (pixel baselines are never deleted, because the next
165
+ comparison needs them), `feedback` how many local copies of reports already sent, and `budgetMb`
166
+ the total the whole evidence tier may occupy. `0` means keep none, and `"sessions": 0` also stops
167
+ journals being written in the first place.
168
+
169
+ Saved flows, capsules, baselines, the contract and the intent ledger are not touched by any of
170
+ this. They are the part meant to be committed, and a bound that deleted them would be deleting
171
+ the regression checks your team shares.
172
+
173
+ **Your app's own background calls.** An analytics or heartbeat endpoint on your app's own host
174
+ looks exactly like the app's work, so Reticle never guesses. If one of them keeps a verdict
175
+ waiting, or fails and gets blamed on an unrelated action, name it:
176
+
177
+ ```json
178
+ {
179
+ "background": ["/api/analytics/events", "/api/heartbeat"]
180
+ }
181
+ ```
182
+
183
+ Each entry is matched the way `urlContains` is. A listed request stops holding the wait open and
184
+ stops contradicting a claim; when a contradiction is still reported, it lists what was set aside.
185
+ It is never hidden from an assertion that names it: `net { urlContains: "/api/heartbeat" }` still
186
+ sees it. Keep entries specific: `/api` would set aside your whole backend.
187
+ Third-party calls (another site's beacon or SDK) need no entry; they are already set aside.
188
+
153
189
  </Accordion>
154
190
 
155
191
  <Accordion title="vite.config.ts (the plugin)">
@@ -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.2"
178
+ reticle-tauri = "3.4"
179
179
  ```
180
180
 
181
181
  ```rust
@@ -22,7 +22,7 @@ The basics in [Getting Started](getting-started.md) work with **zero app changes
22
22
 
23
23
  Adoption is **free → cheap → targeted**. You don't instrument everything; you reuse what you have, then add the handful of facts the DOM can't express.
24
24
 
25
- **1. Reuse your existing `data-testid` (free).** If you already test with Playwright or Cypress, your testids work in Reticle unchanged; `reticle_query({ by: 'testid', value: 'checkout' })` matches them exactly. No new markup, no new code.
25
+ **1. Reuse your existing `data-testid` (free).** If you already test with Playwright or Cypress, your testids work in Reticle unchanged; `reticle_look({ action: "find", by: 'testid', value: 'checkout' })` matches them exactly. No new markup, no new code.
26
26
 
27
27
  **2. Advertise the surface from your existing constants (cheap).** You already keep a `TestIds` constant object for your E2E suite. Pass it straight in. Now `reticle_capabilities()` tells a fresh agent your whole surface without reading source.
28
28
 
@@ -107,7 +107,7 @@ If `mutate` throws, the mutation never happened, so **the signal is not emitted
107
107
 
108
108
  > **The documented exception:** genuinely view-level signals (render or async completions like `diff:shown` or `caption:generated`, which aren't store state) legitimately stay in your components. Only commit-point signals belong in the store layer.
109
109
 
110
- Pair this with store registration so the agent can _read_ state instead of you emitting a signal per fact: `registerStore('workspace', useWorkspace)`, then `reticle_state({ store: 'workspace' })`.
110
+ Pair this with store registration so the agent can _read_ state instead of you emitting a signal per fact: `registerStore('workspace', useWorkspace)`, then `reticle_look({ action: "state", store: 'workspace' })`.
111
111
 
112
112
  ## 4. Self-registering domains (`registerReticleDomain`)
113
113
 
@@ -164,7 +164,7 @@ Or turn it on with the shipped preset: `plugin.configs.recommended`, which sets
164
164
 
165
165
  Reticle observes and drives a tab through the in-page SDK plus (optionally) CDP. It **cannot bring to front or recover a browser tab the OS won't let it script**: a backgrounded tab, say, or a non-default browser (Dia, etc.) reporting `hidden:true` / `throttled:true`.
166
166
 
167
- When that happens, `reticle_sessions` and every act/assert result carry a `session.recommendation` saying so. The escape hatch is **`reticle drive <url>`** (add `--headed` to watch). Reticle launches and owns a guaranteed-scriptable browser. See [usage §18](usage.md#18-real-input-mode-native-hover--drag) for the full note.
167
+ When that happens, `reticle_session { action: "list" }` and every act/assert result carry a `session.recommendation` saying so. The escape hatch is **`reticle drive <url>`** (add `--headed` to watch). Reticle launches and owns a guaranteed-scriptable browser. See [usage §18](usage.md#18-real-input-mode-native-hover--drag) for the full note.
168
168
 
169
169
  ## Checklist
170
170
 
@@ -45,7 +45,7 @@ This is the design target, and it needs no special setup:
45
45
  - Flows can't bleed into each other: contexts are isolated and every session is scoped by `projectId`.
46
46
  - A single crashed page is reclaimed on its own, and if an agent crashes or hangs its lease stops being touched and the **lease reaper** reclaims the context after a TTL, freeing the slot. One dead agent never starves the others.
47
47
 
48
- `reticle_sessions` lists everything with `projectId` (group by app) and `leased` (pool context vs a human tab), so an orchestrator can see the whole fleet at a glance.
48
+ `reticle_session { action: "list" }` lists everything with `projectId` (group by app) and `leased` (pool context vs a human tab), so an orchestrator can see the whole fleet at a glance.
49
49
 
50
50
  ## Knobs
51
51
 
@@ -76,4 +76,4 @@ module.exports = {
76
76
 
77
77
  ## Why an attribute rather than a runtime lookup
78
78
 
79
- The stamp survives minification of everything else, costs nothing at runtime, and is readable from the DOM node itself. That is what lets [`reticle_inspect`](/tools/inspect) answer with a file and a line rather than a component name and a shrug.
79
+ The stamp survives minification of everything else, costs nothing at runtime, and is readable from the DOM node itself. That is what lets [`reticle_look { action: "element" }`](/tools/inspect) answer with a file and a line rather than a component name and a shrug.
@@ -12,7 +12,7 @@ icon: window
12
12
 
13
13
  This is what makes Reticle different from a browser-automation tool. Because it runs _inside_ the app rather than driving it from outside, it can see a state mutation and a fired signal, not just a rendered pixel. It never imports a Node API; that boundary is enforced by the dependency graph.
14
14
 
15
- [`reticle_query`](/tools/query) speaks role, label and testid instead of CSS selectors through its own local accessibility engine: one engine computes both what elements are called and what they match by, so a reported identity always round-trips.
15
+ [`reticle_look { action: "find" }`](/tools/query) speaks role, label and testid instead of CSS selectors through its own local accessibility engine: one engine computes both what elements are called and what they match by, so a reported identity always round-trips.
16
16
 
17
17
  ## When you need it directly
18
18
 
@@ -90,7 +90,7 @@ Also exported: `getCapabilities()`, `hasCapabilities()`, `setCapabilitiesListene
90
90
 
91
91
  ## State adapters
92
92
 
93
- Register a store and its contents become readable through [`reticle_state`](/tools/state).
93
+ Register a store and its contents become readable through [`reticle_look { action: "state" }`](/tools/state).
94
94
 
95
95
  `registerStore`, `unregisterStore`, `storeNames`, `readStores`, `readStoresWithTruncation`.
96
96
 
@@ -76,7 +76,7 @@ import { useReticleStore } from '@reticlehq/react/store';
76
76
 
77
77
  function Cart() {
78
78
  const [items, setItems] = useState([]);
79
- useReticleStore('cart', items); // now readable via reticle_state
79
+ useReticleStore('cart', items); // now readable via reticle_look { action: "state" }
80
80
  }
81
81
  ```
82
82
 
@@ -87,5 +87,5 @@ function Cart() {
87
87
  React 19 dropped `_debugSource`, so `identify` can name the component but not the file unless something stamps the source at build time. That is [`@reticlehq/babel-plugin`](/packages/babel-plugin), pulled in for you by [`@reticlehq/vite-plugin`](/packages/vite-plugin) or [`@reticlehq/next`](/packages/next).
88
88
 
89
89
  <Card title="Reading component state" icon="layer-group" href="/state-management">
90
- What `reticle_state` can see, and how to widen it.
90
+ What `reticle_look { action: "state" }` can see, and how to widen it.
91
91
  </Card>
@@ -21,7 +21,7 @@ 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.2"
24
+ reticle-tauri = "3.4"
25
25
  ```
26
26
 
27
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.
@@ -61,7 +61,7 @@ Plus a dynamic import of your dev module if one exists. It looks for `src/reticl
61
61
  | `token` | `string` | `readPairingToken()`, from `~/.reticle/pairing-token` |
62
62
  | `sourceMapping` | `boolean` | `true`. Set `false` to skip the Babel pass |
63
63
  | `inject` | `boolean` | `true`. Set `false` to call `connect()` yourself |
64
- | `desktop` | `boolean` | `false`. When `true` the plugin also applies to `vite build` and passes `allowInProduction: true`, which is what an Electron or Tauri renderer needs |
64
+ | `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
65
  | `captureNetworkBodies` | `boolean` | `false`. Also enabled by `VITE_RETICLE_CAPTURE_BODIES=1` |
66
66
  | `onWarn` | `(message: string) => void` | `console.warn` |
67
67
 
@@ -87,7 +87,7 @@ Types: `ReticleVitePluginOptions`, `ReticleVitePlugin`, `ViteDevServerLike`.
87
87
  reticle({ desktop: true });
88
88
  ```
89
89
 
90
- A packaged Electron or Tauri renderer is a production build loaded from a custom protocol, so the default guards would refuse. This one flag drops `apply: 'serve'` and opts the connect call into production.
90
+ A packaged Electron or Tauri renderer is loaded from a custom protocol with no dev server and reports `NODE_ENV=production`, so the default guards would refuse. This flag injects the connect into the entry module and opts it into production. It does NOT instrument a release: a production-mode `vite build` (the default) ships no Reticle code, exactly like a web build. To drive a packaged renderer with no dev server, build it with `vite build --mode development`.
91
91
 
92
92
  <Card title="Desktop wiring in full" icon="display" href="/desktop">
93
93
  Including the Tauri CSP whose failure is completely silent.
package/docs/packages.mdx CHANGED
@@ -38,12 +38,12 @@ You never install `@reticlehq/server`. Your agent runs it with `npx`.
38
38
 
39
39
  The package split is not cosmetic. Each boundary enforces something:
40
40
 
41
- | Package | Runs in | Hard rule |
42
- | --------- | ----------- | ------------------------------------------------------ |
43
- | `core` | both | Depends only on `zod`. Sits at the bottom of the graph |
44
- | `browser` | the browser | Never imports a Node API |
45
- | `server` | Node | Never imports a DOM API |
46
- | `react` | the browser | Optional. Core must work without it |
41
+ | Package | Runs in | Hard rule |
42
+ | --- | --- | --- |
43
+ | `core` | both | Depends only on `zod` and `open-verification`. Sits at the bottom of the graph |
44
+ | `browser` | the browser | Never imports a Node API |
45
+ | `server` | Node | Never imports a DOM API |
46
+ | `react` | the browser | Optional. Core must work without it |
47
47
 
48
48
  Those rules are why the browser SDK cannot accidentally pull in a filesystem call, and why the server cannot accidentally depend on `window`. They are enforced by the dependency graph, not by discipline.
49
49
 
@@ -72,7 +72,7 @@ Those rules are why the browser SDK cannot accidentally pull in a filesystem cal
72
72
 
73
73
  **Why it exists:** this is the part that makes Reticle different from a browser-automation tool. Because it runs _inside_ the app rather than driving it from outside, it can see a state mutation and a fired signal, not just a rendered pixel.
74
74
 
75
- **Depends on:** `@reticlehq/core`. [`reticle_query`](/tools/query) speaks role, label and testid rather than CSS selectors through its own local accessibility engine, so what a snapshot reports is exactly what a query matches.
75
+ **Depends on:** `@reticlehq/core`. [`reticle_look { action: "find" }`](/tools/query) speaks role, label and testid rather than CSS selectors through its own local accessibility engine, so what a snapshot reports is exactly what a query matches.
76
76
 
77
77
  **Install it directly when** you are not on React, or you want `connect()` under your own control:
78
78
 
@@ -147,7 +147,7 @@ export default defineConfig({ plugins: [reticle(), react()] });
147
147
 
148
148
  **Stamps `data-reticle-source="file:line:col"` onto JSX host elements.**
149
149
 
150
- **Why it exists:** React 19 dropped `_debugSource`, which is what source mapping used to rely on. This plugin puts the information back, at build time, in dev only. Without it, `reticle_inspect` can still tell you the component name but not the file.
150
+ **Why it exists:** React 19 dropped `_debugSource`, which is what source mapping used to rely on. This plugin puts the information back, at build time, in dev only. Without it, `reticle_look { action: "element" }` can still tell you the component name but not the file.
151
151
 
152
152
  **Depends on:** nothing. **Peer:** `@babel/core`.
153
153
 
@@ -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.2"
242
+ reticle-tauri = "3.4"
243
243
  ```
244
244
 
245
245
  <Warning>