@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,156 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: reticle_tools and reticle_run
|
|
3
|
+
description: Discover the tools that are not advertised, load their argument grammar on demand, and invoke any of them by name.
|
|
4
|
+
icon: boxes-stacked
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
`reticle_tools` lists every Reticle tool and, on request, returns the full argument grammar for the ones you name. `reticle_run` then invokes any of them. Reach for the pair whenever you need a capability that is not in the default advertised surface, which is most of what Reticle can do.
|
|
8
|
+
|
|
9
|
+
Reticle ships 46 tools plus these two meta-tools. On the default profile your agent is shown 17 of them plus the meta pair, so 29 sit in the cold tail. These two are how it reaches those 29 without paying for their schemas on every turn.
|
|
10
|
+
|
|
11
|
+
`reticle_tools` discovers. `reticle_run` invokes. Together they cost two tool definitions instead of twenty-nine.
|
|
12
|
+
|
|
13
|
+
## Discovering what exists
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
{}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Returns every tool with a one-line summary. A sample of what lives in the cold tail:
|
|
20
|
+
|
|
21
|
+
| Tool | What it does |
|
|
22
|
+
| ----------------------- | ---------------------------------------------------------------------- |
|
|
23
|
+
| `reticle_capabilities` | The app's advertised testable surface, testids, signals, stores, flows |
|
|
24
|
+
| `reticle_flow_verify` | Replay every saved flow, return one consolidated suite verdict |
|
|
25
|
+
| `reticle_screenshot` | Pixel screenshot of the driven page, saved as a visual baseline |
|
|
26
|
+
| `reticle_visual_diff` | Perceptually diff the live page against that baseline |
|
|
27
|
+
| `reticle_network_mock` | Force a 500, go offline, or delay a response |
|
|
28
|
+
| `reticle_viewport` | Pin the viewport so screenshots are reproducible across machines |
|
|
29
|
+
| `reticle_crawl` | Click every reachable control and report anomalies, with no script |
|
|
30
|
+
| `reticle_clock` | Freeze time or fast-forward timers, toasts, debounces, auto-dismiss |
|
|
31
|
+
| `reticle_storage` | localStorage, sessionStorage and readable cookies |
|
|
32
|
+
| `reticle_coverage` | Which controls you have driven this session, and which you have not |
|
|
33
|
+
| `reticle_verify_change` | Give it the files you edited; it replays the flows that cover them |
|
|
34
|
+
| `reticle_reconcile` | Compare what the API returned against what the page actually renders |
|
|
35
|
+
| `reticle_scroll_to` | Find a row in a virtualised list that has not rendered yet |
|
|
36
|
+
|
|
37
|
+
The response also tells you which surface is active:
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
{
|
|
41
|
+
"profile": {
|
|
42
|
+
"active": "all",
|
|
43
|
+
"source": "RETICLE_ADVERTISE_ALL_TOOLS set in the DAEMON's environment at startup",
|
|
44
|
+
"note": "The profile is read once at daemon startup: change RETICLE_TOOL_PROFILE and restart the daemon, or it has no effect. Under this profile every unadvertised tool is reachable through reticle_run; under `full` there are no meta-tools because every tool is advertised directly."
|
|
45
|
+
},
|
|
46
|
+
"next": "Load params with reticle_tools { names:[…] }, then call reticle_run { tool, args }."
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
That capture is from a daemon started with `RETICLE_ADVERTISE_ALL_TOOLS=1`. On a default daemon, `active` reads `default` and names the environment variable as unset.
|
|
51
|
+
|
|
52
|
+
<Warning>
|
|
53
|
+
"Read once at daemon startup" is doing real work in that sentence. Setting the environment
|
|
54
|
+
variable in a shell where a daemon is already running changes nothing, and the resulting "I set it
|
|
55
|
+
and nothing happened" is very hard to debug from the outside.
|
|
56
|
+
</Warning>
|
|
57
|
+
|
|
58
|
+
## Loading argument grammar
|
|
59
|
+
|
|
60
|
+
Summaries are enough to choose a tool, not to call one. Load the full parameters for the ones you want:
|
|
61
|
+
|
|
62
|
+
```json
|
|
63
|
+
{ "names": ["reticle_network_mock", "reticle_clock"] }
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Each named tool comes back with its full description and a `params` array of `{ name, required, description }`. This is the point of the design. Schemas arrive when they are needed, rather than on every turn forever.
|
|
67
|
+
|
|
68
|
+
<Warning>
|
|
69
|
+
Do this rather than guessing. `reticle_run` refuses an unknown parameter instead of running the
|
|
70
|
+
call, and hands you the real parameter list so the retry is one turn rather than three:
|
|
71
|
+
|
|
72
|
+
```json
|
|
73
|
+
{
|
|
74
|
+
"error": "unknown parameter for reticle_flow_save: name",
|
|
75
|
+
"tool": "reticle_flow_save",
|
|
76
|
+
"params": [
|
|
77
|
+
{ "name": "flow", "required": false, "description": "Alias for `flowName`." },
|
|
78
|
+
{ "name": "flowName", "required": true, "description": "Name for the flow file." }
|
|
79
|
+
],
|
|
80
|
+
"hint": "fix the arguments and call reticle_run again"
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
The full `error` string continues: _"NOT applied, so any result would be an answer to a different question."_
|
|
85
|
+
|
|
86
|
+
</Warning>
|
|
87
|
+
|
|
88
|
+
## Invoking
|
|
89
|
+
|
|
90
|
+
```json
|
|
91
|
+
{ "tool": "reticle_capabilities" }
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Real response from an instrumented app, trimmed:
|
|
95
|
+
|
|
96
|
+
```json
|
|
97
|
+
{
|
|
98
|
+
"testids": [
|
|
99
|
+
"nav-overview",
|
|
100
|
+
"nav-deployments",
|
|
101
|
+
"login-email",
|
|
102
|
+
"login-password",
|
|
103
|
+
"login-submit",
|
|
104
|
+
"deploy-table",
|
|
105
|
+
"new-deploy",
|
|
106
|
+
"deploy-submit",
|
|
107
|
+
"…"
|
|
108
|
+
],
|
|
109
|
+
"signals": [
|
|
110
|
+
"nav:changed",
|
|
111
|
+
"auth:granted",
|
|
112
|
+
"auth:denied",
|
|
113
|
+
"deploy:created",
|
|
114
|
+
"deploy:shipped",
|
|
115
|
+
"modal:opened",
|
|
116
|
+
"toast:shown",
|
|
117
|
+
"…"
|
|
118
|
+
],
|
|
119
|
+
"stores": ["app"],
|
|
120
|
+
"flows": [
|
|
121
|
+
{
|
|
122
|
+
"name": "ship-a-deploy",
|
|
123
|
+
"steps": ["nav-deployments", "new-deploy", "deploy-name", "deploy-submit"]
|
|
124
|
+
},
|
|
125
|
+
{ "name": "generate-a-script", "steps": ["nav-compose", "compose-prompt", "compose-generate"] },
|
|
126
|
+
{ "name": "find-old-deploy", "steps": ["nav-deployments", "scroll-to row-3600"] }
|
|
127
|
+
],
|
|
128
|
+
"source": "live"
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
The full response on this fixture carries 49 testids and 16 signals. `source: "live"` means it was read from the running app; pass `{ "fromDisk": true }` to read the git-checked `.reticle/contract.json` instead, which works with no browser attached at all.
|
|
133
|
+
|
|
134
|
+
## Start here, not with a snapshot
|
|
135
|
+
|
|
136
|
+
That `reticle_capabilities` output is the single best first call on an unfamiliar app. It is the app telling you what it considers testable: the elements worth driving, the signals that mean success, and the flows somebody already thought were important.
|
|
137
|
+
|
|
138
|
+
Compared with snapshotting the page and guessing from element names, it is both cheaper and more truthful. `auth:granted` is what the app means by "logged in", and no amount of looking at the DOM will tell you that.
|
|
139
|
+
|
|
140
|
+
```json
|
|
141
|
+
{
|
|
142
|
+
"tool": "reticle_network_mock",
|
|
143
|
+
"args": { "mocks": [{ "urlContains": "/api/deploys", "status": 500 }] }
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
```json
|
|
148
|
+
{ "applied": true, "count": 1 }
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Then drive the flow and see whether your error state actually works. Most do not, which is the point. `{ "clear": true }` turns it off and answers `{ "applied": true, "count": 0 }`.
|
|
152
|
+
|
|
153
|
+
<Note>
|
|
154
|
+
`reticle_run` returns whatever the invoked tool returns, unchanged. It is a transport, not a
|
|
155
|
+
wrapper. So a tool that produces a verdict still produces one through `run`.
|
|
156
|
+
</Note>
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: reticle_wait_for
|
|
3
|
+
description: Block until a predicate holds. Or return immediately if it is already true in the recent buffer.
|
|
4
|
+
icon: hourglass
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
`reticle_wait_for` blocks until a predicate holds, or returns straight away if it is already satisfied in the recent event buffer. Reach for it when you are waiting on something you did not cause. It reads and waits; it does not produce a verdict, so finish with [`reticle_assert`](/tools-assert).
|
|
8
|
+
|
|
9
|
+
It takes the same predicate grammar as [`reticle_act_and_wait`](/tools-act-and-wait), without the action. Use it when the thing you are waiting for was triggered by something other than your own click. A timer, a websocket push, a background refresh.
|
|
10
|
+
|
|
11
|
+
## Example
|
|
12
|
+
|
|
13
|
+
```json
|
|
14
|
+
{
|
|
15
|
+
"predicate": { "kind": "text", "contains": "Invalid email or password" },
|
|
16
|
+
"timeout_ms": 3000
|
|
17
|
+
}
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Real response:
|
|
21
|
+
|
|
22
|
+
```json
|
|
23
|
+
{
|
|
24
|
+
"pass": true,
|
|
25
|
+
"evidence": [
|
|
26
|
+
{
|
|
27
|
+
"ref": "e606",
|
|
28
|
+
"role": "alert",
|
|
29
|
+
"name": "Invalid email or password",
|
|
30
|
+
"visible": true,
|
|
31
|
+
"source": "src/components/Login.tsx:72",
|
|
32
|
+
"states": ["present", "visible", "enabled"]
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
The evidence is the element itself, with the file and line that rendered it.
|
|
39
|
+
|
|
40
|
+
<Note>
|
|
41
|
+
A `text` predicate matches **presence** by default, so an element that is in the DOM but hidden
|
|
42
|
+
satisfies it and comes back with `visible: false` and `states: ["present", "hidden", "enabled"]`.
|
|
43
|
+
If you need it on screen, say so: `{ "kind": "text", "contains": "…", "visible": true }`.
|
|
44
|
+
</Note>
|
|
45
|
+
|
|
46
|
+
The field is `contains`. `value` and `text` are accepted as aliases and rewritten to it, but `contains` is what the published schema declares.
|
|
47
|
+
|
|
48
|
+
## It checks the buffer first
|
|
49
|
+
|
|
50
|
+
`wait_for` does not always wait. If the predicate is already satisfied in the recent event buffer, it returns immediately. This means you can act, then wait, without racing. The event that happened while you were composing the second call is not lost.
|
|
51
|
+
|
|
52
|
+
## Arguments
|
|
53
|
+
|
|
54
|
+
| Argument | What it does |
|
|
55
|
+
| ------------------------ | ----------------------------------------------------------------- |
|
|
56
|
+
| `predicate` (or `until`) | `{ kind, ...fields }`, see the [predicate reference](/predicates) |
|
|
57
|
+
| `timeout_ms` | Maximum wait. Default 4000 |
|
|
58
|
+
| `since` | Cursor from a prior act, to widen or narrow the window explicitly |
|
|
59
|
+
|
|
60
|
+
By default the wait only counts events since your last act, so a signal that fired before the action cannot satisfy it. A miss returns a near-miss diagnosis rather than a bare `false`:
|
|
61
|
+
|
|
62
|
+
```json
|
|
63
|
+
{
|
|
64
|
+
"pass": false,
|
|
65
|
+
"failureReason": "no element matched {\"text\":\"Deployments\"}",
|
|
66
|
+
"observed": "no matching element on the page",
|
|
67
|
+
"expected": "an element matching {\"text\":\"Deployments\"}",
|
|
68
|
+
"assertion": "element.present",
|
|
69
|
+
"evidence": { "presentTestids": ["login-email", "login-password", "login-submit"] }
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
`presentTestids` there is the answer to the real question. The text was missing because the app had logged out, not because the render was slow.
|
|
74
|
+
|
|
75
|
+
## Prefer `act_and_wait` when you caused it
|
|
76
|
+
|
|
77
|
+
If your own action is supposed to trigger the thing, put the predicate in the action:
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{ "ref": "e605", "action": "click", "until": { "kind": "signal", "name": "auth:granted" } }
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
One call instead of two, no gap for an event to slip through, and, the part that actually matters, the expectation is recorded _before_ the action rather than chosen after it.
|
|
84
|
+
|
|
85
|
+
Save `wait_for` for consequences you did not cause.
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 'Troubleshooting: it worked on my tab'
|
|
3
|
+
sidebarTitle: Troubleshooting
|
|
4
|
+
description: Nothing connected, the click did nothing, the verdict says unknown. The failures people actually hit, and the diagnostic for each.
|
|
5
|
+
icon: stethoscope
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
**Run `npx @reticlehq/server doctor` first.** It checks Chromium, the daemon, the port and the connected sessions in one command, and it names the problem in most cases. If `sessions` reads zero, your app is not reaching the bridge, and a port mismatch is the usual reason.
|
|
9
|
+
|
|
10
|
+
Reticle is a verification layer that runs a dev-only SDK inside your running web app. Two halves have to be working: your agent needs the MCP server registered, and your app needs the SDK connected to the local daemon. Almost every failure below is one of those two halves being absent.
|
|
11
|
+
|
|
12
|
+
Most of these were hit while writing these docs. The diagnostics quoted are real output.
|
|
13
|
+
|
|
14
|
+
## Start here
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npx @reticlehq/server doctor
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
reticle doctor
|
|
22
|
+
node v22.14.0
|
|
23
|
+
chromium ✓ installed
|
|
24
|
+
daemon ✓ running on :4400 (pid 24735, v<the version you have>)
|
|
25
|
+
sessions ✓ 1 page connected
|
|
26
|
+
bridge port 4400 (your app must dial THIS port, not your dev-server port)
|
|
27
|
+
daemon log /Users/you/.reticle/daemon-4400.log
|
|
28
|
+
tracing RETICLE_TRACE=1 on the daemon for per-stage timings in that log
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
One command, the whole setup. If this is clean and things still fail, the problem is in the app rather than the wiring.
|
|
32
|
+
|
|
33
|
+
The `sessions` line is the one to read first. Zero connected pages is a failing check, not a footnote, because it is the state a setup most often stalls in: everything installed, the daemon up, and nothing having dialled in. When it is zero, `doctor` prints the same diagnosis described below underneath the checklist, so you do not have to call a tool to see it.
|
|
34
|
+
|
|
35
|
+
## "No browser session connected"
|
|
36
|
+
|
|
37
|
+
By far the most common. Reticle's own diagnostic is unusually good here. It tells you whether the wiring was ever correct:
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
{
|
|
41
|
+
"sessionCount": 0,
|
|
42
|
+
"why": "no browser session connected, but one WAS connected to this daemon earlier, so the wiring is correct. The tab was closed, navigated away, or hard-reloaded. Ask the human to reopen the app (or run `reticle open`), or reload the tab. You do not have to wait for the human: reticle_lease {action:\"acquire\", url} opens a browser Reticle drives itself, and returns a sessionId you can use immediately (reach it with reticle_run {tool:\"reticle_lease\"} if it is not advertised directly; release it when you finish). Then call reticle_sessions again."
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Read the `why`. If it says one **was** connected earlier, stop debugging your config and just reopen the tab. If it says nothing ever connected, the wiring itself is wrong, so work through the list below.
|
|
47
|
+
|
|
48
|
+
If nothing ever connected:
|
|
49
|
+
|
|
50
|
+
- Is the app running, and open in a browser? If nothing is serving it, see [Who starts the dev server](#who-starts-the-dev-server): this is the agent's job, not a question to put to you.
|
|
51
|
+
- Is `reticle.connect()` actually executing? Check the dev guard is true.
|
|
52
|
+
- **Port mismatch.** This is the big one.
|
|
53
|
+
|
|
54
|
+
### Who starts the dev server
|
|
55
|
+
|
|
56
|
+
**The agent does.** If no dev server is listening, the agent reads your project's own dev script out of `package.json`, runs it in the background, tells you in one line that it is running and how to stop it, and carries on. It used to be told the opposite, "Reticle never starts the dev server for you, that's your job", and agents obeyed it exactly: they read the rule, declined to start anything, and ended the turn with nothing verified.
|
|
57
|
+
|
|
58
|
+
The daemon still does not do it, on purpose. A build process started by a long-lived background daemon is invisible to whoever's machine it is running on, was never consented to, cannot easily be stopped, and orphans when the daemon exits. It would also mean a piece of standing infrastructure runs arbitrary `package.json` scripts. An agent already has shell access in your repo, already runs install and build commands, and runs inside a host that asks you before it does. A dev server the agent starts is in the transcript, attributable to a step you approved, and stoppable.
|
|
59
|
+
|
|
60
|
+
The agent does not have to work out the command. When `reticle_sessions` comes back with nothing connected, it carries a `next_action` naming which of four cases this is and, where one applies, the literal command and port: start the dev server, run `reticle init`, open the app, or reopen a tab that went away. The command is read from this project's own scripts, so a project with no recognisable dev script gets no command rather than a guess.
|
|
61
|
+
|
|
62
|
+
The guards, which apply wherever this instruction appears:
|
|
63
|
+
|
|
64
|
+
1. **Never start a second one.** If something is already listening on the app's port, it is adopted.
|
|
65
|
+
2. **Never guess the command.** It comes from `package.json` scripts. If there is no recognisable dev script, the agent says so and stops rather than inventing one.
|
|
66
|
+
3. **Never kill anything**: not a dev server, not a daemon, not a port holder, including one it started.
|
|
67
|
+
4. **Background it, and say so.** You must know a server is running and how to stop it. A dev server you do not know about is the same failure one step later.
|
|
68
|
+
5. **The permission prompt is your agent host's.** Nothing in Reticle bypasses or auto-approves it, and you can always decline.
|
|
69
|
+
|
|
70
|
+
The corollary matters as much: if a dev server IS already running and nothing connects, the cause is the SDK not loading in the page. An agent that answers this state by asking you to start a server you are already running has ended the conversation with nothing fixed. Work the checklist above instead.
|
|
71
|
+
|
|
72
|
+
### The port mismatch
|
|
73
|
+
|
|
74
|
+
Your app dials a port; the daemon listens on one. When they disagree, the app runs perfectly and silently never connects. The browser console says so:
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
[Reticle] this page could not open a websocket to ws://localhost:4460/reticle. 3 attempts, all
|
|
78
|
+
failed. That is everything the page can see: from inside the browser it cannot tell a daemon that
|
|
79
|
+
is not there from one it is not allowed to reach, so this is not evidence about the daemon. What
|
|
80
|
+
answers it: run `npx @reticlehq/server status` to see whether one is listening and on which port.
|
|
81
|
+
If your app runs in a container, devcontainer or WSL, the daemon is on a different host, so set
|
|
82
|
+
the URL explicitly (Vite: VITE_RETICLE_WS_URL, or reticle.connect({ url })). An https page cannot
|
|
83
|
+
open a ws:// socket at all. Still retrying…
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
That message names the exact address it tried. Compare its port with `bridge port` from `doctor` and set whichever is wrong:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
VITE_RETICLE_WS_URL=ws://localhost:4400/reticle pnpm dev
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
<Warning>
|
|
93
|
+
The bridge port is **not** your dev-server port. A dev server on 4312 and a daemon on 4400 is
|
|
94
|
+
normal and correct.
|
|
95
|
+
</Warning>
|
|
96
|
+
|
|
97
|
+
## The click did nothing
|
|
98
|
+
|
|
99
|
+
Check whether the tab is throttled. Every response tells you:
|
|
100
|
+
|
|
101
|
+
```json
|
|
102
|
+
"warning": "tab throttled; timer/rAF/pointer gestures may silently no-op; refocus before driving"
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
A backgrounded browser tab has its timers suppressed. Synthetic pointer gestures and timers can silently no-op, so an action reports success and nothing happens.
|
|
106
|
+
|
|
107
|
+
Three fixes, in order of preference:
|
|
108
|
+
|
|
109
|
+
1. **Drive a lease**. A context Reticle owns, never backgrounded:
|
|
110
|
+
|
|
111
|
+
```json
|
|
112
|
+
{ "tool": "reticle_lease", "args": { "action": "acquire", "url": "http://localhost:4312/" } }
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Release it when you finish: `{ "action": "release", "sessionId": "lease-…" }`.
|
|
116
|
+
|
|
117
|
+
2. **Focus the tab.**
|
|
118
|
+
3. **Fail loudly** instead of pretending. Pass `refuseWhenThrottled: true` to your action.
|
|
119
|
+
|
|
120
|
+
If the tab is fine, check `occluded` on the element. A click that lands on a modal overlay is the other half of "the button doesn't work":
|
|
121
|
+
|
|
122
|
+
```json
|
|
123
|
+
{ "occluded": true, "occludedBy": "div.modal-backdrop" }
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## "ref no longer resolves to an element"
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
That ref is stale: refs are invalidated whenever the DOM re-renders, so any action that navigated,
|
|
130
|
+
opened a modal, re-sorted a list or changed the page invalidates every ref taken before it.
|
|
131
|
+
Reticle refuses here rather than clicking whatever now occupies that slot.
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
This is Reticle protecting you, not failing. Re-query for a fresh ref.
|
|
135
|
+
|
|
136
|
+
Better: use `reticle_act_and_wait { until }` for actions that change the page, so the next ref is taken after things settle.
|
|
137
|
+
|
|
138
|
+
<Warning>
|
|
139
|
+
Refs never survive a full navigation. A new document means new refs, the same button was `e5`
|
|
140
|
+
before a navigation and `e103` after.
|
|
141
|
+
</Warning>
|
|
142
|
+
|
|
143
|
+
## The verdict says `unknown`
|
|
144
|
+
|
|
145
|
+
`verified: "unknown"` means Reticle drove the app and could not tell. It is **not** a pass.
|
|
146
|
+
|
|
147
|
+
The usual cause is a throttled tab: throttling suppresses the quiescence detection used to decide the page has settled, so even a successful action can come back unsettled. Drive a lease and try again.
|
|
148
|
+
|
|
149
|
+
If it persists on an unthrottled context, that is worth reporting. Reticle's own response says so:
|
|
150
|
+
|
|
151
|
+
```json
|
|
152
|
+
"feedback_invite": "Reticle could not tell what happened here. If you expected otherwise, reticle_feedback. An unknown verdict is our defect, not yours"
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## A negative result you are not sure about
|
|
156
|
+
|
|
157
|
+
Before concluding "no request fired", read the buffer note:
|
|
158
|
+
|
|
159
|
+
```json
|
|
160
|
+
"buffer": { "held": 15, "dropped": 529, "note": "…a negative result here may be a false negative; the evidence may have expired…" }
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
"Nothing found" and "I no longer have what you asked about" are different answers. Grade sooner, or widen the buffer.
|
|
164
|
+
|
|
165
|
+
## The agent cannot find an element
|
|
166
|
+
|
|
167
|
+
- `reticle_snapshot { mode: "interactive" }` shows everything actionable.
|
|
168
|
+
- Add a `data-testid` for a stable handle.
|
|
169
|
+
- Narrow with `scope`. A CSS selector or a ref.
|
|
170
|
+
|
|
171
|
+
## Assertions are flaky on async UIs
|
|
172
|
+
|
|
173
|
+
- Use `timeout_ms` on `assert` and `wait_for`.
|
|
174
|
+
- Pass the `since` cursor from `reticle_act` so only post-action events count. Without it, an assertion can pass on an event from two clicks ago.
|
|
175
|
+
|
|
176
|
+
## `reticle_state` returns nothing
|
|
177
|
+
|
|
178
|
+
`storeNames` empty means no store was registered. `reticle_state` reads what your app registered in `src/reticle-dev.ts`.
|
|
179
|
+
|
|
180
|
+
<Warning>
|
|
181
|
+
Pass the **store**, not `() => store.getState()`. The getter form is read-only and silently produces
|
|
182
|
+
empty `stateDiffs`. Which reads as "nothing changed" and means "I was never watching".
|
|
183
|
+
</Warning>
|
|
184
|
+
|
|
185
|
+
## Source file is not resolving on React 19
|
|
186
|
+
|
|
187
|
+
React 19 dropped `_debugSource`. Wire up `@reticlehq/babel-plugin`. Or just use `@reticlehq/vite-plugin` or `@reticlehq/next`, which both include it. Without it you get component identity but no `file:line`.
|
|
188
|
+
|
|
189
|
+
## `ERESOLVE` installing next to a prerelease
|
|
190
|
+
|
|
191
|
+
`@reticlehq/next` declares `peer next >=13` and `@reticlehq/react` declares `peer react >=18`. On a Next canary or React RC, npm refuses. See [the prerelease notes](/getting-started#installing-alongside-a-nextjs-or-react-prerelease).
|
|
192
|
+
|
|
193
|
+
## Restarting things
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
npx @reticlehq/server stop # clean daemon shutdown, no pkill needed
|
|
197
|
+
npx @reticlehq/server status # confirm it came back
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
<Warning>
|
|
201
|
+
Do not kill port 4400 with `lsof -ti tcp:4400 | xargs kill -9`. That matches the MCP proxy as well
|
|
202
|
+
as the daemon and takes your agent's connection down with it. Use `reticle stop`, or at minimum
|
|
203
|
+
`lsof -sTCP:LISTEN`.
|
|
204
|
+
</Warning>
|
|
205
|
+
|
|
206
|
+
## Sessions piling up
|
|
207
|
+
|
|
208
|
+
Stale sessions pointing at dev servers you restarted an hour ago look completely plausible in a list, and one of them will get picked.
|
|
209
|
+
|
|
210
|
+
```json
|
|
211
|
+
{ "action": "end" }
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
`reticle_session { action: "end" }` when you are done, `{ action: "yield" }` when pausing. Both revive on your next action.
|
|
215
|
+
|
|
216
|
+
## Frequently asked questions
|
|
217
|
+
|
|
218
|
+
<AccordionGroup>
|
|
219
|
+
<Accordion title="Why does reticle_sessions return nothing when my app is clearly running?">
|
|
220
|
+
Your app running is not the same as your app being connected. The SDK has to dial the daemon's
|
|
221
|
+
bridge port over a WebSocket. If `npx @reticlehq/server doctor` shows the daemon up and
|
|
222
|
+
`sessions` at zero, either `reticle.connect()` never executed (check the dev guard is actually
|
|
223
|
+
true) or the app dialled the wrong port. The browser console names the exact address it tried.
|
|
224
|
+
</Accordion>
|
|
225
|
+
|
|
226
|
+
<Accordion title="Which port should my app dial?">
|
|
227
|
+
The bridge port, which defaults to `4400`. It is **not** your dev-server port. A dev server on
|
|
228
|
+
4312 and a daemon on 4400 is the normal, correct arrangement. `doctor` prints the bridge port
|
|
229
|
+
under `bridge port`.
|
|
230
|
+
</Accordion>
|
|
231
|
+
|
|
232
|
+
<Accordion title="I restarted my agent and the reticle tools still are not there.">
|
|
233
|
+
If you registered the MCP server while the agent was running, restart the agent process itself:
|
|
234
|
+
quit and reopen Claude Code, reload the window in Cursor, or press Start in `.vscode/mcp.json` in
|
|
235
|
+
VS Code. `/mcp` only manages servers that were already loaded, so it cannot discover a new one. If
|
|
236
|
+
the tools are still missing, run `claude mcp list` and check `reticle` is present.
|
|
237
|
+
</Accordion>
|
|
238
|
+
|
|
239
|
+
<Accordion title="Does a verdict of unknown mean the test failed?">
|
|
240
|
+
No, and it does not mean it passed either. `verified: "unknown"` means Reticle drove the app and
|
|
241
|
+
could not tell what happened, usually because the page never settled inside the observation
|
|
242
|
+
window. Report it as unknown. If you hit one on an unthrottled context and believe it is wrong,
|
|
243
|
+
that is a Reticle defect worth sending with `reticle_feedback`.
|
|
244
|
+
</Accordion>
|
|
245
|
+
|
|
246
|
+
<Accordion title="Is it safe to kill port 4400 to restart things?">
|
|
247
|
+
No. `lsof -ti tcp:4400 | xargs kill -9` matches your agent's MCP proxy as well as the daemon and
|
|
248
|
+
takes the connection down with it. Use `npx @reticlehq/server stop`, or at minimum add
|
|
249
|
+
`-sTCP:LISTEN` so only the listener matches.
|
|
250
|
+
</Accordion>
|
|
251
|
+
|
|
252
|
+
<Accordion title="Why does my agent click a button and nothing happens?">
|
|
253
|
+
Check the response for a `warning` about a throttled tab. A backgrounded browser tab has its
|
|
254
|
+
timers suppressed, so synthetic pointer gestures can silently no-op while the action still
|
|
255
|
+
reports success. Drive a lease instead, which is a context Reticle owns and never backgrounds.
|
|
256
|
+
If the tab is fine, check `occluded` on the element: a click landing on a modal overlay looks
|
|
257
|
+
identical from the outside.
|
|
258
|
+
</Accordion>
|
|
259
|
+
</AccordionGroup>
|
|
260
|
+
|
|
261
|
+
<Card title="Still stuck?" icon="comments" href="/tools-session-and-feedback">
|
|
262
|
+
`reticle feedback --agent` works even when nothing is installed and the daemon will not start.
|
|
263
|
+
</Card>
|