@reticlehq/server 2.7.0 → 2.8.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 (236) hide show
  1. package/README.md +14 -5
  2. package/SKILL.md +64 -29
  3. package/dist/capsule/causal-summary.d.ts +20 -0
  4. package/dist/capsule/causal-summary.js +31 -6
  5. package/dist/capsule/divergence.js +7 -1
  6. package/dist/cli/chromium-hint.d.ts +33 -5
  7. package/dist/cli/chromium-hint.js +82 -12
  8. package/dist/cli/cli-doctor.js +28 -25
  9. package/dist/cli/cli-kill.d.ts +58 -0
  10. package/dist/cli/cli-kill.js +162 -0
  11. package/dist/cli/cli-launch.d.ts +17 -0
  12. package/dist/cli/cli-launch.js +28 -0
  13. package/dist/cli/cli-parse.d.ts +16 -1
  14. package/dist/cli/cli-parse.js +32 -9
  15. package/dist/cli/cli-port.d.ts +8 -0
  16. package/dist/cli/cli-port.js +16 -0
  17. package/dist/cli/cli-verify.js +2 -2
  18. package/dist/cli/doctor-sessions-line.d.ts +12 -0
  19. package/dist/cli/doctor-sessions-line.js +66 -0
  20. package/dist/cli/port-holder.d.ts +10 -0
  21. package/dist/cli/port-holder.js +26 -2
  22. package/dist/cli.js +99 -14
  23. package/dist/crawl/crawl-tools.js +12 -2
  24. package/dist/crawl/crawl.d.ts +13 -0
  25. package/dist/crawl/crawl.js +50 -2
  26. package/dist/events/contradictions.d.ts +14 -0
  27. package/dist/events/contradictions.js +26 -17
  28. package/dist/events/predicate-eval.d.ts +20 -1
  29. package/dist/events/predicate-eval.js +125 -3
  30. package/dist/events/predicate.js +170 -18
  31. package/dist/flows/flow-classify.js +1 -1
  32. package/dist/flows/flow-tools.js +12 -4
  33. package/dist/flows/heal-run.js +1 -1
  34. package/dist/honesty/blind-spots.js +6 -2
  35. package/dist/honesty/unsettled.d.ts +40 -0
  36. package/dist/honesty/unsettled.js +78 -0
  37. package/dist/honesty/verified.d.ts +7 -0
  38. package/dist/honesty/verified.js +3 -3
  39. package/dist/index.js +3 -0
  40. package/dist/init/agent-rules.d.ts +16 -0
  41. package/dist/init/agent-rules.js +96 -22
  42. package/dist/init/astro-patch.d.ts +2 -1
  43. package/dist/init/astro-patch.js +11 -5
  44. package/dist/init/capabilities.d.ts +22 -0
  45. package/dist/init/capabilities.js +76 -0
  46. package/dist/init/confirm.d.ts +96 -0
  47. package/dist/init/confirm.js +138 -0
  48. package/dist/init/cra.js +3 -2
  49. package/dist/init/non-js-project.js +29 -5
  50. package/dist/init/plan-framework.js +53 -15
  51. package/dist/init/plan.d.ts +40 -4
  52. package/dist/init/plan.js +163 -40
  53. package/dist/init/run.d.ts +24 -2
  54. package/dist/init/run.js +148 -42
  55. package/dist/init/slash-command.d.ts +1 -1
  56. package/dist/init/slash-command.js +46 -6
  57. package/dist/init/snippets.d.ts +44 -4
  58. package/dist/init/snippets.js +161 -37
  59. package/dist/init/vite-config.js +29 -3
  60. package/dist/input/network-mock-tools.d.ts +19 -0
  61. package/dist/input/network-mock-tools.js +29 -4
  62. package/dist/license/license.js +1 -1
  63. package/dist/mcp/mcp-proxy.d.ts +69 -3
  64. package/dist/mcp/mcp-proxy.js +205 -20
  65. package/dist/mcp/mcp.js +23 -7
  66. package/dist/mcp/proxy-lifecycle.d.ts +1 -1
  67. package/dist/mcp/proxy-lifecycle.js +1 -1
  68. package/dist/pool/browser-pool.d.ts +22 -2
  69. package/dist/pool/browser-pool.js +44 -4
  70. package/dist/project/learned-routes.d.ts +24 -0
  71. package/dist/project/learned-routes.js +63 -0
  72. package/dist/project/project-store.d.ts +6 -0
  73. package/dist/project/project-store.js +25 -1
  74. package/dist/session/no-session-diagnosis.d.ts +19 -0
  75. package/dist/session/no-session-diagnosis.js +71 -18
  76. package/dist/session/no-session-watch.js +12 -0
  77. package/dist/session/ref-provenance.d.ts +54 -0
  78. package/dist/session/ref-provenance.js +61 -0
  79. package/dist/session/session-lease.js +1 -1
  80. package/dist/telemetry/automation-hint.d.ts +17 -0
  81. package/dist/telemetry/automation-hint.js +71 -0
  82. package/dist/telemetry/bug-found.d.ts +0 -20
  83. package/dist/telemetry/bug-found.js +38 -21
  84. package/dist/telemetry/cli-telemetry.js +7 -1
  85. package/dist/telemetry/feedback.js +1 -1
  86. package/dist/telemetry/init-telemetry.js +9 -1
  87. package/dist/telemetry/install-source.d.ts +36 -0
  88. package/dist/telemetry/install-source.js +40 -0
  89. package/dist/telemetry/run-telemetry.js +4 -1
  90. package/dist/telemetry/session-metrics.js +5 -0
  91. package/dist/telemetry/telemetry.d.ts +5 -1
  92. package/dist/telemetry/telemetry.js +15 -2
  93. package/dist/telemetry/tool-refused.d.ts +19 -0
  94. package/dist/telemetry/tool-refused.js +55 -0
  95. package/dist/telemetry/verification-of.js +46 -7
  96. package/dist/temp-dir.d.ts +27 -0
  97. package/dist/temp-dir.js +46 -0
  98. package/dist/tools/act-tools.js +45 -1
  99. package/dist/tools/assert-grade.d.ts +1 -1
  100. package/dist/tools/assert-grade.js +27 -5
  101. package/dist/tools/assert-verdict.js +18 -1
  102. package/dist/tools/contract-tools.js +4 -0
  103. package/dist/tools/dynamic-tools.js +1 -1
  104. package/dist/tools/error-recovery.d.ts +10 -0
  105. package/dist/tools/error-recovery.js +64 -4
  106. package/dist/tools/feedback-invite.js +1 -1
  107. package/dist/tools/invoke-tool.js +139 -23
  108. package/dist/tools/lease-tools.d.ts +29 -1
  109. package/dist/tools/lease-tools.js +58 -5
  110. package/dist/tools/navigate-result.js +1 -1
  111. package/dist/tools/observe-tools.js +1 -1
  112. package/dist/tools/observed-nothing.js +1 -1
  113. package/dist/tools/react-grace.d.ts +48 -0
  114. package/dist/tools/react-grace.js +87 -0
  115. package/dist/tools/read-tools.js +20 -4
  116. package/dist/tools/settle-in-flight.d.ts +79 -0
  117. package/dist/tools/settle-in-flight.js +106 -0
  118. package/dist/tools/snapshot-delta.d.ts +7 -0
  119. package/dist/tools/snapshot-delta.js +130 -6
  120. package/dist/tools/tool-surface.js +19 -0
  121. package/dist/tools/tools.js +16 -4
  122. package/docs/README.md +56 -11
  123. package/docs/actions.mdx +87 -0
  124. package/docs/agent-cheatsheet.md +93 -29
  125. package/docs/architecture.md +46 -35
  126. package/docs/benchmarks.md +76 -72
  127. package/docs/best-practices.mdx +211 -0
  128. package/docs/capabilities.mdx +387 -0
  129. package/docs/cli/affected.mdx +51 -0
  130. package/docs/cli/capsules.mdx +69 -0
  131. package/docs/cli/cloud.mdx +127 -0
  132. package/docs/cli/doctor.mdx +76 -0
  133. package/docs/cli/drive.mdx +55 -0
  134. package/docs/cli/feedback.mdx +67 -0
  135. package/docs/cli/gate.mdx +64 -0
  136. package/docs/cli/help.mdx +92 -0
  137. package/docs/cli/hunt.mdx +57 -0
  138. package/docs/cli/identify.mdx +62 -0
  139. package/docs/cli/init.mdx +94 -0
  140. package/docs/cli/kill.mdx +91 -0
  141. package/docs/cli/license.mdx +48 -0
  142. package/docs/cli/mcp.mdx +61 -0
  143. package/docs/cli/open.mdx +68 -0
  144. package/docs/cli/restart.mdx +60 -0
  145. package/docs/cli/rollback.mdx +35 -0
  146. package/docs/cli/serve.mdx +62 -0
  147. package/docs/cli/status.mdx +64 -0
  148. package/docs/cli/stop.mdx +56 -0
  149. package/docs/cli/telemetry.mdx +57 -0
  150. package/docs/cli/update.mdx +52 -0
  151. package/docs/cli/verify.mdx +57 -0
  152. package/docs/cli/version.mdx +39 -0
  153. package/docs/cli/watch.mdx +55 -0
  154. package/docs/cli.mdx +219 -0
  155. package/docs/debugging.md +13 -9
  156. package/docs/deploy-checks.md +15 -11
  157. package/docs/desktop-apps.md +49 -40
  158. package/docs/desktop.mdx +188 -0
  159. package/docs/docs.json +363 -0
  160. package/docs/enterprise.md +20 -16
  161. package/docs/faq.mdx +88 -0
  162. package/docs/fixtures.md +11 -7
  163. package/docs/flows.md +26 -22
  164. package/docs/for-agents.md +71 -0
  165. package/docs/frameworks.mdx +199 -0
  166. package/docs/gate-plan.md +45 -41
  167. package/docs/gates.md +22 -18
  168. package/docs/getting-started.md +76 -65
  169. package/docs/human-control.md +22 -18
  170. package/docs/index.mdx +101 -0
  171. package/docs/install-agentic.mdx +215 -0
  172. package/docs/install-manual.mdx +194 -0
  173. package/docs/instrumentation.mdx +232 -0
  174. package/docs/integration-patterns.md +38 -34
  175. package/docs/local-registry.md +16 -12
  176. package/docs/multi-agent-testing.md +16 -12
  177. package/docs/packages/babel-plugin.mdx +70 -0
  178. package/docs/packages/browser.mdx +111 -0
  179. package/docs/packages/core.mdx +106 -0
  180. package/docs/packages/electron.mdx +87 -0
  181. package/docs/packages/eslint-plugin.mdx +84 -0
  182. package/docs/packages/next.mdx +91 -0
  183. package/docs/packages/react.mdx +91 -0
  184. package/docs/packages/server.mdx +98 -0
  185. package/docs/packages/tauri.mdx +63 -0
  186. package/docs/packages/test.mdx +108 -0
  187. package/docs/packages/vite-plugin.mdx +96 -0
  188. package/docs/packages.mdx +217 -0
  189. package/docs/platform-integration.md +33 -26
  190. package/docs/predicates.mdx +179 -0
  191. package/docs/quickstart.mdx +211 -0
  192. package/docs/recipes.mdx +242 -0
  193. package/docs/skill-file.mdx +105 -0
  194. package/docs/state-management.mdx +197 -0
  195. package/docs/style.css +14 -0
  196. package/docs/system-map.md +47 -32
  197. package/docs/telemetry-contract.md +93 -50
  198. package/docs/telemetry-events.mdx +430 -0
  199. package/docs/telemetry.md +57 -52
  200. package/docs/testing.md +10 -6
  201. package/docs/token-efficiency.md +30 -26
  202. package/docs/tools-act-and-wait.mdx +123 -0
  203. package/docs/tools-act-sequence.mdx +120 -0
  204. package/docs/tools-act.mdx +82 -0
  205. package/docs/tools-assert.mdx +70 -0
  206. package/docs/tools-console.mdx +59 -0
  207. package/docs/tools-inspect.mdx +85 -0
  208. package/docs/tools-navigate.mdx +63 -0
  209. package/docs/tools-network.mdx +86 -0
  210. package/docs/tools-observe.mdx +89 -0
  211. package/docs/tools-overview.mdx +157 -0
  212. package/docs/tools-query.mdx +82 -0
  213. package/docs/tools-session-and-feedback.mdx +91 -0
  214. package/docs/tools-sessions.mdx +65 -0
  215. package/docs/tools-snapshot.mdx +75 -0
  216. package/docs/tools-state.mdx +81 -0
  217. package/docs/tools-tools-and-run.mdx +125 -0
  218. package/docs/tools-wait-for.mdx +66 -0
  219. package/docs/troubleshooting.mdx +193 -0
  220. package/docs/usage.md +175 -153
  221. package/docs/vs-chrome-devtools-mcp.mdx +82 -0
  222. package/docs/vs-playwright-mcp.mdx +85 -0
  223. package/docs/vs-screenshots.mdx +96 -0
  224. package/docs/what-is-reticle.mdx +63 -0
  225. package/docs/why-reticle.mdx +107 -0
  226. package/package.json +2 -2
  227. package/docs/matrix/2.5.0/claude-code-machine.json +0 -19
  228. package/docs/matrix/2.5.0/codex-machine.json +0 -20
  229. package/docs/matrix/2.5.0/cursor-machine.json +0 -22
  230. package/docs/matrix/2.5.0/gemini-machine.json +0 -22
  231. package/docs/matrix/2.5.0/opencode-machine.json +0 -22
  232. package/docs/matrix/2.5.0/vscode-machine.json +0 -22
  233. package/docs/matrix/2.5.0/windsurf-machine.json +0 -22
  234. package/docs/matrix/MATRIX.md +0 -26
  235. package/docs/matrix/README.md +0 -59
  236. package/docs/mint.json +0 -61
@@ -0,0 +1,48 @@
1
+ ---
2
+ title: reticle license
3
+ description: Show the enterprise license status resolved from the environment, offline.
4
+ icon: key
5
+ ---
6
+
7
+ `reticle license` reports whether an enterprise license is active. It resolves entirely from the environment. Nothing leaves the machine.
8
+
9
+ ```bash
10
+ npx @reticlehq/server license
11
+ ```
12
+
13
+ No flags.
14
+
15
+ ## What it prints
16
+
17
+ One `reticle_license` line. Real capture on a checkout with no issuer key configured:
18
+
19
+ ```json
20
+ {
21
+ "t": "2026-08-14T19:38:38.331Z",
22
+ "event": "reticle_license",
23
+ "status": "eval",
24
+ "detail": "evaluation mode: enterprise features run free (no issuer key configured)"
25
+ }
26
+ ```
27
+
28
+ | `status` | Meaning |
29
+ | --------- | --------------------------------------------- |
30
+ | `active` | A valid license is present |
31
+ | `eval` | Evaluation mode. Enterprise features run free |
32
+ | `missing` | No license, and the build expects one |
33
+
34
+ `detail` is a sentence explaining the status.
35
+
36
+ ## Exit codes
37
+
38
+ Always `0`.
39
+
40
+ ## Worked example
41
+
42
+ ```bash
43
+ npx @reticlehq/server license | jq -r .status
44
+ ```
45
+
46
+ <Card title="What enterprise covers" icon="building" href="/enterprise">
47
+ The licensed surface, and what stays Apache 2.0.
48
+ </Card>
@@ -0,0 +1,61 @@
1
+ ---
2
+ title: reticle mcp
3
+ description: Run the MCP stdio proxy your agent talks to, starting a daemon if one is not already up.
4
+ icon: plug
5
+ ---
6
+
7
+ `reticle mcp` is the command your agent runs. It is the MCP server the editor launches: a stdio proxy that bridges the client to the daemon's SSE endpoint, starting a daemon first if the port is empty.
8
+
9
+ ```bash
10
+ npx @reticlehq/server mcp [--port N] [--drive <url>] [--headless] [--headed] [--http] [--http-port N] [--http-token T]
11
+ ```
12
+
13
+ This is what `reticle init` registers, so you rarely type it yourself.
14
+
15
+ ## Flags
16
+
17
+ | Flag | Type | Default | What it does |
18
+ | --- | --- | --- | --- |
19
+ | `--port N` | number | `4400` (or `RETICLE_PORT`, or the port in `.reticle.json`) | Bridge port |
20
+ | `--drive <url>` | string | unset | Have the daemon launch its own browser at this URL, so the agent has autonomous control without relying on your tab |
21
+ | `--headless` | boolean | `true` for `mcp` | Hide that browser |
22
+ | `--headed` | boolean | `false` | Show it |
23
+ | `--http` | boolean | `false` | Forward the HTTP verify endpoint flags to the daemon it spawns |
24
+ | `--http-port N` | number | unset | Port for that endpoint |
25
+ | `--http-token T` | string | unset | Bearer token for it |
26
+
27
+ ## The rule this command lives by
28
+
29
+ The proxy **is** the MCP server the editor launched. Nothing respawns it, so an uncaught throw here is what a user experiences as "the MCP server disconnected". Three behaviours follow from that:
30
+
31
+ - Crash handlers write to the proxy's own log file, not just stderr, because the editor swallows stderr.
32
+ - A daemon that is not there is not fatal. The proxy answers `initialize` itself, serves the cached tool catalog, and retries a daemon on every client request. Present and complaining beats absent, because absent needs a human.
33
+ - Reconnect is self-healing: if the daemon exited, crashed, was stopped, or shut itself down as idle, the reconnect path spawns a new one rather than retrying a dead port until the budget runs out.
34
+
35
+ ## What it prints
36
+
37
+ Structured lines to the proxy log (`~/.reticle/`), not to your terminal, since stdout is the MCP transport.
38
+
39
+ | Event | Meaning |
40
+ | --- | --- |
41
+ | `reticle_mcp_daemon_started` | It spawned a daemon |
42
+ | `reticle_mcp_daemon_unavailable` | It could not, and is serving anyway |
43
+ | `reticle_mcp_proxy_first_connect_failed` | The first connect was refused. Expected when the daemon is still coming up |
44
+
45
+ ## Exit codes
46
+
47
+ Runs for the life of the editor session.
48
+
49
+ ## Worked example
50
+
51
+ ```json
52
+ {
53
+ "mcpServers": {
54
+ "reticle": { "command": "npx", "args": ["@reticlehq/server", "mcp"] }
55
+ }
56
+ }
57
+ ```
58
+
59
+ <Card title="The tools this exposes" icon="screwdriver-wrench" href="/tools-overview">
60
+ The full surface your agent gets once this is registered.
61
+ </Card>
@@ -0,0 +1,68 @@
1
+ ---
2
+ title: reticle open
3
+ description: Show the app in a browser, reusing the already-connected tab when there is one.
4
+ icon: window-maximize
5
+ ---
6
+
7
+ `reticle open` is the one-command "show me the app". It resolves the port, makes sure a daemon is up, and then either reuses the tab that is already connected or opens a new one.
8
+
9
+ ```bash
10
+ npx @reticlehq/server open [url] [--port N]
11
+ ```
12
+
13
+ ## Arguments and flags
14
+
15
+ | Argument | Type | Default | What it does |
16
+ | --- | --- | --- | --- |
17
+ | `url` | string, positional, optional | unset | The URL to open. Omit it to reuse a connected tab |
18
+ | `--port N` | number | `4400` (or `RETICLE_PORT`, or the port in `.reticle.json`) | Bridge port. If nothing is on it, `open` discovers a running daemon rather than making you hunt |
19
+
20
+ It is idempotent. Re-running never piles up duplicate tabs.
21
+
22
+ ## What it prints
23
+
24
+ One `reticle_open` line, whose fields say which of four things happened.
25
+
26
+ | Fields | Meaning |
27
+ | --- | --- |
28
+ | `reusing` | A connected tab was already on the right page. Nothing was opened |
29
+ | `reusing` + `requested` + `note` | A tab is connected on that origin but sitting on a different page. It was **left there**, not navigated. Drive it with `reticle_navigate` or open the URL yourself |
30
+ | `opened` + `connected: true` | A browser was launched and a Reticle session appeared |
31
+ | `opened` + `connected: false` + `note` | The URL went to the system default browser and no session showed up within 8 seconds. Almost always means the app carries no SDK, or dials a different port |
32
+ | `error` | No app connected and no URL given, or the browser could not be launched |
33
+
34
+ <Note>
35
+ `connected` is measured, not assumed. This command polls for a **new** session rather than printing
36
+ `{"opened": url}` unconditionally, so a run where nothing opened no longer looks like one where it did.
37
+ When the launcher itself cannot run, there is no `opened` field at all. Real capture:
38
+
39
+ ```
40
+ {"event":"reticle_open","port":4499,"error":"could not launch a browser: spawn open ENOENT","recovery":"Nothing was opened. This command asks the OS to open a url in your default browser (`open` on this platform) and that failed, so the fix is on the OS side: open the url yourself, or set a default browser."}
41
+ ```
42
+
43
+ </Note>
44
+
45
+ <Warning>
46
+ This command does **not** use Reticle's own Chromium. It hands the URL to your system default
47
+ browser, so a `chromium` warning from `reticle doctor` has nothing to do with an `open` that came
48
+ back `connected: false`. That misread cost a reporter an afternoon in their bridge config.
49
+ </Warning>
50
+
51
+ <Warning>
52
+ For an Electron or Tauri app there is no URL to open. Start the app the way you normally would; it
53
+ dials the bridge itself.
54
+ </Warning>
55
+
56
+ ## Exit codes
57
+
58
+ | Code | Meaning |
59
+ | ---- | ------------------------------------------------------------------- |
60
+ | `0` | Reused, opened, or reported that no app is connected |
61
+ | `1` | A browser could not be launched, or the daemon could not be reached |
62
+
63
+ ## Worked example
64
+
65
+ ```bash
66
+ npx @reticlehq/server open http://localhost:5173
67
+ npx @reticlehq/server status # confirm the session is really there
68
+ ```
@@ -0,0 +1,60 @@
1
+ ---
2
+ title: reticle restart
3
+ description: Free the bridge port and put a daemon back on it, reporting each half separately.
4
+ icon: rotate
5
+ ---
6
+
7
+ `reticle restart` is [`reticle kill`](/cli/kill) followed by a daemon start that waits for a real bind.
8
+
9
+ ```bash
10
+ npx @reticlehq/server restart [--port N] [--force]
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 port to restart on |
18
+ | `--force` | boolean | `false` | Passed to the kill half: clear a listener that is not a Reticle daemon |
19
+
20
+ ## The two halves are reported separately
21
+
22
+ A restart that killed the old daemon and then could not start a new one leaves you somewhere quite different from one that could not kill anything at all, and a single `ok: false` cannot tell you which happened. So each half prints its own line.
23
+
24
+ Real capture, restarting over a running daemon:
25
+
26
+ ```
27
+ {"event":"reticle_killed","port":4499,"pid":84513,"escalated":false,"listenerIdentified":true,"note":"only the listener was signalled. Any `reticle mcp` proxy on this port holds a client connection, not the port, and was left alone — it goes dormant and starts a fresh daemon on the next tool call."}
28
+ {"event":"reticle_daemon_spawned","port":4499}
29
+ ```
30
+
31
+ Real capture, when the port is held by something that is not ours:
32
+
33
+ ```
34
+ {"event":"reticle_kill_refused","port":4498,"reason":"pid 84537 (\"Python\") is listening, and it is not a Reticle daemon — it never answered /status and it is not the pid Reticle recorded. Killing it would be killing someone else's process. Run it again with --force if that is what you meant, or start Reticle on another port.","holder":"Python"}
35
+ {"event":"reticle_restart_aborted","port":4498,"reason":"the port was not freed, so nothing was started — the old holder is still there"}
36
+ ```
37
+
38
+ <Note>
39
+ The start half is `serve`'s, which waits for the daemon to **answer** before claiming it started
40
+ and exits non-zero when it does not. A restart never reports success for a daemon that never
41
+ bound.
42
+ </Note>
43
+
44
+ ## Exit codes
45
+
46
+ | Code | Meaning |
47
+ | ---- | --------------------------------------------------------- |
48
+ | `0` | The port was freed and a daemon is answering on it |
49
+ | `1` | The port was not freed, or the new daemon did not come up |
50
+
51
+ ## Worked example
52
+
53
+ ```bash
54
+ npx @reticlehq/server restart # after an upgrade, so the new version is the one serving
55
+ npx @reticlehq/server status
56
+ ```
57
+
58
+ <Card title="Why not lsof" icon="skull" href="/cli/kill">
59
+ The pipeline everyone reaches for kills the agent's own MCP proxy along with the daemon.
60
+ </Card>
@@ -0,0 +1,35 @@
1
+ ---
2
+ title: reticle rollback
3
+ description: Restore the previously installed Reticle server version and restart.
4
+ icon: arrow-rotate-left
5
+ ---
6
+
7
+ `reticle rollback` is the undo for [`reticle update`](/cli/update). It restores the previous server version and restarts.
8
+
9
+ ```bash
10
+ npx @reticlehq/server rollback
11
+ ```
12
+
13
+ No flags.
14
+
15
+ ## What it prints
16
+
17
+ Nothing on the happy path: `rollback()` replaces the process. A failure logs `reticle_rollback_failed` with the error message.
18
+
19
+ Telemetry records the move as a `version_changed` event with `direction: "rollback"`, which is treated as a release-quality alarm rather than a routine version move.
20
+
21
+ ## Exit codes
22
+
23
+ | Code | Meaning |
24
+ | ---- | ----------------------------------------------------------- |
25
+ | `0` | The previous version was restored (the process is replaced) |
26
+ | `1` | There was nothing to roll back to, or the restore threw |
27
+
28
+ ## Worked example
29
+
30
+ ```bash
31
+ npx @reticlehq/server update
32
+ # the new build misbehaves:
33
+ npx @reticlehq/server rollback
34
+ npx @reticlehq/server version
35
+ ```
@@ -0,0 +1,62 @@
1
+ ---
2
+ title: reticle serve
3
+ description: Start the Reticle daemon on the bridge port and wait until it has actually bound.
4
+ icon: play
5
+ ---
6
+
7
+ `reticle serve` starts the daemon: the WebSocket bridge your app dials into, plus the tool engine behind it. It spawns a detached child and then waits for that child to answer `/status` before reporting success.
8
+
9
+ ```bash
10
+ npx @reticlehq/server serve [--port N] [--drive <url>] [--headless] [--headed] [--http] [--http-port N] [--http-token T]
11
+ ```
12
+
13
+ Most people never type this. Your agent runs [`reticle mcp`](/cli/mcp), which starts a daemon itself if one is not already up.
14
+
15
+ ## Flags
16
+
17
+ | Flag | Type | Default | What it does |
18
+ | --- | --- | --- | --- |
19
+ | `--port N` | number | `4400` (or `RETICLE_PORT`, or the port in `.reticle.json`) | Bridge port to bind |
20
+ | `--drive <url>` | string | unset | Launch Reticle's own browser at this URL instead of waiting for your tab |
21
+ | `--headless` | boolean | `true` for `serve` | Hide the browser |
22
+ | `--headed` | boolean | `false` | Show it. `serve` owns the pooled browser behind leases, which is batch work, so it hides by default |
23
+ | `--http` | boolean | `false` | Also expose the HTTP verify endpoint |
24
+ | `--http-port N` | number | unset | Port for that endpoint |
25
+ | `--http-token T` | string | unset | Bearer token the endpoint requires |
26
+
27
+ ## What it prints
28
+
29
+ One structured line. When a daemon already owns the port, it says so and does nothing:
30
+
31
+ ```json
32
+ { "t": "2026-08-14T19:39:13.230Z", "event": "reticle_daemon_already_running", "port": 4400 }
33
+ ```
34
+
35
+ A successful spawn logs `reticle_daemon_spawned` with the port. A port held by something that is not a Reticle daemon is refused up front rather than spawned into:
36
+
37
+ ```
38
+ reticle_daemon_start_refused
39
+ ```
40
+
41
+ ## Exit codes
42
+
43
+ | Code | Meaning |
44
+ | ---- | --------------------------------------------------------------------------------- |
45
+ | `0` | A daemon is up on the port, whether this run started it or found it |
46
+ | `1` | The port is held by a foreign process, or the child never bound within 15 seconds |
47
+
48
+ <Note>
49
+ `serve` reports the **bind**, not the spawn. It used to exit `0` the moment it forked, while the
50
+ child died on an `EADDRINUSE` nobody joined back up. It now waits for the daemon to answer.
51
+ </Note>
52
+
53
+ ## Worked example
54
+
55
+ ```bash
56
+ npx @reticlehq/server serve --port 4400
57
+ npx @reticlehq/server status
58
+ ```
59
+
60
+ <Card title="What the daemon is" icon="sitemap" href="/architecture">
61
+ The bridge, the tool engine, and where `.reticle/` lives.
62
+ </Card>
@@ -0,0 +1,64 @@
1
+ ---
2
+ title: reticle status
3
+ description: Ask whether the Reticle daemon is up and which app sessions have connected to it.
4
+ icon: heart-pulse
5
+ ---
6
+
7
+ `reticle status` is the command that tells you whether the install actually finished. Not a tick in a checklist: a connected app.
8
+
9
+ ```bash
10
+ npx @reticlehq/server status [--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 daemon to ask |
18
+
19
+ ## What it prints
20
+
21
+ One JSON line on stdout. Real capture, daemon up and no app connected:
22
+
23
+ ```json
24
+ {
25
+ "t": "2026-08-14T19:38:37.737Z",
26
+ "event": "reticle_status",
27
+ "port": 4400,
28
+ "running": true,
29
+ "pid": 4795,
30
+ "sessionCount": 0,
31
+ "sessions": [],
32
+ "why": "no browser session connected. Two things to weigh, and neither of them is proof. (1) Nothing is listening on the ports Reticle scans ... (2) There is no `.reticle.json` in the directory this daemon is running in ..."
33
+ }
34
+ ```
35
+
36
+ | Field | Meaning |
37
+ | --- | --- |
38
+ | `running` | Whether a usable daemon owns the port |
39
+ | `presence` | Present when the pid file is dead: `daemon`, `foreign`, or `absent`. The port is asked, not just the pid file |
40
+ | `pid` | The daemon process |
41
+ | `sessionCount` / `sessions` | Connected app sessions, each with `sessionId`, `url`, `throttled`, `stale` |
42
+ | `why` | Present when zero sessions connected. Names the two likely causes and refuses to assert either |
43
+ | `updateAvailable` | Present when a newer server version is on the registry |
44
+
45
+ <Note>
46
+ `status` asks the **port**, not only the pid file. `running: false` used to be printed about a
47
+ port that was demonstrably occupied, which sent the reader off to start a daemon that could never
48
+ bind.
49
+ </Note>
50
+
51
+ ## Exit codes
52
+
53
+ Always `0`. This command answers a question; it does not judge the answer.
54
+
55
+ ## Worked example
56
+
57
+ ```bash
58
+ npx @reticlehq/server init
59
+ npx @reticlehq/server status # a session in the list means the app is genuinely wired
60
+ ```
61
+
62
+ <Card title="Nothing connected?" icon="triangle-exclamation" href="/troubleshooting">
63
+ The bridge port is not your dev server port, and that is the most common cause.
64
+ </Card>
@@ -0,0 +1,56 @@
1
+ ---
2
+ title: reticle stop
3
+ description: Stop the Reticle daemon on a port, escalating from SIGTERM to SIGKILL if it will not go.
4
+ icon: circle-stop
5
+ ---
6
+
7
+ `reticle stop` reads the pid recorded for the port and stops that process.
8
+
9
+ ```bash
10
+ npx @reticlehq/server stop [--port N] [--quiet]
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 daemon to stop |
18
+ | `--quiet` | boolean | `false` | Print nothing. For scripts that stop a daemon that may not be running |
19
+
20
+ ## How it stops
21
+
22
+ 1. `SIGTERM` first, then poll every 100ms.
23
+ 2. Still alive after 5 seconds: `SIGKILL`. A daemon that ignores `SIGTERM` is wedged, which is the one situation this command exists for, and giving up there left the port held and a human reaching for `kill -9`.
24
+ 3. Still alive 2 seconds after that: report `reticle_daemon_stop_timeout` with the pid and exit `1`. Surviving `SIGKILL` means the pid is not yours to kill, or it is an unkillable zombie. Neither is retryable.
25
+
26
+ ## What it prints
27
+
28
+ | Event | When |
29
+ | --- | --- |
30
+ | `reticle_daemon_stopped` | It stopped. Carries `port`, `pid`, and `escalated: true` if it took a `SIGKILL` |
31
+ | `reticle_daemon_not_running` | No live pid for that port. The stale pid file is removed |
32
+ | `reticle_daemon_stop_timeout` | It survived everything. Exits `1` |
33
+
34
+ ## Exit codes
35
+
36
+ | Code | Meaning |
37
+ | ---- | ------------------------------ |
38
+ | `0` | Stopped, or was not running |
39
+ | `1` | The process survived `SIGKILL` |
40
+
41
+ <Warning>
42
+ Do not stop a daemon with `lsof -ti tcp:4400 | xargs kill -9`. That pattern matches the agent's
43
+ own `reticle mcp` proxy as well as the daemon and takes both down. Use this command, or [`reticle
44
+ kill`](/cli/kill).
45
+ </Warning>
46
+
47
+ ## When this is not enough
48
+
49
+ `stop` needs the pid Reticle recorded. If the pid file is stale, was never written, or the port is held by a daemon from another checkout, `stop` reports `reticle_daemon_not_running` about a port that is demonstrably occupied. [`reticle kill`](/cli/kill) asks the **port** instead and is the command for that case.
50
+
51
+ ## Worked example
52
+
53
+ ```bash
54
+ npx @reticlehq/server stop --port 4400 --quiet && npx @reticlehq/server serve --port 4400
55
+ npx @reticlehq/server restart --port 4400 # the same thing, honest about each half
56
+ ```
@@ -0,0 +1,57 @@
1
+ ---
2
+ title: reticle telemetry
3
+ description: Show, enable, or disable Reticle's anonymous usage metrics on this machine.
4
+ icon: chart-line
5
+ ---
6
+
7
+ `reticle telemetry` is the user-facing control for anonymous usage metrics.
8
+
9
+ ```bash
10
+ npx @reticlehq/server telemetry [status|enable|disable]
11
+ ```
12
+
13
+ ## Sub-actions
14
+
15
+ | Action | Default | What it does |
16
+ | --- | --- | --- |
17
+ | `status` | yes, when nothing is given | Report the current state, why it is that state, and where the policy lives |
18
+ | `enable` | | Turn metrics on for this machine |
19
+ | `disable` | | Persist a machine-wide opt-out. Unlike `RETICLE_TELEMETRY=0`, this survives shells |
20
+
21
+ Any other word is a usage error: `unknown telemetry action: <word>`, exit `1`.
22
+
23
+ ## What it prints
24
+
25
+ Human-readable lines on stdout, like [`doctor`](/cli/doctor). Real capture inside a Reticle source checkout:
26
+
27
+ ```
28
+ telemetry disabled (this is a Reticle source checkout; developing it is not using it)
29
+ policy https://github.com/reticlehq/reticle/blob/main/docs/telemetry.md
30
+ ```
31
+
32
+ When it is enabled, a third line names every way to turn it off:
33
+
34
+ ```
35
+ opt out reticle telemetry disable (or RETICLE_TELEMETRY=0 / DO_NOT_TRACK=1)
36
+ ```
37
+
38
+ ## Exit codes
39
+
40
+ | Code | Meaning |
41
+ | ---- | ------------------------------------ |
42
+ | `0` | Status shown, or the setting changed |
43
+ | `1` | Unknown sub-action |
44
+
45
+ ## Worked example
46
+
47
+ ```bash
48
+ npx @reticlehq/server telemetry status
49
+ npx @reticlehq/server telemetry disable
50
+ ```
51
+
52
+ <Card title="Exactly what is collected" icon="shield-check" href="/telemetry">
53
+ The complete list, in plain language, and every way to switch it off.
54
+ </Card>
55
+ <Card title="Every event, in schema detail" icon="database" href="/telemetry-events">
56
+ The contributor reference: payload blocks, field types, and what each event exists to answer.
57
+ </Card>
@@ -0,0 +1,52 @@
1
+ ---
2
+ title: reticle update
3
+ description: Install the latest Reticle server version, sync the project SDK to match, and restart.
4
+ icon: arrow-up
5
+ ---
6
+
7
+ `reticle update` moves the installed server forward and brings the app's SDK with it.
8
+
9
+ ```bash
10
+ npx @reticlehq/server update
11
+ ```
12
+
13
+ No flags.
14
+
15
+ ## What it does, in order
16
+
17
+ 1. Ask the registry what is available.
18
+ 2. Compare by **direction**, not inequality. A registry version that merely differs is not a newer one, and the old check happily installed a downgrade.
19
+ 3. Nothing newer: log `reticle_update` with `ok: false` and `message: "already on the latest version"`, then stop.
20
+ 4. Otherwise sync the **app's SDK first**. `reticle update` used to swap only the CLI, so the command whose job is keeping an install current was itself a way to produce a version-skewed pair.
21
+ 5. Then apply the CLI update, which execs and exits. Your agent client restarts it.
22
+
23
+ ## What it prints
24
+
25
+ | Event | Fields |
26
+ | --- | --- |
27
+ | `reticle_update` | `ok`, and either `from` and `to`, or `message` and `version` |
28
+ | `reticle_update_sdk` | `synced`, `packages`, `to`, `packageManager`. Or `synced: false` with `reason: "no @reticlehq packages in this project"` |
29
+ | `reticle_update_sdk_failed` | A `hint` naming the exact command to run by hand |
30
+ | `reticle_update_failed` | The error |
31
+
32
+ The SDK sync is best effort and non-fatal on purpose. This command gets run from wherever the human happens to be standing, which is often not an app at all.
33
+
34
+ ## Exit codes
35
+
36
+ | Code | Meaning |
37
+ | ---- | -------------------------------------------------------------------- |
38
+ | `0` | Already current, or the update was applied (the process is replaced) |
39
+ | `1` | The update check or install threw |
40
+
41
+ ## Worked example
42
+
43
+ ```bash
44
+ npx @reticlehq/server version # 2.8.0
45
+ npx @reticlehq/server update
46
+ ```
47
+
48
+ <Warning>
49
+ Attaching to a running daemon is what a daemon is for, which means an upgrade does not take effect
50
+ until that daemon dies. Run [`reticle stop`](/cli/stop) afterwards if you need the new build
51
+ serving immediately.
52
+ </Warning>
@@ -0,0 +1,57 @@
1
+ ---
2
+ title: reticle verify
3
+ description: Drive a URL once, replay every saved flow, and exit zero only on a real pass.
4
+ icon: circle-check
5
+ ---
6
+
7
+ `reticle verify` is the CI command: no model in the loop, no MCP. It boots the engine in drive mode, waits for the in-page SDK to dial back, replays every saved flow, renders the verdict, and exits.
8
+
9
+ ```bash
10
+ npx @reticlehq/server verify <url> [--headed] [--timeout N] [--storage-state <file>]
11
+ ```
12
+
13
+ It uses the same runner and the same verdict as the MCP and HTTP paths, so a platform agent that can only run a shell command gets a byte-identical artifact.
14
+
15
+ ## Arguments and flags
16
+
17
+ | Argument | Type | Default | What it does |
18
+ | --- | --- | --- | --- |
19
+ | `url` | string, positional, **required** | none | The preview URL to drive |
20
+ | `--headed` | boolean | `false` (headless) | Show the browser |
21
+ | `--timeout N` | number, ms | `15000` | How long to wait for a browser session to dial back |
22
+ | `--storage-state <file>` | string | unset | A Playwright storage state file. This is how you verify flows behind a login without scripting the login every time |
23
+
24
+ ## What it prints
25
+
26
+ The rendered run report on stdout. On failure it names the cause on stderr instead, and there are two refusals worth knowing:
27
+
28
+ ```
29
+ No app connected: Reticle drove the URL but no @reticlehq/browser session dialed back.
30
+ Make sure the SDK is in the build and reticle.connect() runs on the preview page
31
+ ```
32
+
33
+ ```
34
+ No saved flows to verify (.reticle/flows is empty), so refusing to report a pass for verifying nothing.
35
+ ```
36
+
37
+ <Warning>
38
+ Both of those are honesty guards, and both exit `1`. Verifying nothing is never a pass.
39
+ </Warning>
40
+
41
+ ## Exit codes
42
+
43
+ | Code | Meaning |
44
+ | ---- | ----------------------------------------------------------------- |
45
+ | `0` | The verdict was a pass |
46
+ | `1` | Failed, or no session, or no flows, or the engine could not start |
47
+
48
+ ## Worked example
49
+
50
+ ```bash
51
+ npm run build && npm run preview &
52
+ npx @reticlehq/server verify http://localhost:4173 --timeout 60000
53
+ ```
54
+
55
+ <Card title="Recording the flows this replays" icon="vial" href="/testing">
56
+ Flows are recorded interactively, then committed to `.reticle/flows/`.
57
+ </Card>
@@ -0,0 +1,39 @@
1
+ ---
2
+ title: reticle version
3
+ description: Print the version of the Reticle server that is actually executing.
4
+ icon: tag
5
+ ---
6
+
7
+ `reticle version` prints the running package version. It is the diagnostic to reach for when you need to know which build `npx` actually resolved, which is not always the one you expected.
8
+
9
+ ```bash
10
+ npx @reticlehq/server version
11
+ npx @reticlehq/server --version
12
+ npx @reticlehq/server -v
13
+ ```
14
+
15
+ All three are the same command. No flags.
16
+
17
+ ## What it prints
18
+
19
+ One `reticle_version` line. Real capture:
20
+
21
+ ```json
22
+ { "t": "2026-08-14T19:38:37.595Z", "event": "reticle_version", "version": "2.8.0" }
23
+ ```
24
+
25
+ ## Exit codes
26
+
27
+ Always `0`.
28
+
29
+ ## Worked example
30
+
31
+ ```bash
32
+ npx @reticlehq/server version | jq -r .version
33
+ ```
34
+
35
+ <Note>
36
+ The version here is the CLI's. A daemon that was already running keeps serving its own build until
37
+ it exits, so [`reticle doctor`](/cli/doctor) is the command that compares the two and names a
38
+ skew.
39
+ </Note>