@reticlehq/server 2.7.0 → 2.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (357) hide show
  1. package/README.md +14 -5
  2. package/SKILL.md +130 -778
  3. package/dist/bridge/bridge.d.ts +23 -0
  4. package/dist/bridge/bridge.js +80 -2
  5. package/dist/bridge/bridge.test-harness.d.ts +5 -0
  6. package/dist/bridge/bridge.test-harness.js +6 -4
  7. package/dist/capsule/causal-summary.d.ts +36 -1
  8. package/dist/capsule/causal-summary.js +33 -7
  9. package/dist/capsule/divergence.js +7 -1
  10. package/dist/cli/chromium-hint.d.ts +33 -5
  11. package/dist/cli/chromium-hint.js +82 -12
  12. package/dist/cli/cli-doctor.js +65 -34
  13. package/dist/cli/cli-flow-commands.js +8 -8
  14. package/dist/cli/cli-kill.d.ts +58 -0
  15. package/dist/cli/cli-kill.js +162 -0
  16. package/dist/cli/cli-parse.d.ts +16 -1
  17. package/dist/cli/cli-parse.js +32 -9
  18. package/dist/cli/cli-port.d.ts +32 -0
  19. package/dist/cli/cli-port.js +82 -35
  20. package/dist/cli/cli-verify.d.ts +21 -0
  21. package/dist/cli/cli-verify.js +47 -3
  22. package/dist/cli/config-discovery.d.ts +35 -0
  23. package/dist/cli/config-discovery.js +163 -0
  24. package/dist/cli/doctor-daemon-line.js +4 -1
  25. package/dist/cli/doctor-project-line.d.ts +37 -0
  26. package/dist/cli/doctor-project-line.js +35 -0
  27. package/dist/cli/doctor-rows.d.ts +51 -0
  28. package/dist/cli/doctor-rows.js +54 -0
  29. package/dist/cli/doctor-sessions-line.d.ts +12 -0
  30. package/dist/cli/doctor-sessions-line.js +69 -0
  31. package/dist/cli/drive-attach.d.ts +99 -0
  32. package/dist/cli/drive-attach.js +203 -0
  33. package/dist/cli/drive-command.d.ts +13 -0
  34. package/dist/cli/drive-command.js +103 -0
  35. package/dist/cli/open-note.d.ts +20 -0
  36. package/dist/cli/open-note.js +37 -0
  37. package/dist/cli/port-holder.d.ts +10 -0
  38. package/dist/cli/port-holder.js +26 -2
  39. package/dist/cli/status-next-action.d.ts +37 -0
  40. package/dist/cli/status-next-action.js +61 -0
  41. package/dist/cli.js +119 -39
  42. package/dist/crawl/crawl-tools.js +12 -2
  43. package/dist/crawl/crawl.d.ts +13 -0
  44. package/dist/crawl/crawl.js +50 -2
  45. package/dist/events/contradictions.d.ts +46 -0
  46. package/dist/events/contradictions.js +35 -22
  47. package/dist/events/declared.d.ts +45 -0
  48. package/dist/events/declared.js +73 -0
  49. package/dist/events/echo-mismatch.d.ts +8 -2
  50. package/dist/events/echo-mismatch.js +33 -5
  51. package/dist/events/event-filters.d.ts +1 -1
  52. package/dist/events/event-filters.js +7 -4
  53. package/dist/events/predicate-eval.d.ts +17 -72
  54. package/dist/events/predicate-eval.js +117 -236
  55. package/dist/events/predicate-parse.js +31 -3
  56. package/dist/events/predicate-route.d.ts +32 -0
  57. package/dist/events/predicate-route.js +102 -0
  58. package/dist/events/predicate-schema.d.ts +99 -0
  59. package/dist/events/predicate-schema.js +309 -0
  60. package/dist/events/predicate.d.ts +8 -0
  61. package/dist/events/predicate.js +296 -22
  62. package/dist/flows/annotate-tools.js +3 -0
  63. package/dist/flows/annotate.js +18 -4
  64. package/dist/flows/coverage.d.ts +38 -5
  65. package/dist/flows/coverage.js +30 -4
  66. package/dist/flows/decision.d.ts +15 -0
  67. package/dist/flows/decision.js +1 -1
  68. package/dist/flows/flow-classify.js +1 -1
  69. package/dist/flows/flow-replay-run.js +8 -1
  70. package/dist/flows/flow-tools.js +21 -5
  71. package/dist/flows/heal-run.js +1 -1
  72. package/dist/flows/replay.js +3 -0
  73. package/dist/honesty/accepted-write.d.ts +3 -0
  74. package/dist/honesty/accepted-write.js +8 -3
  75. package/dist/honesty/already-true.js +15 -0
  76. package/dist/honesty/blind-spots.js +10 -2
  77. package/dist/honesty/honesty.d.ts +11 -0
  78. package/dist/honesty/honesty.js +1 -0
  79. package/dist/honesty/uncaptured-bodies.d.ts +4 -2
  80. package/dist/honesty/uncaptured-bodies.js +9 -2
  81. package/dist/honesty/unread-outcome.d.ts +8 -0
  82. package/dist/honesty/unread-outcome.js +36 -9
  83. package/dist/honesty/unsettled.d.ts +49 -0
  84. package/dist/honesty/unsettled.js +82 -0
  85. package/dist/honesty/verified.d.ts +36 -3
  86. package/dist/honesty/verified.js +54 -11
  87. package/dist/http-server.d.ts +19 -0
  88. package/dist/http-server.js +202 -4
  89. package/dist/impact/impact-recorder.d.ts +23 -0
  90. package/dist/impact/impact-recorder.js +76 -0
  91. package/dist/impact/impact-store.d.ts +47 -0
  92. package/dist/impact/impact-store.js +171 -0
  93. package/dist/index.d.ts +7 -0
  94. package/dist/index.js +47 -10
  95. package/dist/init/agent-rules.d.ts +36 -0
  96. package/dist/init/agent-rules.js +132 -22
  97. package/dist/init/astro-patch.d.ts +2 -1
  98. package/dist/init/astro-patch.js +38 -6
  99. package/dist/init/capabilities.d.ts +22 -0
  100. package/dist/init/capabilities.js +76 -0
  101. package/dist/init/confirm.d.ts +114 -0
  102. package/dist/init/confirm.js +165 -0
  103. package/dist/init/connect-steps.d.ts +2 -0
  104. package/dist/init/connect-steps.js +50 -0
  105. package/dist/init/cra.js +3 -2
  106. package/dist/init/csp-check.d.ts +38 -0
  107. package/dist/init/csp-check.js +92 -0
  108. package/dist/init/csp-doctor.d.ts +25 -0
  109. package/dist/init/csp-doctor.js +49 -0
  110. package/dist/init/cursor.js +6 -9
  111. package/dist/init/detect.d.ts +8 -0
  112. package/dist/init/detect.js +33 -3
  113. package/dist/init/mcp-clients.d.ts +1 -0
  114. package/dist/init/mcp-clients.js +51 -7
  115. package/dist/init/mcp.d.ts +15 -0
  116. package/dist/init/mcp.js +19 -0
  117. package/dist/init/non-js-project.js +29 -5
  118. package/dist/init/plan-framework.d.ts +10 -0
  119. package/dist/init/plan-framework.js +78 -16
  120. package/dist/init/plan.d.ts +47 -6
  121. package/dist/init/plan.js +228 -69
  122. package/dist/init/run.d.ts +24 -2
  123. package/dist/init/run.js +157 -45
  124. package/dist/init/slash-command.d.ts +1 -1
  125. package/dist/init/slash-command.js +54 -6
  126. package/dist/init/snippets.d.ts +45 -5
  127. package/dist/init/snippets.js +194 -42
  128. package/dist/init/vite-config.js +53 -5
  129. package/dist/input/network-mock-tools.d.ts +19 -0
  130. package/dist/input/network-mock-tools.js +37 -5
  131. package/dist/input/scroll-find.d.ts +6 -0
  132. package/dist/input/scroll-find.js +17 -2
  133. package/dist/input/scroll-tools.js +4 -0
  134. package/dist/journal/attach-journal.d.ts +9 -1
  135. package/dist/journal/attach-journal.js +13 -2
  136. package/dist/journal/journal-query.d.ts +13 -0
  137. package/dist/journal/journal-query.js +28 -3
  138. package/dist/journal/workspace-gitignore.d.ts +10 -0
  139. package/dist/journal/workspace-gitignore.js +59 -0
  140. package/dist/license/license.js +1 -1
  141. package/dist/mcp/mcp-proxy.d.ts +35 -30
  142. package/dist/mcp/mcp-proxy.js +306 -104
  143. package/dist/mcp/mcp.d.ts +10 -1
  144. package/dist/mcp/mcp.js +70 -34
  145. package/dist/mcp/proxy-handshake.d.ts +82 -1
  146. package/dist/mcp/proxy-handshake.js +109 -2
  147. package/dist/mcp/proxy-lifecycle.d.ts +11 -2
  148. package/dist/mcp/proxy-lifecycle.js +12 -3
  149. package/dist/mcp/proxy-log.d.ts +63 -0
  150. package/dist/mcp/proxy-log.js +132 -0
  151. package/dist/mcp/server-instructions.d.ts +17 -0
  152. package/dist/mcp/server-instructions.js +56 -0
  153. package/dist/mcp/shared-params.d.ts +27 -0
  154. package/dist/mcp/shared-params.js +36 -0
  155. package/dist/pool/browser-pool.d.ts +22 -2
  156. package/dist/pool/browser-pool.js +44 -4
  157. package/dist/project/learned-routes.d.ts +24 -0
  158. package/dist/project/learned-routes.js +63 -0
  159. package/dist/project/project-store.d.ts +6 -0
  160. package/dist/project/project-store.js +25 -1
  161. package/dist/project/reticle-dir.d.ts +2 -0
  162. package/dist/project/reticle-dir.js +1 -0
  163. package/dist/session/connection-memory.d.ts +59 -0
  164. package/dist/session/connection-memory.js +108 -0
  165. package/dist/session/dev-command.d.ts +26 -0
  166. package/dist/session/dev-command.js +89 -0
  167. package/dist/session/dev-server-probe.d.ts +68 -0
  168. package/dist/session/dev-server-probe.js +102 -7
  169. package/dist/session/last-act.d.ts +26 -0
  170. package/dist/session/last-act.js +35 -1
  171. package/dist/session/live-control-tools.js +42 -5
  172. package/dist/session/no-session-diagnosis.d.ts +67 -2
  173. package/dist/session/no-session-diagnosis.js +236 -27
  174. package/dist/session/no-session-next-action.d.ts +46 -0
  175. package/dist/session/no-session-next-action.js +85 -0
  176. package/dist/session/no-session-watch.d.ts +40 -1
  177. package/dist/session/no-session-watch.js +174 -8
  178. package/dist/session/pending-commands.d.ts +12 -0
  179. package/dist/session/pending-commands.js +13 -1
  180. package/dist/session/ref-provenance.d.ts +54 -0
  181. package/dist/session/ref-provenance.js +61 -0
  182. package/dist/session/session-lease.js +1 -1
  183. package/dist/session/session-manager.d.ts +4 -0
  184. package/dist/session/session-manager.js +35 -5
  185. package/dist/session/session.d.ts +10 -1
  186. package/dist/session/session.js +146 -5
  187. package/dist/telemetry/app-instrumented.d.ts +8 -0
  188. package/dist/telemetry/app-instrumented.js +10 -0
  189. package/dist/telemetry/automation-hint.d.ts +17 -0
  190. package/dist/telemetry/automation-hint.js +71 -0
  191. package/dist/telemetry/bug-found.d.ts +15 -17
  192. package/dist/telemetry/bug-found.js +52 -21
  193. package/dist/telemetry/cli-telemetry.js +7 -1
  194. package/dist/telemetry/daemon-telemetry.js +24 -0
  195. package/dist/telemetry/feedback.js +1 -1
  196. package/dist/telemetry/init-telemetry.js +9 -1
  197. package/dist/telemetry/install-source.d.ts +56 -0
  198. package/dist/telemetry/install-source.js +74 -0
  199. package/dist/telemetry/instrumentation-stall.d.ts +50 -0
  200. package/dist/telemetry/instrumentation-stall.js +90 -0
  201. package/dist/telemetry/run-telemetry.js +4 -1
  202. package/dist/telemetry/session-metrics.d.ts +8 -0
  203. package/dist/telemetry/session-metrics.js +15 -0
  204. package/dist/telemetry/telemetry.d.ts +7 -1
  205. package/dist/telemetry/telemetry.js +26 -2
  206. package/dist/telemetry/tool-refused.d.ts +19 -0
  207. package/dist/telemetry/tool-refused.js +55 -0
  208. package/dist/telemetry/verification-of.js +46 -7
  209. package/dist/temp-dir.d.ts +27 -0
  210. package/dist/temp-dir.js +46 -0
  211. package/dist/tools/act-tools.js +209 -28
  212. package/dist/tools/assert-grade.d.ts +1 -1
  213. package/dist/tools/assert-grade.js +27 -5
  214. package/dist/tools/assert-verdict.js +49 -7
  215. package/dist/tools/browser-tools.js +10 -0
  216. package/dist/tools/contract-tools.js +4 -0
  217. package/dist/tools/dynamic-tools.js +16 -7
  218. package/dist/tools/error-recovery.d.ts +10 -0
  219. package/dist/tools/error-recovery.js +73 -9
  220. package/dist/tools/feedback-invite.js +1 -1
  221. package/dist/tools/invoke-tool.js +159 -26
  222. package/dist/tools/lease-hint.d.ts +30 -8
  223. package/dist/tools/lease-hint.js +65 -14
  224. package/dist/tools/lease-tools.d.ts +40 -1
  225. package/dist/tools/lease-tools.js +181 -83
  226. package/dist/tools/navigate-result.js +1 -1
  227. package/dist/tools/observe-tools.js +10 -4
  228. package/dist/tools/observed-nothing.js +1 -1
  229. package/dist/tools/react-grace.d.ts +52 -0
  230. package/dist/tools/react-grace.js +90 -0
  231. package/dist/tools/read-tools.js +67 -5
  232. package/dist/tools/resolve-target.d.ts +33 -0
  233. package/dist/tools/resolve-target.js +53 -0
  234. package/dist/tools/settle-in-flight.d.ts +94 -0
  235. package/dist/tools/settle-in-flight.js +146 -0
  236. package/dist/tools/snapshot-delta.d.ts +10 -0
  237. package/dist/tools/snapshot-delta.js +194 -9
  238. package/dist/tools/tool-kit.d.ts +8 -0
  239. package/dist/tools/tool-surface.d.ts +60 -0
  240. package/dist/tools/tool-surface.js +86 -1
  241. package/dist/tools/tools.js +61 -8
  242. package/dist/tools/unadvertised-help.js +9 -6
  243. package/docs/README.md +55 -11
  244. package/docs/actions.mdx +120 -0
  245. package/docs/agent-cheatsheet.md +95 -29
  246. package/docs/architecture.md +52 -35
  247. package/docs/benchmarks.md +127 -75
  248. package/docs/best-practices.mdx +216 -0
  249. package/docs/capabilities.mdx +534 -0
  250. package/docs/cli/affected.mdx +53 -0
  251. package/docs/cli/capsules.mdx +70 -0
  252. package/docs/cli/cloud.mdx +153 -0
  253. package/docs/cli/doctor.mdx +109 -0
  254. package/docs/cli/drive.mdx +74 -0
  255. package/docs/cli/feedback.mdx +67 -0
  256. package/docs/cli/gate.mdx +64 -0
  257. package/docs/cli/help.mdx +94 -0
  258. package/docs/cli/hunt.mdx +73 -0
  259. package/docs/cli/identify.mdx +76 -0
  260. package/docs/cli/init.mdx +121 -0
  261. package/docs/cli/kill.mdx +91 -0
  262. package/docs/cli/license.mdx +48 -0
  263. package/docs/cli/mcp.mdx +61 -0
  264. package/docs/cli/open.mdx +74 -0
  265. package/docs/cli/restart.mdx +60 -0
  266. package/docs/cli/rollback.mdx +35 -0
  267. package/docs/cli/serve.mdx +69 -0
  268. package/docs/cli/status.mdx +88 -0
  269. package/docs/cli/stop.mdx +64 -0
  270. package/docs/cli/telemetry.mdx +57 -0
  271. package/docs/cli/update.mdx +52 -0
  272. package/docs/cli/verify.mdx +76 -0
  273. package/docs/cli/version.mdx +39 -0
  274. package/docs/cli/watch.mdx +62 -0
  275. package/docs/cli.mdx +241 -0
  276. package/docs/debugging.md +16 -10
  277. package/docs/deploy-checks.md +45 -12
  278. package/docs/desktop.mdx +384 -0
  279. package/docs/docs.json +364 -0
  280. package/docs/enterprise.md +22 -16
  281. package/docs/faq.mdx +102 -0
  282. package/docs/fixtures.md +13 -7
  283. package/docs/flows.md +29 -23
  284. package/docs/for-agents.md +71 -0
  285. package/docs/frameworks.mdx +238 -0
  286. package/docs/gate-plan.md +48 -42
  287. package/docs/gates.md +28 -22
  288. package/docs/getting-started.md +129 -77
  289. package/docs/human-control.md +24 -18
  290. package/docs/index.mdx +143 -0
  291. package/docs/install-agentic.mdx +224 -0
  292. package/docs/install-manual.mdx +196 -0
  293. package/docs/instrumentation.mdx +238 -0
  294. package/docs/integration-patterns.md +41 -35
  295. package/docs/local-registry.md +19 -13
  296. package/docs/multi-agent-testing.md +19 -13
  297. package/docs/packages/babel-plugin.mdx +79 -0
  298. package/docs/packages/browser.mdx +111 -0
  299. package/docs/packages/core.mdx +116 -0
  300. package/docs/packages/electron.mdx +85 -0
  301. package/docs/packages/eslint-plugin.mdx +86 -0
  302. package/docs/packages/next.mdx +89 -0
  303. package/docs/packages/react.mdx +91 -0
  304. package/docs/packages/server.mdx +98 -0
  305. package/docs/packages/tauri.mdx +63 -0
  306. package/docs/packages/test.mdx +119 -0
  307. package/docs/packages/vite-plugin.mdx +94 -0
  308. package/docs/packages.mdx +218 -0
  309. package/docs/platform-integration.md +35 -26
  310. package/docs/predicates.mdx +248 -0
  311. package/docs/quickstart.mdx +257 -0
  312. package/docs/recipes.mdx +282 -0
  313. package/docs/skill-file.mdx +107 -0
  314. package/docs/state-management.mdx +199 -0
  315. package/docs/style.css +14 -0
  316. package/docs/system-map.md +50 -33
  317. package/docs/telemetry-contract.md +106 -52
  318. package/docs/telemetry-events.mdx +475 -0
  319. package/docs/telemetry.md +63 -55
  320. package/docs/testing.md +44 -6
  321. package/docs/token-efficiency.md +37 -27
  322. package/docs/tools-act-and-wait.mdx +173 -0
  323. package/docs/tools-act-sequence.mdx +137 -0
  324. package/docs/tools-act.mdx +95 -0
  325. package/docs/tools-assert.mdx +129 -0
  326. package/docs/tools-console.mdx +63 -0
  327. package/docs/tools-inspect.mdx +88 -0
  328. package/docs/tools-navigate.mdx +99 -0
  329. package/docs/tools-network.mdx +119 -0
  330. package/docs/tools-observe.mdx +145 -0
  331. package/docs/tools-overview.mdx +160 -0
  332. package/docs/tools-query.mdx +126 -0
  333. package/docs/tools-session-and-feedback.mdx +112 -0
  334. package/docs/tools-sessions.mdx +94 -0
  335. package/docs/tools-snapshot.mdx +129 -0
  336. package/docs/tools-state.mdx +104 -0
  337. package/docs/tools-tools-and-run.mdx +156 -0
  338. package/docs/tools-wait-for.mdx +85 -0
  339. package/docs/troubleshooting.mdx +263 -0
  340. package/docs/usage.md +209 -165
  341. package/docs/vs-chrome-devtools-mcp.mdx +123 -0
  342. package/docs/vs-playwright-mcp.mdx +125 -0
  343. package/docs/vs-screenshots.mdx +137 -0
  344. package/docs/what-is-reticle.mdx +63 -0
  345. package/docs/why-reticle.mdx +109 -0
  346. package/package.json +5 -5
  347. package/docs/desktop-apps.md +0 -256
  348. package/docs/matrix/2.5.0/claude-code-machine.json +0 -19
  349. package/docs/matrix/2.5.0/codex-machine.json +0 -20
  350. package/docs/matrix/2.5.0/cursor-machine.json +0 -22
  351. package/docs/matrix/2.5.0/gemini-machine.json +0 -22
  352. package/docs/matrix/2.5.0/opencode-machine.json +0 -22
  353. package/docs/matrix/2.5.0/vscode-machine.json +0 -22
  354. package/docs/matrix/2.5.0/windsurf-machine.json +0 -22
  355. package/docs/matrix/MATRIX.md +0 -26
  356. package/docs/matrix/README.md +0 -59
  357. package/docs/mint.json +0 -61
@@ -0,0 +1,153 @@
1
+ ---
2
+ title: reticle cloud commands
3
+ description: Sign in, link a repository, and read runs and regressions from Reticle Cloud.
4
+ icon: cloud
5
+ ---
6
+
7
+ Ten subcommands bind this repository to Reticle Cloud so runs and flows land on a dashboard. They dispatch before the local parser, so `reticle login` is one tool, not a second binary.
8
+
9
+ ```bash
10
+ npx @reticlehq/server <login|logout|whoami|link|project|config|push|runs|regression|share>
11
+ ```
12
+
13
+ These are thin clients over the `/v1` API. The moat is the server, not the verbs.
14
+
15
+ ## Where credentials live
16
+
17
+ | Path | Contents | Secret |
18
+ | --- | --- | --- |
19
+ | `~/.reticle/session.json` | `{ url, token, orgName }` from `reticle login` | Yes |
20
+ | `~/.reticle/credentials.json` | Project-scoped API keys from `reticle link`, keyed by `projectId` | Yes |
21
+ | `<repo>/.reticle/cloud.json` | `{ projectId, projectName, url, sync, verify }`. The non-secret binding | No, commit it |
22
+
23
+ Auth for any command is `RETICLE_CLOUD_KEY` from the environment (the agent path) if set, otherwise the login token. `RETICLE_CLOUD_URL` overrides the endpoint; the default is `http://localhost:8890`.
24
+
25
+ ## The commands
26
+
27
+ ### `reticle login`
28
+
29
+ ```bash
30
+ npx @reticlehq/server login # browser device flow (the default)
31
+ npx @reticlehq/server login --email you@acme.com # headless: requests a code
32
+ npx @reticlehq/server login --email you@acme.com --code 123456 # headless: exchanges it
33
+ npx @reticlehq/server login --email you@acme.com --org "Acme" # --org is consulted only for a brand new account
34
+ ```
35
+
36
+ With no `--email`, it runs a browser device flow like `gh auth login`: fetch a device and user code, open the browser to approve, poll until confirmed. With `--email` it keeps the two-step code path for CI and servers, because it proves you own the inbox before handing out a session. A local cloud whose dev mailer cannot deliver echoes the code back and completes in one command.
37
+
38
+ ### `reticle logout`
39
+
40
+ Empties `session.json`. Per-project keys in `credentials.json` stay. Prints `{ "loggedOut": true }`.
41
+
42
+ ### `reticle whoami`
43
+
44
+ The one call to make when you do not know your state. Real capture:
45
+
46
+ ```json
47
+ {
48
+ "loggedInAs": "acme",
49
+ "repo": {
50
+ "attached": false,
51
+ "projectId": null,
52
+ "url": null,
53
+ "sync": { "runs": true, "memory": true, "flows": true },
54
+ "verify": "local"
55
+ }
56
+ }
57
+ ```
58
+
59
+ An unattached repo also gets a next-step nudge on stderr, telling you to run `reticle link`:
60
+
61
+ ```
62
+ → this repo is not attached ... run `reticle link`
63
+ ```
64
+
65
+ `whoami` exits `0` either way. Throughout this page, the punctuation joining the two halves of a message is shown as `...`.
66
+
67
+ ### `reticle link`
68
+
69
+ ```bash
70
+ npx @reticlehq/server link [--project <name|id>]
71
+ ```
72
+
73
+ Binds this repository to a cloud project. With a login token it **mints** a project-scoped key, so there is nothing to paste. With `RETICLE_CLOUD_KEY` already set, it resolves that key's project instead. `--project` accepts a slug id or a display name; omitted, it uses the `default` project. Writes `cloud.json` and the key.
74
+
75
+ ### `reticle project`
76
+
77
+ ```bash
78
+ npx @reticlehq/server project ls
79
+ npx @reticlehq/server project create "My App"
80
+ npx @reticlehq/server project rename <projectId> "New name"
81
+ npx @reticlehq/server project rm <projectId>
82
+ ```
83
+
84
+ `rename` and `rm` work but are missing from the top-level `reticle help` block, which lists only `<ls|create <name>>`. The command's own usage error names all four. Missing or malformed arguments exit `2`:
85
+
86
+ ```
87
+ reticle: usage: reticle project <ls|create <name>|rename <id> <name>|rm <id>>
88
+ ```
89
+
90
+ ### `reticle config`
91
+
92
+ ```bash
93
+ npx @reticlehq/server config [--runs on|off] [--memory on|off] [--flows on|off] [--verify local|server]
94
+ ```
95
+
96
+ Edits `.reticle/cloud.json` in place. Any value other than `on` or `off` (or `local` or `server` for `--verify`) exits `2`. Requires the repo to be linked; run in an unlinked repo it exits `2` before it looks at the flags at all:
97
+
98
+ ```
99
+ reticle: no .reticle/cloud.json here ... run `reticle link` first
100
+ ```
101
+
102
+ ### `reticle push`
103
+
104
+ Sends local run artifacts from `.reticle` to the linked project, honoring the sync policy. With `sync.runs` off it does nothing and says so. Prints `{ pushed, failed, total, project }`.
105
+
106
+ ### `reticle runs`
107
+
108
+ The linked project's recent run artifacts. The key scopes the query server-side.
109
+
110
+ ### `reticle regression`
111
+
112
+ The CI gate: which flows broke relative to before. **Exits `3`** when any flow regressed, which is the whole point of it being a separate command.
113
+
114
+ ### `reticle share`
115
+
116
+ ```bash
117
+ npx @reticlehq/server share <runId>
118
+ ```
119
+
120
+ Mints a public proof link for one run. A missing `runId` exits `2`:
121
+
122
+ ```
123
+ reticle: usage: reticle share <runId>
124
+ ```
125
+
126
+ ## When the repo is not attached
127
+
128
+ `push`, `runs` and `regression` all need a project to talk to. Without one they exit `1` with the same line on stderr, measured:
129
+
130
+ ```
131
+ reticle: cloud not attached here ... run `reticle link` (or set RETICLE_CLOUD_URL/KEY)
132
+ ```
133
+
134
+ ## Exit codes
135
+
136
+ | Code | Meaning |
137
+ | ---- | ----------------------------------------------------------------------------------- |
138
+ | `0` | Success |
139
+ | `1` | The API call failed, or the repository is not attached where attachment is required |
140
+ | `2` | Usage error, or not signed in and no `RETICLE_CLOUD_KEY` |
141
+ | `3` | `regression` only: at least one flow broke |
142
+
143
+ Output is pretty-printed JSON on stdout. Errors and next-step nudges go to stderr, so an agent parsing stdout is unaffected.
144
+
145
+ ## Worked example
146
+
147
+ ```bash
148
+ npx @reticlehq/server login
149
+ npx @reticlehq/server project create "Checkout"
150
+ npx @reticlehq/server link --project "Checkout"
151
+ npx @reticlehq/server verify http://localhost:4173 # runs auto-push once linked
152
+ npx @reticlehq/server regression # exit 3 fails the pipeline
153
+ ```
@@ -0,0 +1,109 @@
1
+ ---
2
+ title: reticle doctor
3
+ description: 'Diagnose the Reticle setup in one command: Chromium, daemon, bridge port, logs, and desktop wiring.'
4
+ icon: stethoscope
5
+ ---
6
+
7
+ `reticle doctor` collapses the setup failure modes into one command. It is the first thing to run when something is wrong.
8
+
9
+ ```bash
10
+ npx @reticlehq/server doctor [--port N]
11
+ ```
12
+
13
+ ## Flags
14
+
15
+ | Flag | Type | Default | What it does |
16
+ | --- | --- | --- | --- |
17
+ | `--port N` | number | `4400` (or `RETICLE_PORT`, or the port in `.reticle.json`) | Which bridge port to diagnose |
18
+
19
+ ## What it prints
20
+
21
+ Human-readable lines on stdout, not the JSON log. Real capture:
22
+
23
+ ```
24
+ reticle doctor
25
+ node v22.14.0
26
+ chromium ✓ installed (chromium-1234)
27
+ daemon ✓ running on :4400 (pid 72698, v2.8.0)
28
+ sessions ✓ 1 page connected
29
+ bridge port 4400 (your app must dial THIS port, not your dev-server port)
30
+ daemon log /Users/you/.reticle/daemon-4400.log
31
+ tracing RETICLE_TRACE=1 on the daemon for per-stage timings in that log
32
+ ```
33
+
34
+ When nothing has connected, the `sessions` line fails and the daemon's own diagnosis is appended under the checklist. Real capture, against a daemon on a scratch port that no app had dialled, with the diagnosis wrapped for width and trimmed at the ellipsis:
35
+
36
+ ```
37
+ sessions ✗ no page has connected to this daemon
38
+ bridge port 4499 (your app must dial THIS port, not your dev-server port)
39
+ daemon log /Users/you/.reticle/daemon-4499.log
40
+ tracing RETICLE_TRACE=1 on the daemon for per-stage timings in that log
41
+
42
+ nothing has connected. What the daemon can tell from here:
43
+ no browser session connected. Two things to weigh, and neither of them is proof. (1) Nothing is
44
+ listening on the ports Reticle scans (3000, 3001, 4200, 4321, 5000, 5173, 5174, 8000, 8080, 8100,
45
+ 9000, 1420, 3100, 4173, 5175, 7860, 8501), so the dev server may not be running ...
46
+ ```
47
+
48
+ | Line | What it checks |
49
+ | --- | --- |
50
+ | `node` | The Node version running the CLI |
51
+ | `chromium` | Whether the exact Chromium revision the bundled Playwright wants is on disk. The most common silent failure |
52
+ | `daemon` | Whether the port holds a Reticle daemon, a foreign process (named where possible), or nothing. Adds a `version` line when the daemon's version or contract fingerprint disagrees with the CLI's |
53
+ | `sessions` | Whether any page has actually connected. Zero is a FAILING check rather than a neutral note, because it is the state the setup most often stalls in: wired correctly, daemon up, nothing dialled in. When it is zero the daemon's own no-session diagnosis prints below the checklist |
54
+ | `bridge port` | The port your app must dial, spelled out because mixing it up with the dev server port is the most common setup failure |
55
+ | `port check` | Only when your project's configured port disagrees with the one the daemon is on. Prints the mismatch rather than leaving you to spot it across two lines |
56
+ | `daemon log` | Where the structured daemon log lives |
57
+ | `tracing` | How to turn that log into a per-stage trace |
58
+ | `desktop` | Only on a desktop project. Every Electron and Tauri misconfiguration here fails silently, so it is diagnosed explicitly |
59
+
60
+ ## The chromium line
61
+
62
+ Playwright pins one Chromium revision per version, and the daemon launches that one and no other. So the check is not "is a Chromium there" but "is _this_ revision there", and the three answers have three different fixes.
63
+
64
+ All three captures below are real, taken by pointing `PLAYWRIGHT_BROWSERS_PATH` at a full root, a stale root, and an empty one.
65
+
66
+ **`✓ installed`** means the wanted revision is on disk. Nothing to do.
67
+
68
+ ```
69
+ chromium ✓ installed (chromium-1234)
70
+ ```
71
+
72
+ **`✗ wrong revision`** means builds are installed and none of them is the wanted one. One pinned download away. The line names the revision Playwright wants, then every revision the root actually holds, then the exact command:
73
+
74
+ ```
75
+ chromium ✗ wrong revision ... the bundled playwright wants chromium-1234;
76
+ /tmp/pwroot holds chromium-1194, chromium-1208. run: npx playwright@1.62.1 install chromium
77
+ ```
78
+
79
+ **`✗ missing`** means the browsers root holds no Chromium at all. It prints the full executable path it looked for, so you can see which root it searched. If that is not where your browsers live, `PLAYWRIGHT_BROWSERS_PATH` is what moves it:
80
+
81
+ ```
82
+ chromium ✗ missing ... looked for /tmp/emptyroot/chromium-1234/chrome-mac-arm64/Google Chrome
83
+ for Testing.app/Contents/MacOS/Google Chrome for Testing; run: npx playwright@1.62.1 install chromium
84
+ ```
85
+
86
+ Both failing lines are one line in the terminal, wrapped here for width, and the punctuation that separates the verdict from its explanation is shown as `...`. The revision number and the pinned Playwright version come from the build you are running, so yours may differ from these; use the ones your own `doctor` prints.
87
+
88
+ The wanted revision and the root are both read back off the path Playwright itself resolves, so `PLAYWRIGHT_BROWSERS_PATH` and every platform default (including `%LOCALAPPDATA%\ms-playwright` on Windows) are honoured without this command keeping its own table of roots.
89
+
90
+ <Warning>
91
+ Run the command `doctor` prints, not `npx playwright install chromium`. The unpinned form resolves
92
+ the newest Playwright, downloads *its* revision, and leaves the check saying exactly what it said
93
+ before. That loop is why the line names the version to pin to.
94
+ </Warning>
95
+
96
+ ## Exit codes
97
+
98
+ Always `0`. `doctor` reports; it does not gate.
99
+
100
+ ## Worked example
101
+
102
+ ```bash
103
+ npx @reticlehq/server doctor
104
+ # then run the chromium command doctor printed, verbatim
105
+ ```
106
+
107
+ <Card title="Deeper debugging" icon="bug" href="/debugging">
108
+ Reading the daemon log, and what `RETICLE_TRACE=1` adds to it.
109
+ </Card>
@@ -0,0 +1,74 @@
1
+ ---
2
+ title: reticle drive
3
+ description: Run Reticle in the foreground against a URL, with the browser visible, for debugging.
4
+ icon: gauge-high
5
+ ---
6
+
7
+ `reticle drive` runs the engine in the foreground and launches a browser at the URL you give it. It exists for debugging: you watch the run happen.
8
+
9
+ ```bash
10
+ npx @reticlehq/server drive <url> [--headless] [--headed]
11
+ ```
12
+
13
+ ## Arguments and flags
14
+
15
+ | Argument | Type | Default | What it does |
16
+ | ------------ | -------------------------------- | ------------------------ | ----------------- |
17
+ | `url` | string, positional, **required** | none | The page to drive |
18
+ | `--headed` | boolean | on by default outside CI | Show the browser |
19
+ | `--headless` | boolean | on when `CI` is set | Hide it |
20
+
21
+ `drive` is the one interactive command in the family, so it is the one that shows the browser by default. `serve`, `mcp` and the internal daemon own the pooled browser behind leases, which is batch work, and hide theirs.
22
+
23
+ ## What it prints
24
+
25
+ `reticle_started` with the port on success, `reticle_start_failed` with the error otherwise. When a daemon already owns the port it prints `reticle_drive_attached` with the session it opened instead. See [When a daemon already has the port](#when-a-daemon-already-has-the-port).
26
+
27
+ Omitting the URL is a usage error. Real capture, with the usage block that follows it trimmed:
28
+
29
+ ```
30
+ {"t":"2026-08-15T18:43:06.977Z","event":"reticle_usage_error","message":"drive needs a url"}
31
+ drive needs a url
32
+
33
+ usage: npx @reticlehq/server <command> (or `reticle <command>` once the bin is on your PATH)
34
+ ...
35
+ ```
36
+
37
+ <Note>
38
+ `drive` takes **no `--port` flag**. Any flag other than `--headed` or `--headless` is rejected as
39
+ `unknown argument '--port'`. To drive on a different port, set `RETICLE_PORT` or put the port in
40
+ `.reticle.json`.
41
+ </Note>
42
+
43
+ ## Exit codes
44
+
45
+ | Code | Meaning |
46
+ | ---- | --------------------------------------------------------------------- |
47
+ | `0` | Running in the foreground, or attached with a connected session |
48
+ | `1` | No URL, an unknown flag, the engine failed to start, or attach failed |
49
+
50
+ ## When a daemon already has the port
51
+
52
+ A daemon on `:4400` is the normal state the moment any agent connects, and `drive` does not fight it for the port: it **asks that daemon** for a browser instead. The daemon opens a fresh isolated, never-throttled context, the same one `reticle_lease` hands an agent, and `drive` prints the session id and exits.
53
+
54
+ ```bash
55
+ $ npx @reticlehq/server drive http://localhost:5173
56
+ {"event":"reticle_drive_attached","port":4400,"url":"http://localhost:5173","sessionId":"lease-9f2b…","ready":true}
57
+ ```
58
+
59
+ A plain-text line follows it naming the same session, how long it survives untouched (any tool call against it resets that), and, if the page never dialled the bridge, why.
60
+
61
+ That session lives in the daemon, so the tools your agent already has open can address it by id. You do **not** need `reticle stop` first, and should not use it: the MCP proxy respawns a daemon as soon as the next tool call arrives, which is a race a manual `stop` loses.
62
+
63
+ Attaching means the browser is the daemon's pooled, headless one, so `--headed` cannot apply. To watch a browser instead, drive on a port no daemon owns (`RETICLE_PORT=4460`).
64
+
65
+ <Note>
66
+ If the port is held by something that is **not** a Reticle daemon, `drive` refuses and names the
67
+ holder. It can neither bind nor attach. [`reticle verify`](/cli/verify) still binds its own port.
68
+ </Note>
69
+
70
+ ## Worked example
71
+
72
+ ```bash
73
+ npx @reticlehq/server drive http://localhost:5173
74
+ ```
@@ -0,0 +1,67 @@
1
+ ---
2
+ title: reticle feedback
3
+ description: Send a report to the Reticle maintainers from the shell, including from a setup that never finished.
4
+ icon: comment
5
+ ---
6
+
7
+ `reticle feedback` is the feedback channel as a command: no prompts, no editor, no account. It exists so the cost of telling the maintainers something is lower than the cost of shrugging and moving on.
8
+
9
+ ```bash
10
+ npx @reticlehq/server feedback [--rating 1-5] [--bug] "what worked, what didn't"
11
+ npx @reticlehq/server feedback --agent --kind <bug|gap|ambiguity|feature_request|improvement> "what happened"
12
+ ```
13
+
14
+ The `--agent` form is for an agent that cannot reach the `reticle_feedback` tool: during `init`, while instrumentation is half wired, or when the daemon will not start. Those are the reports that are hardest to hear and most needed, because every other path requires the tool surface to already work.
15
+
16
+ ## Flags
17
+
18
+ | Flag | Type | Default | What it does |
19
+ | --- | --- | --- | --- |
20
+ | `--rating N` | integer 1 to 5 | unset | A human's overall take. A bare rating with no words is a valid report |
21
+ | `--bug` | boolean | `false` | Shorthand for `--kind bug` |
22
+ | `--kind K` | one of `bug`, `gap`, `ambiguity`, `feature_request`, `improvement`, `experience` | `experience`, or `bug` with `--bug` | The report's class. Wins over `--bug` |
23
+ | `--agent` | boolean | `false` | File as the agent, so agent reports never dilute the human rating signal |
24
+
25
+ Everything that is not a flag or a flag's value becomes the message, joined with spaces. Quoting is still your job for shell reasons.
26
+
27
+ ## What it prints
28
+
29
+ The payload is printed **before** it is sent, every time. A channel that carries free text and does not show you what it sends is asking for trust it has not earned.
30
+
31
+ ```
32
+ sending {"source":"human","kind":"experience","stack":"vite","runtime":"web"}
33
+ redacted email (removed before sending)
34
+ thanks your feedback is in. it genuinely changes what gets built next.
35
+ ```
36
+
37
+ `not sent` replaces the last line when the send failed or telemetry is off, and names the reason. Humans who have never identified also get an offer of a reply route, printed after the receipt rather than as a prompt.
38
+
39
+ Run with no message and no rating, it prints usage and exits `1`. Real capture:
40
+
41
+ ```
42
+ usage: reticle feedback [--rating 1-5] [--bug] "what worked, what didn't"
43
+ agents: reticle feedback --agent --kind <bug|gap|ambiguity|feature_request|improvement|experience> "what happened"
44
+ your words go to the maintainers; nothing from your app is ever included.
45
+ ```
46
+
47
+ ## Exit codes
48
+
49
+ | Code | Meaning |
50
+ | ---- | --------------------------------------------------------------- |
51
+ | `0` | The report was submitted, or attempted and reported as not sent |
52
+ | `1` | No message and no rating, or an invalid `--rating` or `--kind` |
53
+
54
+ ## Worked example
55
+
56
+ ```bash
57
+ npx @reticlehq/server feedback --agent --kind gap \
58
+ "no way to drive a contenteditable rich-text editor; had to skip the flow"
59
+ ```
60
+
61
+ <Card
62
+ title="The same channel from inside a session"
63
+ icon="comments"
64
+ href="/tools-session-and-feedback"
65
+ >
66
+ `reticle_feedback` when the tools are reachable.
67
+ </Card>
@@ -0,0 +1,64 @@
1
+ ---
2
+ title: reticle gate
3
+ description: Exit non-zero unless passing verification artifacts cover every flow the changed files affect.
4
+ icon: shield-halved
5
+ ---
6
+
7
+ `reticle gate` is what makes verification unavoidable. It computes the [affected](/cli/affected) flows, looks for a passing artifact for each, and fails the command if any is missing. An agent that edits a covered file cannot call itself finished without re-verifying.
8
+
9
+ ```bash
10
+ npx @reticlehq/server gate [--since <ref>] [file...]
11
+ ```
12
+
13
+ ## Arguments and flags
14
+
15
+ | Argument | Type | Default | What it does |
16
+ | --- | --- | --- | --- |
17
+ | `file...` | strings, positional | none | Explicit changed files |
18
+ | `--since <ref>` | string | `HEAD` when no files are given | Also include files git reports as changed since this ref |
19
+
20
+ ## What blocks and what does not
21
+
22
+ | Category | Blocking | Why |
23
+ | --- | --- | --- |
24
+ | `uncovered` | Yes | An affected flow with no passing artifact |
25
+ | `downgraded` | Yes | A flow whose assertions were weakened since its last passing run. A green bought by weakening the test is the gaming move this exists to stop |
26
+ | `deletedCoverage` | Yes | A flow that covered a changed file and has since vanished. Coverage deleted, not satisfied |
27
+ | `quarantined` | No | Flows the flake ledger has quarantined. Surfaced, never blocking, because one unexplained flake that blocks a merge destroys trust in the red |
28
+
29
+ ## What it prints
30
+
31
+ One `reticle_gate` line. Real capture from this repository, with the flow lists trimmed for length:
32
+
33
+ ```json
34
+ {
35
+ "t": "2026-08-15T18:42:58.434Z",
36
+ "event": "reticle_gate",
37
+ "pass": false,
38
+ "uncovered": ["WEB-flow", "deploy-journey", "verify-route", "verify-500"],
39
+ "quarantined": ["asserted-demo", "blast-radius-compose", "drift-demo", "qa2-flow"],
40
+ "coverage": { "pct": 0, "covered": 0, "total": 47 }
41
+ }
42
+ ```
43
+
44
+ `downgraded` and `deletedCoverage` appear only when they are non-empty, and neither was present in that run. The CLI prints this as a single line of JSON; it is pretty-printed here to be readable.
45
+
46
+ ## Exit codes
47
+
48
+ | Code | Meaning |
49
+ | --- | --- |
50
+ | `0` | Every affected, non-flaky flow has a passing artifact and nothing was weakened or deleted |
51
+ | `1` | Something is uncovered, downgraded or deleted. Also `1` on any internal fault: the gate fails closed |
52
+
53
+ Measured on this repository, `npx @reticlehq/server gate --since HEAD~1` exited `1` with the output above: 0 of 47 flows covered, 39 uncovered and 8 quarantined.
54
+
55
+ ## Worked example
56
+
57
+ ```yaml
58
+ - run: npx @reticlehq/server verify http://localhost:4173
59
+ - run: npx @reticlehq/server gate --since ${{ github.event.pull_request.base.sha }}
60
+ ```
61
+
62
+ <Card title="Wiring this into CI" icon="rocket" href="/deploy-checks">
63
+ Where the gate sits relative to build, verify, and merge.
64
+ </Card>
@@ -0,0 +1,94 @@
1
+ ---
2
+ title: reticle help
3
+ description: Print the complete Reticle command grammar, every command and every flag, on one screen.
4
+ icon: circle-question
5
+ ---
6
+
7
+ `reticle help` prints the whole usage block to stdout and exits `0`.
8
+
9
+ ```bash
10
+ npx @reticlehq/server help
11
+ npx @reticlehq/server --help
12
+ npx @reticlehq/server -h
13
+ ```
14
+
15
+ All three are the same command.
16
+
17
+ <Warning>
18
+ There is no per-command help. `reticle init --help` is not a help request, it is an unknown
19
+ argument: the parser rejects it, prints `unknown argument '--help'` followed by this same block,
20
+ and exits `1`. This page and the rest of this section are the per-command reference.
21
+ </Warning>
22
+
23
+ ## What it prints
24
+
25
+ Real capture, in full:
26
+
27
+ ```
28
+ usage: npx @reticlehq/server <command> (or `reticle <command>` once the bin is on your PATH)
29
+
30
+ reticle init [--dry-run] [--port N] [--no-mcp] [--no-install] [--app <dir>] (wire Reticle into the project in this directory)
31
+ --app picks WHICH app in a monorepo, when several are found
32
+ --no-mcp skips MORE than the server registration: also the agent rule files
33
+ (CLAUDE.md / AGENTS.md / .cursor) and the /reticle command, because all three
34
+ only make sense once the tools are reachable.
35
+ reticle serve [--port N] [--drive <url>] [--headless] [--http] [--http-port N] [--http-token T]
36
+ reticle stop [--port N] [--quiet] (stop the daemon we started, by its recorded pid)
37
+ reticle kill [--port N] [--force] (free the port by its LISTENER, never the agent's mcp proxy)
38
+ reticle restart [--port N] [--force] (kill, then start a daemon and wait for a real bind)
39
+ reticle status [--port N]
40
+ reticle doctor [--port N] (one command to diagnose setup: Chromium, daemon, port)
41
+ reticle open [url] [--port N] (show the app: reuse the connected tab, else open one)
42
+ reticle verify <url> [--headed] [--timeout N] [--storage-state <file>] (one-shot: drive the URL, verify saved flows, exit 0=pass)
43
+ reticle affected [--since <ref>] [file...] (which saved flows must re-verify for the changed files)
44
+ reticle gate [--since <ref>] [file...] (exit non-zero unless passing artifacts cover the affected flows)
45
+ reticle watch [url] (on save, report which saved flows must re-verify)
46
+ reticle drive <url> [--headless] (foreground mode, for debugging)
47
+ reticle mcp [--port N] [--drive <url>] [--headless] (MCP stdio proxy; auto-starts daemon if needed)
48
+ reticle update (install the latest server version and restart)
49
+ reticle rollback (restore the previous server version and restart)
50
+ reticle license (show enterprise license status: active | eval | missing)
51
+ reticle telemetry [status|enable|disable] (anonymous usage metrics; status shows what's sent + the policy)
52
+ reticle feedback [--rating 1-5] [--bug] "message" (tell us what worked and what didn't; prints exactly what it sends)
53
+ reticle feedback --agent --kind <bug|gap|ambiguity|feature_request|improvement> "message"
54
+ (agents: file from anywhere, including a setup that never finished)
55
+ reticle identify --context company|side_project|open_source|learning [--company N] [--email E] [--forget]
56
+ (OPT-IN: tell us who you are, e.g. for support or an enterprise trial)
57
+
58
+ Cloud (link this project to Reticle Cloud; runs/flows recorded on the dashboard):
59
+ reticle login --email <e> [--code <c>] [--org <n>] (sign in: mails a code, then exchanges it)
60
+ reticle link [--project <name|id>] (bind this repo: mints a scoped key, writes .reticle/cloud.json)
61
+ reticle whoami (who am I signed in as, and is this repo attached?)
62
+ reticle project <ls|create <name>> (list or create cloud projects)
63
+ reticle config [--runs on|off] [--memory on|off] [--flows on|off] [--verify local|server]
64
+ reticle push (send local run artifacts to the dashboard)
65
+ reticle runs | regression | share <runId> (read cloud state; regression exits 3 if any flow broke)
66
+
67
+ 'drive' shows the browser; everything else is hidden (serve/mcp own the pool behind leases, replay
68
+ and the spec runner: batch work). --headed opts any of them in, --headless hides drive, CI hides it.
69
+ ```
70
+
71
+ ## Errors print it too
72
+
73
+ Any usage error prints the offending thing first, then this same block on stderr, and exits `1`:
74
+
75
+ ```
76
+ {"t":"2026-08-15T18:42:48.476Z","event":"reticle_usage_error","message":"unknown command 'nonsense-cmd'"}
77
+ unknown command 'nonsense-cmd'
78
+
79
+ usage: npx @reticlehq/server <command> (or `reticle <command>` once the bin is on your PATH)
80
+ ... the whole block above ...
81
+ ```
82
+
83
+ Two audiences, two channels: the structured line for logs and scripts, the plain text for the person who just typed the command.
84
+
85
+ ## Exit codes
86
+
87
+ | Code | Meaning |
88
+ | ---- | ------------------------------------------------- |
89
+ | `0` | Help was requested |
90
+ | `1` | Help was printed because something else was wrong |
91
+
92
+ <Note>
93
+ A bare `reticle` with no arguments is **not** help. It is [`reticle serve`](/cli/serve).
94
+ </Note>
@@ -0,0 +1,73 @@
1
+ ---
2
+ title: reticle hunt
3
+ description: Aggregate many crawl reports into one false-green rate across already-merged changes.
4
+ icon: crosshairs
5
+ ---
6
+
7
+ `reticle hunt` is arithmetic, not driving. You point it at a directory of crawl reports (one JSON file per checkout, each produced by `reticle_crawl`) and it turns the pile into the one number the core claim needs: across N already-merged, already-green changes, how many carried a candidate false green?
8
+
9
+ ```bash
10
+ npx @reticlehq/server hunt <dir-of-crawl-reports>
11
+ ```
12
+
13
+ No control arm is needed. Those changes shipped, so the counterfactual is already established.
14
+
15
+ ## Arguments
16
+
17
+ | Argument | Type | Default | What it does |
18
+ | --- | --- | --- | --- |
19
+ | `<dir>` | string, positional, **required** | none | Directory of `*.json` crawl reports. Each file is one crawl over one checkout |
20
+
21
+ Each input file is read for `label` (falling back to the filename), `anomalies[]`, and `stepsRun`.
22
+
23
+ ## What it prints
24
+
25
+ One `reticle_hunt` line with the summary. Real capture over a directory of two reports, one of them carrying a contradiction and a console error, with the `headline` sentence trimmed at the ellipsis:
26
+
27
+ ```json
28
+ {
29
+ "t": "2026-08-15T18:43:18.333Z",
30
+ "event": "reticle_hunt",
31
+ "runs": 2,
32
+ "runsWithCoverage": 2,
33
+ "runsWithContradictions": 1,
34
+ "contradictions": 1,
35
+ "singleChannelFaults": 1,
36
+ "byKind": { "ui-advanced-request-failed": 1, "console-error": 1 },
37
+ "flagged": ["abc123"],
38
+ "headline": "1 of 2 merged, already-green changes carried a candidate false green (1 contradictions) ..."
39
+ }
40
+ ```
41
+
42
+ | Field | Meaning |
43
+ | --- | --- |
44
+ | `runs` | Report files read |
45
+ | `runsWithCoverage` | Runs that drove at least one control. The only honest denominator: a run that drove nothing is not evidence of cleanliness |
46
+ | `runsWithContradictions` | Runs with at least one cross-channel contradiction |
47
+ | `contradictions` | Total contradictions. The kinds are `ui-advanced-request-failed`, `signal-contradicted`, `response-ignored`, `duplicate-request`, `request-never-settled`, `failure-misattributed` |
48
+ | `singleChannelFaults` | Everything else: console errors, failed requests, dead controls. Context, not the claim |
49
+ | `byKind` | Counts per anomaly kind |
50
+ | `flagged` | The labels with contradictions, so each can be confirmed by hand |
51
+ | `headline` | A sentence phrased so it cannot overstate itself. It says "candidate", because every flag still needs manual confirmation |
52
+
53
+ ## Exit codes
54
+
55
+ Always `0`. A read failure is logged as `reticle_hunt_failed`. Omitting the directory is a usage error:
56
+
57
+ ```
58
+ {"t":"2026-08-15T18:43:06.525Z","event":"reticle_usage_error","message":"usage: reticle hunt <dir-of-crawl-reports>"}
59
+ usage: reticle hunt <dir-of-crawl-reports>
60
+ ```
61
+
62
+ That path exits `1`.
63
+
64
+ ## Worked example
65
+
66
+ ```bash
67
+ for sha in $(git log --format=%H -n 30 main); do
68
+ git checkout "$sha" && npm run dev &
69
+ # drive reticle_crawl over the app, write the JSON:
70
+ # .../reports/$sha.json
71
+ done
72
+ npx @reticlehq/server hunt ./reports
73
+ ```