@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.
- package/README.md +14 -5
- package/SKILL.md +130 -778
- package/dist/bridge/bridge.d.ts +23 -0
- package/dist/bridge/bridge.js +80 -2
- package/dist/bridge/bridge.test-harness.d.ts +5 -0
- package/dist/bridge/bridge.test-harness.js +6 -4
- package/dist/capsule/causal-summary.d.ts +36 -1
- package/dist/capsule/causal-summary.js +33 -7
- package/dist/capsule/divergence.js +7 -1
- package/dist/cli/chromium-hint.d.ts +33 -5
- package/dist/cli/chromium-hint.js +82 -12
- package/dist/cli/cli-doctor.js +65 -34
- package/dist/cli/cli-flow-commands.js +8 -8
- package/dist/cli/cli-kill.d.ts +58 -0
- package/dist/cli/cli-kill.js +162 -0
- package/dist/cli/cli-parse.d.ts +16 -1
- package/dist/cli/cli-parse.js +32 -9
- package/dist/cli/cli-port.d.ts +32 -0
- package/dist/cli/cli-port.js +82 -35
- package/dist/cli/cli-verify.d.ts +21 -0
- package/dist/cli/cli-verify.js +47 -3
- package/dist/cli/config-discovery.d.ts +35 -0
- package/dist/cli/config-discovery.js +163 -0
- package/dist/cli/doctor-daemon-line.js +4 -1
- package/dist/cli/doctor-project-line.d.ts +37 -0
- package/dist/cli/doctor-project-line.js +35 -0
- package/dist/cli/doctor-rows.d.ts +51 -0
- package/dist/cli/doctor-rows.js +54 -0
- package/dist/cli/doctor-sessions-line.d.ts +12 -0
- package/dist/cli/doctor-sessions-line.js +69 -0
- package/dist/cli/drive-attach.d.ts +99 -0
- package/dist/cli/drive-attach.js +203 -0
- package/dist/cli/drive-command.d.ts +13 -0
- package/dist/cli/drive-command.js +103 -0
- package/dist/cli/open-note.d.ts +20 -0
- package/dist/cli/open-note.js +37 -0
- package/dist/cli/port-holder.d.ts +10 -0
- package/dist/cli/port-holder.js +26 -2
- package/dist/cli/status-next-action.d.ts +37 -0
- package/dist/cli/status-next-action.js +61 -0
- package/dist/cli.js +119 -39
- package/dist/crawl/crawl-tools.js +12 -2
- package/dist/crawl/crawl.d.ts +13 -0
- package/dist/crawl/crawl.js +50 -2
- package/dist/events/contradictions.d.ts +46 -0
- package/dist/events/contradictions.js +35 -22
- package/dist/events/declared.d.ts +45 -0
- package/dist/events/declared.js +73 -0
- package/dist/events/echo-mismatch.d.ts +8 -2
- package/dist/events/echo-mismatch.js +33 -5
- package/dist/events/event-filters.d.ts +1 -1
- package/dist/events/event-filters.js +7 -4
- package/dist/events/predicate-eval.d.ts +17 -72
- package/dist/events/predicate-eval.js +117 -236
- package/dist/events/predicate-parse.js +31 -3
- package/dist/events/predicate-route.d.ts +32 -0
- package/dist/events/predicate-route.js +102 -0
- package/dist/events/predicate-schema.d.ts +99 -0
- package/dist/events/predicate-schema.js +309 -0
- package/dist/events/predicate.d.ts +8 -0
- package/dist/events/predicate.js +296 -22
- package/dist/flows/annotate-tools.js +3 -0
- package/dist/flows/annotate.js +18 -4
- package/dist/flows/coverage.d.ts +38 -5
- package/dist/flows/coverage.js +30 -4
- package/dist/flows/decision.d.ts +15 -0
- package/dist/flows/decision.js +1 -1
- package/dist/flows/flow-classify.js +1 -1
- package/dist/flows/flow-replay-run.js +8 -1
- package/dist/flows/flow-tools.js +21 -5
- package/dist/flows/heal-run.js +1 -1
- package/dist/flows/replay.js +3 -0
- package/dist/honesty/accepted-write.d.ts +3 -0
- package/dist/honesty/accepted-write.js +8 -3
- package/dist/honesty/already-true.js +15 -0
- package/dist/honesty/blind-spots.js +10 -2
- package/dist/honesty/honesty.d.ts +11 -0
- package/dist/honesty/honesty.js +1 -0
- package/dist/honesty/uncaptured-bodies.d.ts +4 -2
- package/dist/honesty/uncaptured-bodies.js +9 -2
- package/dist/honesty/unread-outcome.d.ts +8 -0
- package/dist/honesty/unread-outcome.js +36 -9
- package/dist/honesty/unsettled.d.ts +49 -0
- package/dist/honesty/unsettled.js +82 -0
- package/dist/honesty/verified.d.ts +36 -3
- package/dist/honesty/verified.js +54 -11
- package/dist/http-server.d.ts +19 -0
- package/dist/http-server.js +202 -4
- package/dist/impact/impact-recorder.d.ts +23 -0
- package/dist/impact/impact-recorder.js +76 -0
- package/dist/impact/impact-store.d.ts +47 -0
- package/dist/impact/impact-store.js +171 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +47 -10
- package/dist/init/agent-rules.d.ts +36 -0
- package/dist/init/agent-rules.js +132 -22
- package/dist/init/astro-patch.d.ts +2 -1
- package/dist/init/astro-patch.js +38 -6
- package/dist/init/capabilities.d.ts +22 -0
- package/dist/init/capabilities.js +76 -0
- package/dist/init/confirm.d.ts +114 -0
- package/dist/init/confirm.js +165 -0
- package/dist/init/connect-steps.d.ts +2 -0
- package/dist/init/connect-steps.js +50 -0
- package/dist/init/cra.js +3 -2
- package/dist/init/csp-check.d.ts +38 -0
- package/dist/init/csp-check.js +92 -0
- package/dist/init/csp-doctor.d.ts +25 -0
- package/dist/init/csp-doctor.js +49 -0
- package/dist/init/cursor.js +6 -9
- package/dist/init/detect.d.ts +8 -0
- package/dist/init/detect.js +33 -3
- package/dist/init/mcp-clients.d.ts +1 -0
- package/dist/init/mcp-clients.js +51 -7
- package/dist/init/mcp.d.ts +15 -0
- package/dist/init/mcp.js +19 -0
- package/dist/init/non-js-project.js +29 -5
- package/dist/init/plan-framework.d.ts +10 -0
- package/dist/init/plan-framework.js +78 -16
- package/dist/init/plan.d.ts +47 -6
- package/dist/init/plan.js +228 -69
- package/dist/init/run.d.ts +24 -2
- package/dist/init/run.js +157 -45
- package/dist/init/slash-command.d.ts +1 -1
- package/dist/init/slash-command.js +54 -6
- package/dist/init/snippets.d.ts +45 -5
- package/dist/init/snippets.js +194 -42
- package/dist/init/vite-config.js +53 -5
- package/dist/input/network-mock-tools.d.ts +19 -0
- package/dist/input/network-mock-tools.js +37 -5
- package/dist/input/scroll-find.d.ts +6 -0
- package/dist/input/scroll-find.js +17 -2
- package/dist/input/scroll-tools.js +4 -0
- package/dist/journal/attach-journal.d.ts +9 -1
- package/dist/journal/attach-journal.js +13 -2
- package/dist/journal/journal-query.d.ts +13 -0
- package/dist/journal/journal-query.js +28 -3
- package/dist/journal/workspace-gitignore.d.ts +10 -0
- package/dist/journal/workspace-gitignore.js +59 -0
- package/dist/license/license.js +1 -1
- package/dist/mcp/mcp-proxy.d.ts +35 -30
- package/dist/mcp/mcp-proxy.js +306 -104
- package/dist/mcp/mcp.d.ts +10 -1
- package/dist/mcp/mcp.js +70 -34
- package/dist/mcp/proxy-handshake.d.ts +82 -1
- package/dist/mcp/proxy-handshake.js +109 -2
- package/dist/mcp/proxy-lifecycle.d.ts +11 -2
- package/dist/mcp/proxy-lifecycle.js +12 -3
- package/dist/mcp/proxy-log.d.ts +63 -0
- package/dist/mcp/proxy-log.js +132 -0
- package/dist/mcp/server-instructions.d.ts +17 -0
- package/dist/mcp/server-instructions.js +56 -0
- package/dist/mcp/shared-params.d.ts +27 -0
- package/dist/mcp/shared-params.js +36 -0
- package/dist/pool/browser-pool.d.ts +22 -2
- package/dist/pool/browser-pool.js +44 -4
- package/dist/project/learned-routes.d.ts +24 -0
- package/dist/project/learned-routes.js +63 -0
- package/dist/project/project-store.d.ts +6 -0
- package/dist/project/project-store.js +25 -1
- package/dist/project/reticle-dir.d.ts +2 -0
- package/dist/project/reticle-dir.js +1 -0
- package/dist/session/connection-memory.d.ts +59 -0
- package/dist/session/connection-memory.js +108 -0
- package/dist/session/dev-command.d.ts +26 -0
- package/dist/session/dev-command.js +89 -0
- package/dist/session/dev-server-probe.d.ts +68 -0
- package/dist/session/dev-server-probe.js +102 -7
- package/dist/session/last-act.d.ts +26 -0
- package/dist/session/last-act.js +35 -1
- package/dist/session/live-control-tools.js +42 -5
- package/dist/session/no-session-diagnosis.d.ts +67 -2
- package/dist/session/no-session-diagnosis.js +236 -27
- package/dist/session/no-session-next-action.d.ts +46 -0
- package/dist/session/no-session-next-action.js +85 -0
- package/dist/session/no-session-watch.d.ts +40 -1
- package/dist/session/no-session-watch.js +174 -8
- package/dist/session/pending-commands.d.ts +12 -0
- package/dist/session/pending-commands.js +13 -1
- package/dist/session/ref-provenance.d.ts +54 -0
- package/dist/session/ref-provenance.js +61 -0
- package/dist/session/session-lease.js +1 -1
- package/dist/session/session-manager.d.ts +4 -0
- package/dist/session/session-manager.js +35 -5
- package/dist/session/session.d.ts +10 -1
- package/dist/session/session.js +146 -5
- package/dist/telemetry/app-instrumented.d.ts +8 -0
- package/dist/telemetry/app-instrumented.js +10 -0
- package/dist/telemetry/automation-hint.d.ts +17 -0
- package/dist/telemetry/automation-hint.js +71 -0
- package/dist/telemetry/bug-found.d.ts +15 -17
- package/dist/telemetry/bug-found.js +52 -21
- package/dist/telemetry/cli-telemetry.js +7 -1
- package/dist/telemetry/daemon-telemetry.js +24 -0
- package/dist/telemetry/feedback.js +1 -1
- package/dist/telemetry/init-telemetry.js +9 -1
- package/dist/telemetry/install-source.d.ts +56 -0
- package/dist/telemetry/install-source.js +74 -0
- package/dist/telemetry/instrumentation-stall.d.ts +50 -0
- package/dist/telemetry/instrumentation-stall.js +90 -0
- package/dist/telemetry/run-telemetry.js +4 -1
- package/dist/telemetry/session-metrics.d.ts +8 -0
- package/dist/telemetry/session-metrics.js +15 -0
- package/dist/telemetry/telemetry.d.ts +7 -1
- package/dist/telemetry/telemetry.js +26 -2
- package/dist/telemetry/tool-refused.d.ts +19 -0
- package/dist/telemetry/tool-refused.js +55 -0
- package/dist/telemetry/verification-of.js +46 -7
- package/dist/temp-dir.d.ts +27 -0
- package/dist/temp-dir.js +46 -0
- package/dist/tools/act-tools.js +209 -28
- package/dist/tools/assert-grade.d.ts +1 -1
- package/dist/tools/assert-grade.js +27 -5
- package/dist/tools/assert-verdict.js +49 -7
- package/dist/tools/browser-tools.js +10 -0
- package/dist/tools/contract-tools.js +4 -0
- package/dist/tools/dynamic-tools.js +16 -7
- package/dist/tools/error-recovery.d.ts +10 -0
- package/dist/tools/error-recovery.js +73 -9
- package/dist/tools/feedback-invite.js +1 -1
- package/dist/tools/invoke-tool.js +159 -26
- package/dist/tools/lease-hint.d.ts +30 -8
- package/dist/tools/lease-hint.js +65 -14
- package/dist/tools/lease-tools.d.ts +40 -1
- package/dist/tools/lease-tools.js +181 -83
- package/dist/tools/navigate-result.js +1 -1
- package/dist/tools/observe-tools.js +10 -4
- package/dist/tools/observed-nothing.js +1 -1
- package/dist/tools/react-grace.d.ts +52 -0
- package/dist/tools/react-grace.js +90 -0
- package/dist/tools/read-tools.js +67 -5
- package/dist/tools/resolve-target.d.ts +33 -0
- package/dist/tools/resolve-target.js +53 -0
- package/dist/tools/settle-in-flight.d.ts +94 -0
- package/dist/tools/settle-in-flight.js +146 -0
- package/dist/tools/snapshot-delta.d.ts +10 -0
- package/dist/tools/snapshot-delta.js +194 -9
- package/dist/tools/tool-kit.d.ts +8 -0
- package/dist/tools/tool-surface.d.ts +60 -0
- package/dist/tools/tool-surface.js +86 -1
- package/dist/tools/tools.js +61 -8
- package/dist/tools/unadvertised-help.js +9 -6
- package/docs/README.md +55 -11
- package/docs/actions.mdx +120 -0
- package/docs/agent-cheatsheet.md +95 -29
- package/docs/architecture.md +52 -35
- package/docs/benchmarks.md +127 -75
- package/docs/best-practices.mdx +216 -0
- package/docs/capabilities.mdx +534 -0
- package/docs/cli/affected.mdx +53 -0
- package/docs/cli/capsules.mdx +70 -0
- package/docs/cli/cloud.mdx +153 -0
- package/docs/cli/doctor.mdx +109 -0
- package/docs/cli/drive.mdx +74 -0
- package/docs/cli/feedback.mdx +67 -0
- package/docs/cli/gate.mdx +64 -0
- package/docs/cli/help.mdx +94 -0
- package/docs/cli/hunt.mdx +73 -0
- package/docs/cli/identify.mdx +76 -0
- package/docs/cli/init.mdx +121 -0
- package/docs/cli/kill.mdx +91 -0
- package/docs/cli/license.mdx +48 -0
- package/docs/cli/mcp.mdx +61 -0
- package/docs/cli/open.mdx +74 -0
- package/docs/cli/restart.mdx +60 -0
- package/docs/cli/rollback.mdx +35 -0
- package/docs/cli/serve.mdx +69 -0
- package/docs/cli/status.mdx +88 -0
- package/docs/cli/stop.mdx +64 -0
- package/docs/cli/telemetry.mdx +57 -0
- package/docs/cli/update.mdx +52 -0
- package/docs/cli/verify.mdx +76 -0
- package/docs/cli/version.mdx +39 -0
- package/docs/cli/watch.mdx +62 -0
- package/docs/cli.mdx +241 -0
- package/docs/debugging.md +16 -10
- package/docs/deploy-checks.md +45 -12
- package/docs/desktop.mdx +384 -0
- package/docs/docs.json +364 -0
- package/docs/enterprise.md +22 -16
- package/docs/faq.mdx +102 -0
- package/docs/fixtures.md +13 -7
- package/docs/flows.md +29 -23
- package/docs/for-agents.md +71 -0
- package/docs/frameworks.mdx +238 -0
- package/docs/gate-plan.md +48 -42
- package/docs/gates.md +28 -22
- package/docs/getting-started.md +129 -77
- package/docs/human-control.md +24 -18
- package/docs/index.mdx +143 -0
- package/docs/install-agentic.mdx +224 -0
- package/docs/install-manual.mdx +196 -0
- package/docs/instrumentation.mdx +238 -0
- package/docs/integration-patterns.md +41 -35
- package/docs/local-registry.md +19 -13
- package/docs/multi-agent-testing.md +19 -13
- package/docs/packages/babel-plugin.mdx +79 -0
- package/docs/packages/browser.mdx +111 -0
- package/docs/packages/core.mdx +116 -0
- package/docs/packages/electron.mdx +85 -0
- package/docs/packages/eslint-plugin.mdx +86 -0
- package/docs/packages/next.mdx +89 -0
- package/docs/packages/react.mdx +91 -0
- package/docs/packages/server.mdx +98 -0
- package/docs/packages/tauri.mdx +63 -0
- package/docs/packages/test.mdx +119 -0
- package/docs/packages/vite-plugin.mdx +94 -0
- package/docs/packages.mdx +218 -0
- package/docs/platform-integration.md +35 -26
- package/docs/predicates.mdx +248 -0
- package/docs/quickstart.mdx +257 -0
- package/docs/recipes.mdx +282 -0
- package/docs/skill-file.mdx +107 -0
- package/docs/state-management.mdx +199 -0
- package/docs/style.css +14 -0
- package/docs/system-map.md +50 -33
- package/docs/telemetry-contract.md +106 -52
- package/docs/telemetry-events.mdx +475 -0
- package/docs/telemetry.md +63 -55
- package/docs/testing.md +44 -6
- package/docs/token-efficiency.md +37 -27
- package/docs/tools-act-and-wait.mdx +173 -0
- package/docs/tools-act-sequence.mdx +137 -0
- package/docs/tools-act.mdx +95 -0
- package/docs/tools-assert.mdx +129 -0
- package/docs/tools-console.mdx +63 -0
- package/docs/tools-inspect.mdx +88 -0
- package/docs/tools-navigate.mdx +99 -0
- package/docs/tools-network.mdx +119 -0
- package/docs/tools-observe.mdx +145 -0
- package/docs/tools-overview.mdx +160 -0
- package/docs/tools-query.mdx +126 -0
- package/docs/tools-session-and-feedback.mdx +112 -0
- package/docs/tools-sessions.mdx +94 -0
- package/docs/tools-snapshot.mdx +129 -0
- package/docs/tools-state.mdx +104 -0
- package/docs/tools-tools-and-run.mdx +156 -0
- package/docs/tools-wait-for.mdx +85 -0
- package/docs/troubleshooting.mdx +263 -0
- package/docs/usage.md +209 -165
- package/docs/vs-chrome-devtools-mcp.mdx +123 -0
- package/docs/vs-playwright-mcp.mdx +125 -0
- package/docs/vs-screenshots.mdx +137 -0
- package/docs/what-is-reticle.mdx +63 -0
- package/docs/why-reticle.mdx +109 -0
- package/package.json +5 -5
- package/docs/desktop-apps.md +0 -256
- package/docs/matrix/2.5.0/claude-code-machine.json +0 -19
- package/docs/matrix/2.5.0/codex-machine.json +0 -20
- package/docs/matrix/2.5.0/cursor-machine.json +0 -22
- package/docs/matrix/2.5.0/gemini-machine.json +0 -22
- package/docs/matrix/2.5.0/opencode-machine.json +0 -22
- package/docs/matrix/2.5.0/vscode-machine.json +0 -22
- package/docs/matrix/2.5.0/windsurf-machine.json +0 -22
- package/docs/matrix/MATRIX.md +0 -26
- package/docs/matrix/README.md +0 -59
- package/docs/mint.json +0 -61
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: reticle identify
|
|
3
|
+
description: Opt in to telling the Reticle maintainers who you are, and undo it at any time.
|
|
4
|
+
icon: id-card
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
`reticle identify` attaches a name, a company, an email and a usage context to this machine's Reticle install and sends them to the maintainers, so support or an enterprise trial has someone to talk to. It is off unless you run it, and `reticle identify --forget` undoes it.
|
|
8
|
+
|
|
9
|
+
It is opt-in and deliberately not interactive. A prompt in the middle of someone's work is pressure, and this is the one command where the choice has to be free. You type what you want to share, or you never run it at all.
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npx @reticlehq/server identify --context <company|side_project|open_source|learning> [--company "Acme"] [--email you@acme.com] [--forget]
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Flags
|
|
16
|
+
|
|
17
|
+
| Flag | Type | Default | What it does |
|
|
18
|
+
| --- | --- | --- | --- |
|
|
19
|
+
| `--context K` | one of `company`, `side_project`, `open_source`, `learning` | none. Required unless `--forget` | What Reticle is being used for |
|
|
20
|
+
| `--company N` | string | unset | Your company name. Optional |
|
|
21
|
+
| `--email E` | string | unset | An address to reach you on. Optional |
|
|
22
|
+
| `--forget` | boolean | `false` | Delete the local identity file and stop sending it |
|
|
23
|
+
|
|
24
|
+
Every field except the context is optional, so you can say "this is a company" without saying which, or name the company without leaving an address.
|
|
25
|
+
|
|
26
|
+
## What it prints
|
|
27
|
+
|
|
28
|
+
The consent notice, then the exact payload, then the result:
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
sending {"context":"company","company":"Acme","email":"you@acme.com"}
|
|
32
|
+
thanks saved and sent. we may reach out; `reticle identify --forget` undoes this.
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
`not sent` replaces the last line when telemetry is disabled on the machine, in which case the identity is saved locally only.
|
|
36
|
+
|
|
37
|
+
With `--forget`:
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
forgotten the local identity file is deleted; nothing further is sent.
|
|
41
|
+
to have what was already sent removed, email support@reticlehq.com
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Run with no valid `--context`, it prints the current identity (if any), the usage, and the full consent notice, and exits `1`. Real capture on a machine with no identity on file:
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
usage: reticle identify --context <company|side_project|open_source|learning>
|
|
48
|
+
[--company "Acme"] [--email you@acme.com] [--forget]
|
|
49
|
+
|
|
50
|
+
This sends the details you type here to the Reticle maintainers, so we can contact you and
|
|
51
|
+
understand how teams use Reticle. It is linked to this machine's anonymous id, which means it
|
|
52
|
+
also connects the anonymous usage already recorded from this machine to what you enter now.
|
|
53
|
+
Nothing about your app, your code, or your repository is included, and nothing else changes.
|
|
54
|
+
Undo it any time with `reticle identify --forget` (that stops future sends and deletes the local file;
|
|
55
|
+
email support@reticlehq.com to have what was already sent removed).
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
<Warning>
|
|
59
|
+
Identifying links this machine's anonymous id to what you type, which also connects the anonymous
|
|
60
|
+
usage already recorded from this machine to that identity. The command says so before it sends
|
|
61
|
+
anything. Nothing about your app, your code, or your repository is ever included.
|
|
62
|
+
</Warning>
|
|
63
|
+
|
|
64
|
+
## Exit codes
|
|
65
|
+
|
|
66
|
+
| Code | Meaning |
|
|
67
|
+
| ---- | ------------------------------------------------------------------------------ |
|
|
68
|
+
| `0` | Identity saved, or forgotten, or usage printed when an identity already exists |
|
|
69
|
+
| `1` | No valid `--context` and no identity on file |
|
|
70
|
+
|
|
71
|
+
## Worked example
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
npx @reticlehq/server identify --context open_source --email maintainer@example.com
|
|
75
|
+
npx @reticlehq/server identify --forget
|
|
76
|
+
```
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: reticle init
|
|
3
|
+
description: Wire Reticle into the project in the current directory, registering the MCP server and installing the SDK.
|
|
4
|
+
icon: wand-magic-sparkles
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
`reticle init` is the one command a person runs before anything else. It inspects the directory it is standing in, works out the framework, and writes every piece of wiring Reticle needs: the MCP server registration, the agent rule files, the dev dependencies, `.reticle.json`, and the bundler plugin.
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx @reticlehq/server init [--dry-run] [--port N] [--no-mcp] [--no-install] [--app <dir>] [--yes]
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Flags
|
|
14
|
+
|
|
15
|
+
| Flag | Type | Default | What it does |
|
|
16
|
+
| --- | --- | --- | --- |
|
|
17
|
+
| `--dry-run` | boolean | `false` | Print the full plan and write nothing |
|
|
18
|
+
| `--port N` | number | unset (resolves to `4400`) | Bridge port to write into the config |
|
|
19
|
+
| `--no-mcp` | boolean | `false` (MCP is registered) | Skip the MCP registration **and** the agent rule files (`CLAUDE.md`, `AGENTS.md`, `.cursor`) and the `/reticle` command |
|
|
20
|
+
| `--no-install` | boolean | `false` (deps are installed) | Do not run the install. The step becomes `[⚠]` and prints the `add -D` command for you to run by hand, rather than vanishing from the plan |
|
|
21
|
+
| `--app <dir>` | string | unset | Pick which app to wire in a monorepo, without changing directory |
|
|
22
|
+
| `--yes` | boolean | `false` | Accepted for scripting. `init` has no interactive prompts today, so it is a no-op |
|
|
23
|
+
|
|
24
|
+
<Warning>
|
|
25
|
+
`--no-mcp` skips more than the server registration. The agent rule files and the `/reticle`
|
|
26
|
+
command go with it, because all three only make sense once the tools are reachable.
|
|
27
|
+
</Warning>
|
|
28
|
+
|
|
29
|
+
## What it prints
|
|
30
|
+
|
|
31
|
+
A plan, one line per step, each with a status mark: `✓` written, `·` already in place or left alone, `⚠` needs a hand, `–` deliberately skipped by a flag. Captured from a real `--dry-run` inside `apps/bench-app`:
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
reticle init (dry run, no files written)
|
|
35
|
+
in /Users/you/reticle/apps/bench-app
|
|
36
|
+
|
|
37
|
+
[·] MCP server (Claude, global) → global (claude user scope)
|
|
38
|
+
reticle already registered (install once, used by every project)
|
|
39
|
+
[·] MCP server (Cursor, global) → /Users/you/.cursor/mcp.json
|
|
40
|
+
reticle already in Cursor global config
|
|
41
|
+
[⚠] MCP server (Codex CLI) → /Users/you/.codex/config.toml
|
|
42
|
+
add this to /Users/you/.codex/config.toml by hand:
|
|
43
|
+
[mcp_servers.reticle]
|
|
44
|
+
command = "npx"
|
|
45
|
+
args = ["@reticlehq/server", "mcp"]
|
|
46
|
+
|
|
47
|
+
[✓] Agent verification rule → CLAUDE.md
|
|
48
|
+
teach the agent to verify features with Reticle after building them
|
|
49
|
+
[✓] Agent verification rule → AGENTS.md
|
|
50
|
+
teach the agent to verify features with Reticle after building them
|
|
51
|
+
[✓] Full agent rules → RETICLE.md
|
|
52
|
+
the reference the always-loaded rule points at (when NOT to verify, recovery, feedback)
|
|
53
|
+
[✓] The /reticle command → .claude/commands/reticle.md
|
|
54
|
+
type /reticle to verify one flow in the browser
|
|
55
|
+
[✓] Install dependencies → package.json
|
|
56
|
+
pnpm add -D @reticlehq/react@2.8.0 @reticlehq/vite-plugin@2.8.0
|
|
57
|
+
[✓] Reticle config → .reticle.json
|
|
58
|
+
write project config (framework + port)
|
|
59
|
+
[✓] Vite plugin → vite.config.ts
|
|
60
|
+
add reticle() to plugins (also injects connect())
|
|
61
|
+
[·] Capabilities + store → src/reticle-dev.ts
|
|
62
|
+
file exists, left alone, it is yours to edit
|
|
63
|
+
|
|
64
|
+
Restart `vite`.
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Below the plan it also prints the two things that actually finish the install: restart your agent so it re-reads its MCP server list, then run `npx @reticlehq/server status` to confirm the app connected.
|
|
68
|
+
|
|
69
|
+
With `--no-mcp`, the whole MCP and rules group collapses into one skipped line:
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
[–] MCP server (global) → global (claude user scope)
|
|
73
|
+
--no-mcp ... also skips the agent rule files (CLAUDE.md / AGENTS.md / .cursor) and the /reticle command
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Run from a workspace root with several apps, it refuses to guess, names them, and exits `1`:
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
Several apps found in this workspace. Re-run `reticle init` inside the one you want:
|
|
80
|
+
packages/next
|
|
81
|
+
packages/vite-plugin
|
|
82
|
+
apps/atlas
|
|
83
|
+
apps/bench-app
|
|
84
|
+
apps/electron-smoke
|
|
85
|
+
apps/large-dom-bench
|
|
86
|
+
apps/next-smoke
|
|
87
|
+
apps/tauri-smoke
|
|
88
|
+
apps/vibe-builder-demo
|
|
89
|
+
|
|
90
|
+
Or name one without changing directory: reticle init --app packages/next
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Given `--app`, it says which directory it moved to before printing the plan:
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
No app in this directory ... wiring apps/bench-app instead.
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
In the two captures above, the punctuation that separates the two halves of the sentence is shown as `...`.
|
|
100
|
+
|
|
101
|
+
## Exit codes
|
|
102
|
+
|
|
103
|
+
| Code | Meaning |
|
|
104
|
+
| ---- | --------------------------------------------------------------------------------------- |
|
|
105
|
+
| `0` | The plan ran. Steps marked `⚠` still need a hand, and do not change the code |
|
|
106
|
+
| `1` | Init failed, an unknown flag was passed, or several apps were found and none was chosen |
|
|
107
|
+
|
|
108
|
+
An unknown flag is rejected by name: `reticle init --bogus` prints `unknown argument '--bogus'`, then the full usage block, and exits `1`.
|
|
109
|
+
|
|
110
|
+
## Worked example
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
cd apps/web
|
|
114
|
+
npx @reticlehq/server init --dry-run # read the plan first
|
|
115
|
+
npx @reticlehq/server init # then run it
|
|
116
|
+
npx @reticlehq/server status # confirm the app actually connected
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
<Card title="The install, step by step" icon="wand-magic-sparkles" href="/install-agentic">
|
|
120
|
+
What each step writes and how to read the four status marks.
|
|
121
|
+
</Card>
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: reticle kill
|
|
3
|
+
description: Free the bridge port by killing its listener, without touching the agent's own MCP proxy.
|
|
4
|
+
icon: skull
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
`reticle kill` frees the bridge port. It asks **who is listening** on the port and signals that one process, which is the whole difference between this command and the shell pipeline everybody reaches for.
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx @reticlehq/server kill [--port N] [--force]
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
<Warning>
|
|
14
|
+
Never free the port with `lsof -ti tcp:4400 | xargs kill -9`. `reticle mcp` holds a **client**
|
|
15
|
+
socket on that port, so `-ti` lists the proxy right beside the daemon and the pipeline kills both.
|
|
16
|
+
When the proxy dies, the agent's next tool calls get no reply at all: not an error, not a timeout.
|
|
17
|
+
Nothing is written to the proxy log either, because the process that writes it is the one that
|
|
18
|
+
died. That is the mechanism behind most "my MCP disconnected" reports.
|
|
19
|
+
</Warning>
|
|
20
|
+
|
|
21
|
+
## Flags
|
|
22
|
+
|
|
23
|
+
| Flag | Type | Default | What it does |
|
|
24
|
+
| --- | --- | --- | --- |
|
|
25
|
+
| `--port N` | number | `4400` (or `RETICLE_PORT`, or the port in `.reticle.json`) | Which port to free |
|
|
26
|
+
| `--force` | boolean | `false` | Kill the listener even when it is not a Reticle daemon |
|
|
27
|
+
|
|
28
|
+
## kill or stop?
|
|
29
|
+
|
|
30
|
+
They target different things, and the distinction matters exactly when you are stuck.
|
|
31
|
+
|
|
32
|
+
| | `reticle stop` | `reticle kill` |
|
|
33
|
+
| --- | --- | --- |
|
|
34
|
+
| Finds the process by | the pid recorded in Reticle's own state | the **listener** on the port |
|
|
35
|
+
| Works when the pid file is stale or was never written | no | yes |
|
|
36
|
+
| Works on a daemon from another checkout | no | yes |
|
|
37
|
+
| Works without `lsof` (Windows, slim containers) | yes | yes, falling back to the recorded pid and saying so |
|
|
38
|
+
|
|
39
|
+
Reach for `stop` in a script that shuts down a daemon it started. Reach for `kill` when the port is held and you want it back.
|
|
40
|
+
|
|
41
|
+
## How it decides
|
|
42
|
+
|
|
43
|
+
1. Look up the listener with `lsof -nP -iTCP:<port> -sTCP:LISTEN`. Client sockets are excluded by construction, so the proxy is never a candidate.
|
|
44
|
+
2. It is Reticle's if it answers `/status`, **or** if it is the pid Reticle recorded for the port. `/status` outranks the pid file, so a daemon started from another checkout is still recognised as ours.
|
|
45
|
+
3. Anything else is refused, by name, unless `--force`.
|
|
46
|
+
4. `SIGTERM`, then `SIGKILL` after 5 seconds, then report that it survived and exit `1`.
|
|
47
|
+
|
|
48
|
+
## What it prints
|
|
49
|
+
|
|
50
|
+
Real captures, taken against a daemon started on a scratch port. The long `note` and `reason` strings are trimmed at the ellipsis. Measured exit codes: `0` for killed and nothing-to-do, `1` for refused.
|
|
51
|
+
|
|
52
|
+
Killed:
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
{"t":"2026-08-15T18:43:43.590Z","event":"reticle_killed","port":4499,"pid":78621,"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 ..."}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Refused, because the listener is not ours. This one was captured with `python3 -m http.server 4498` holding the port:
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
{"t":"2026-08-15T18:43:57.128Z","event":"reticle_kill_refused","port":4498,"reason":"pid 78795 (\"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"}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Nothing to free:
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
{"t":"2026-08-15T18:43:43.784Z","event":"reticle_kill_nothing_to_do","port":4499,"presence":"free"}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
| Event | When |
|
|
71
|
+
| --- | --- |
|
|
72
|
+
| `reticle_killed` | The listener is gone. `escalated: true` means it took a `SIGKILL`; `forced: true` means `--force` overrode a refusal |
|
|
73
|
+
| `reticle_kill_refused` | The listener is not a Reticle daemon and `--force` was not given. Exits `1` |
|
|
74
|
+
| `reticle_kill_survived` | It survived `SIGKILL`. The port is still held. Exits `1` |
|
|
75
|
+
| `reticle_kill_nothing_to_do` | No listener, and no live recorded pid |
|
|
76
|
+
|
|
77
|
+
`listenerIdentified: false` means `lsof` could not run and the pid came from Reticle's records rather than from an observed listener. Those are different claims, so the field says which one you got.
|
|
78
|
+
|
|
79
|
+
## Exit codes
|
|
80
|
+
|
|
81
|
+
| Code | Meaning |
|
|
82
|
+
| ---- | ------------------------------------------------------------------ |
|
|
83
|
+
| `0` | The port is free |
|
|
84
|
+
| `1` | The port is still held: refused, or the process survived `SIGKILL` |
|
|
85
|
+
|
|
86
|
+
## Worked example
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
npx @reticlehq/server kill # free 4400
|
|
90
|
+
npx @reticlehq/server status # confirm
|
|
91
|
+
```
|
|
@@ -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-15T18:42:26.758Z",
|
|
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>
|
package/docs/cli/mcp.mdx
ADDED
|
@@ -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,74 @@
|
|
|
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
|
+
Calling it with no URL when nothing has connected is the other `error` shape. It exits `0`, because reporting "there is nothing to show you" is a complete answer. Real capture, with the sentence break shown as `...`:
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
{"t":"2026-08-15T18:43:41.651Z","event":"reticle_open","port":4499,"error":"no app connected ... pass a url: reticle open <url>. Desktop app (Electron/Tauri)? There is no url to open: start it as you normally would and it connects to this bridge itself."}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
</Note>
|
|
50
|
+
|
|
51
|
+
<Warning>
|
|
52
|
+
This command does **not** use Reticle's own Chromium. It hands the URL to your system default
|
|
53
|
+
browser, so a `chromium` warning from `reticle doctor` has nothing to do with an `open` that came
|
|
54
|
+
back `connected: false`. That misread cost a reporter an afternoon in their bridge config.
|
|
55
|
+
</Warning>
|
|
56
|
+
|
|
57
|
+
<Warning>
|
|
58
|
+
For an Electron or Tauri app there is no URL to open. Start the app the way you normally would; it
|
|
59
|
+
dials the bridge itself.
|
|
60
|
+
</Warning>
|
|
61
|
+
|
|
62
|
+
## Exit codes
|
|
63
|
+
|
|
64
|
+
| Code | Meaning |
|
|
65
|
+
| ---- | ------------------------------------------------------------------- |
|
|
66
|
+
| `0` | Reused, opened, or reported that no app is connected |
|
|
67
|
+
| `1` | A browser could not be launched, or the daemon could not be reached |
|
|
68
|
+
|
|
69
|
+
## Worked example
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
npx @reticlehq/server open http://localhost:5173
|
|
73
|
+
npx @reticlehq/server status # confirm the session is really there
|
|
74
|
+
```
|
|
@@ -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 (exit `0`), with the long `note` trimmed at the ellipsis:
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
{"t":"2026-08-15T18:43:41.949Z","event":"reticle_killed","port":4499,"pid":78137,"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 ..."}
|
|
28
|
+
{"t":"2026-08-15T18:43:42.258Z","event":"reticle_daemon_spawned","port":4499}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Real capture, when the port is held by something that is not ours (exit `1`). Both `reason` strings are trimmed at the ellipsis:
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
{"t":"2026-08-15T18:43:57.317Z","event":"reticle_kill_refused","port":4498,"reason":"pid 78795 (\"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
|
+
{"t":"2026-08-15T18:43:57.318Z","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,69 @@
|
|
|
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-15T18:43:33.065Z", "event": "reticle_daemon_already_running", "port": 4499 }
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
A successful spawn logs `reticle_daemon_spawned` with the port:
|
|
36
|
+
|
|
37
|
+
```json
|
|
38
|
+
{ "t": "2026-08-15T18:43:32.604Z", "event": "reticle_daemon_spawned", "port": 4499 }
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
A port held by something that is not a Reticle daemon is refused up front rather than spawned into. The reason is repeated as plain text on stderr for the person who typed the command. Real capture, with `python3 -m http.server 4498` holding the port and the punctuation between the two halves of the reason shown as `...`:
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
{"t":"2026-08-15T18:43:57.478Z","event":"reticle_daemon_start_refused","port":4498,"presence":"foreign","reason":"port 4498 is held by another process that is not a Reticle daemon ... a daemon cannot bind it. Stop that process, or run Reticle on a different port (`--port`), then retry."}
|
|
45
|
+
port 4498 is held by another process that is not a Reticle daemon ... a daemon cannot bind it. Stop that process, or run Reticle on a different port (`--port`), then retry.
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Exit codes
|
|
49
|
+
|
|
50
|
+
| Code | Meaning |
|
|
51
|
+
| ---- | --------------------------------------------------------------------------------- |
|
|
52
|
+
| `0` | A daemon is up on the port, whether this run started it or found it |
|
|
53
|
+
| `1` | The port is held by a foreign process, or the child never bound within 15 seconds |
|
|
54
|
+
|
|
55
|
+
<Note>
|
|
56
|
+
`serve` reports the **bind**, not the spawn. It used to exit `0` the moment it forked, while the
|
|
57
|
+
child died on an `EADDRINUSE` nobody joined back up. It now waits for the daemon to answer.
|
|
58
|
+
</Note>
|
|
59
|
+
|
|
60
|
+
## Worked example
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
npx @reticlehq/server serve --port 4400
|
|
64
|
+
npx @reticlehq/server status
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
<Card title="What the daemon is" icon="sitemap" href="/architecture">
|
|
68
|
+
The bridge, the tool engine, and where `.reticle/` lives.
|
|
69
|
+
</Card>
|