@reticlehq/server 2.8.0 → 2.10.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/SKILL.md +130 -813
- 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/capsule-store.d.ts +2 -2
- package/dist/capsule/causal-summary.d.ts +16 -1
- package/dist/capsule/causal-summary.js +2 -1
- package/dist/cli/cli-doctor.js +41 -13
- package/dist/cli/cli-flow-commands.js +8 -8
- package/dist/cli/cli-launch.d.ts +0 -17
- package/dist/cli/cli-launch.js +0 -28
- package/dist/cli/cli-parse.d.ts +1 -1
- package/dist/cli/cli-parse.js +1 -1
- package/dist/cli/cli-port.d.ts +24 -0
- package/dist/cli/cli-port.js +66 -35
- package/dist/cli/cli-verify.d.ts +21 -0
- package/dist/cli/cli-verify.js +45 -1
- 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.js +6 -3
- 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/status-next-action.d.ts +37 -0
- package/dist/cli/status-next-action.js +61 -0
- package/dist/cli.js +65 -70
- package/dist/crawl/crawl.d.ts +7 -2
- package/dist/crawl/crawl.js +52 -9
- package/dist/ee/audit-log.js +2 -2
- package/dist/events/body-failures.d.ts +2 -2
- package/dist/events/contradiction-folds.d.ts +45 -0
- package/dist/events/contradiction-folds.js +42 -0
- package/dist/events/contradictions.d.ts +51 -1
- package/dist/events/contradictions.js +26 -7
- package/dist/events/declared.d.ts +45 -0
- package/dist/events/declared.js +73 -0
- package/dist/events/echo-mismatch.d.ts +9 -3
- 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 -91
- package/dist/events/predicate-eval.js +85 -326
- 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 +127 -5
- package/dist/events/stale-response.d.ts +2 -3
- package/dist/events/stale-response.js +49 -2
- package/dist/events/unit-mismatch.d.ts +2 -2
- 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-replay-run.js +8 -1
- package/dist/flows/flow-tools.js +9 -1
- package/dist/flows/replay.js +3 -0
- package/dist/flows/verify-change-tools.js +1 -1
- 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 +4 -0
- 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 +9 -0
- package/dist/honesty/unsettled.js +7 -3
- package/dist/honesty/verified.d.ts +29 -3
- package/dist/honesty/verified.js +67 -8
- 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 +25 -0
- package/dist/index.js +60 -10
- package/dist/init/agent-rules.d.ts +20 -0
- package/dist/init/agent-rules.js +36 -0
- package/dist/init/astro-patch.js +27 -1
- package/dist/init/confirm.d.ts +21 -3
- package/dist/init/confirm.js +32 -5
- package/dist/init/connect-steps.d.ts +2 -0
- package/dist/init/connect-steps.js +50 -0
- 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 +16 -2
- package/dist/init/mcp.js +23 -1
- package/dist/init/plan-framework.d.ts +10 -0
- package/dist/init/plan-framework.js +25 -1
- package/dist/init/plan.d.ts +7 -2
- package/dist/init/plan.js +66 -30
- package/dist/init/run.js +11 -5
- package/dist/init/slash-command.d.ts +1 -1
- package/dist/init/slash-command.js +12 -4
- package/dist/init/snippets.d.ts +1 -1
- package/dist/init/snippets.js +35 -7
- package/dist/init/vite-config.js +24 -2
- package/dist/input/network-mock-tools.js +8 -1
- 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.d.ts +69 -4
- package/dist/license/license.js +84 -15
- package/dist/mcp/mcp-proxy.d.ts +7 -93
- package/dist/mcp/mcp-proxy.js +183 -250
- package/dist/mcp/mcp.d.ts +27 -2
- package/dist/mcp/mcp.js +77 -36
- package/dist/mcp/proxy-daemon-probe.d.ts +8 -0
- package/dist/mcp/proxy-daemon-probe.js +48 -0
- package/dist/mcp/proxy-handshake.d.ts +82 -1
- package/dist/mcp/proxy-handshake.js +110 -3
- package/dist/mcp/proxy-lifecycle.d.ts +10 -1
- package/dist/mcp/proxy-lifecycle.js +11 -2
- 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/mcp/sse-frame-parser.d.ts +19 -0
- package/dist/mcp/sse-frame-parser.js +41 -0
- 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 +55 -2
- package/dist/session/no-session-diagnosis.js +199 -22
- 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 +172 -11
- package/dist/session/pending-commands.d.ts +12 -0
- package/dist/session/pending-commands.js +13 -1
- package/dist/session/session-manager.d.ts +4 -0
- package/dist/session/session-manager.js +35 -5
- package/dist/session/session-readiness.js +1 -1
- 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/bug-found.d.ts +18 -0
- package/dist/telemetry/bug-found.js +14 -0
- package/dist/telemetry/daemon-telemetry.js +29 -0
- package/dist/telemetry/install-source.d.ts +20 -0
- package/dist/telemetry/install-source.js +34 -0
- package/dist/telemetry/instrumentation-stall.d.ts +57 -0
- package/dist/telemetry/instrumentation-stall.js +103 -0
- package/dist/telemetry/license-activation.d.ts +48 -0
- package/dist/telemetry/license-activation.js +57 -0
- package/dist/telemetry/session-metrics.d.ts +8 -0
- package/dist/telemetry/session-metrics.js +10 -0
- package/dist/telemetry/telemetry.d.ts +3 -1
- package/dist/telemetry/telemetry.js +23 -3
- package/dist/tools/act-tools.js +166 -29
- package/dist/tools/assert-verdict.js +32 -7
- package/dist/tools/browser-tools.js +10 -0
- package/dist/tools/dynamic-tools.js +17 -8
- package/dist/tools/error-recovery.js +10 -6
- package/dist/tools/feedback-tools.js +31 -6
- package/dist/tools/invoke-tool.d.ts +1 -1
- package/dist/tools/invoke-tool.js +30 -8
- package/dist/tools/lease-hint.d.ts +30 -8
- package/dist/tools/lease-hint.js +65 -14
- package/dist/tools/lease-tools.d.ts +11 -0
- package/dist/tools/lease-tools.js +141 -96
- package/dist/tools/observe-tools.js +9 -3
- package/dist/tools/react-grace.d.ts +4 -0
- package/dist/tools/react-grace.js +6 -3
- package/dist/tools/read-tools.js +47 -1
- 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 +15 -0
- package/dist/tools/settle-in-flight.js +42 -2
- package/dist/tools/snapshot-delta.d.ts +3 -0
- package/dist/tools/snapshot-delta.js +67 -6
- package/dist/tools/tool-kit.d.ts +38 -3
- package/dist/tools/tool-names.d.ts +2 -0
- package/dist/tools/tool-names.js +2 -0
- package/dist/tools/tool-surface.d.ts +60 -0
- package/dist/tools/tool-surface.js +84 -19
- package/dist/tools/tools.js +61 -5
- package/dist/tools/unadvertised-help.js +9 -6
- package/docs/README.md +1 -2
- package/docs/actions.mdx +41 -8
- package/docs/agent-cheatsheet.md +6 -4
- package/docs/architecture.md +6 -0
- package/docs/benchmarks.md +60 -12
- package/docs/best-practices.mdx +11 -6
- package/docs/capabilities.mdx +204 -57
- package/docs/cli/affected.mdx +6 -4
- package/docs/cli/capsules.mdx +9 -8
- package/docs/cli/cloud.mdx +30 -4
- package/docs/cli/doctor.mdx +41 -8
- package/docs/cli/drive.mdx +34 -15
- package/docs/cli/gate.mdx +6 -6
- package/docs/cli/help.mdx +8 -6
- package/docs/cli/hunt.mdx +20 -4
- package/docs/cli/identify.mdx +16 -2
- package/docs/cli/init.mdx +35 -8
- package/docs/cli/kill.mdx +5 -5
- package/docs/cli/license.mdx +1 -1
- package/docs/cli/open.mdx +6 -0
- package/docs/cli/restart.mdx +6 -6
- package/docs/cli/serve.mdx +10 -3
- package/docs/cli/status.mdx +29 -5
- package/docs/cli/stop.mdx +8 -0
- package/docs/cli/verify.mdx +20 -1
- package/docs/cli/version.mdx +1 -1
- package/docs/cli/watch.mdx +9 -2
- package/docs/cli.mdx +44 -22
- package/docs/debugging.md +3 -1
- package/docs/deploy-checks.md +31 -2
- package/docs/desktop.mdx +276 -80
- package/docs/docs.json +13 -12
- package/docs/enterprise.md +9 -3
- package/docs/faq.mdx +49 -35
- package/docs/fixtures.md +2 -0
- package/docs/flows.md +7 -5
- package/docs/for-agents.md +3 -3
- package/docs/frameworks.mdx +46 -7
- package/docs/gate-plan.md +4 -2
- package/docs/gates.md +8 -6
- package/docs/getting-started.md +53 -12
- package/docs/human-control.md +2 -0
- package/docs/index.mdx +43 -1
- package/docs/install-agentic.mdx +13 -4
- package/docs/install-manual.mdx +6 -4
- package/docs/instrumentation.mdx +7 -1
- package/docs/integration-patterns.md +3 -1
- package/docs/local-registry.md +4 -2
- package/docs/multi-agent-testing.md +3 -1
- package/docs/packages/babel-plugin.mdx +15 -6
- package/docs/packages/browser.mdx +2 -2
- package/docs/packages/core.mdx +26 -16
- package/docs/packages/electron.mdx +5 -7
- package/docs/packages/eslint-plugin.mdx +5 -3
- package/docs/packages/next.mdx +3 -5
- package/docs/packages/react.mdx +3 -3
- package/docs/packages/server.mdx +2 -2
- package/docs/packages/tauri.mdx +6 -6
- package/docs/packages/test.mdx +18 -7
- package/docs/packages/vite-plugin.mdx +4 -6
- package/docs/packages.mdx +14 -13
- package/docs/platform-integration.md +2 -0
- package/docs/predicates.mdx +76 -7
- package/docs/quickstart.mdx +51 -5
- package/docs/recipes.mdx +63 -23
- package/docs/skill-file.mdx +3 -1
- package/docs/state-management.mdx +2 -0
- package/docs/system-map.md +3 -1
- package/docs/telemetry-contract.md +33 -5
- package/docs/telemetry-events.mdx +63 -18
- package/docs/telemetry.md +8 -5
- package/docs/testing.md +35 -1
- package/docs/token-efficiency.md +8 -2
- package/docs/tools-act-and-wait.mdx +64 -14
- package/docs/tools-act-sequence.mdx +34 -17
- package/docs/tools-act.mdx +24 -11
- package/docs/tools-assert.mdx +69 -10
- package/docs/tools-console.mdx +11 -7
- package/docs/tools-inspect.mdx +11 -8
- package/docs/tools-navigate.mdx +41 -5
- package/docs/tools-network.mdx +42 -9
- package/docs/tools-observe.mdx +66 -10
- package/docs/tools-overview.mdx +26 -23
- package/docs/tools-query.mdx +52 -8
- package/docs/tools-session-and-feedback.mdx +35 -9
- package/docs/tools-sessions.mdx +39 -10
- package/docs/tools-snapshot.mdx +57 -3
- package/docs/tools-state.mdx +24 -1
- package/docs/tools-tools-and-run.mdx +55 -24
- package/docs/tools-wait-for.mdx +34 -15
- package/docs/troubleshooting.mdx +80 -10
- package/docs/usage.md +46 -24
- package/docs/vs-chrome-devtools-mcp.mdx +41 -0
- package/docs/vs-playwright-mcp.mdx +42 -2
- package/docs/vs-screenshots.mdx +42 -1
- package/docs/what-is-reticle.mdx +1 -1
- package/docs/why-reticle.mdx +3 -1
- package/package.json +5 -5
- package/docs/desktop-apps.md +0 -265
package/docs/tools-overview.mdx
CHANGED
|
@@ -1,33 +1,35 @@
|
|
|
1
1
|
---
|
|
2
|
-
title:
|
|
2
|
+
title: Reticle tools overview
|
|
3
3
|
sidebarTitle: Tools overview
|
|
4
|
-
description: The
|
|
4
|
+
description: The tools your agent sees every turn, the many more it can reach on demand, and why the advertised surface is deliberately small.
|
|
5
5
|
icon: wrench
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
Reticle ships
|
|
8
|
+
Reticle ships 46 tools plus two meta-tools. On the default profile your agent is shown **19** of them: 17 that do the work, plus `reticle_tools` and `reticle_run`, which reach the other 29 on demand. Only `reticle_act_and_wait` and `reticle_assert` produce a verdict.
|
|
9
9
|
|
|
10
10
|
That is not a limitation, it's the design. MCP re-sends every advertised tool definition to the model on **every single turn**, so the tool list is not a menu you pay for once. It's rent.
|
|
11
11
|
|
|
12
|
-
A wider surface costs tokens on every message. Less obviously, it makes the model wander: give it
|
|
12
|
+
A wider surface costs tokens on every message. Less obviously, it makes the model wander: give it fifty ways to look at a page and it will try several before doing anything useful.
|
|
13
13
|
|
|
14
|
-
The other
|
|
14
|
+
The other 29 are one call away, never unreachable. `reticle_tools` lists them and `reticle_run` invokes them.
|
|
15
15
|
|
|
16
16
|
<Note>
|
|
17
|
-
Measured off the real wire on 2026-08-
|
|
18
|
-
surface is **
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
through one tokenizer in a single pass
|
|
17
|
+
Measured off the real wire on 2026-08-16, by reading `tools/list` from a fresh daemon: the default
|
|
18
|
+
surface is **19 tools at 22,023 bytes**, against **48 tools at 134,992 bytes** when
|
|
19
|
+
`RETICLE_ADVERTISE_ALL_TOOLS` is set. That is 6.1x more, charged on every message.
|
|
20
|
+
[`bench/harness/schema-tax.mjs`](/token-efficiency) converts those bytes to tokens by putting
|
|
21
|
+
every server through one tokenizer in a single pass. Re-measure before quoting any of it; the
|
|
22
|
+
surface grows.
|
|
22
23
|
</Note>
|
|
23
24
|
|
|
24
|
-
## The default
|
|
25
|
+
## The default 19
|
|
25
26
|
|
|
26
27
|
Grouped by the job they do in the verify loop.
|
|
27
28
|
|
|
28
29
|
<CardGroup cols={2}>
|
|
29
30
|
<Card title="Look" icon="magnifying-glass">
|
|
30
|
-
`reticle_snapshot` · `reticle_query` · `reticle_inspect` · `reticle_sessions`
|
|
31
|
+
`reticle_snapshot` · `reticle_query` · `reticle_inspect` · `reticle_sessions` ·
|
|
32
|
+
`reticle_capabilities`
|
|
31
33
|
</Card>
|
|
32
34
|
<Card title="Act" icon="hand-pointer">
|
|
33
35
|
`reticle_act` · `reticle_act_and_wait` · `reticle_act_sequence` · `reticle_navigate`
|
|
@@ -49,7 +51,7 @@ Grouped by the job they do in the verify loop.
|
|
|
49
51
|
however many tools it used and however confident the summary sounds.
|
|
50
52
|
</Warning>
|
|
51
53
|
|
|
52
|
-
## Why these
|
|
54
|
+
## Why these and not others
|
|
53
55
|
|
|
54
56
|
Each one earned its slot, and a couple are there because of measured mistakes.
|
|
55
57
|
|
|
@@ -64,16 +66,16 @@ Those repeats were not retries. The calls succeeded and got repeated, because th
|
|
|
64
66
|
Direct `reticle_network` and `reticle_console` stay advertised even though `reticle_observe` can filter for both, because two obvious tools beat one clever tool with a filter grammar.
|
|
65
67
|
|
|
66
68
|
<Tip>
|
|
67
|
-
Trimming further has a floor. An
|
|
68
|
-
model loses scaffolding and wanders on harder flows. That reading is old enough to be dated
|
|
69
|
+
Trimming further has a floor. An eight-tool cut measurably dropped real-agent accuracy, because
|
|
70
|
+
the model loses scaffolding and wanders on harder flows. That reading is old enough to be dated
|
|
69
71
|
evidence rather than proof, and a fresh A/B against a leaner surface is still unrun. Small is
|
|
70
72
|
good; empty is not.
|
|
71
73
|
</Tip>
|
|
72
74
|
|
|
73
|
-
## Reaching the other
|
|
75
|
+
## Reaching the other 29
|
|
74
76
|
|
|
75
77
|
```json
|
|
76
|
-
{ "
|
|
78
|
+
{ "tool": "reticle_verify", "args": { "action": "flows" } }
|
|
77
79
|
```
|
|
78
80
|
|
|
79
81
|
`reticle_run` takes a tool name and its arguments. `reticle_tools` lists what's available and returns the full argument grammar for any of them, so your agent can discover a tool mid-task without you having pre-loaded its schema.
|
|
@@ -85,10 +87,10 @@ Notable residents of the cold tail: flow recording and replay, visual diffing an
|
|
|
85
87
|
Reticle tells you what each answer cost, because a verification tool that quietly eats your context window is not saving you anything:
|
|
86
88
|
|
|
87
89
|
```json
|
|
88
|
-
"cost": { "bytes":
|
|
90
|
+
"cost": { "bytes": 944, "tokens": 236 }
|
|
89
91
|
```
|
|
90
92
|
|
|
91
|
-
That is a real `reticle_query` response: seven buttons found, with source pointers, for
|
|
93
|
+
That is a real `reticle_query` response: seven buttons found, with source pointers, for 236 tokens.
|
|
92
94
|
|
|
93
95
|
## Every response tells you when not to trust it
|
|
94
96
|
|
|
@@ -104,8 +106,8 @@ When the event buffer has evicted old events, a negative result might be a false
|
|
|
104
106
|
|
|
105
107
|
```json
|
|
106
108
|
"buffer": {
|
|
107
|
-
"held":
|
|
108
|
-
"dropped":
|
|
109
|
+
"held": 535,
|
|
110
|
+
"dropped": 10,
|
|
109
111
|
"note": "event buffer evicted older events (age/size cap): a negative result here may be a false negative; the evidence may have expired. Grade sooner or widen the buffer."
|
|
110
112
|
}
|
|
111
113
|
```
|
|
@@ -122,6 +124,7 @@ A tool that says "no requests found" when it actually means "I lost the ones you
|
|
|
122
124
|
| [`reticle_query`](/tools-query) | Where is the thing I mean? |
|
|
123
125
|
| [`reticle_inspect`](/tools-inspect) | Everything about one element, down to source and design tokens |
|
|
124
126
|
| [`reticle_sessions`](/tools-sessions) | Which tabs are connected, and can they actually be driven? |
|
|
127
|
+
| [`reticle_capabilities`](/tools-tools-and-run) | What does this app say is testable? Testids, signals, stores, flows |
|
|
125
128
|
|
|
126
129
|
### Act
|
|
127
130
|
|
|
@@ -148,10 +151,10 @@ A tool that says "no requests found" when it actually means "I lost the ones you
|
|
|
148
151
|
| --- | --- |
|
|
149
152
|
| [`reticle_assert`](/tools-assert) | Did the named consequence hold? **Produces a verdict** |
|
|
150
153
|
| [`reticle_tools`](/tools-tools-and-run) | What else is available, and what are its arguments? |
|
|
151
|
-
| [`reticle_run`](/tools-tools-and-run) | Invoke any of the other
|
|
154
|
+
| [`reticle_run`](/tools-tools-and-run) | Invoke any of the other 29 |
|
|
152
155
|
| [`reticle_session`](/tools-session-and-feedback) | Hand control back to the human |
|
|
153
156
|
| [`reticle_feedback`](/tools-session-and-feedback) | Tell the maintainers Reticle got something wrong |
|
|
154
157
|
|
|
155
158
|
<Card title="The complete reference" icon="book" href="/usage">
|
|
156
|
-
Every tool, every argument, including the
|
|
159
|
+
Every tool, every argument, including the 29 in the cold tail.
|
|
157
160
|
</Card>
|
package/docs/tools-query.mdx
CHANGED
|
@@ -12,14 +12,14 @@ icon: magnifying-glass
|
|
|
12
12
|
{ "by": "role", "value": "button", "limit": 6 }
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
Real response from a running app:
|
|
15
|
+
Real response from a running app, with four of the six elements trimmed out for length:
|
|
16
16
|
|
|
17
17
|
```json
|
|
18
18
|
{
|
|
19
19
|
"count": 7,
|
|
20
20
|
"elements": [
|
|
21
21
|
{
|
|
22
|
-
"ref": "
|
|
22
|
+
"ref": "e118",
|
|
23
23
|
"role": "button",
|
|
24
24
|
"name": "Overview",
|
|
25
25
|
"visible": true,
|
|
@@ -27,7 +27,7 @@ Real response from a running app:
|
|
|
27
27
|
"states": ["present", "visible", "enabled"]
|
|
28
28
|
},
|
|
29
29
|
{
|
|
30
|
-
"ref": "
|
|
30
|
+
"ref": "e120",
|
|
31
31
|
"role": "button",
|
|
32
32
|
"name": "Compose",
|
|
33
33
|
"visible": true,
|
|
@@ -37,11 +37,11 @@ Real response from a running app:
|
|
|
37
37
|
],
|
|
38
38
|
"total": 7,
|
|
39
39
|
"truncated": true,
|
|
40
|
-
"cost": { "bytes":
|
|
40
|
+
"cost": { "bytes": 944, "tokens": 236 }
|
|
41
41
|
}
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
-
Seven buttons, each with a `ref` to act on and a source file to open, for
|
|
44
|
+
Seven buttons, each with a `ref` to act on and a source file to open, for 236 tokens.
|
|
45
45
|
|
|
46
46
|
## Arguments
|
|
47
47
|
|
|
@@ -63,16 +63,60 @@ Every argument also has a predicate spelling, so `{ "role": "button" }` works as
|
|
|
63
63
|
"Are there still three rows?" does not require three row descriptors:
|
|
64
64
|
|
|
65
65
|
```json
|
|
66
|
-
{ "by": "testid", "value": "
|
|
66
|
+
{ "by": "testid", "value": "login-submit", "count_only": true }
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
+
```json
|
|
70
|
+
{ "count": 1, "cost": { "bytes": 11, "tokens": 3 } }
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Three tokens. Note that `total` is not emitted on this path, because `count` already is the total.
|
|
74
|
+
|
|
75
|
+
## A zero-match result tells you what _is_ there
|
|
76
|
+
|
|
77
|
+
```json
|
|
78
|
+
{ "by": "testid", "value": "compose-prompt" }
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
```json
|
|
82
|
+
{
|
|
83
|
+
"count": 0,
|
|
84
|
+
"elements": [],
|
|
85
|
+
"hint": {
|
|
86
|
+
"route": "/hostile",
|
|
87
|
+
"knownEmptyState": true,
|
|
88
|
+
"presentTestids": [
|
|
89
|
+
"brand",
|
|
90
|
+
"nav-overview",
|
|
91
|
+
"nav-deployments",
|
|
92
|
+
"nav-compose",
|
|
93
|
+
"nav-diagnostics",
|
|
94
|
+
"nav-hostile",
|
|
95
|
+
"session-pill",
|
|
96
|
+
"cmdk-open",
|
|
97
|
+
"sign-out",
|
|
98
|
+
"hostile-view",
|
|
99
|
+
"hostile-ticker",
|
|
100
|
+
"hostile-feed-count"
|
|
101
|
+
],
|
|
102
|
+
"presentRegions": [
|
|
103
|
+
{ "role": "list", "childCount": 0, "name": "hostile-feed", "sample": [] },
|
|
104
|
+
{ "role": "banner", "childCount": 0, "sample": [] }
|
|
105
|
+
]
|
|
106
|
+
},
|
|
107
|
+
"cost": { "bytes": 402, "tokens": 101 }
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
The testid existed, on another route. `hint.route` says where you actually are, `presentTestids` says what is on this page instead, and `presentRegions` distinguishes an empty list from a missing one. All of it without paying for a snapshot.
|
|
112
|
+
|
|
69
113
|
## Reading the response
|
|
70
114
|
|
|
71
115
|
`ref` is the handle for every other tool: `act`, `inspect`, `state`. It stays valid until the element leaves the DOM, so you do not need to re-snapshot between actions on the same element.
|
|
72
116
|
|
|
73
|
-
`source` appears when `@reticlehq/react` is installed. Note that
|
|
117
|
+
`source` appears when `@reticlehq/react` is installed. Note that both sidebar buttons above report `Sidebar.tsx:41`, and so do the three trimmed out of the example. That is the line where the component renders all five in a loop, which is exactly the line you want to edit.
|
|
74
118
|
|
|
75
|
-
`truncated: true` with `total: 7` means `limit` cut the list, not that Reticle ran out of room.
|
|
119
|
+
`truncated: true` with `total: 7` means `limit` cut the list, not that Reticle ran out of room. Neither field is emitted when nothing was cut, so their absence is itself the signal that you are looking at every match.
|
|
76
120
|
|
|
77
121
|
`states` distinguishes `present` from `visible` from `enabled`. An element can be all three and still be covered by a modal. [`reticle_inspect`](/tools-inspect) reports `occluded` for that.
|
|
78
122
|
|
|
@@ -4,26 +4,36 @@ description: Hand the session back to the human, end it cleanly, and tell the ma
|
|
|
4
4
|
icon: comments
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
`reticle_session` manages the boundary between the agent and the human watching: hand control back, end the session, narrate what you are doing, and drain the bugs they pinned on elements. `reticle_feedback` is how you tell the Reticle maintainers that Reticle itself got something wrong. Neither tool touches your app, and neither produces a verdict.
|
|
8
8
|
|
|
9
9
|
## reticle_session
|
|
10
10
|
|
|
11
11
|
The presenter panel in your app shows a live transcript of what the agent is doing. It reads "live" until the agent says otherwise. So an agent that wanders off without a word leaves a panel claiming work is in progress forever.
|
|
12
12
|
|
|
13
|
-
| Action
|
|
14
|
-
|
|
|
15
|
-
| `yield`
|
|
16
|
-
| `end`
|
|
17
|
-
| `tune`
|
|
13
|
+
| Action | What it does |
|
|
14
|
+
| ---------- | ------------------------------------------------------------------------ |
|
|
15
|
+
| `yield` | Hand control back between turns. `mode: "waiting"` or `"ask"`. Revivable |
|
|
16
|
+
| `end` | The task is done. Frees the session; revives on the next action |
|
|
17
|
+
| `tune` | Adjust session behaviour, such as `idleEndMs`, the idle-end window |
|
|
18
|
+
| `resume` | Clear a pause the human applied |
|
|
19
|
+
| `messages` | Drain the human-to-agent inbox |
|
|
20
|
+
| `review` | List, and with `resolve`, retire the mistakes a human pinned to elements |
|
|
21
|
+
| `narrate` | State your intent on the presenter panel, with an optional `level` |
|
|
18
22
|
|
|
19
23
|
```json
|
|
20
24
|
{ "action": "yield", "mode": "waiting" }
|
|
21
25
|
```
|
|
22
26
|
|
|
23
|
-
|
|
27
|
+
`review` returns a real reading rather than a silent empty:
|
|
24
28
|
|
|
25
29
|
```json
|
|
26
|
-
"
|
|
30
|
+
{ "marks": [], "pendingCount": 0 }
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Reticle nudges you about all of this. Every response on a long-running session carries a reminder:
|
|
34
|
+
|
|
35
|
+
```json
|
|
36
|
+
"session_age_warning": "Session s223e0fad-e012-43f9-a23d-6d585470c90d has been open for 21 minutes. If your task is complete, call reticle_session{action:\"end\"} now."
|
|
27
37
|
```
|
|
28
38
|
|
|
29
39
|
And each lease carries the rule in the payload itself:
|
|
@@ -60,6 +70,11 @@ Reticle is built for agents, which creates an unusual problem: the primary user'
|
|
|
60
70
|
| `ambiguity` | The check ran but you could not tell what the answer meant |
|
|
61
71
|
| `feature_request` | You wished a capability existed |
|
|
62
72
|
| `improvement` | It works, but costs too many calls |
|
|
73
|
+
| `experience` | Something worked notably well (pair it with `rating`, 1-5) |
|
|
74
|
+
|
|
75
|
+
`experience` is the only kind here that is not a complaint, and that is why it exists. Every other row grows the corpus into a defect list, which says nothing about which parts are worth protecting when we change them. File it unprompted, when you actually notice it, and name the concrete moment: which call, what it saved you, what you would have done instead.
|
|
76
|
+
|
|
77
|
+
The `rating` is secondary to that text on purpose. A score produced because something asked for one is indistinguishable from a score that was earned, and once both sit in the same column neither means anything. The text is the part that can be acted on or quoted.
|
|
63
78
|
|
|
64
79
|
### It will tell you when it cannot send
|
|
65
80
|
|
|
@@ -69,11 +84,22 @@ Feedback is not fire-and-forget, and it does not pretend to succeed:
|
|
|
69
84
|
{
|
|
70
85
|
"sent": false,
|
|
71
86
|
"accepted": false,
|
|
72
|
-
"reason": "this is a Reticle source checkout, where telemetry is disabled by design, so feedback has nowhere to go. Open an issue at https://github.com/reticlehq/reticle/issues instead.",
|
|
87
|
+
"reason": "this is a Reticle source checkout, where telemetry is disabled by design, so feedback has nowhere to go. Open an issue at https://github.com/reticlehq/reticle/issues instead, or run from the app you are verifying.",
|
|
88
|
+
"redacted": [],
|
|
89
|
+
"context": {
|
|
90
|
+
"stack": "react",
|
|
91
|
+
"client": "claude-code",
|
|
92
|
+
"runtime": "web",
|
|
93
|
+
"engine": "blink",
|
|
94
|
+
"driver": "cdp",
|
|
95
|
+
"mcpScope": "user"
|
|
96
|
+
},
|
|
73
97
|
"note": "NOT accepted (see reason). Tell the human what you found so it is not lost."
|
|
74
98
|
}
|
|
75
99
|
```
|
|
76
100
|
|
|
101
|
+
`redacted` names anything stripped from your report before it left the machine, so you can see what was and was not sent. `context` is the environment attached automatically, which is why a useful report costs one call and no boilerplate.
|
|
102
|
+
|
|
77
103
|
That is a real response, captured while writing these docs. The instruction in `note` is the important part: when the report cannot be delivered, say so in your answer to the human rather than letting the finding evaporate.
|
|
78
104
|
|
|
79
105
|
### From the shell, when the tools are unreachable
|
package/docs/tools-sessions.mdx
CHANGED
|
@@ -4,34 +4,63 @@ description: List every connected browser tab, with the health fields that tell
|
|
|
4
4
|
icon: list-check
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
`reticle_sessions` lists every browser tab currently connected to the Reticle daemon, with the health fields that decide whether it can actually be driven. Reach for it first when a tool says no session is connected, and after every [`reticle_navigate`](/tools-navigate) that came back `confirmed: false`.
|
|
8
|
+
|
|
7
9
|
```json
|
|
8
10
|
{}
|
|
9
11
|
```
|
|
10
12
|
|
|
11
|
-
Real response
|
|
13
|
+
Real response from a healthy session:
|
|
12
14
|
|
|
13
15
|
```json
|
|
14
16
|
{
|
|
15
17
|
"sessions": [
|
|
16
18
|
{
|
|
17
|
-
"sessionId": "
|
|
18
|
-
"url": "http://localhost:
|
|
19
|
+
"sessionId": "sba6117a6-24ec-494d-8c2c-e2958cff2e7f",
|
|
20
|
+
"url": "http://localhost:4310/",
|
|
19
21
|
"title": "Reticle · Mission Control",
|
|
20
22
|
"adapters": ["react"],
|
|
21
23
|
"hasCapabilities": true,
|
|
22
|
-
"hidden":
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
24
|
+
"hidden": false,
|
|
25
|
+
"lastSeenMs": 155,
|
|
26
|
+
"throttled": false,
|
|
27
|
+
"focused": true,
|
|
28
|
+
"attachment": { "connectedSinceMs": 18654, "outages": 0 },
|
|
26
29
|
"realInputAvailable": false,
|
|
27
|
-
"leased": false
|
|
28
|
-
"attachment": { "connectedSinceMs": 827874, "outages": 0 },
|
|
29
|
-
"recommendation": "tab hidden/throttled and may be un-focusable from here; refocus it, or run `reticle drive <url>` for a guaranteed scriptable context"
|
|
30
|
+
"leased": false
|
|
30
31
|
}
|
|
31
32
|
]
|
|
32
33
|
}
|
|
33
34
|
```
|
|
34
35
|
|
|
36
|
+
A backgrounded tab adds a `recommendation` telling you what to do about it, and `attachment` grows a `lastOutage` once the connection has dropped at least once:
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"hidden": false,
|
|
41
|
+
"throttled": true,
|
|
42
|
+
"attachment": {
|
|
43
|
+
"connectedSinceMs": 1217047,
|
|
44
|
+
"outages": 3,
|
|
45
|
+
"lastOutage": { "startedMs": 1786818483776, "durationMs": 967 }
|
|
46
|
+
},
|
|
47
|
+
"recommendation": "tab hidden/throttled and may be un-focusable from here; refocus it, or run `reticle drive <url>` for a guaranteed scriptable context"
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## When nothing is connected
|
|
52
|
+
|
|
53
|
+
An empty list is not silent. It comes back with a `why` that separates the two causes, and refuses to guess between them:
|
|
54
|
+
|
|
55
|
+
```json
|
|
56
|
+
{
|
|
57
|
+
"sessions": [],
|
|
58
|
+
"why": "no browser session connected. Two things to weigh, and neither of them is proof. (1) Nothing is listening on the ports Reticle scans, so the dev server may not be running. That scan is narrow though: a server on any other port is invisible to it, so if the app IS running, ask for its URL rather than assuming it is down, and open it with `reticle open <url>`. (2) There is no `.reticle.json` in the directory this daemon is running in. That is the file `reticle init` writes, so the app may carry no Reticle SDK."
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
That string is trimmed. The full text also lists the exact ports it scanned and warns that in a monorepo the daemon often runs at the root while the app lives in a subdirectory, so you should check the app's own directory before re-running `init`.
|
|
63
|
+
|
|
35
64
|
## The fields that decide whether driving will work
|
|
36
65
|
|
|
37
66
|
| Field | Why it matters |
|
package/docs/tools-snapshot.mdx
CHANGED
|
@@ -24,6 +24,7 @@ icon: camera
|
|
|
24
24
|
{
|
|
25
25
|
"tree": "",
|
|
26
26
|
"nodes": 0,
|
|
27
|
+
"truncated": false,
|
|
27
28
|
"status": { "route": "/", "title": "Reticle · Mission Control" },
|
|
28
29
|
"cost": { "bytes": 98, "tokens": 25 }
|
|
29
30
|
}
|
|
@@ -39,7 +40,7 @@ Ninety-eight bytes to answer "where am I?". Use it after a navigation instead of
|
|
|
39
40
|
|
|
40
41
|
```json
|
|
41
42
|
{
|
|
42
|
-
"tree": "- textbox \"Email\" (ref=
|
|
43
|
+
"tree": "- textbox \"Email\" (ref=e303) [value=\"admin@reticle.dev\"]\n- textbox \"Password\" (ref=e304) [value=\"[REDACTED]\"]\n- button \"Sign in\" (ref=e305)",
|
|
43
44
|
"nodes": 3,
|
|
44
45
|
"truncated": false,
|
|
45
46
|
"status": { "route": "/deployments", "title": "Reticle · Mission Control" },
|
|
@@ -63,7 +64,45 @@ Everything you can act on, with a `ref` for each, for 65 tokens. Note the passwo
|
|
|
63
64
|
{ "mode": "interactive", "diff": true }
|
|
64
65
|
```
|
|
65
66
|
|
|
66
|
-
|
|
67
|
+
When nothing moved since your last look of the same scope and mode, that costs 20 tokens and says so:
|
|
68
|
+
|
|
69
|
+
```json
|
|
70
|
+
{
|
|
71
|
+
"mode": "unchanged",
|
|
72
|
+
"status": { "route": "/", "title": "Reticle · Mission Control" },
|
|
73
|
+
"cost": { "bytes": 79, "tokens": 20 }
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
When something did move, you get only what changed. This is the same call after a login replaced the form with the app shell:
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"mode": "delta",
|
|
82
|
+
"delta": {
|
|
83
|
+
"added": [
|
|
84
|
+
"- button \"Overview\" (ref=e17)",
|
|
85
|
+
"- button \"Deployments40\" (ref=e18)",
|
|
86
|
+
"- button \"Compose\" (ref=e19)",
|
|
87
|
+
"- button \"Diagnostics\" (ref=e20)",
|
|
88
|
+
"- button \"Hostile\" (ref=e21)",
|
|
89
|
+
"- button \"Search or jump to…⌘K\" (ref=e22)",
|
|
90
|
+
"- button \"Sign out\" (ref=e23)"
|
|
91
|
+
],
|
|
92
|
+
"removed": [
|
|
93
|
+
"- textbox \"Email\" (ref=e4) [value=\"admin@reticle.dev\"]",
|
|
94
|
+
"- textbox \"Password\" (ref=e5) [value=\"[REDACTED]\"]",
|
|
95
|
+
"- button \"Sign in\" (ref=e3)"
|
|
96
|
+
],
|
|
97
|
+
"addedCount": 7,
|
|
98
|
+
"removedCount": 3
|
|
99
|
+
},
|
|
100
|
+
"status": { "route": "/", "title": "Reticle · Mission Control" },
|
|
101
|
+
"cost": { "bytes": 545, "tokens": 137 }
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
A route change resets it: the next call after one returns a full snapshot rather than a delta against a page that no longer exists.
|
|
67
106
|
|
|
68
107
|
<Tip>
|
|
69
108
|
Reach for [`reticle_query`](/tools-query) instead when you already know what you're looking for.
|
|
@@ -72,4 +111,19 @@ After the first snapshot, ask only for the delta. On a page where one row appear
|
|
|
72
111
|
|
|
73
112
|
## Refs change across documents
|
|
74
113
|
|
|
75
|
-
Refs are stable while the element is in the DOM. A full navigation builds a new document, so refs are re-issued.
|
|
114
|
+
Refs are stable while the element is in the DOM. A full navigation builds a new document, so refs are re-issued. Across the captures on this page the same "Sign in" button was `e105`, then `e305`, then `e3`, because each reload built a new document. Snapshot after navigating; don't reuse refs across one.
|
|
115
|
+
|
|
116
|
+
Reticle refuses a stale ref rather than clicking whatever now occupies that slot:
|
|
117
|
+
|
|
118
|
+
```json
|
|
119
|
+
{
|
|
120
|
+
"error": "ref 'e303' no longer resolves to an element",
|
|
121
|
+
"recovery": "That ref is stale: refs are invalidated whenever the DOM re-renders, so any action that navigated, opened a modal, re-sorted a list or changed the page invalidates every ref taken before it. Call reticle_query again for a fresh ref and retry the action."
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
<Note>
|
|
126
|
+
That `recovery` string is trimmed. The full text also recommends
|
|
127
|
+
[`reticle_act_and_wait`](/tools-act-and-wait) with `until`, so the next ref is taken after the
|
|
128
|
+
page settles.
|
|
129
|
+
</Note>
|
package/docs/tools-state.mdx
CHANGED
|
@@ -4,6 +4,8 @@ description: Read live framework state directly from the running app. What it be
|
|
|
4
4
|
icon: database
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
`reticle_state` reads live framework state straight out of the running app, without the app broadcasting anything. Reach for it when the DOM looks right and you want to know whether the application actually accepted the change, which is where false greens live.
|
|
8
|
+
|
|
7
9
|
The DOM tells you what the app _drew_. `reticle_state` tells you what it _believes_. The gap between those two is where false greens live: a row appears in the table, the store never changed, and a reload makes the row vanish.
|
|
8
10
|
|
|
9
11
|
## Example
|
|
@@ -46,6 +48,25 @@ Drill in once you know what you want:
|
|
|
46
48
|
{ "store": "app", "path": "auth" }
|
|
47
49
|
```
|
|
48
50
|
|
|
51
|
+
```json
|
|
52
|
+
{
|
|
53
|
+
"store": "app",
|
|
54
|
+
"path": "auth",
|
|
55
|
+
"found": true,
|
|
56
|
+
"value": { "email": "admin@reticle.dev" },
|
|
57
|
+
"storeNames": ["__reticle_renders", "app", "queries"]
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
A wrong `path` comes back `{ "found": false, "availableKeys": [...] }` rather than an empty value, so a typo is diagnosable instead of looking like an empty store.
|
|
62
|
+
|
|
63
|
+
<Warning>
|
|
64
|
+
`reticle_state` asks the page and waits. On a backgrounded tab the page may never answer, and you
|
|
65
|
+
get `"command 'state_read' timed out after 8000ms"` with a recovery note pointing at
|
|
66
|
+
[`reticle_sessions`](/tools-sessions). That is a fact about the tab, not a Reticle failure. Bring
|
|
67
|
+
it to the front, or drive your own browser.
|
|
68
|
+
</Warning>
|
|
69
|
+
|
|
49
70
|
## You have to register stores first
|
|
50
71
|
|
|
51
72
|
`reticle_state` reads what your app registered in `src/reticle-dev.ts`. With nothing registered, `storeNames` comes back empty and this tool has nothing to say.
|
|
@@ -71,7 +92,9 @@ A `POST` returning `200` proves the server was reachable. A row in the DOM prove
|
|
|
71
92
|
State does. When [`reticle_act_and_wait`](/quickstart) reports
|
|
72
93
|
|
|
73
94
|
```json
|
|
74
|
-
"stateDiffs": [
|
|
95
|
+
"stateDiffs": [
|
|
96
|
+
{ "path": "auth", "from": null, "to": "{\"email\":\"admin@reticle.dev\"}", "atMs": 44403 }
|
|
97
|
+
]
|
|
75
98
|
```
|
|
76
99
|
|
|
77
100
|
that is the app itself saying the login took. A mock that returns `200` without touching state gets caught right there, and nowhere else.
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: reticle_tools and reticle_run
|
|
3
|
-
description: Discover the
|
|
3
|
+
description: Discover the tools that are not advertised, load their argument grammar on demand, and invoke any of them by name.
|
|
4
4
|
icon: boxes-stacked
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
|
|
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
8
|
|
|
9
|
-
|
|
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.
|
|
10
12
|
|
|
11
13
|
## Discovering what exists
|
|
12
14
|
|
|
@@ -16,35 +18,37 @@ Reticle advertises 18 tools and ships 48. These two meta-tools are how your agen
|
|
|
16
18
|
|
|
17
19
|
Returns every tool with a one-line summary. A sample of what lives in the cold tail:
|
|
18
20
|
|
|
19
|
-
| Tool
|
|
20
|
-
|
|
|
21
|
-
| `reticle_capabilities`
|
|
22
|
-
| `
|
|
23
|
-
| `reticle_screenshot`
|
|
24
|
-
| `reticle_visual_diff`
|
|
25
|
-
| `reticle_network_mock`
|
|
26
|
-
| `reticle_viewport`
|
|
27
|
-
| `
|
|
28
|
-
| `reticle_clock`
|
|
29
|
-
| `reticle_storage`
|
|
30
|
-
| `
|
|
31
|
-
| `
|
|
32
|
-
| `reticle_reconcile`
|
|
33
|
-
| `reticle_scroll_to`
|
|
21
|
+
| Tool | What it does |
|
|
22
|
+
| --- | --- |
|
|
23
|
+
| `reticle_capabilities` | The app's advertised testable surface, testids, signals, stores, flows |
|
|
24
|
+
| `reticle_verify` (`flows`) | 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_verify` (`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_verify` (`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 |
|
|
34
36
|
|
|
35
37
|
The response also tells you which surface is active:
|
|
36
38
|
|
|
37
39
|
```json
|
|
38
40
|
{
|
|
39
41
|
"profile": {
|
|
40
|
-
"active": "
|
|
41
|
-
"source": "
|
|
42
|
-
"note": "The profile is read once at daemon startup: change
|
|
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."
|
|
43
45
|
},
|
|
44
46
|
"next": "Load params with reticle_tools { names:[…] }, then call reticle_run { tool, args }."
|
|
45
47
|
}
|
|
46
48
|
```
|
|
47
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
|
+
|
|
48
52
|
<Warning>
|
|
49
53
|
"Read once at daemon startup" is doing real work in that sentence. Setting the environment
|
|
50
54
|
variable in a shell where a daemon is already running changes nothing, and the resulting "I set it
|
|
@@ -59,7 +63,27 @@ Summaries are enough to choose a tool, not to call one. Load the full parameters
|
|
|
59
63
|
{ "names": ["reticle_network_mock", "reticle_clock"] }
|
|
60
64
|
```
|
|
61
65
|
|
|
62
|
-
This is the point of the design. Schemas arrive when they are needed, rather than on every turn forever.
|
|
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>
|
|
63
87
|
|
|
64
88
|
## Invoking
|
|
65
89
|
|
|
@@ -98,12 +122,15 @@ Real response from an instrumented app, trimmed:
|
|
|
98
122
|
"name": "ship-a-deploy",
|
|
99
123
|
"steps": ["nav-deployments", "new-deploy", "deploy-name", "deploy-submit"]
|
|
100
124
|
},
|
|
101
|
-
{ "name": "generate-a-script", "steps": ["nav-compose", "compose-prompt", "compose-generate"] }
|
|
125
|
+
{ "name": "generate-a-script", "steps": ["nav-compose", "compose-prompt", "compose-generate"] },
|
|
126
|
+
{ "name": "find-old-deploy", "steps": ["nav-deployments", "scroll-to row-3600"] }
|
|
102
127
|
],
|
|
103
128
|
"source": "live"
|
|
104
129
|
}
|
|
105
130
|
```
|
|
106
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
|
+
|
|
107
134
|
## Start here, not with a snapshot
|
|
108
135
|
|
|
109
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.
|
|
@@ -117,7 +144,11 @@ Compared with snapshotting the page and guessing from element names, it is both
|
|
|
117
144
|
}
|
|
118
145
|
```
|
|
119
146
|
|
|
120
|
-
|
|
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 }`.
|
|
121
152
|
|
|
122
153
|
<Note>
|
|
123
154
|
`reticle_run` returns whatever the invoked tool returns, unchanged. It is a transport, not a
|