@reticlehq/server 3.6.0 → 3.7.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 (614) hide show
  1. package/SKILL.md +122 -123
  2. package/dist/command/cli/adhoc-suite.d.ts +14 -0
  3. package/dist/command/cli/adhoc-suite.js +42 -7
  4. package/dist/command/cli/adhoc-verdict.d.ts +18 -2
  5. package/dist/command/cli/adhoc-verdict.js +70 -6
  6. package/dist/command/cli/answers/gate-exit.d.ts +23 -0
  7. package/dist/command/cli/answers/gate-exit.js +45 -0
  8. package/dist/command/cli/answers/gate-hook-message.d.ts +2 -0
  9. package/dist/command/cli/answers/gate-hook-message.js +3 -1
  10. package/dist/command/cli/auth/device-flow.d.ts +13 -2
  11. package/dist/command/cli/auth/device-flow.js +17 -0
  12. package/dist/command/cli/cli-doctor.js +14 -0
  13. package/dist/command/cli/cli-flow-commands.d.ts +0 -11
  14. package/dist/command/cli/cli-flow-commands.js +28 -105
  15. package/dist/command/cli/cli-kill.js +3 -2
  16. package/dist/command/cli/cli-parse-grammar.d.ts +24 -0
  17. package/dist/command/cli/cli-parse-grammar.js +75 -0
  18. package/dist/command/cli/cli-parse-verify.d.ts +2 -0
  19. package/dist/command/cli/cli-parse-verify.js +18 -0
  20. package/dist/command/cli/cli-parse.d.ts +19 -28
  21. package/dist/command/cli/cli-parse.js +82 -182
  22. package/dist/command/cli/cli-update-commands.d.ts +1 -1
  23. package/dist/command/cli/cli-update-commands.js +61 -9
  24. package/dist/command/cli/cli-usage.d.ts +33 -0
  25. package/dist/command/cli/cli-usage.js +287 -0
  26. package/dist/command/cli/cli-verify.d.ts +34 -4
  27. package/dist/command/cli/cli-verify.js +81 -12
  28. package/dist/command/cli/cloud-cli.d.ts +13 -0
  29. package/dist/command/cli/cloud-cli.js +145 -333
  30. package/dist/command/cli/cloud-kit.d.ts +12 -0
  31. package/dist/command/cli/cloud-kit.js +41 -2
  32. package/dist/command/cli/cloud-link.d.ts +57 -0
  33. package/dist/command/cli/cloud-link.js +308 -0
  34. package/dist/command/cli/cloud-login.d.ts +15 -1
  35. package/dist/command/cli/cloud-login.js +67 -13
  36. package/dist/command/cli/context-command.d.ts +1 -0
  37. package/dist/command/cli/context-command.js +33 -0
  38. package/dist/command/cli/daemon-start-options.d.ts +3 -0
  39. package/dist/command/cli/daemon-start-options.js +24 -3
  40. package/dist/command/cli/doctor/doctor-coverage-line.d.ts +2 -0
  41. package/dist/command/cli/doctor/doctor-coverage-line.js +47 -0
  42. package/dist/command/cli/doctor/doctor-project-line.d.ts +0 -12
  43. package/dist/command/cli/doctor/doctor-project-line.js +5 -4
  44. package/dist/command/cli/doctor/doctor-rows.d.ts +6 -0
  45. package/dist/command/cli/doctor/doctor-rows.js +6 -0
  46. package/dist/command/cli/doctor/doctor-signing-line.d.ts +38 -0
  47. package/dist/command/cli/doctor/doctor-signing-line.js +114 -0
  48. package/dist/command/cli/known-regression.d.ts +13 -0
  49. package/dist/command/cli/known-regression.js +34 -0
  50. package/dist/command/cli/launch/sdk-version-match.d.ts +12 -0
  51. package/dist/command/cli/launch/sdk-version-match.js +25 -0
  52. package/dist/command/cli/lifecycle/daemon-lifecycle.js +11 -2
  53. package/dist/command/cli/mcp-command.d.ts +6 -0
  54. package/dist/command/cli/mcp-command.js +13 -5
  55. package/dist/command/cli/ports/port-holder.js +1 -1
  56. package/dist/command/cli/project-name.d.ts +29 -1
  57. package/dist/command/cli/project-name.js +107 -2
  58. package/dist/command/cli/setup-mcp-cli.d.ts +17 -1
  59. package/dist/command/cli/setup-mcp-cli.js +29 -8
  60. package/dist/command/cli/status/status-lines.d.ts +1 -0
  61. package/dist/command/cli/status/status-lines.js +47 -2
  62. package/dist/command/cli/status/workspace-links.d.ts +10 -0
  63. package/dist/command/cli/status/workspace-links.js +29 -0
  64. package/dist/command/cli/try-command.d.ts +96 -0
  65. package/dist/command/cli/try-command.js +362 -0
  66. package/dist/command/cli/tutorial.d.ts +0 -100
  67. package/dist/command/cli/tutorial.js +0 -178
  68. package/dist/command/cli/verify-results.d.ts +19 -0
  69. package/dist/command/cli/verify-results.js +29 -0
  70. package/dist/command/cli-onboarding.d.ts +0 -11
  71. package/dist/command/cli-onboarding.js +0 -15
  72. package/dist/command/cli.d.ts +14 -0
  73. package/dist/command/cli.js +103 -83
  74. package/dist/command/daemon/daemon-resilience.js +4 -4
  75. package/dist/command/daemon/daemon-resolve.d.ts +9 -1
  76. package/dist/command/daemon/daemon-resolve.js +49 -10
  77. package/dist/command/setup/bringup/bridge-port.d.ts +3 -1
  78. package/dist/command/setup/bringup/bridge-port.js +13 -3
  79. package/dist/command/setup/bringup/dev-server-log-cap.js +2 -0
  80. package/dist/command/setup/bringup/ensure-daemon.js +9 -2
  81. package/dist/command/setup/init/agent-restart.d.ts +23 -0
  82. package/dist/command/setup/init/agent-restart.js +28 -0
  83. package/dist/command/setup/init/init-port.d.ts +10 -1
  84. package/dist/command/setup/init/init-port.js +22 -2
  85. package/dist/command/setup/init/init-runtime.d.ts +12 -2
  86. package/dist/command/setup/init/init-runtime.js +96 -37
  87. package/dist/command/setup/node-effects.d.ts +2 -0
  88. package/dist/command/setup/node-effects.js +36 -8
  89. package/dist/command/setup/probe/existing-app.d.ts +12 -0
  90. package/dist/command/setup/probe/existing-app.js +14 -0
  91. package/dist/command/setup/remaining-steps.js +1 -1
  92. package/dist/command/setup/run-setup.d.ts +29 -9
  93. package/dist/command/setup/run-setup.js +34 -28
  94. package/dist/command/setup/setup-command.d.ts +23 -0
  95. package/dist/command/setup/setup-command.js +57 -4
  96. package/dist/command/setup/setup-mcp.js +25 -2
  97. package/dist/command/setup/tauri-signing.d.ts +19 -0
  98. package/dist/command/setup/tauri-signing.js +79 -0
  99. package/dist/command/setup/terminal/listeners.d.ts +10 -1
  100. package/dist/command/setup/terminal/listeners.js +37 -6
  101. package/dist/command/update/update-nudge.d.ts +9 -0
  102. package/dist/command/update/update-nudge.js +1 -1
  103. package/dist/command/update/updater.js +11 -15
  104. package/dist/command/version/version-nudge.js +3 -0
  105. package/dist/command/version/version-skew.d.ts +20 -1
  106. package/dist/command/version/version-skew.js +38 -2
  107. package/dist/features/crawl/crawl.js +14 -1
  108. package/dist/features/exhaust/ledger.d.ts +14 -14
  109. package/dist/features/harness/drive-report.d.ts +39 -5
  110. package/dist/features/harness/drive-report.js +271 -54
  111. package/dist/features/harness/drive-runs.d.ts +120 -0
  112. package/dist/features/harness/drive-runs.js +289 -0
  113. package/dist/features/harness/drivers.d.ts +1 -1
  114. package/dist/features/harness/drivers.js +1 -1
  115. package/dist/features/harness/explore/console-pages.d.ts +15 -0
  116. package/dist/features/harness/explore/console-pages.js +146 -0
  117. package/dist/features/harness/explore/disparity.d.ts +19 -0
  118. package/dist/features/harness/explore/disparity.js +71 -0
  119. package/dist/features/harness/explore/fake-app.d.ts +16 -0
  120. package/dist/features/harness/explore/fake-app.js +49 -0
  121. package/dist/features/harness/explore/goal-search.d.ts +26 -0
  122. package/dist/features/harness/explore/goal-search.js +144 -0
  123. package/dist/features/harness/explore/page-tree.d.ts +49 -0
  124. package/dist/features/harness/explore/page-tree.js +148 -0
  125. package/dist/features/harness/explore/site-map.d.ts +34 -0
  126. package/dist/features/harness/explore/site-map.js +150 -0
  127. package/dist/features/harness/goals.d.ts +68 -7
  128. package/dist/features/harness/goals.js +289 -36
  129. package/dist/features/harness/harness.d.ts +30 -1
  130. package/dist/features/harness/harness.js +141 -7
  131. package/dist/features/harness/platform/local-apps.d.ts +36 -3
  132. package/dist/features/harness/platform/local-apps.js +81 -5
  133. package/dist/features/harness/platform/persona-credentials.d.ts +20 -0
  134. package/dist/features/harness/platform/persona-credentials.js +69 -0
  135. package/dist/features/harness/platform/platform-drives.d.ts +61 -0
  136. package/dist/features/harness/platform/platform-drives.js +114 -0
  137. package/dist/features/harness/platform/refusal.d.ts +52 -0
  138. package/dist/features/harness/platform/refusal.js +71 -0
  139. package/dist/features/harness/platform/remote-drive.d.ts +8 -2
  140. package/dist/features/harness/platform/remote-drive.js +22 -9
  141. package/dist/features/harness/platform/script.d.ts +57 -11
  142. package/dist/features/harness/platform/script.js +144 -12
  143. package/dist/features/harness/platform/server-driver.d.ts +17 -4
  144. package/dist/features/harness/platform/server-driver.js +29 -26
  145. package/dist/features/harness/platform-config.d.ts +38 -5
  146. package/dist/features/harness/platform-config.js +93 -8
  147. package/dist/features/harness/route-guess.d.ts +13 -0
  148. package/dist/features/harness/route-guess.js +49 -0
  149. package/dist/features/harness/script/script-run.d.ts +30 -1
  150. package/dist/features/harness/script/script-run.js +355 -48
  151. package/dist/features/license/license.d.ts +2 -2
  152. package/dist/features/visual/step-shots.d.ts +31 -0
  153. package/dist/features/visual/step-shots.js +231 -0
  154. package/dist/features/visual/visual-tools.js +22 -14
  155. package/dist/hooks/client-directory.d.ts +18 -0
  156. package/dist/hooks/client-directory.js +57 -0
  157. package/dist/hooks/coding-agents.d.ts +34 -0
  158. package/dist/hooks/coding-agents.js +117 -0
  159. package/dist/hooks/driven-by.d.ts +21 -2
  160. package/dist/hooks/driven-by.js +42 -2
  161. package/dist/hooks/hook-bus.d.ts +4 -0
  162. package/dist/hooks/hook-bus.js +18 -0
  163. package/dist/index.d.ts +1 -0
  164. package/dist/index.js +26 -183
  165. package/dist/judgement/capsule/capsule-store.d.ts +2 -2
  166. package/dist/judgement/capsule/causal-summary.d.ts +15 -1
  167. package/dist/judgement/capsule/causal-summary.js +33 -0
  168. package/dist/judgement/runs/artifact/build-verification-run.d.ts +1 -1
  169. package/dist/judgement/runs/artifact/build-verification-run.js +20 -4
  170. package/dist/judgement/runs/artifact/gap-summary.d.ts +0 -18
  171. package/dist/judgement/runs/artifact/gap-summary.js +12 -3
  172. package/dist/judgement/runs/artifact/replay-mapping.js +25 -9
  173. package/dist/judgement/runs/artifact/run-store.d.ts +13 -1
  174. package/dist/judgement/runs/artifact/run-store.js +175 -8
  175. package/dist/judgement/runs/context-tools.js +59 -1
  176. package/dist/judgement/runs/default-run-id.d.ts +3 -0
  177. package/dist/judgement/runs/default-run-id.js +16 -0
  178. package/dist/judgement/runs/drive-run.d.ts +53 -5
  179. package/dist/judgement/runs/drive-run.js +234 -20
  180. package/dist/judgement/runs/resume.d.ts +44 -0
  181. package/dist/judgement/runs/resume.js +137 -0
  182. package/dist/judgement/runs/reticle-runner.js +5 -2
  183. package/dist/judgement/runs/runner-port.d.ts +5 -1
  184. package/dist/judgement/runs/runner-port.js +8 -2
  185. package/dist/judgement/runs/verification-sync.d.ts +2 -0
  186. package/dist/judgement/runs/verification-sync.js +36 -15
  187. package/dist/language/flows/decision.js +2 -1
  188. package/dist/language/flows/fields/flow-secret-field.d.ts +12 -0
  189. package/dist/language/flows/fields/flow-secret-field.js +25 -2
  190. package/dist/language/flows/flow-anchor.d.ts +7 -2
  191. package/dist/language/flows/flow-anchor.js +10 -3
  192. package/dist/language/flows/flow-intent.d.ts +1 -0
  193. package/dist/language/flows/flow-journey.d.ts +6 -0
  194. package/dist/language/flows/flow-journey.js +20 -0
  195. package/dist/language/flows/flow-learning.d.ts +4 -0
  196. package/dist/language/flows/flow-learning.js +37 -3
  197. package/dist/language/flows/flow-replay-run.js +16 -18
  198. package/dist/language/flows/flow-replay-types.d.ts +1 -1
  199. package/dist/language/flows/flow-replay.d.ts +18 -1
  200. package/dist/language/flows/flow-replay.js +22 -7
  201. package/dist/language/flows/flow-result.d.ts +22 -1
  202. package/dist/language/flows/flow-result.js +47 -2
  203. package/dist/language/flows/flow-step-runners.d.ts +2 -0
  204. package/dist/language/flows/flow-step-runners.js +12 -6
  205. package/dist/language/flows/flow-store-for-session.js +5 -1
  206. package/dist/language/flows/flow-tools.d.ts +10 -0
  207. package/dist/language/flows/flow-tools.js +61 -62
  208. package/dist/language/flows/flows.d.ts +16 -1
  209. package/dist/language/flows/flows.js +69 -10
  210. package/dist/language/flows/narrow-write.d.ts +7 -0
  211. package/dist/language/flows/narrow-write.js +36 -1
  212. package/dist/language/flows/recording/recording-backtrack.js +14 -1
  213. package/dist/language/flows/recording/tape/recordings.d.ts +29 -1
  214. package/dist/language/flows/recording/tape/recordings.js +60 -10
  215. package/dist/language/flows/replay.js +29 -6
  216. package/dist/language/flows/single-replay.d.ts +7 -0
  217. package/dist/language/flows/single-replay.js +26 -0
  218. package/dist/language/flows/verify-change-tools.d.ts +1 -0
  219. package/dist/language/flows/verify-change-tools.js +200 -193
  220. package/dist/memory/cloud/cloud-config.d.ts +10 -1
  221. package/dist/memory/cloud/cloud-config.js +19 -5
  222. package/dist/memory/cloud/cloud-sync.js +3 -3
  223. package/dist/memory/cloud/harness-config.d.ts +49 -0
  224. package/dist/memory/cloud/harness-config.js +16 -20
  225. package/dist/memory/cloud/memory-scope.d.ts +17 -0
  226. package/dist/memory/cloud/memory-scope.js +22 -0
  227. package/dist/memory/cloud/sync-cycle.d.ts +32 -4
  228. package/dist/memory/cloud/sync-cycle.js +113 -12
  229. package/dist/memory/cloud/sync-daemon.d.ts +11 -0
  230. package/dist/memory/cloud/sync-daemon.js +114 -4
  231. package/dist/memory/cloud/sync-disk.js +26 -2
  232. package/dist/memory/cloud/sync-screenshots.d.ts +32 -0
  233. package/dist/memory/cloud/sync-screenshots.js +105 -0
  234. package/dist/memory/cloud/unsynced-roots.d.ts +47 -0
  235. package/dist/memory/cloud/unsynced-roots.js +166 -0
  236. package/dist/memory/impact/account-watch.d.ts +16 -1
  237. package/dist/memory/impact/account-watch.js +26 -1
  238. package/dist/memory/impact/impact-store.d.ts +1 -4
  239. package/dist/memory/impact/impact-store.js +32 -42
  240. package/dist/memory/intent/inline-intent.d.ts +1 -0
  241. package/dist/memory/intent/intent-shard-store.js +16 -4
  242. package/dist/memory/intent/intent-shard.d.ts +12 -0
  243. package/dist/memory/intent/intent-store.d.ts +1 -0
  244. package/dist/memory/intent/intent-tools.js +42 -2
  245. package/dist/memory/intent/open-intents.d.ts +6 -0
  246. package/dist/memory/intent/open-intents.js +10 -1
  247. package/dist/memory/intent/settled-words.d.ts +24 -0
  248. package/dist/memory/intent/settled-words.js +130 -0
  249. package/dist/memory/journal/drive-flow.d.ts +16 -0
  250. package/dist/memory/journal/drive-flow.js +34 -2
  251. package/dist/memory/journal/drive-run-flush.d.ts +2 -0
  252. package/dist/memory/journal/drive-run-flush.js +20 -5
  253. package/dist/memory/journal/journal-recorder.js +46 -3
  254. package/dist/memory/journal/on-disk/retention.d.ts +5 -0
  255. package/dist/memory/journal/on-disk/retention.js +27 -2
  256. package/dist/memory/journal/on-disk/workspace-tiers.js +2 -0
  257. package/dist/memory/journal/session-end.d.ts +15 -1
  258. package/dist/memory/journal/session-end.js +38 -7
  259. package/dist/memory/project/artifact-root-resolver.js +33 -5
  260. package/dist/memory/project/artifact-root.d.ts +4 -3
  261. package/dist/memory/project/artifact-root.js +2 -2
  262. package/dist/memory/project/dir/reticle-dir.d.ts +14 -0
  263. package/dist/memory/project/dir/reticle-dir.js +23 -2
  264. package/dist/memory/project/link-directory.d.ts +15 -0
  265. package/dist/memory/project/link-directory.js +44 -0
  266. package/dist/memory/project/root-claims.d.ts +6 -0
  267. package/dist/memory/project/root-claims.js +39 -0
  268. package/dist/memory/project/session-root.d.ts +2 -0
  269. package/dist/memory/project/session-root.js +9 -1
  270. package/dist/memory/project/sync-status.d.ts +46 -0
  271. package/dist/memory/project/sync-status.js +135 -1
  272. package/dist/memory/recall/memory-tools.js +46 -3
  273. package/dist/memory/recall/platform-memory.d.ts +34 -0
  274. package/dist/memory/recall/platform-memory.js +139 -0
  275. package/dist/memory/recall/project-memory.js +36 -8
  276. package/dist/portal/bridge/bridge.d.ts +9 -5
  277. package/dist/portal/bridge/bridge.js +66 -23
  278. package/dist/portal/bridge/harness-request.d.ts +23 -0
  279. package/dist/portal/bridge/harness-request.js +27 -0
  280. package/dist/portal/bridge/wrong-path.d.ts +17 -0
  281. package/dist/portal/bridge/wrong-path.js +35 -0
  282. package/dist/portal/input/network-mock-tools.js +11 -2
  283. package/dist/portal/input/real-input.d.ts +2 -0
  284. package/dist/portal/input/real-input.js +13 -10
  285. package/dist/portal/pool/browser-pool.d.ts +48 -0
  286. package/dist/portal/pool/browser-pool.js +120 -2
  287. package/dist/portal/pool/context-permissions.d.ts +33 -0
  288. package/dist/portal/pool/context-permissions.js +33 -0
  289. package/dist/portal/pool/lease-marker-stamp.d.ts +23 -0
  290. package/dist/portal/pool/lease-marker-stamp.js +49 -0
  291. package/dist/portal/pool/playwright-launcher.d.ts +27 -5
  292. package/dist/portal/pool/playwright-launcher.js +59 -14
  293. package/dist/portal/pool/pool-contract.d.ts +21 -1
  294. package/dist/portal/session/agent-link.d.ts +8 -0
  295. package/dist/portal/session/agent-link.js +17 -0
  296. package/dist/portal/session/command-payload.js +6 -1
  297. package/dist/portal/session/daemon-answers.d.ts +3 -3
  298. package/dist/portal/session/daemon-answers.js +4 -2
  299. package/dist/portal/session/dev-server/dev-command.d.ts +9 -0
  300. package/dist/portal/session/dev-server/dev-command.js +27 -1
  301. package/dist/portal/session/facts/observed-state.d.ts +16 -18
  302. package/dist/portal/session/facts/observed-state.js +46 -3
  303. package/dist/portal/session/human/live-control.d.ts +9 -2
  304. package/dist/portal/session/human/live-control.js +12 -3
  305. package/dist/portal/session/live-control-tools.js +82 -13
  306. package/dist/portal/session/narration-args.d.ts +5 -0
  307. package/dist/portal/session/narration-args.js +17 -0
  308. package/dist/portal/session/no-session-diagnosis.d.ts +1 -1
  309. package/dist/portal/session/no-session-diagnosis.js +31 -9
  310. package/dist/portal/session/no-session-next-action.d.ts +20 -0
  311. package/dist/portal/session/no-session-next-action.js +134 -61
  312. package/dist/portal/session/no-session-watch.js +179 -22
  313. package/dist/portal/session/presence/session-lease.js +1 -1
  314. package/dist/portal/session/recorded-gaps.d.ts +97 -0
  315. package/dist/portal/session/recorded-gaps.js +251 -0
  316. package/dist/portal/session/session-health.d.ts +11 -0
  317. package/dist/portal/session/session-health.js +3 -1
  318. package/dist/portal/session/session-info.js +2 -1
  319. package/dist/portal/session/session-manager.d.ts +18 -0
  320. package/dist/portal/session/session-manager.js +54 -3
  321. package/dist/portal/session/session-successor.d.ts +8 -0
  322. package/dist/portal/session/session-successor.js +1 -1
  323. package/dist/portal/session/session.d.ts +15 -28
  324. package/dist/portal/session/session.js +60 -61
  325. package/dist/portal/session/timing/command-timeout.js +25 -1
  326. package/dist/portal/session/timing/wall-clock.d.ts +1 -1
  327. package/dist/portal/session/timing/wall-clock.js +1 -1
  328. package/dist/portal/session/zero-install-first-call.d.ts +31 -0
  329. package/dist/portal/session/zero-install-first-call.js +88 -0
  330. package/dist/start-options.d.ts +7 -1
  331. package/dist/start-wiring.d.ts +63 -0
  332. package/dist/start-wiring.js +169 -0
  333. package/dist/status-payload.d.ts +13 -1
  334. package/dist/status-payload.js +13 -1
  335. package/dist/surface/http-server.js +7 -1
  336. package/dist/surface/mcp/attach-memory.d.ts +1 -0
  337. package/dist/surface/mcp/attach-memory.js +12 -1
  338. package/dist/surface/mcp/mcp-proxy.d.ts +4 -0
  339. package/dist/surface/mcp/mcp-proxy.js +29 -8
  340. package/dist/surface/mcp/mcp.d.ts +23 -0
  341. package/dist/surface/mcp/mcp.js +34 -4
  342. package/dist/surface/mcp/proxy/drive-calls.d.ts +10 -0
  343. package/dist/surface/mcp/proxy/drive-calls.js +27 -0
  344. package/dist/surface/mcp/proxy/mcp-post-transport.js +5 -0
  345. package/dist/surface/mcp/server-instructions.js +22 -14
  346. package/dist/surface/mcp/shared-params.js +1 -1
  347. package/dist/surface/mcp/surface-vocabulary.d.ts +2 -0
  348. package/dist/surface/mcp/surface-vocabulary.js +1 -0
  349. package/dist/surface/tools/account-tool.d.ts +22 -0
  350. package/dist/surface/tools/account-tool.js +157 -0
  351. package/dist/surface/tools/act/act-danger.d.ts +11 -0
  352. package/dist/surface/tools/act/act-danger.js +38 -1
  353. package/dist/surface/tools/act/act-observation.d.ts +33 -0
  354. package/dist/surface/tools/act/act-observation.js +57 -0
  355. package/dist/surface/tools/act/act-preflight.js +25 -2
  356. package/dist/surface/tools/act/act-target.js +8 -3
  357. package/dist/surface/tools/act/resolve-target.d.ts +1 -1
  358. package/dist/surface/tools/act/resolve-target.js +18 -3
  359. package/dist/surface/tools/act/screen-request.d.ts +34 -0
  360. package/dist/surface/tools/act/screen-request.js +113 -0
  361. package/dist/surface/tools/act/sequence-grade.d.ts +8 -0
  362. package/dist/surface/tools/act/sequence-grade.js +13 -2
  363. package/dist/surface/tools/act-sequence-tool.js +136 -27
  364. package/dist/surface/tools/act-tools.d.ts +0 -9
  365. package/dist/surface/tools/act-tools.js +48 -34
  366. package/dist/surface/tools/agent/app-notes-learning.d.ts +7 -0
  367. package/dist/surface/tools/agent/app-notes-learning.js +80 -0
  368. package/dist/surface/tools/agent/app-notes.d.ts +4 -0
  369. package/dist/surface/tools/agent/app-notes.js +48 -0
  370. package/dist/surface/tools/agent/build-staleness.d.ts +7 -0
  371. package/dist/surface/tools/agent/build-staleness.js +62 -0
  372. package/dist/surface/tools/agent/compact-envelope.d.ts +80 -0
  373. package/dist/surface/tools/agent/compact-envelope.js +374 -0
  374. package/dist/surface/tools/agent/for-the-agent.d.ts +12 -0
  375. package/dist/surface/tools/agent/for-the-agent.js +44 -0
  376. package/dist/surface/tools/agent/notices.d.ts +50 -0
  377. package/dist/surface/tools/agent/notices.js +152 -0
  378. package/dist/surface/tools/agent/reteach.d.ts +11 -0
  379. package/dist/surface/tools/agent/reteach.js +50 -0
  380. package/dist/surface/tools/args/alias-args.d.ts +5 -0
  381. package/dist/surface/tools/args/alias-args.js +10 -0
  382. package/dist/surface/tools/args/confirm-dangerous-arg.d.ts +6 -0
  383. package/dist/surface/tools/args/confirm-dangerous-arg.js +6 -0
  384. package/dist/surface/tools/assert/assert-source.d.ts +15 -0
  385. package/dist/surface/tools/assert/assert-source.js +40 -0
  386. package/dist/surface/tools/assert/assert-verdict.js +25 -15
  387. package/dist/surface/tools/browser-tools.js +43 -1
  388. package/dist/surface/tools/chat-drives.d.ts +75 -0
  389. package/dist/surface/tools/chat-drives.js +265 -21
  390. package/dist/surface/tools/coverage-tools.d.ts +2 -10
  391. package/dist/surface/tools/coverage-tools.js +2 -53
  392. package/dist/surface/tools/dynamic-tools.js +29 -1
  393. package/dist/surface/tools/empty-session-list.d.ts +10 -0
  394. package/dist/surface/tools/empty-session-list.js +45 -5
  395. package/dist/surface/tools/error-recovery.d.ts +8 -0
  396. package/dist/surface/tools/error-recovery.js +69 -5
  397. package/dist/surface/tools/explore-tools.d.ts +23 -2
  398. package/dist/surface/tools/explore-tools.js +377 -74
  399. package/dist/surface/tools/feedback-tools.d.ts +2 -3
  400. package/dist/surface/tools/feedback-tools.js +4 -3
  401. package/dist/surface/tools/gap-novelty.d.ts +3 -1
  402. package/dist/surface/tools/gap-novelty.js +8 -1
  403. package/dist/surface/tools/harness-explore.d.ts +52 -73
  404. package/dist/surface/tools/harness-explore.js +177 -146
  405. package/dist/surface/tools/harness-gate.d.ts +88 -0
  406. package/dist/surface/tools/harness-gate.js +235 -0
  407. package/dist/surface/tools/harness-hunt.d.ts +43 -0
  408. package/dist/surface/tools/harness-hunt.js +215 -0
  409. package/dist/surface/tools/harness-plan.d.ts +5 -0
  410. package/dist/surface/tools/harness-plan.js +7 -0
  411. package/dist/surface/tools/harness-script.d.ts +22 -0
  412. package/dist/surface/tools/harness-script.js +256 -38
  413. package/dist/surface/tools/harness-tab-guard.d.ts +5 -0
  414. package/dist/surface/tools/harness-tab-guard.js +27 -0
  415. package/dist/surface/tools/harness-toolset.d.ts +8 -0
  416. package/dist/surface/tools/harness-toolset.js +27 -4
  417. package/dist/surface/tools/human-notes.d.ts +16 -0
  418. package/dist/surface/tools/human-notes.js +27 -0
  419. package/dist/surface/tools/invoke-tool.d.ts +5 -2
  420. package/dist/surface/tools/invoke-tool.js +220 -93
  421. package/dist/surface/tools/lease-hint.js +26 -5
  422. package/dist/surface/tools/lease-permissions.d.ts +33 -0
  423. package/dist/surface/tools/lease-permissions.js +73 -0
  424. package/dist/surface/tools/lease-readiness.d.ts +38 -0
  425. package/dist/surface/tools/lease-readiness.js +57 -0
  426. package/dist/surface/tools/lease-seed.d.ts +20 -0
  427. package/dist/surface/tools/lease-seed.js +45 -1
  428. package/dist/surface/tools/lease-tools.d.ts +10 -1
  429. package/dist/surface/tools/lease-tools.js +119 -69
  430. package/dist/surface/tools/live-call-text.js +2 -2
  431. package/dist/surface/tools/merge-tools.js +42 -2
  432. package/dist/surface/tools/merged-name-redirect.js +4 -0
  433. package/dist/surface/tools/next-step.d.ts +11 -1
  434. package/dist/surface/tools/next-step.js +73 -18
  435. package/dist/surface/tools/observe-tools.js +43 -5
  436. package/dist/surface/tools/platform-moment.d.ts +60 -0
  437. package/dist/surface/tools/platform-moment.js +132 -4
  438. package/dist/surface/tools/read-tools.js +65 -14
  439. package/dist/surface/tools/reticle-result.d.ts +120 -0
  440. package/dist/surface/tools/reticle-result.js +364 -0
  441. package/dist/surface/tools/tool-kit.d.ts +68 -2
  442. package/dist/surface/tools/tool-kit.js +73 -1
  443. package/dist/surface/tools/tools.js +25 -13
  444. package/dist/telemetry/account-envelope.d.ts +7 -0
  445. package/dist/telemetry/account-envelope.js +61 -0
  446. package/dist/telemetry/agent-client.d.ts +15 -0
  447. package/dist/telemetry/agent-client.js +57 -0
  448. package/dist/telemetry/app-instrumented.js +9 -2
  449. package/dist/telemetry/argument-shape.d.ts +7 -0
  450. package/dist/telemetry/argument-shape.js +86 -1
  451. package/dist/telemetry/automation-hint.d.ts +2 -3
  452. package/dist/telemetry/automation-hint.js +33 -8
  453. package/dist/telemetry/cli-telemetry.js +7 -2
  454. package/dist/telemetry/daemon-telemetry.js +3 -0
  455. package/dist/telemetry/error-fingerprint.d.ts +10 -1
  456. package/dist/telemetry/error-fingerprint.js +61 -5
  457. package/dist/telemetry/feedback-cli.d.ts +0 -13
  458. package/dist/telemetry/feedback-cli.js +0 -77
  459. package/dist/telemetry/feedback.d.ts +13 -0
  460. package/dist/telemetry/feedback.js +183 -17
  461. package/dist/telemetry/harness-run.d.ts +18 -0
  462. package/dist/telemetry/harness-run.js +80 -0
  463. package/dist/telemetry/hud-events.d.ts +16 -0
  464. package/dist/telemetry/hud-events.js +27 -0
  465. package/dist/telemetry/hud-metrics.d.ts +27 -6
  466. package/dist/telemetry/hud-metrics.js +99 -25
  467. package/dist/telemetry/init-telemetry.js +2 -2
  468. package/dist/telemetry/install-source.d.ts +13 -25
  469. package/dist/telemetry/install-source.js +44 -3
  470. package/dist/telemetry/mcp-connection.d.ts +0 -14
  471. package/dist/telemetry/mcp-connection.js +5 -1
  472. package/dist/telemetry/onboarding-firsts.d.ts +32 -0
  473. package/dist/telemetry/onboarding-firsts.js +81 -6
  474. package/dist/telemetry/platform-linked.d.ts +5 -0
  475. package/dist/telemetry/platform-linked.js +32 -0
  476. package/dist/telemetry/project-profile.js +5 -3
  477. package/dist/telemetry/proxy-telemetry.js +4 -1
  478. package/dist/telemetry/session-metrics.d.ts +15 -4
  479. package/dist/telemetry/session-metrics.js +88 -52
  480. package/dist/telemetry/telemetry.d.ts +26 -2
  481. package/dist/telemetry/telemetry.js +102 -21
  482. package/dist/telemetry/verification-of.d.ts +3 -1
  483. package/dist/telemetry/verification-of.js +12 -4
  484. package/dist/wire-journal.d.ts +2 -2
  485. package/dist/wire-journal.js +16 -5
  486. package/docs/README.md +2 -2
  487. package/docs/actions.mdx +6 -3
  488. package/docs/adapters.md +1 -1
  489. package/docs/agent-cheatsheet.md +24 -27
  490. package/docs/architecture.md +5 -5
  491. package/docs/autodrive.md +13 -12
  492. package/docs/benchmarks.md +5 -5
  493. package/docs/best-practices.mdx +27 -9
  494. package/docs/capabilities.mdx +14 -16
  495. package/docs/cli/affected.mdx +1 -1
  496. package/docs/cli/cloud.mdx +54 -75
  497. package/docs/cli/doctor.mdx +8 -3
  498. package/docs/cli/drive.mdx +12 -12
  499. package/docs/cli/feedback.mdx +3 -3
  500. package/docs/cli/gate.mdx +7 -2
  501. package/docs/cli/help.mdx +50 -55
  502. package/docs/cli/init.mdx +32 -15
  503. package/docs/cli/license.mdx +12 -8
  504. package/docs/cli/mcp.mdx +4 -4
  505. package/docs/cli/open.mdx +3 -3
  506. package/docs/cli/report.mdx +4 -2
  507. package/docs/cli/restart.mdx +2 -2
  508. package/docs/cli/rollback.mdx +14 -8
  509. package/docs/cli/serve.mdx +4 -4
  510. package/docs/cli/setup.mdx +23 -0
  511. package/docs/cli/status.mdx +13 -4
  512. package/docs/cli/stop.mdx +67 -8
  513. package/docs/cli/try.mdx +62 -0
  514. package/docs/cli/update.mdx +4 -3
  515. package/docs/cli/verify.mdx +17 -6
  516. package/docs/cli/version.mdx +3 -2
  517. package/docs/cli.mdx +110 -41
  518. package/docs/debugging.md +3 -3
  519. package/docs/deploy-checks.md +1 -1
  520. package/docs/desktop.mdx +5 -3
  521. package/docs/enterprise.md +11 -10
  522. package/docs/environment.mdx +5 -2
  523. package/docs/faq.mdx +3 -3
  524. package/docs/first-drive.md +5 -4
  525. package/docs/flows.md +35 -27
  526. package/docs/for-agents.md +4 -5
  527. package/docs/frameworks.mdx +32 -21
  528. package/docs/getting-started.md +66 -64
  529. package/docs/human-control.md +15 -14
  530. package/docs/index.mdx +15 -43
  531. package/docs/install-agentic.mdx +22 -37
  532. package/docs/install-manual.mdx +22 -12
  533. package/docs/instrumentation.mdx +5 -3
  534. package/docs/integration-patterns.md +7 -7
  535. package/docs/license-activation.mdx +1 -1
  536. package/docs/multi-agent-testing.md +24 -6
  537. package/docs/packages/babel-plugin.mdx +4 -2
  538. package/docs/packages/browser.mdx +16 -10
  539. package/docs/packages/core.mdx +12 -5
  540. package/docs/packages/electron.mdx +3 -2
  541. package/docs/packages/engine.mdx +1 -1
  542. package/docs/packages/eslint-plugin.mdx +18 -12
  543. package/docs/packages/next.mdx +8 -7
  544. package/docs/packages/open-verification.mdx +1 -1
  545. package/docs/packages/server.mdx +5 -5
  546. package/docs/packages/tauri.mdx +8 -8
  547. package/docs/packages/test.mdx +4 -10
  548. package/docs/packages/vite-plugin.mdx +11 -4
  549. package/docs/packages.mdx +11 -15
  550. package/docs/platform-integration.md +6 -5
  551. package/docs/predicates.mdx +40 -24
  552. package/docs/quickstart.mdx +58 -29
  553. package/docs/required-checks.md +8 -7
  554. package/docs/reticle-manual.md +15 -5
  555. package/docs/skill-file.mdx +17 -79
  556. package/docs/skill-setup.md +9 -9
  557. package/docs/skill.md +200 -0
  558. package/docs/system-map.md +7 -7
  559. package/docs/telemetry.md +22 -24
  560. package/docs/testing.md +4 -4
  561. package/docs/token-efficiency.md +12 -12
  562. package/docs/tools/act-and-wait.mdx +9 -2
  563. package/docs/tools/act-sequence.mdx +6 -7
  564. package/docs/tools/act.mdx +2 -2
  565. package/docs/tools/assert.mdx +18 -17
  566. package/docs/tools/console.mdx +9 -9
  567. package/docs/tools/inspect.mdx +16 -7
  568. package/docs/tools/look.mdx +24 -0
  569. package/docs/tools/navigate.mdx +5 -3
  570. package/docs/tools/network.mdx +2 -2
  571. package/docs/tools/observe.mdx +6 -6
  572. package/docs/tools/overview.mdx +34 -33
  573. package/docs/tools/query.mdx +5 -5
  574. package/docs/tools/session-and-feedback.mdx +13 -4
  575. package/docs/tools/sessions.mdx +8 -8
  576. package/docs/tools/snapshot.mdx +6 -5
  577. package/docs/tools/state.mdx +9 -9
  578. package/docs/tools/tools-and-run.mdx +26 -24
  579. package/docs/tools/verify.mdx +28 -0
  580. package/docs/tools/wait-for.mdx +8 -4
  581. package/docs/troubleshooting.mdx +21 -6
  582. package/docs/usage.md +51 -45
  583. package/docs/use-cases.mdx +3 -3
  584. package/docs/vs-chrome-devtools-mcp.mdx +9 -6
  585. package/docs/vs-playwright-mcp.mdx +3 -1
  586. package/docs/what-is-recorded.md +7 -5
  587. package/docs/what-is-reticle.mdx +2 -2
  588. package/docs/why-reticle.mdx +1 -1
  589. package/package.json +6 -5
  590. package/dist/command/cli/demo/demo-page.d.ts +0 -78
  591. package/dist/command/cli/demo/demo-page.js +0 -249
  592. package/dist/command/cli/demo/demo-run.d.ts +0 -38
  593. package/dist/command/cli/demo/demo-run.js +0 -138
  594. package/dist/judgement/hunt/hunt-report.d.ts +0 -49
  595. package/dist/judgement/hunt/hunt-report.js +0 -84
  596. package/dist/language/flows/buddy-status.d.ts +0 -25
  597. package/dist/language/flows/buddy-status.js +0 -32
  598. package/dist/language/flows/change/watch-batcher.d.ts +0 -18
  599. package/dist/language/flows/change/watch-batcher.js +0 -19
  600. package/dist/memory/cloud/harness-offer.d.ts +0 -44
  601. package/dist/memory/cloud/harness-offer.js +0 -145
  602. package/dist/surface/tools/feature-capture.d.ts +0 -151
  603. package/dist/surface/tools/feature-capture.js +0 -235
  604. package/dist/surface/tools/tool-hit-rate.d.ts +0 -87
  605. package/dist/surface/tools/tool-hit-rate.js +0 -90
  606. package/dist/telemetry/harness-drive.d.ts +0 -4
  607. package/dist/telemetry/harness-drive.js +0 -35
  608. package/dist/telemetry/identify.d.ts +0 -22
  609. package/dist/telemetry/identify.js +0 -73
  610. package/docs/cli/capsules.mdx +0 -70
  611. package/docs/cli/hunt.mdx +0 -73
  612. package/docs/cli/identify.mdx +0 -76
  613. package/docs/cli/kill.mdx +0 -91
  614. package/docs/cli/watch.mdx +0 -62
@@ -4,9 +4,9 @@ description: 'Watch the agent’s live transcript, steer it mid-run, or end the
4
4
  icon: hand
5
5
  ---
6
6
 
7
- With the presenter on (`reticle.connect({ present: true })`), the floating panel in your page lets you watch the agent's live transcript and steer it: **pause** it (its next action tool refuses and returns your guidance), **send** it a correction that rides back on its next tool result, or **end** the session. You can also point at a broken element with **Flag a bug** and hand the agent the element plus its source `file:line`.
7
+ With the presenter on (`reticle.connect({ present: true })`), the floating panel in your page lets you watch the agent's live transcript and steer it: **pause** it (its next action tool refuses until you resume) or **end** the session. You can also point at a broken element with **Flag a bug** and hand the agent the element plus its source `file:line`.
8
8
 
9
- When you run with the presenter on (`reticle.connect({ present: true })`), the floating panel is a **two-way control surface**. You watch the agent's live transcript _and_ can steer it (pause it, send it a correction, or end the session) without leaving the page. There's also a clean, unmistakable "session ended" signal for both you and the agent.
9
+ When you run with the presenter on (`reticle.connect({ present: true })`), the floating panel is a **two-way control surface**. You watch the agent's live transcript _and_ can steer it (pause it or end the session) without leaving the page. To tell the agent something, talk to it in its own window: the panel sends it no text. There's also a clean, unmistakable "session ended" signal for both you and the agent.
10
10
 
11
11
  ## Watch the testing score climb (the live verdict tally)
12
12
 
@@ -16,8 +16,7 @@ The panel header shows a running **✓N ✗M** tally: the verdict score, live. I
16
16
 
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
- - **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` (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.
19
+ - **Pause.** The agent's next `reticle_act` (single or `steps`) / `reticle_act_and_wait` **refuses to execute** and returns `{ paused: true, guidance: […], hint: "…" }`. The page is untouched until resume. _Read-only tools (`reticle_look`, `reticle_observe`) still work_, so the agent can look while paused.
21
20
  - **End.** The session is over; the panel shows "Session ended" and clears.
22
21
 
23
22
  ## From the panel (the human)
@@ -26,6 +25,8 @@ The floating panel (bottom-center, `present: true`) gives you:
26
25
 
27
26
  - **Pause / Resume**: one toggle. Paused turns the panel + page border **amber** with a `PAUSED` badge.
28
27
  - **End** ends the session: panel turns **emerald**, shows `Session ended · <summary>`, then fades away.
28
+ - **Coding agent.** The Agent Log names the coding agent attached to Reticle (`Claude Code connected`, read from the MCP handshake). With no agent attached it says `No coding agent connected` and offers **Copy prompt**, a prompt to paste into one.
29
+ - **Run Harness**, on the Harness page, drives the page as a person you pick: First-time visitor (the default), Returning power user, On a phone, slow connection, Keyboard only, Careless user (bad and unexpected input), Admin / settings, or Custom… in your own words. The pick is remembered per project. The agent hears about the drive on its next tool call (`harness`), with the `runId` to follow it.
29
30
  - **Minimise (▾)** collapses the panel to a bar that streams only the live line; click the bar to restore.
30
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. 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.
31
32
 
@@ -34,26 +35,26 @@ The floating panel (bottom-center, `present: true`) gives you:
34
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:
35
36
 
36
37
  1. **You** flag the element and type the problem → Reticle emits a `HUMAN_MARK`.
37
- 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.
38
- 3. **The agent** opens the file, fixes it, and calls `reticle_session {action:"review"}({ resolve: "m1" })`.
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
+ 3. **The agent** opens the file, fixes it, and calls `reticle_session({ action: "review", resolve: "m1" })`.
39
40
  4. **You** see **"✓ fixed: \<your note\>"** land in the panel. Flag → fix → confirmation.
40
41
 
41
- See [`reticle_session {action:"review"}` in the usage guide](/usage) for the tool shape. Suppress the button with `annotate: false` if you don't want it.
42
+ See [`reticle_session { action: "review" }` in the usage guide](/usage) for the tool shape. Suppress the button with `annotate: false` if you don't want it.
42
43
 
43
44
  ## From the agent (the tools)
44
45
 
45
46
  | Tool | Args | Effect |
46
47
  | --- | --- | --- |
47
- | `reticle_session {action:"end"}` | `{ summary?, sessionId? }` | end the session; the panel shows "Session ended · summary" |
48
- | `reticle_session {action:"resume"}` | `{ sessionId? }` | clear a pause and continue |
49
- | `reticle_session {action:"messages"}` | `{ sessionId? }` | drain + read pending human messages (explicit poll) |
50
- | `reticle_session {action:"review"}` | `{ resolve?, all?, sessionId? }` | list the bugs the human flagged; resolve one once fixed |
48
+ | `reticle_session { action: "end" }` | `{ summary?, sessionId? }` | end the session; the panel shows "Session ended · summary" |
49
+ | `reticle_session { action: "resume" }` | `{ sessionId? }` | clear a pause and continue |
50
+ | `reticle_session { action: "messages" }` | `{ sessionId? }` | drain + read pending human messages (explicit poll) |
51
+ | `reticle_session { action: "review" }` | `{ resolve?, all?, sessionId? }` | list the bugs the human flagged; resolve one once fixed |
51
52
 
52
- When paused, every action tool short-circuits with the human's guidance, so the agent learns of the pause on its very next action. The agent's expected behavior: **read the guidance, adjust the plan, then call `reticle_session {action:"resume"}`** (or wait for the human to click Resume). The agent can also end the run itself with `reticle_session {action:"end"}({ summary })` when it's done. Either path shows the same "ended" state.
53
+ When paused, every action tool short-circuits with the human's guidance, so the agent learns of the pause on its very next action. The agent's expected behavior: **read the guidance, adjust the plan, then call `reticle_session { action: "resume" }`** (or wait for the human to click Resume). The agent can also end the run itself with `reticle_session({ action: "end", summary })` when it's done. Either path shows the same "ended" state.
53
54
 
54
55
  ## Piggybacked guidance
55
56
 
56
- Even without a pause, action/observe/assert results carry a `control` block when there's something to tell the agent:
57
+ Even without a pause, any Reticle tool result carries a `control` block when there's something to tell the agent:
57
58
 
58
59
  ```jsonc
59
60
  { since, dispatched, settled, result, control: { state: "active", guidance: ["looks good, keep going"] } }
@@ -65,4 +66,4 @@ Even without a pause, action/observe/assert results carry a `control` block when
65
66
 
66
67
  Add this to your operating prompt / `CLAUDE.md` (see the [agent cheat-sheet](agent-cheatsheet.md)):
67
68
 
68
- > The human may pause you or send guidance from the Reticle panel. On any `reticle_act` result with `paused: true`, stop, read `guidance`, adjust, then call `reticle_session {action:"resume"}`. Treat a `control.guidance` field on any result as a live instruction from the human.
69
+ > The human may pause you from the Reticle panel. On any `reticle_act` result with `paused: true`, stop, read `guidance`, adjust, then call `reticle_session { action: "resume" }`. Treat a `control.guidance` field on any result as a live instruction from the human.
package/docs/index.mdx CHANGED
@@ -14,64 +14,36 @@ It answers the only question that matters: did the change actually work? On Reac
14
14
 
15
15
  ## Install it
16
16
 
17
- Two commands. The first goes in a terminal, before you open your coding agent:
17
+ Four steps. Each command says what it did and is safe to run twice. Needs Node 20.11 or newer.
18
18
 
19
- <CodeGroup>
19
+ | Step | Command | Once per | It worked when |
20
+ | --- | --- | --- | --- |
21
+ | 1. Install | `curl -fsSL https://raw.githubusercontent.com/reticlehq/reticle/main/install/install.sh \| sh` | machine | it says Reticle is on this machine, not in your app yet |
22
+ | 2. Wire your app | `reticle init` (in your app's folder) | project | it lists the files it changed and reports a connected session |
23
+ | 3. Connect _(optional)_ | `reticle connect --project "My App"` | project | `reticle status` shows this folder linked |
24
+ | 4. Sync _(optional)_ | `reticle sync` | whenever you like | your runs show on the dashboard |
20
25
 
21
- ```bash macOS / Linux
22
- curl -fsSL https://raw.githubusercontent.com/reticlehq/reticle/main/install/install.sh | sh
23
- ```
24
-
25
- ```powershell Windows
26
- irm https://raw.githubusercontent.com/reticlehq/reticle/main/install/install.ps1 | iex
27
- ```
28
-
29
- </CodeGroup>
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 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.
26
+ On Windows, step 1 is `irm https://raw.githubusercontent.com/reticlehq/reticle/main/install/install.ps1 | iex`. The installer puts `reticle` on your PATH, registers it with every coding agent it finds. It does not wire your app: that is step 2. Skip step 2 and your agent's first `reticle_session` call wires the app instead. The [quickstart](/quickstart) walks every step.
32
27
 
33
- ### Or hand the whole thing to your agent
28
+ A session listed means the SDK reached the page. Setup is finished when the first run returns a verdict.
34
29
 
35
- Copy the block below into Claude Code, Cursor, Copilot, Codex, Windsurf, OpenCode, or any MCP agent. It ends with the only definition of "installed" that counts: one real flow driven, one real verdict returned.
30
+ ### Then hand it to your agent
36
31
 
37
- ```text
38
- Reticle is the proof layer for AI coding agents. It runs a dev-only SDK inside my
39
- running web app, so instead of guessing whether your change worked, you can drive
40
- the real app and read what actually happened: the network calls, the store, the
41
- console, the routes, the DOM. You get back pass, fail, or "couldn't tell", with
42
- the file:line to fix. No screenshots, no vision model, no test syntax.
32
+ The installer ends with **Next steps**. Do them in order:
43
33
 
44
- Use it because you cannot otherwise tell whether your own code works. Reading the
45
- diff proves nothing, and unit tests do not run the app. Reticle is how you check
46
- your work before telling me it is done, and how you stop reporting "fixed" over a
47
- silent 500.
48
-
49
- Install it now:
50
-
51
- RETICLE_INSTALL_SOURCE=docs_site npx @reticlehq/server@latest init
52
-
53
- That one command wires the project, starts the dev server, opens the app and
54
- waits for it to connect. Do not walk it by hand: read what it prints, do anything
55
- it says is outstanding, and re-run it, which is safe. It exits non-zero until the
56
- app connects, and that connection, not a config file, is what "installed" means.
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
60
- https://docs.reticle.sh/install-manual.md.
61
-
62
- Afterwards, use it whenever you change any user-facing behaviour.
63
- ```
34
+ 1. **Restart your coding agent.** An agent loads its MCP tools only when it starts, so one that was open during the install cannot see Reticle yet. That restart is why setup begins with a command, not a prompt.
35
+ 2. **Paste the prompt the installer printed** into the agent, opened in your app's folder. The agent runs `reticle init`, wires your app, and drives one real flow to a verdict.
64
36
 
65
37
  <Tip>
66
38
  The plugin and the skills CLI are alternatives to the *registration* half only, not to `init`:
67
- neither one touches your app, so you still run the command above afterwards to instrument it. On
39
+ neither one touches your app, so you still run `reticle init` afterwards to instrument it. On
68
40
  Claude Code, `/plugin marketplace add reticlehq/reticle` then `/plugin install reticle@reticlehq`
69
41
  registers the MCP server and the skills in one step; on most other agents, `npx skills add
70
42
  reticlehq/reticle`.
71
43
  </Tip>
72
44
 
73
45
  <Card title="What that command actually changes" icon="wand-magic-sparkles" href="/install-agentic">
74
- The four files it writes, the marks it prints, and how to read its report.
46
+ The files it writes, the marks it prints, and how to read its report.
75
47
  </Card>
76
48
 
77
49
  <CardGroup cols={3}>
@@ -29,43 +29,27 @@ The install is designed for the agent to run rather than you. The agent is about
29
29
  bin name on your PATH, which is the only context where the unscoped name is ours.
30
30
  </Warning>
31
31
 
32
- ## What do I paste into my coding agent to install Reticle?
32
+ ## What do I give my coding agent?
33
33
 
34
- Copy this whole block into Claude Code, Cursor, Copilot, Codex, Windsurf, OpenCode, or any MCP agent. It tells the agent what Reticle is, why it should want it, and what counts as finished. That last part is the one that matters.
34
+ Not a prompt first: a command. Run the installer in a terminal:
35
35
 
36
- ```text
37
- Reticle is the proof layer for AI coding agents. It runs a dev-only SDK inside my
38
- running web app, so instead of guessing whether your change worked, you can drive
39
- the real app and read what actually happened: the network calls, the store, the
40
- console, the routes, the DOM. You get back pass, fail, or "couldn't tell", with
41
- the file:line to fix. No screenshots, no vision model, no test syntax.
42
-
43
- Use it because you cannot otherwise tell whether your own code works. Reading the
44
- diff proves nothing, and unit tests do not run the app. Reticle is how you check
45
- your work before telling me it is done, and how you stop reporting "fixed" over a
46
- silent 500.
47
-
48
- Install it now:
36
+ ```bash
37
+ curl -fsSL https://raw.githubusercontent.com/reticlehq/reticle/main/install/install.sh | sh
38
+ ```
49
39
 
50
- RETICLE_INSTALL_SOURCE=docs_site npx @reticlehq/server@latest init
40
+ On Windows: `irm https://raw.githubusercontent.com/reticlehq/reticle/main/install/install.ps1 | iex`.
51
41
 
52
- Then follow https://docs.reticle.sh/install-agentic.md and, if anything needs a
53
- manual edit, https://docs.reticle.sh/install-manual.md. Do not stop until you have
54
- driven one real flow in my app and produced a verdict. That, not a config file, is
55
- what "installed" means.
42
+ It registers Reticle with every coding agent it finds and closes with **Next steps**: restart your agent if it is already open, then paste the prompt it printed. That prompt is the one to give the agent. It has the agent run `init`, close the coverage gaps `reticle doctor` lists, and sets what counts as finished: one real flow in your app driven to a verdict, not a config file.
56
43
 
57
- Afterwards, use it whenever you change any user-facing behaviour.
58
- ```
44
+ The order matters. An agent reads its MCP server list when it starts, so a prompt pasted into an agent that is already running has no `reticle_*` tools to call until that agent restarts.
59
45
 
60
46
  <Tip>
61
47
  Prefer installing the skills instead? `npx skills add reticlehq/reticle` on most agents, or
62
48
  `/plugin marketplace add reticlehq/reticle` then `/plugin install reticle@reticlehq` on Claude
63
- Code, which registers the MCP server and all eleven skills in one step. Then type `/reticle` and
49
+ Code, which registers the MCP server and the Reticle skill in one step. Then type `/reticle` and
64
50
  the agent runs this same setup from the skill.
65
51
  </Tip>
66
52
 
67
- The `RETICLE_INSTALL_SOURCE=docs_site` marker is how we tell which published route an install came through. It is self-declared by this page and never inferred, it carries no information about you or your project, and dropping it changes nothing about the install.
68
-
69
53
  <Note>
70
54
  Everything on this page is real output. It was captured by scaffolding a pristine `npm create
71
55
  vite` React app and running `init` inside it while writing this.
@@ -122,8 +106,9 @@ There are five, and they mean different things. This is the part worth understan
122
106
  | `ℹ` | Done, but incomplete in a way that matters | **Yes, read it** |
123
107
 
124
108
  <Warning>
125
- A `⚠` is not cosmetic. In the run above, Reticle could not write the Codex CLI's TOML config, so
126
- it printed the exact block to paste. Leave it and Codex simply never sees the tools.
109
+ A `⚠` is not cosmetic. In the run above, Reticle could not write the Codex CLI's TOML config (the
110
+ `codex` command was not installed to do it), so it printed the exact block to paste. Leave it and
111
+ Codex simply never sees the tools.
127
112
  </Warning>
128
113
 
129
114
  That `ℹ` line is the one people skim past, so here it is in full:
@@ -138,7 +123,7 @@ That `ℹ` line is the one people skim past, so here it is in full:
138
123
 
139
124
  ## What it actually changes
140
125
 
141
- Four files in your project, none of them mysterious.
126
+ The files it writes in your project, none of them mysterious.
142
127
 
143
128
  <AccordionGroup>
144
129
  <Accordion title=".reticle.json (project config)">
@@ -206,7 +191,7 @@ Four files in your project, none of them mysterious.
206
191
 
207
192
  <Accordion title="src/reticle-dev.ts (your capabilities)">
208
193
  ```ts
209
- // Dev-only. Imported automatically by @reticlehq/vite-plugin, so you do not need to import it.
194
+ // Dev-only. Loaded for you after connect() by @reticlehq/vite-plugin's injected connect, so you do not import it.
210
195
  // Self-guards on import.meta.env.DEV, so it is a no-op in a production build.
211
196
  import { registerCapabilities } from '@reticlehq/react';
212
197
 
@@ -244,9 +229,9 @@ Three of these are answers only the caller has. `init` reads your repository; it
244
229
 
245
230
  | Flag | When you want it |
246
231
  | --- | --- |
247
- | `persona: "<what>"` | **Name the journey worth proving**, on the FIRST RUN (`reticle_verify { action: "explore", persona: "<the journey worth proving>" }`), not on `init`, which does not drive. Reticle can list the buttons on a page; it cannot know that checkout matters and the theme toggle does not. Naming it is the difference between a drive that finishes and one that spends its budget looking for something to do. |
232
+ | `persona: "<what>"` | **Name the journey worth proving**, on the FIRST RUN (`reticle_verify { action: "explore", persona: "<the journey worth proving>" }`, on a project linked with `reticle connect`; otherwise drive it with `reticle_act_and_wait`), not on `init`, which does not drive. Reticle can list the buttons on a page; it cannot know that checkout matters and the theme toggle does not. Naming it is the difference between a drive that finishes and one that spends its budget looking for something to do. |
248
233
  | `--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
- | `--app <dir>` | Monorepos. `init` can find the apps that are servable; only your request says which one you are working in. |
234
+ | `--app <dir>` | Monorepos. `init` can find the apps that are servable; only your request says which one you are working in. It writes that app's files only; add `--start` to boot it too. |
250
235
  | `--license <key>` | Writes `RETICLE_LICENSE_KEY` to `.env` and keeps `.env` out of git. Do not do those two by hand. |
251
236
  | `--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
237
  | `--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. |
@@ -270,16 +255,16 @@ That writes the files, registers the MCP server with every agent it finds, pre-a
270
255
 
271
256
  Two things to know afterwards:
272
257
 
273
- - **A GUI client reads its config at startup.** Cursor, Antigravity, Claude Desktop and VS Code need a window reload before the new rules take effect. The CLIs pick them up on their next run.
258
+ - **A GUI client reads its config at startup.** Cursor, Antigravity and VS Code need a window reload before the new server or rules take effect. The CLIs pick them up on their next run.
274
259
  - **The pre-approval is scoped to `reticle` alone**, never a blanket rule for every MCP server, and never a global auto-run switch. If a client's approval file did not exist before, `init` says so in a line, because in Cursor's case that file supersedes what you had approved inside the app.
275
260
 
276
- Drop `--files-only` to get the full run: boot the app, drive a flow, return a verdict.
261
+ Drop `--files-only` for the full run: boot the app and wait for a session to connect. Proving a flow is the first run, a separate call.
277
262
 
278
- ## The two restarts you no longer have to think about
263
+ ## The two restarts, and when you need them
279
264
 
280
- **Your dev server: `init` handles it.** A dev server that was already running read your build config before `init` edited it, so it keeps serving the old bundle and nothing connects. `init` restarts it and waits for the port to answer, rather than telling you to.
265
+ **Your dev server: restart it once.** One that was already running read your build config before `init` edited it, so it keeps serving a bundle without the SDK. Restart it and hard-reload the tab. `init` names this case when it finds it.
281
266
 
282
- **Your agent: not on the critical path any more.** Your agent read its MCP server list at startup, before Reticle existed, and no slash command re-reads it. `/mcp` manages servers already loaded, so it cannot pick up a new one. That used to mean stopping the install to restart. It does not now: the flow is driven by a child agent process started after registration, which reads the list `init` just wrote. Your own session picks the tools up whenever you next start it, and nothing is waiting on that. This is a once-per-machine annoyance in any case, because Reticle registers globally.
267
+ **Your agent: restart it once, if the tools are missing.** An agent reads its MCP server list when it starts. If it started before Reticle was registered, the `reticle_*` tools are not in this session, and no slash command re-reads the list (`/mcp` manages servers already loaded). Restart the agent once. `reticle init --relaunch` prints the exact command that resumes this conversation with the tools loaded. Until then, `npx @reticlehq/server verify <url> --expect '<predicate JSON>'` proves a flow from the shell. Reticle registers globally, so this happens once per machine.
283
268
 
284
269
  ## Confirm it worked
285
270
 
@@ -287,7 +272,7 @@ Drop `--files-only` to get the full run: boot the app, drive a flow, return a ve
287
272
  npx @reticlehq/server status
288
273
  ```
289
274
 
290
- It confirms the app connected, or tells you exactly why it hasn't. A session in the list is the install actually finished. Not a green tick. A connected app.
275
+ It confirms the app connected, or tells you exactly why it hasn't. A session listed means the SDK reached the page. Setup is finished when the first run returns a verdict.
291
276
 
292
277
  <Card title="Something marked ⚠?" icon="screwdriver-wrench" href="/install-manual">
293
278
  The manual install covers every step `init` can't automate, per agent and per framework.
@@ -19,7 +19,7 @@ npx @reticlehq/server init # in your project
19
19
 
20
20
  The first registers the MCP server with every agent it can reach. The second wires the app. See the [quickstart](/quickstart).
21
21
 
22
- This page is for the cases those cannot cover: a machine where piping a script is not allowed, an agent Reticle does not know, or a step the installer reported as needing a hand (Codex CLI is the usual one, because its config is TOML that Reticle will not rewrite).
22
+ This page is for the cases those cannot cover: a machine where piping a script is not allowed, an agent Reticle does not know, or a step the installer reported as needing a hand (Codex CLI is the usual one when the `codex` command is not installed, because its config is TOML that Reticle will not rewrite itself).
23
23
 
24
24
  </Warning>
25
25
 
@@ -42,8 +42,8 @@ There is no config file that all agents share. Each harness has its own path and
42
42
  | Cursor | `~/.cursor/mcp.json` | `mcpServers` | no |
43
43
  | VS Code | `.vscode/mcp.json` | `servers` | no |
44
44
  | Windsurf | `~/.codeium/windsurf/mcp_config.json` | `mcpServers` | no |
45
- | OpenCode | `opencode.json` | `mcp` | `"local"` required |
46
- | Codex CLI | `.codex/config.toml` | `[mcp_servers.reticle]` | no |
45
+ | OpenCode | `~/.config/opencode/opencode.jsonc` | `mcp` | `"local"` required |
46
+ | Codex CLI | `~/.codex/config.toml` | `[mcp_servers.reticle]` | no |
47
47
  | Zed | `~/.config/zed/settings.json` | `context_servers` | no |
48
48
 
49
49
  ### Claude Code
@@ -86,7 +86,7 @@ Same shape, different file and root key. Cursor and Windsurf use `mcpServers`; V
86
86
 
87
87
  ### Codex CLI
88
88
 
89
- TOML, in `.codex/config.toml`. This is the one `init` cannot write for you:
89
+ TOML, in `~/.codex/config.toml`. With the `codex` command installed, `init` runs `codex mcp add reticle -- npx @reticlehq/server mcp` for you, and only when the file has no `reticle` entry yet, because that command replaces one without asking. Without the command, `init` cannot write it for you:
90
90
 
91
91
  ```toml
92
92
  [mcp_servers.reticle]
@@ -133,25 +133,33 @@ export default defineConfig({
133
133
  });
134
134
  ```
135
135
 
136
- That's the whole web install. The plugin stamps source locations onto elements. The thing that turns a DOM node into `src/components/Login.tsx:81`. And injects `connect()` so you can't forget it.
136
+ That's the whole web install. The plugin stamps source locations onto elements. That is what turns a DOM node into `src/components/Login.tsx:81`. It also injects `connect()` with the pairing token, so you can't forget either.
137
137
 
138
138
  ### Anything without the plugin
139
139
 
140
- If you're not on Vite or Next, call `connect()` yourself, guarded so it never reaches production:
140
+ Run `npx @reticlehq/server init` even here: it wires plain HTML, Angular, Remix, Astro, SvelteKit and the rest, and it is the part that gets the **pairing token** to the page without writing it into anything you ship.
141
+
142
+ If you really are wiring `connect()` by hand, pass the token. The daemon writes it to `~/.reticle/pairing-token` on first start and refuses a page that does not present it, on localhost too. Without it the page console says `bridge refused the connection: authentication failed: no pairing token on the page…`.
141
143
 
142
144
  ```ts
143
- import { reticle } from '@reticlehq/browser';
145
+ import { reticle, SESSION_AUTO } from '@reticlehq/browser';
144
146
 
145
- if (import.meta.env.DEV) reticle.connect();
147
+ if (import.meta.env.DEV) {
148
+ // The contents of ~/.reticle/pairing-token, supplied at dev time (here as a Vite env var).
149
+ // Never commit it, and never let it reach a production build.
150
+ reticle.connect({ session: SESSION_AUTO, token: import.meta.env.VITE_RETICLE_TOKEN });
151
+ }
146
152
  ```
147
153
 
154
+ Start the dev server with `VITE_RETICLE_TOKEN="$(cat ~/.reticle/pairing-token)"`, or pin your own secret with `RETICLE_TOKEN=<secret>` in the MCP server's environment and give the page the same value. Set it on the dev command only, never in a `.env` file: a production build reads `.env` and would embed the token in the JavaScript it ships. Not on Vite? Do the same with your bundler's dev-only flag and its way of passing a value to the browser.
155
+
148
156
  <Note>
149
157
  `connect()` is dev-only by design. Guard it with whatever your bundler gives you:
150
158
  `import.meta.env.DEV`, `process.env.NODE_ENV !== 'production'`, or a build flag. Reticle also
151
159
  self-guards, but two locks on a door that leads to your users is a reasonable number.
152
160
  </Note>
153
161
 
154
- ### Tauri. and the step whose failure is silent
162
+ ### Tauri, and the step whose failure is silent
155
163
 
156
164
  The frontend is identical to any web app. The CSP is not optional:
157
165
 
@@ -175,7 +183,7 @@ Screenshots and headless mode need the Rust crate, which is versioned independen
175
183
 
176
184
  ```toml
177
185
  [dependencies]
178
- reticle-tauri = "3.6"
186
+ reticle-tauri = "3.7"
179
187
  ```
180
188
 
181
189
  ```rust
@@ -184,6 +192,8 @@ tauri::Builder::default()
184
192
  .on_page_load(reticle_tauri::on_page_load)
185
193
  ```
186
194
 
195
+ **Dev builds only.** In a release build the crate is inert: `reticle_capture` refuses and `on_page_load` does nothing, so the binary you sign and ship carries no Reticle capability. A release build you test with Reticle (a CI fixture) turns it on with `reticle-tauri = { version = "3.7", features = ["in-release"] }`.
196
+
187
197
  IPC observation needs nothing on the Rust side. An `invoke('load_todos')` already reaches Reticle as `ipc://load_todos`.
188
198
 
189
199
  <Card title="Electron, and the rest of desktop" icon="display" href="/desktop">
@@ -196,9 +206,9 @@ IPC observation needs nothing on the Rust side. An `invoke('load_todos')` alread
196
206
  npx @reticlehq/server status
197
207
  ```
198
208
 
199
- A session in the output means the app connected. That. Not a tick in a checklist, is the install finished.
209
+ A session listed means the SDK reached the page. Setup is finished when the first run returns a verdict.
200
210
 
201
- If it says nothing connected, the usual cause is a port disagreement between your app and the daemon. The browser console will carry `[Reticle] this page could not open a websocket to …` naming the exact address it tried; set it explicitly with `VITE_RETICLE_WS_URL=ws://localhost:4400/reticle` or `reticle.connect({ url })`.
211
+ If it says nothing connected, the usual causes are a port disagreement between your app and the daemon, or a hand-wired `connect()` without the pairing token. The browser console will carry `[Reticle] this page could not open a websocket to …` naming the exact address it tried; set it explicitly with `RETICLE_PORT=4400 pnpm dev` (Vite plugin), `reticle({ port: 4400 })` in `vite.config`, or `reticle.connect({ url: 'ws://localhost:4400/reticle' })` by hand.
202
212
 
203
213
  Still stuck? `npx @reticlehq/server doctor` checks Chromium, the daemon and the port in one command.
204
214
 
@@ -27,7 +27,9 @@ Every verdict carries an `honesty.grade`. How strong the evidence actually was.
27
27
  </Card>
28
28
  </CardGroup>
29
29
 
30
- Here is the same login, verified two ways. First with a network predicate and no instrumentation leaned on:
30
+ The full ladder, strongest first, is `signal`, `net`, `state`, `presence`, `none`: a matched request grades `net`, between a signal and a store change.
31
+
32
+ Here is the same login, verified two ways. First with an element predicate and no instrumentation leaned on:
31
33
 
32
34
  ```json
33
35
  "honesty": { "grade": "presence", "coverage": { "pct": 100 }, "integrity": { "clean": true } }
@@ -181,7 +183,7 @@ This is the one that surprises people, so here it is in full. A successful login
181
183
  "signals": ["auth:granted"]
182
184
  },
183
185
  "honesty": { "grade": "signal", "integrity": { "clean": true } },
184
- "feedback_invite": "Reticle could not tell what happened here. If you expected otherwise, reticle_feedback. An unknown verdict is our defect, not yours"
186
+ "feedback_invite": "Reticle could not tell what happened here. If you expected otherwise, reticle_session { action: \"feedback\" }. An unknown verdict is our defect, not yours"
185
187
  }
186
188
  ```
187
189
 
@@ -214,7 +216,7 @@ Signals rot the way every convention rots: someone adds a mutation, forgets the
214
216
  npm i -D @reticlehq/eslint-plugin
215
217
  ```
216
218
 
217
- One rule. State changed, so a signal must fire, makes the signal layer self-enforcing. It is the only mechanism we have found that survives contact with a deadline.
219
+ One rule, `require-signal-on-mutation` (state changed, so a signal must fire), makes the signal layer self-enforcing. It is the only mechanism we have found that survives contact with a deadline.
218
220
 
219
221
  ## Start with one flow
220
222
 
@@ -4,7 +4,7 @@ description: 'The recommended shape for a real codebase: a minimal production fo
4
4
  icon: shapes
5
5
  ---
6
6
 
7
- The recommended shape for a real codebase is three decisions: put `createReticleEmitter()` in one `app/emit.ts` so components depend on an interface and `@reticlehq/browser` never reaches your production bundle; emit signals from the **store layer** rather than from N call sites; and let each feature self-register its testids and signals with `registerReticleDomain`. Then turn on `reticle/require-signal-on-mutation` so the signal layer cannot silently rot.
7
+ The recommended shape for a real codebase is three decisions: put `createReticleEmitter()` in one `app/emit.ts` so components depend on an interface and `@reticlehq/browser` is imported in exactly one place; emit signals from the **store layer** rather than from N call sites; and let each feature self-register its testids and signals with `registerReticleDomain`. Then turn on `reticle/require-signal-on-mutation` so the signal layer cannot silently rot.
8
8
 
9
9
  The basics in [Getting Started](getting-started.md) work with **zero app changes**. This doc is the _recommended_ shape for a real codebase: a minimal production footprint, a signal layer that can't silently drift, and an adoption path that starts paying off on day one, with no rewrite required.
10
10
 
@@ -24,7 +24,7 @@ Adoption is **free → cheap → targeted**. You don't instrument everything; yo
24
24
 
25
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
- **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.
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_run({ tool: "reticle_capabilities", args: {} })` tells a fresh agent your whole surface without reading source.
28
28
 
29
29
  ```ts
30
30
  import { registerCapabilities } from '@reticlehq/browser';
@@ -49,7 +49,7 @@ That's day-one usefulness with no rewrite. The rest of this doc is how to do ste
49
49
 
50
50
  ## 2. Inject the emitter (zero prod bundle)
51
51
 
52
- The #1 objection: _"I don't want a test tool in my production bundle."_ The answer: components never import `@reticlehq/browser`. They depend on a tiny structural interface, `ReticleEmitter` (`{ signal, state }`), and the real emitter is injected once at the top. `createReticleEmitter()` returns an emitter that proxies to the connected `reticle` singleton and is a **safe no-op** until `reticle.connect()` runs, so nothing breaks in production or before connect, and **`@reticlehq/browser` stays out of the prod bundle.**
52
+ The #1 objection: _"I don't want a test tool in my production bundle."_ The answer: components never import `@reticlehq/browser`. They depend on a tiny structural interface, `ReticleEmitter` (`{ signal, state }`), and the real emitter is injected once at the top. `createReticleEmitter()` returns an emitter that proxies to the connected `reticle` singleton and is a **safe no-op** until `reticle.connect()` runs, so nothing breaks in production or before connect. With the Vite plugin, a production build replaces `@reticlehq/browser` with an inert stub, so **the SDK stays out of the prod bundle**; with another bundler, `app/emit.ts` is the one import to gate.
53
53
 
54
54
  ```ts
55
55
  // app/emit.ts: the one place that touches @reticlehq/browser
@@ -133,7 +133,7 @@ import { registerReticleDomain } from '@reticlehq/browser';
133
133
  registerReticleDomain({ testids: ['search-input'], signals: ['search:ran'] });
134
134
  ```
135
135
 
136
- Importing both modules in dev makes `reticle_capabilities()` return the merged surface (`testids: ['section-list', 'section-add', 'search-input']`, `signals: ['section:reordered', 'search:ran']`, `stores: ['workspace']`). `registerReticleDomain` is a thin convenience over `registerCapabilities`, with the same merge-idempotent, HMR-safe semantics, so it composes with §1's "use your existing constants." (Named flows stay an explicit `registerCapabilities({ flows })` concern: their last-writer-wins semantics don't fit "accumulate from many domains.")
136
+ Importing both modules in dev makes `reticle_run({ tool: "reticle_capabilities", args: {} })` return the merged surface (`testids: ['section-list', 'section-add', 'search-input']`, `signals: ['section:reordered', 'search:ran']`, `stores: ['workspace']`). `registerReticleDomain` is a thin convenience over `registerCapabilities`, with the same merge-idempotent, HMR-safe semantics, so it composes with §1's "use your existing constants." (Named flows stay an explicit `registerCapabilities({ flows })` concern: their last-writer-wins semantics don't fit "accumulate from many domains.")
137
137
 
138
138
  ## 5. Keep the signal layer from rotting (`@reticlehq/eslint-plugin`)
139
139
 
@@ -158,20 +158,20 @@ export default [
158
158
  ];
159
159
  ```
160
160
 
161
- Or turn it on with the shipped preset: `plugin.configs.recommended`, which sets `reticle/require-signal-on-mutation` to `warn` (with empty no-op defaults you then configure) and the plugin's other rule, `reticle/no-internal-tags`, to `error`. A function that calls a mutator and a signal together passes; a mutator with no signal reports `store mutation without a mapped Reticle signal`. The documented view-level exceptions from §3 simply don't list those view callees as `mutators`, so they never fire.
161
+ Or turn it on with the shipped preset: `plugin.configs.recommended`, which sets `reticle/require-signal-on-mutation` to `warn` (with empty no-op defaults you then configure) and the plugin's other two rules, `reticle/no-internal-tags` and `reticle/no-runaway-comment`, to `error`. A function that calls a mutator and a signal together passes; a mutator with no signal reports `store mutation without a mapped Reticle signal`. The documented view-level exceptions from §3 simply don't list those view callees as `mutators`, so they never fire.
162
162
 
163
163
  ## 6. Limitation: un-scriptable tabs, use `reticle drive`
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_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.
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>`**, which opens in the foreground (`--headless` hides it). 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
 
171
171
  - [ ] One `app/emit.ts` is the **only** module importing `@reticlehq/browser`; components import the emitter.
172
172
  - [ ] `reticle.connect()` is dev-gated; the prod bundle has no `@reticlehq/browser`.
173
173
  - [ ] Signals fire from the store layer (middleware or `commitAndSignal`); view-level exceptions are explicit.
174
- - [ ] Each domain self-registers via `registerReticleDomain`; `reticle_capabilities()` returns the full surface.
174
+ - [ ] Each domain self-registers via `registerReticleDomain`; `reticle_run({ tool: "reticle_capabilities", args: {} })` returns the full surface.
175
175
  - [ ] Existing Playwright/Cypress testids are reused, not duplicated.
176
176
  - [ ] `reticle/require-signal-on-mutation` is enabled with your `mutators` + `signalCallee`.
177
177
  - [ ] The team knows `reticle drive <url>` for un-scriptable tabs.
@@ -78,7 +78,7 @@ You do not need `NODE_ENV` set, a project, a dev server, or a running app. This
78
78
  | `missing` | Reticle found no key in its environment. | The variable is not visible to this process. See below. |
79
79
  | `expired` | The key was valid and its term has ended. | Contact us to renew. |
80
80
  | `invalid` | The key was not accepted. | Usually a copy or paste problem. See below. |
81
- | `eval` | This build has no licensing configured. | You are on a build older than licensing. Update. |
81
+ | `eval` | This build has no issuer key: a source build or a dev checkout. | Install the published `@reticlehq/server` package. |
82
82
 
83
83
  ## Over time
84
84
 
@@ -4,7 +4,7 @@ description: 'Several apps at once, ports that shift between runs, and many agen
4
4
  icon: users
5
5
  ---
6
6
 
7
- Many agents can drive the same app at once without a browser each: `reticle_lease {action:"acquire"}` hands each one an **isolated context** (its own cookies, storage and DOM) from a single shared headless Chromium. One daemon per machine, and identity is the **app** (a stable `projectId` stamped by the build plugin), not the port, so an app that boots on `:3001` today is still the same app.
7
+ Many agents can drive the same app at once without a browser each: `reticle_run { tool: "reticle_lease", args: { action: "acquire" } }` hands each one an **isolated context** (its own cookies, storage and DOM) from a single shared headless Chromium. One daemon per machine, and identity is the **app** (a stable `projectId` stamped by the build plugin), not the port, so an app that boots on `:3001` today is still the same app.
8
8
 
9
9
  Reticle is built for the messy real world: several apps running at once, ports that shift between runs, and many agents driving different flows of the same app in parallel, without each one spinning up its own Chromium. This page explains how that works and how to use it.
10
10
 
@@ -20,27 +20,45 @@ Reticle is built for the messy real world: several apps running at once, ports t
20
20
  1. Add the plugin (Vite/Next) or one `reticle.connect()` call. (See [getting-started](./getting-started.md).)
21
21
  2. Start your app as you normally do.
22
22
  3. Open it in a browser; the in-page panel shows Reticle is connected.
23
- 4. Click around; flag anything that looks wrong with the "Flag a bug" annotator. The agent drains those with `reticle_session {action:"review"}`.
23
+ 4. Click around; flag anything that looks wrong with the "Flag a bug" annotator. The agent drains those with `reticle_session { action: "review" }`.
24
24
 
25
25
  ## Agent testing: ~2 minutes
26
26
 
27
27
  With the app running and instrumented, an agent drives a flow end to end:
28
28
 
29
29
  ```text
30
- reticle_lease {action:"acquire"} { url: "http://localhost:3000/dashboard" }
30
+ reticle_run { tool: "reticle_lease", args: { action: "acquire", url: "http://localhost:3000/dashboard" } }
31
31
  → { sessionId: "lease-…", ready: true, leased: 1, queued: 0 }
32
32
  reticle_act { sessionId, ... } # drive the flow
33
33
  reticle_assert { sessionId, ... } # verify intent
34
- reticle_lease {action:"release"} { sessionId } # free the slot
34
+ reticle_run { tool: "reticle_lease", args: { action: "release", sessionId } } # free the slot
35
35
  ```
36
36
 
37
- `reticle_lease {action:"acquire"}` opens a fresh isolated headless context against your **already-running** app, stamps the lease identity into the URL so the app's own SDK registers under a sessionId you can target, and waits until that tab has connected (`ready: true`) before returning, so the sessionId is usable immediately. Release when the flow finishes.
37
+ `reticle_run { tool: "reticle_lease", args: { action: "acquire" } }` opens a fresh isolated headless context against your **already-running** app, stamps the lease identity into the URL so the app's own SDK registers under a sessionId you can target, and waits until that tab has connected (`ready: true`) before returning, so the sessionId is usable immediately. Release when the flow finishes.
38
+
39
+ ## Permissions
40
+
41
+ A lease starts with every permission undecided. Pass `permissions` to grant some on the app's origin before the first navigation, so the first render already sees them:
42
+
43
+ ```text
44
+ reticle_run { tool: "reticle_lease", args: { action: "acquire", url: "http://localhost:3000/map", permissions: ["geolocation"] } }
45
+ ```
46
+
47
+ Acquiring again on an origin that already has a lease returns that lease, and its grants never change there, because it may be another agent's live tab. The same list is a plain reuse and a different one is refused. To change them, release the lease and acquire again. Names are Playwright's, such as `geolocation`, `clipboard-read`, `clipboard-write` and `notifications`; one the browser does not know is refused with its reason.
48
+
49
+ | What the page reads | Without `permissions` | After a grant |
50
+ | --- | --- | --- |
51
+ | `navigator.permissions.query({ name })` | `prompt` | `granted` |
52
+ | `Notification.permission`, in Playwright's headless shell (the default) | `denied` | still `denied` |
53
+ | `Notification.permission`, in an installed Chrome the pool falls back to | `default` | `granted` |
54
+
55
+ The headless shell has no notification support, so a notifications grant never reaches `Notification.permission` there. When you ask for `notifications`, the lease reads the value back from the page and says so in `hint` whenever the page cannot see the grant.
38
56
 
39
57
  ## 10 agents, 10 flows, one dashboard
40
58
 
41
59
  This is the design target, and it needs no special setup:
42
60
 
43
- - Each agent calls `reticle_lease {action:"acquire"}` for the same dashboard URL → its own isolated context (own cookies/storage) in the **one** shared Chromium.
61
+ - Each agent calls `reticle_run { tool: "reticle_lease", args: { action: "acquire" } }` for the same dashboard URL → its own isolated context (own cookies/storage) in the **one** shared Chromium.
44
62
  - The pool caps simultaneous contexts (`RETICLE_MAX_CONTEXTS`, default scales with CPU under a ceiling); extra acquires queue and proceed as slots free.
45
63
  - Flows can't bleed into each other: contexts are isolated and every session is scoped by `projectId`.
46
64
  - 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.
@@ -8,7 +8,7 @@ icon: file-code
8
8
 
9
9
  React 19 dropped `_debugSource`, which is what source mapping used to rely on, so without this the tools can tell you the component name but not the file.
10
10
 
11
- **Apache 2.0. CommonJS. No runtime dependencies. Peer dependency: `@babel/core ^7`.**
11
+ **Apache 2.0. CommonJS. One runtime dependency, `@reticlehq/core` (for the attribute name). Peer dependency: `@babel/core ^7`.**
12
12
 
13
13
  ## What it stamps
14
14
 
@@ -36,6 +36,8 @@ The path is relative to `process.cwd()`, with backslashes normalized to forward
36
36
  ## What it skips
37
37
 
38
38
  - Component tags. Only lowercase host elements are stamped, because a component's own JSX gets stamped where it is defined.
39
+ - Lowercase tags that are not HTML or SVG elements, such as react-three-fiber's `<mesh>`. Only known DOM tags are stamped, because a custom renderer can crash on the attribute.
40
+ - Files whose first non-empty line is a comment holding exactly `@reticle-ignore`.
39
41
  - Elements that already carry the attribute.
40
42
  - Nodes with no location information.
41
43
  - Anything whose tag name is not a plain `JSXIdentifier`.
@@ -56,7 +58,7 @@ One export, via `export =`. There are no named exports and no `default` interop
56
58
  function reticleSourcePlugin({ types }: { types: typeof BabelTypes }): PluginObj<PluginPass>;
57
59
  ```
58
60
 
59
- The Babel plugin name is `reticle-source`. Its visitor handles `JSXOpeningElement` only.
61
+ The Babel plugin name is `reticle-source`. Its visitor handles `Program` (to read the ignore marker) and `JSXOpeningElement`.
60
62
 
61
63
  **It takes no options.** The plugin reads nothing from `state.opts`.
62
64