@reticlehq/server 2.7.0 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -5
- package/SKILL.md +64 -29
- package/dist/capsule/causal-summary.d.ts +20 -0
- package/dist/capsule/causal-summary.js +31 -6
- 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 +28 -25
- package/dist/cli/cli-kill.d.ts +58 -0
- package/dist/cli/cli-kill.js +162 -0
- package/dist/cli/cli-launch.d.ts +17 -0
- package/dist/cli/cli-launch.js +28 -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 +8 -0
- package/dist/cli/cli-port.js +16 -0
- package/dist/cli/cli-verify.js +2 -2
- package/dist/cli/doctor-sessions-line.d.ts +12 -0
- package/dist/cli/doctor-sessions-line.js +66 -0
- package/dist/cli/port-holder.d.ts +10 -0
- package/dist/cli/port-holder.js +26 -2
- package/dist/cli.js +99 -14
- 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 +14 -0
- package/dist/events/contradictions.js +26 -17
- package/dist/events/predicate-eval.d.ts +20 -1
- package/dist/events/predicate-eval.js +125 -3
- package/dist/events/predicate.js +170 -18
- package/dist/flows/flow-classify.js +1 -1
- package/dist/flows/flow-tools.js +12 -4
- package/dist/flows/heal-run.js +1 -1
- package/dist/honesty/blind-spots.js +6 -2
- package/dist/honesty/unsettled.d.ts +40 -0
- package/dist/honesty/unsettled.js +78 -0
- package/dist/honesty/verified.d.ts +7 -0
- package/dist/honesty/verified.js +3 -3
- package/dist/index.js +3 -0
- package/dist/init/agent-rules.d.ts +16 -0
- package/dist/init/agent-rules.js +96 -22
- package/dist/init/astro-patch.d.ts +2 -1
- package/dist/init/astro-patch.js +11 -5
- package/dist/init/capabilities.d.ts +22 -0
- package/dist/init/capabilities.js +76 -0
- package/dist/init/confirm.d.ts +96 -0
- package/dist/init/confirm.js +138 -0
- package/dist/init/cra.js +3 -2
- package/dist/init/non-js-project.js +29 -5
- package/dist/init/plan-framework.js +53 -15
- package/dist/init/plan.d.ts +40 -4
- package/dist/init/plan.js +163 -40
- package/dist/init/run.d.ts +24 -2
- package/dist/init/run.js +148 -42
- package/dist/init/slash-command.d.ts +1 -1
- package/dist/init/slash-command.js +46 -6
- package/dist/init/snippets.d.ts +44 -4
- package/dist/init/snippets.js +161 -37
- package/dist/init/vite-config.js +29 -3
- package/dist/input/network-mock-tools.d.ts +19 -0
- package/dist/input/network-mock-tools.js +29 -4
- package/dist/license/license.js +1 -1
- package/dist/mcp/mcp-proxy.d.ts +69 -3
- package/dist/mcp/mcp-proxy.js +205 -20
- package/dist/mcp/mcp.js +23 -7
- package/dist/mcp/proxy-lifecycle.d.ts +1 -1
- package/dist/mcp/proxy-lifecycle.js +1 -1
- 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/session/no-session-diagnosis.d.ts +19 -0
- package/dist/session/no-session-diagnosis.js +71 -18
- package/dist/session/no-session-watch.js +12 -0
- 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/telemetry/automation-hint.d.ts +17 -0
- package/dist/telemetry/automation-hint.js +71 -0
- package/dist/telemetry/bug-found.d.ts +0 -20
- package/dist/telemetry/bug-found.js +38 -21
- package/dist/telemetry/cli-telemetry.js +7 -1
- package/dist/telemetry/feedback.js +1 -1
- package/dist/telemetry/init-telemetry.js +9 -1
- package/dist/telemetry/install-source.d.ts +36 -0
- package/dist/telemetry/install-source.js +40 -0
- package/dist/telemetry/run-telemetry.js +4 -1
- package/dist/telemetry/session-metrics.js +5 -0
- package/dist/telemetry/telemetry.d.ts +5 -1
- package/dist/telemetry/telemetry.js +15 -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 +45 -1
- package/dist/tools/assert-grade.d.ts +1 -1
- package/dist/tools/assert-grade.js +27 -5
- package/dist/tools/assert-verdict.js +18 -1
- package/dist/tools/contract-tools.js +4 -0
- package/dist/tools/dynamic-tools.js +1 -1
- package/dist/tools/error-recovery.d.ts +10 -0
- package/dist/tools/error-recovery.js +64 -4
- package/dist/tools/feedback-invite.js +1 -1
- package/dist/tools/invoke-tool.js +139 -23
- package/dist/tools/lease-tools.d.ts +29 -1
- package/dist/tools/lease-tools.js +58 -5
- package/dist/tools/navigate-result.js +1 -1
- package/dist/tools/observe-tools.js +1 -1
- package/dist/tools/observed-nothing.js +1 -1
- package/dist/tools/react-grace.d.ts +48 -0
- package/dist/tools/react-grace.js +87 -0
- package/dist/tools/read-tools.js +20 -4
- package/dist/tools/settle-in-flight.d.ts +79 -0
- package/dist/tools/settle-in-flight.js +106 -0
- package/dist/tools/snapshot-delta.d.ts +7 -0
- package/dist/tools/snapshot-delta.js +130 -6
- package/dist/tools/tool-surface.js +19 -0
- package/dist/tools/tools.js +16 -4
- package/docs/README.md +56 -11
- package/docs/actions.mdx +87 -0
- package/docs/agent-cheatsheet.md +93 -29
- package/docs/architecture.md +46 -35
- package/docs/benchmarks.md +76 -72
- package/docs/best-practices.mdx +211 -0
- package/docs/capabilities.mdx +387 -0
- package/docs/cli/affected.mdx +51 -0
- package/docs/cli/capsules.mdx +69 -0
- package/docs/cli/cloud.mdx +127 -0
- package/docs/cli/doctor.mdx +76 -0
- package/docs/cli/drive.mdx +55 -0
- package/docs/cli/feedback.mdx +67 -0
- package/docs/cli/gate.mdx +64 -0
- package/docs/cli/help.mdx +92 -0
- package/docs/cli/hunt.mdx +57 -0
- package/docs/cli/identify.mdx +62 -0
- package/docs/cli/init.mdx +94 -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 +68 -0
- package/docs/cli/restart.mdx +60 -0
- package/docs/cli/rollback.mdx +35 -0
- package/docs/cli/serve.mdx +62 -0
- package/docs/cli/status.mdx +64 -0
- package/docs/cli/stop.mdx +56 -0
- package/docs/cli/telemetry.mdx +57 -0
- package/docs/cli/update.mdx +52 -0
- package/docs/cli/verify.mdx +57 -0
- package/docs/cli/version.mdx +39 -0
- package/docs/cli/watch.mdx +55 -0
- package/docs/cli.mdx +219 -0
- package/docs/debugging.md +13 -9
- package/docs/deploy-checks.md +15 -11
- package/docs/desktop-apps.md +49 -40
- package/docs/desktop.mdx +188 -0
- package/docs/docs.json +363 -0
- package/docs/enterprise.md +20 -16
- package/docs/faq.mdx +88 -0
- package/docs/fixtures.md +11 -7
- package/docs/flows.md +26 -22
- package/docs/for-agents.md +71 -0
- package/docs/frameworks.mdx +199 -0
- package/docs/gate-plan.md +45 -41
- package/docs/gates.md +22 -18
- package/docs/getting-started.md +76 -65
- package/docs/human-control.md +22 -18
- package/docs/index.mdx +101 -0
- package/docs/install-agentic.mdx +215 -0
- package/docs/install-manual.mdx +194 -0
- package/docs/instrumentation.mdx +232 -0
- package/docs/integration-patterns.md +38 -34
- package/docs/local-registry.md +16 -12
- package/docs/multi-agent-testing.md +16 -12
- package/docs/packages/babel-plugin.mdx +70 -0
- package/docs/packages/browser.mdx +111 -0
- package/docs/packages/core.mdx +106 -0
- package/docs/packages/electron.mdx +87 -0
- package/docs/packages/eslint-plugin.mdx +84 -0
- package/docs/packages/next.mdx +91 -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 +108 -0
- package/docs/packages/vite-plugin.mdx +96 -0
- package/docs/packages.mdx +217 -0
- package/docs/platform-integration.md +33 -26
- package/docs/predicates.mdx +179 -0
- package/docs/quickstart.mdx +211 -0
- package/docs/recipes.mdx +242 -0
- package/docs/skill-file.mdx +105 -0
- package/docs/state-management.mdx +197 -0
- package/docs/style.css +14 -0
- package/docs/system-map.md +47 -32
- package/docs/telemetry-contract.md +93 -50
- package/docs/telemetry-events.mdx +430 -0
- package/docs/telemetry.md +57 -52
- package/docs/testing.md +10 -6
- package/docs/token-efficiency.md +30 -26
- package/docs/tools-act-and-wait.mdx +123 -0
- package/docs/tools-act-sequence.mdx +120 -0
- package/docs/tools-act.mdx +82 -0
- package/docs/tools-assert.mdx +70 -0
- package/docs/tools-console.mdx +59 -0
- package/docs/tools-inspect.mdx +85 -0
- package/docs/tools-navigate.mdx +63 -0
- package/docs/tools-network.mdx +86 -0
- package/docs/tools-observe.mdx +89 -0
- package/docs/tools-overview.mdx +157 -0
- package/docs/tools-query.mdx +82 -0
- package/docs/tools-session-and-feedback.mdx +91 -0
- package/docs/tools-sessions.mdx +65 -0
- package/docs/tools-snapshot.mdx +75 -0
- package/docs/tools-state.mdx +81 -0
- package/docs/tools-tools-and-run.mdx +125 -0
- package/docs/tools-wait-for.mdx +66 -0
- package/docs/troubleshooting.mdx +193 -0
- package/docs/usage.md +175 -153
- package/docs/vs-chrome-devtools-mcp.mdx +82 -0
- package/docs/vs-playwright-mcp.mdx +85 -0
- package/docs/vs-screenshots.mdx +96 -0
- package/docs/what-is-reticle.mdx +63 -0
- package/docs/why-reticle.mdx +107 -0
- package/package.json +2 -2
- 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,157 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Tools overview: 18 up front, 30 on call
|
|
3
|
+
sidebarTitle: Tools overview
|
|
4
|
+
description: The 18 tools your agent sees every turn, the 30 more it can reach on demand, and why the surface is deliberately small.
|
|
5
|
+
icon: wrench
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Reticle ships 48 tools. Your agent is shown **18** of them.
|
|
9
|
+
|
|
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
|
+
|
|
12
|
+
A wider surface costs tokens on every message. Less obviously, it makes the model wander: give it forty ways to look at a page and it will try several before doing anything useful.
|
|
13
|
+
|
|
14
|
+
The other 30 tools are one call away, never unreachable. `reticle_tools` lists them and `reticle_run` invokes them.
|
|
15
|
+
|
|
16
|
+
<Note>
|
|
17
|
+
Measured off the real wire on 2026-08-14, by reading `tools/list` from a fresh daemon: the default
|
|
18
|
+
surface is **18 tools at 21,468 bytes**, against **48 tools at 134,368 bytes**. That is 6.3x more,
|
|
19
|
+
charged on every message. In real tokenizer terms that is roughly **4,930** and **30,200** tokens
|
|
20
|
+
per turn ([measured by `bench/harness/schema-tax.mjs`](/token-efficiency), which puts every server
|
|
21
|
+
through one tokenizer in a single pass). Re-measure before quoting these; the surface grows.
|
|
22
|
+
</Note>
|
|
23
|
+
|
|
24
|
+
## The default 18
|
|
25
|
+
|
|
26
|
+
Grouped by the job they do in the verify loop.
|
|
27
|
+
|
|
28
|
+
<CardGroup cols={2}>
|
|
29
|
+
<Card title="Look" icon="magnifying-glass">
|
|
30
|
+
`reticle_snapshot` · `reticle_query` · `reticle_inspect` · `reticle_sessions`
|
|
31
|
+
</Card>
|
|
32
|
+
<Card title="Act" icon="hand-pointer">
|
|
33
|
+
`reticle_act` · `reticle_act_and_wait` · `reticle_act_sequence` · `reticle_navigate`
|
|
34
|
+
</Card>
|
|
35
|
+
<Card title="Observe" icon="satellite-dish">
|
|
36
|
+
`reticle_observe` · `reticle_network` · `reticle_console` · `reticle_state` · `reticle_wait_for`
|
|
37
|
+
</Card>
|
|
38
|
+
<Card title="Prove & discover" icon="circle-check">
|
|
39
|
+
`reticle_assert` · `reticle_tools` · `reticle_run`
|
|
40
|
+
</Card>
|
|
41
|
+
<Card title="Session & feedback" icon="comment">
|
|
42
|
+
`reticle_session` · `reticle_feedback`
|
|
43
|
+
</Card>
|
|
44
|
+
</CardGroup>
|
|
45
|
+
|
|
46
|
+
<Warning>
|
|
47
|
+
Only **`reticle_act_and_wait`** and **`reticle_assert`** produce a verdict. Everything else moves
|
|
48
|
+
or reads the app and proves nothing. A drive that ends without one of those two has no result,
|
|
49
|
+
however many tools it used and however confident the summary sounds.
|
|
50
|
+
</Warning>
|
|
51
|
+
|
|
52
|
+
## Why these 18 and not others
|
|
53
|
+
|
|
54
|
+
Each one earned its slot, and a couple are there because of measured mistakes.
|
|
55
|
+
|
|
56
|
+
`reticle_inspect` maps a DOM node to `src/components/Sidebar.tsx:41`. Finding a bug is half the job. Knowing which file to open is the half that makes an agent useful.
|
|
57
|
+
|
|
58
|
+
It used to sit in the cold tail, which meant an agent had to already know it existed to use it. So essentially nobody did.
|
|
59
|
+
|
|
60
|
+
`reticle_act_sequence` batches a multi-step interaction into one round trip. It was also in the cold tail, and the consequence showed up in the data: agents drove login forms one call at a time, over and over.
|
|
61
|
+
|
|
62
|
+
Those repeats were not retries. The calls succeeded and got repeated, because the batching tool was invisible. A tool an agent must already know about is a tool that never gets called.
|
|
63
|
+
|
|
64
|
+
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
|
+
|
|
66
|
+
<Tip>
|
|
67
|
+
Trimming further has a floor. An 8-tool cut measurably dropped real-agent accuracy, because the
|
|
68
|
+
model loses scaffolding and wanders on harder flows. That reading is old enough to be dated
|
|
69
|
+
evidence rather than proof, and a fresh A/B against a leaner surface is still unrun. Small is
|
|
70
|
+
good; empty is not.
|
|
71
|
+
</Tip>
|
|
72
|
+
|
|
73
|
+
## Reaching the other 30
|
|
74
|
+
|
|
75
|
+
```json
|
|
76
|
+
{ "name": "reticle_flow_verify", "args": {} }
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
`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.
|
|
80
|
+
|
|
81
|
+
Notable residents of the cold tail: flow recording and replay, visual diffing and screenshots, network mocking, viewport pinning, coverage, autonomous crawling, and the human-in-the-loop session controls.
|
|
82
|
+
|
|
83
|
+
## Every response carries its cost
|
|
84
|
+
|
|
85
|
+
Reticle tells you what each answer cost, because a verification tool that quietly eats your context window is not saving you anything:
|
|
86
|
+
|
|
87
|
+
```json
|
|
88
|
+
"cost": { "bytes": 938, "tokens": 235 }
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
That is a real `reticle_query` response: seven buttons found, with source pointers, for 235 tokens.
|
|
92
|
+
|
|
93
|
+
## Every response tells you when not to trust it
|
|
94
|
+
|
|
95
|
+
This is the part we're proudest of and the part that makes demos slightly less shiny.
|
|
96
|
+
|
|
97
|
+
When the browser tab is backgrounded, every response says so:
|
|
98
|
+
|
|
99
|
+
```json
|
|
100
|
+
"warning": "tab throttled; timer/rAF/pointer gestures may silently no-op; refocus before driving"
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
When the event buffer has evicted old events, a negative result might be a false negative, and it says that too:
|
|
104
|
+
|
|
105
|
+
```json
|
|
106
|
+
"buffer": {
|
|
107
|
+
"held": 15,
|
|
108
|
+
"dropped": 529,
|
|
109
|
+
"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
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
A tool that says "no requests found" when it actually means "I lost the ones you asked about" is worse than useless. It is confidently wrong. Reticle would rather tell you its memory is imperfect.
|
|
114
|
+
|
|
115
|
+
## Reference
|
|
116
|
+
|
|
117
|
+
### Look
|
|
118
|
+
|
|
119
|
+
| Tool | Answers |
|
|
120
|
+
| --- | --- |
|
|
121
|
+
| [`reticle_snapshot`](/tools-snapshot) | What is on this page? Three modes, from full tree to a 25-token route check |
|
|
122
|
+
| [`reticle_query`](/tools-query) | Where is the thing I mean? |
|
|
123
|
+
| [`reticle_inspect`](/tools-inspect) | Everything about one element, down to source and design tokens |
|
|
124
|
+
| [`reticle_sessions`](/tools-sessions) | Which tabs are connected, and can they actually be driven? |
|
|
125
|
+
|
|
126
|
+
### Act
|
|
127
|
+
|
|
128
|
+
| Tool | Answers |
|
|
129
|
+
| --- | --- |
|
|
130
|
+
| [`reticle_act`](/tools-act) | Do this. Proves nothing, and says so |
|
|
131
|
+
| [`reticle_act_and_wait`](/tools-act-and-wait) | Do this, and prove the consequence. **Produces a verdict** |
|
|
132
|
+
| [`reticle_act_sequence`](/tools-act-sequence) | Do these three things in one round trip |
|
|
133
|
+
| [`reticle_navigate`](/tools-navigate) | Go here. Dispatched, not confirmed |
|
|
134
|
+
|
|
135
|
+
### Observe
|
|
136
|
+
|
|
137
|
+
| Tool | Answers |
|
|
138
|
+
| ------------------------------------- | ----------------------------------------------- |
|
|
139
|
+
| [`reticle_observe`](/tools-observe) | Everything that happened in a window |
|
|
140
|
+
| [`reticle_network`](/tools-network) | Which requests fired, with bodies and timings |
|
|
141
|
+
| [`reticle_console`](/tools-console) | What was logged, and whether the read was real |
|
|
142
|
+
| [`reticle_state`](/tools-state) | What the app believes, not what it drew |
|
|
143
|
+
| [`reticle_wait_for`](/tools-wait-for) | Block until something you did not cause happens |
|
|
144
|
+
|
|
145
|
+
### Prove and discover
|
|
146
|
+
|
|
147
|
+
| Tool | Answers |
|
|
148
|
+
| --- | --- |
|
|
149
|
+
| [`reticle_assert`](/tools-assert) | Did the named consequence hold? **Produces a verdict** |
|
|
150
|
+
| [`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 30 |
|
|
152
|
+
| [`reticle_session`](/tools-session-and-feedback) | Hand control back to the human |
|
|
153
|
+
| [`reticle_feedback`](/tools-session-and-feedback) | Tell the maintainers Reticle got something wrong |
|
|
154
|
+
|
|
155
|
+
<Card title="The complete reference" icon="book" href="/usage">
|
|
156
|
+
Every tool, every argument, including the 30 in the cold tail.
|
|
157
|
+
</Card>
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: reticle_query
|
|
3
|
+
description: Find elements by Testing-Library semantics. Role, text, label, placeholder, testid, alt, or React component, including inside open shadow roots.
|
|
4
|
+
icon: magnifying-glass
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
`reticle_query` answers "where is the thing I mean?" without dumping the whole page into your context window. It queries the way a testing library does. By role, label, text, testid. So your agent binds to meaning rather than to DOM structure that a refactor will move.
|
|
8
|
+
|
|
9
|
+
## Example
|
|
10
|
+
|
|
11
|
+
```json
|
|
12
|
+
{ "by": "role", "value": "button", "limit": 6 }
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Real response from a running app:
|
|
16
|
+
|
|
17
|
+
```json
|
|
18
|
+
{
|
|
19
|
+
"count": 7,
|
|
20
|
+
"elements": [
|
|
21
|
+
{
|
|
22
|
+
"ref": "e18",
|
|
23
|
+
"role": "button",
|
|
24
|
+
"name": "Overview",
|
|
25
|
+
"visible": true,
|
|
26
|
+
"source": "src/components/Sidebar.tsx:41",
|
|
27
|
+
"states": ["present", "visible", "enabled"]
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"ref": "e20",
|
|
31
|
+
"role": "button",
|
|
32
|
+
"name": "Compose",
|
|
33
|
+
"visible": true,
|
|
34
|
+
"source": "src/components/Sidebar.tsx:41",
|
|
35
|
+
"states": ["present", "visible", "enabled"]
|
|
36
|
+
}
|
|
37
|
+
],
|
|
38
|
+
"total": 7,
|
|
39
|
+
"truncated": true,
|
|
40
|
+
"cost": { "bytes": 938, "tokens": 235 }
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Seven buttons, each with a `ref` to act on and a source file to open, for 235 tokens.
|
|
45
|
+
|
|
46
|
+
## Arguments
|
|
47
|
+
|
|
48
|
+
| Argument | What it does |
|
|
49
|
+
| ------------ | -------------------------------------------------------------------------- |
|
|
50
|
+
| `by` | `role` · `text` · `label` · `placeholder` · `testid` · `alt` · `component` |
|
|
51
|
+
| `value` | The query value for that strategy |
|
|
52
|
+
| `name` | Accessible-name filter. Narrows a broad `role` query |
|
|
53
|
+
| `scope` | CSS selector or ref, to search inside a subtree |
|
|
54
|
+
| `limit` | Cap the descriptors returned. Cuts tokens hard on broad queries |
|
|
55
|
+
| `count_only` | Return just `{ count }`, around 30x smaller |
|
|
56
|
+
| `attrs` | Extra attributes per match, e.g. `['href']` to inventory links |
|
|
57
|
+
| `self` | Return the `scope` element itself instead of searching inside it |
|
|
58
|
+
|
|
59
|
+
Every argument also has a predicate spelling, so `{ "role": "button" }` works as shorthand for `{ "by": "role", "value": "button" }`.
|
|
60
|
+
|
|
61
|
+
## Use `count_only` when you only need a number
|
|
62
|
+
|
|
63
|
+
"Are there still three rows?" does not require three row descriptors:
|
|
64
|
+
|
|
65
|
+
```json
|
|
66
|
+
{ "by": "testid", "value": "todo-row", "count_only": true }
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Reading the response
|
|
70
|
+
|
|
71
|
+
`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
|
+
|
|
73
|
+
`source` appears when `@reticlehq/react` is installed. Note that all five sidebar buttons above report `Sidebar.tsx:41`. That is the line where the component renders them in a loop, which is exactly the line you want to edit.
|
|
74
|
+
|
|
75
|
+
`truncated: true` with `total: 7` means `limit` cut the list, not that Reticle ran out of room.
|
|
76
|
+
|
|
77
|
+
`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
|
+
|
|
79
|
+
<Tip>
|
|
80
|
+
Query by `testid` when you can. Role and text queries survive refactors well; testids survive
|
|
81
|
+
redesigns, translations, and the day someone rewrites your button labels for the marketing team.
|
|
82
|
+
</Tip>
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: reticle_session and reticle_feedback
|
|
3
|
+
description: Hand the session back to the human, end it cleanly, and tell the maintainers when Reticle got something wrong.
|
|
4
|
+
icon: comments
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Two tools that are not about your app at all. One manages the boundary between agent and human; the other is how Reticle finds out it is broken.
|
|
8
|
+
|
|
9
|
+
## reticle_session
|
|
10
|
+
|
|
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
|
+
|
|
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 the idle-end window |
|
|
18
|
+
|
|
19
|
+
```json
|
|
20
|
+
{ "action": "yield", "mode": "waiting" }
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Reticle nudges you about this. Every response on a long-running session carries a reminder:
|
|
24
|
+
|
|
25
|
+
```json
|
|
26
|
+
"session_age_warning": "Session s7fe3a790… has been open for 15 minutes. If your task is complete, call reticle_session{action:\"end\"} now."
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
And each lease carries the rule in the payload itself:
|
|
30
|
+
|
|
31
|
+
```json
|
|
32
|
+
"session_lease": {
|
|
33
|
+
"IMPORTANT": "When you stop driving, call reticle_session {action:\"yield\", mode:\"waiting\"|\"ask\"}. The panel reads \"live\" until you do."
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
<Tip>
|
|
38
|
+
`yield` when you are pausing and might come back. `end` when you are finished. Both revive on your
|
|
39
|
+
next action, so neither is destructive. The difference is what the human watching the panel is
|
|
40
|
+
told.
|
|
41
|
+
</Tip>
|
|
42
|
+
|
|
43
|
+
## reticle_feedback
|
|
44
|
+
|
|
45
|
+
Reticle is built for agents, which creates an unusual problem: the primary user's experience vanishes the moment its context does. If an agent hits a gap and works around it silently, nobody ever learns the gap existed.
|
|
46
|
+
|
|
47
|
+
```json
|
|
48
|
+
{
|
|
49
|
+
"kind": "bug",
|
|
50
|
+
"text": "What I called, what I expected, what I got, and why Reticle is at fault.",
|
|
51
|
+
"currentApproach": "How I am working around it today.",
|
|
52
|
+
"impact": "What measurably improves if this is fixed."
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
| `kind` | Use it when |
|
|
57
|
+
| ----------------- | ---------------------------------------------------------- |
|
|
58
|
+
| `bug` | A tool returned a wrong or broken result |
|
|
59
|
+
| `gap` | Reticle could not observe something you needed at all |
|
|
60
|
+
| `ambiguity` | The check ran but you could not tell what the answer meant |
|
|
61
|
+
| `feature_request` | You wished a capability existed |
|
|
62
|
+
| `improvement` | It works, but costs too many calls |
|
|
63
|
+
|
|
64
|
+
### It will tell you when it cannot send
|
|
65
|
+
|
|
66
|
+
Feedback is not fire-and-forget, and it does not pretend to succeed:
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"sent": false,
|
|
71
|
+
"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.",
|
|
73
|
+
"note": "NOT accepted (see reason). Tell the human what you found so it is not lost."
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
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
|
+
|
|
79
|
+
### From the shell, when the tools are unreachable
|
|
80
|
+
|
|
81
|
+
The setup that failed to finish is exactly the setup that most needs reporting, and in that state the MCP tools do not exist:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
npx @reticlehq/server feedback --agent --kind gap "reticle init finished but no session ever connected"
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
<Note>
|
|
88
|
+
Report defects in **Reticle**. A bug you find in the app under test is Reticle working correctly,
|
|
89
|
+
and belongs in your answer to the user. Not in a bug report to us. We get a surprising number of
|
|
90
|
+
those, and each one is quietly a compliment.
|
|
91
|
+
</Note>
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: reticle_sessions
|
|
3
|
+
description: List every connected browser tab, with the health fields that tell you whether it can actually be driven.
|
|
4
|
+
icon: list-check
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
```json
|
|
8
|
+
{}
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Real response, one session shown:
|
|
12
|
+
|
|
13
|
+
```json
|
|
14
|
+
{
|
|
15
|
+
"sessions": [
|
|
16
|
+
{
|
|
17
|
+
"sessionId": "s7fe3a790-ab02-4ebb-82b2-24d08a76fd59",
|
|
18
|
+
"url": "http://localhost:4312/",
|
|
19
|
+
"title": "Reticle · Mission Control",
|
|
20
|
+
"adapters": ["react"],
|
|
21
|
+
"hasCapabilities": true,
|
|
22
|
+
"hidden": true,
|
|
23
|
+
"throttled": true,
|
|
24
|
+
"focused": false,
|
|
25
|
+
"lastSeenMs": 21944,
|
|
26
|
+
"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
|
+
}
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## The fields that decide whether driving will work
|
|
36
|
+
|
|
37
|
+
| Field | Why it matters |
|
|
38
|
+
| --- | --- |
|
|
39
|
+
| `throttled` | The browser is deprioritising a background tab. Synthetic timers and pointer gestures may silently no-op |
|
|
40
|
+
| `hidden` / `focused` | Why it's throttled, and what to do about it |
|
|
41
|
+
| `hasCapabilities` | Whether the app registered testids, signals and stores. `false` means [`reticle_state`](/tools-state) has nothing to read |
|
|
42
|
+
| `adapters` | `["react"]` means you get component names and source pointers |
|
|
43
|
+
| `realInputAvailable` | `true` when native CDP input is available, under `reticle drive` |
|
|
44
|
+
| `outages` | How often the connection has dropped. Non-zero is worth investigating |
|
|
45
|
+
|
|
46
|
+
<Warning>
|
|
47
|
+
`throttled: true` is the most common cause of "the click did nothing". Focus the tab, or drive a
|
|
48
|
+
dedicated context. It is not your app being broken. It is the browser saving battery on a tab
|
|
49
|
+
nobody is looking at.
|
|
50
|
+
</Warning>
|
|
51
|
+
|
|
52
|
+
## Confirm after navigating
|
|
53
|
+
|
|
54
|
+
[`reticle_navigate`](/tools-navigate) can only report that a navigation was dispatched. `sessions` is how you confirm one arrived: a session at the new URL means the page loaded **and** is instrumented. No session means one of those two is false, and you find out now rather than after three confusing failures.
|
|
55
|
+
|
|
56
|
+
## Scoping
|
|
57
|
+
|
|
58
|
+
You rarely need to pass `sessionId` to other tools. Reticle scopes to your project, prefers the active tab, and refuses rather than guesses when the choice is ambiguous. A refusal you can act on beats a silent pick of the wrong tab.
|
|
59
|
+
|
|
60
|
+
Pass it explicitly when you genuinely mean one specific tab, such as when testing two apps at once.
|
|
61
|
+
|
|
62
|
+
<Note>
|
|
63
|
+
Sessions accumulate. A stale entry pointing at a dev server you have since restarted will sit there
|
|
64
|
+
looking plausible. `reticle_session { action: "end" }` clears one out.
|
|
65
|
+
</Note>
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: reticle_snapshot
|
|
3
|
+
description: A semantic accessibility snapshot of the page or a subtree, in three sizes. From the full tree down to a 25-token route check.
|
|
4
|
+
icon: camera
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
`reticle_snapshot` is how an agent gets its bearings. It returns the page as semantic structure, not pixels and not raw HTML, and it comes in three sizes so you can pay for only what you need.
|
|
8
|
+
|
|
9
|
+
## Three modes, three prices
|
|
10
|
+
|
|
11
|
+
| Mode | Returns | Real cost on one page |
|
|
12
|
+
| ------------- | ------------------------------------- | --------------------- |
|
|
13
|
+
| `status` | Route and title only | **25 tokens** |
|
|
14
|
+
| `interactive` | Only clickable and focusable elements | **65 tokens** |
|
|
15
|
+
| `full` | Every element | Depends on the page |
|
|
16
|
+
|
|
17
|
+
### `status`. the cheapest possible check
|
|
18
|
+
|
|
19
|
+
```json
|
|
20
|
+
{ "mode": "status" }
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
{
|
|
25
|
+
"tree": "",
|
|
26
|
+
"nodes": 0,
|
|
27
|
+
"status": { "route": "/", "title": "Reticle · Mission Control" },
|
|
28
|
+
"cost": { "bytes": 98, "tokens": 25 }
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Ninety-eight bytes to answer "where am I?". Use it after a navigation instead of re-reading the page.
|
|
33
|
+
|
|
34
|
+
### `interactive`. the default working view
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{ "mode": "interactive" }
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
```json
|
|
41
|
+
{
|
|
42
|
+
"tree": "- textbox \"Email\" (ref=e101) [value=\"admin@reticle.dev\"]\n- textbox \"Password\" (ref=e102) [value=\"[REDACTED]\"]\n- button \"Sign in\" (ref=e103)",
|
|
43
|
+
"nodes": 3,
|
|
44
|
+
"truncated": false,
|
|
45
|
+
"status": { "route": "/deployments", "title": "Reticle · Mission Control" },
|
|
46
|
+
"cost": { "bytes": 260, "tokens": 65 }
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Everything you can act on, with a `ref` for each, for 65 tokens. Note the password arrives `[REDACTED]` without anyone configuring it.
|
|
51
|
+
|
|
52
|
+
## Arguments
|
|
53
|
+
|
|
54
|
+
| Argument | What it does |
|
|
55
|
+
| -------- | ---------------------------------------------------------------------------- |
|
|
56
|
+
| `mode` | `full` · `interactive` · `status` |
|
|
57
|
+
| `scope` | CSS selector or ref, to snapshot one subtree |
|
|
58
|
+
| `diff` | Return only what changed since your last snapshot of the same scope and mode |
|
|
59
|
+
|
|
60
|
+
## `diff` is how you keep a long session cheap
|
|
61
|
+
|
|
62
|
+
```json
|
|
63
|
+
{ "mode": "interactive", "diff": true }
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
After the first snapshot, ask only for the delta. On a page where one row appeared, you get one row rather than the whole list again.
|
|
67
|
+
|
|
68
|
+
<Tip>
|
|
69
|
+
Reach for [`reticle_query`](/tools-query) instead when you already know what you're looking for.
|
|
70
|
+
Snapshot is for orientation; query is for retrieval, and it's almost always cheaper.
|
|
71
|
+
</Tip>
|
|
72
|
+
|
|
73
|
+
## Refs change across documents
|
|
74
|
+
|
|
75
|
+
Refs are stable while the element is in the DOM. A full navigation builds a new document, so refs are re-issued. The same "Sign in" button was `e5` before a navigation and `e103` after. Snapshot after navigating; don't reuse refs across one.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: reticle_state
|
|
3
|
+
description: Read live framework state directly from the running app. What it believes, not just what it rendered, without the app broadcasting anything.
|
|
4
|
+
icon: database
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
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
|
+
|
|
9
|
+
## Example
|
|
10
|
+
|
|
11
|
+
```json
|
|
12
|
+
{ "depth": 2 }
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Real response:
|
|
16
|
+
|
|
17
|
+
```json
|
|
18
|
+
{
|
|
19
|
+
"found": true,
|
|
20
|
+
"value": {
|
|
21
|
+
"stores": {
|
|
22
|
+
"__reticle_renders": "{…1 keys}",
|
|
23
|
+
"app": "{…30 keys}",
|
|
24
|
+
"queries": "{…0 keys}"
|
|
25
|
+
},
|
|
26
|
+
"storeNames": ["__reticle_renders", "app", "queries"]
|
|
27
|
+
},
|
|
28
|
+
"storeNames": ["__reticle_renders", "app", "queries"]
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
`depth: 2` collapsed the contents to size markers: `{…30 keys}` rather than thirty keys of JSON. On a large store this is the difference between a cheap look and a very expensive one.
|
|
33
|
+
|
|
34
|
+
## Arguments
|
|
35
|
+
|
|
36
|
+
| Argument | What it does |
|
|
37
|
+
| -------- | ------------------------------------------------------------ |
|
|
38
|
+
| `store` | A registered store name, e.g. `app` |
|
|
39
|
+
| `path` | Dot-path into a store, e.g. `cart.items.0.qty` |
|
|
40
|
+
| `depth` | Collapse anything deeper than N levels to a size marker |
|
|
41
|
+
| `ref` | Best-effort read of the nearest React component's hook state |
|
|
42
|
+
|
|
43
|
+
Drill in once you know what you want:
|
|
44
|
+
|
|
45
|
+
```json
|
|
46
|
+
{ "store": "app", "path": "auth" }
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## You have to register stores first
|
|
50
|
+
|
|
51
|
+
`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.
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
registerCapabilities({
|
|
55
|
+
stores: [{ name: 'app', store: appStore }],
|
|
56
|
+
});
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
<Warning>
|
|
60
|
+
Pass the **store**, not `() => store.getState()`. The store form wires `subscribe` too, so every
|
|
61
|
+
mutation emits a state diff. The getter form is read-only and silently produces empty diffs, which
|
|
62
|
+
looks like "nothing changed" and is really "I was never watching".
|
|
63
|
+
</Warning>
|
|
64
|
+
|
|
65
|
+
That distinction is the single most common instrumentation mistake, and its failure mode is a verdict that passes when it should not.
|
|
66
|
+
|
|
67
|
+
## Why this is the strongest evidence you have
|
|
68
|
+
|
|
69
|
+
A `POST` returning `200` proves the server was reachable. A row in the DOM proves React rendered something. Neither proves your application accepted the change.
|
|
70
|
+
|
|
71
|
+
State does. When [`reticle_act_and_wait`](/quickstart) reports
|
|
72
|
+
|
|
73
|
+
```json
|
|
74
|
+
"stateDiffs": [{ "path": "auth", "from": null, "to": "{\"email\":\"admin@reticle.dev\"}" }]
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
that is the app itself saying the login took. A mock that returns `200` without touching state gets caught right there, and nowhere else.
|
|
78
|
+
|
|
79
|
+
<Card title="Instrument your app" icon="wrench" href="/instrumentation">
|
|
80
|
+
Registering one store for your most important flow is the highest-value line you can write.
|
|
81
|
+
</Card>
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: reticle_tools and reticle_run
|
|
3
|
+
description: Discover the 30 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 advertises 18 tools and ships 48. These two meta-tools are how your agent reaches the other 30 without paying for their schemas on every turn.
|
|
8
|
+
|
|
9
|
+
`reticle_tools` discovers. `reticle_run` invokes. Together they cost two tool definitions instead of thirty.
|
|
10
|
+
|
|
11
|
+
## Discovering what exists
|
|
12
|
+
|
|
13
|
+
```json
|
|
14
|
+
{}
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Returns every tool with a one-line summary. A sample of what lives in the cold tail:
|
|
18
|
+
|
|
19
|
+
| Tool | What it does |
|
|
20
|
+
| ----------------------- | ---------------------------------------------------------------------- |
|
|
21
|
+
| `reticle_capabilities` | The app's advertised testable surface, testids, signals, stores, flows |
|
|
22
|
+
| `reticle_flow_verify` | Replay every saved flow, return one consolidated suite verdict |
|
|
23
|
+
| `reticle_screenshot` | Pixel screenshot of the driven page, saved as a visual baseline |
|
|
24
|
+
| `reticle_visual_diff` | Perceptually diff the live page against that baseline |
|
|
25
|
+
| `reticle_network_mock` | Force a 500, go offline, or delay a response |
|
|
26
|
+
| `reticle_viewport` | Pin the viewport so screenshots are reproducible across machines |
|
|
27
|
+
| `reticle_crawl` | Click every reachable control and report anomalies, with no script |
|
|
28
|
+
| `reticle_clock` | Freeze time or fast-forward timers, toasts, debounces, auto-dismiss |
|
|
29
|
+
| `reticle_storage` | localStorage, sessionStorage and readable cookies |
|
|
30
|
+
| `reticle_coverage` | Which controls you have driven this session, and which you have not |
|
|
31
|
+
| `reticle_verify_change` | Give it the files you edited; it replays the flows that cover them |
|
|
32
|
+
| `reticle_reconcile` | Compare what the API returned against what the page actually renders |
|
|
33
|
+
| `reticle_scroll_to` | Find a row in a virtualised list that has not rendered yet |
|
|
34
|
+
|
|
35
|
+
The response also tells you which surface is active:
|
|
36
|
+
|
|
37
|
+
```json
|
|
38
|
+
{
|
|
39
|
+
"profile": {
|
|
40
|
+
"active": "default",
|
|
41
|
+
"source": "the one tool surface (RETICLE_ADVERTISE_ALL_TOOLS unset when the daemon started)",
|
|
42
|
+
"note": "The profile is read once at daemon startup: change it and restart the daemon, or it has no effect."
|
|
43
|
+
},
|
|
44
|
+
"next": "Load params with reticle_tools { names:[…] }, then call reticle_run { tool, args }."
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
<Warning>
|
|
49
|
+
"Read once at daemon startup" is doing real work in that sentence. Setting the environment
|
|
50
|
+
variable in a shell where a daemon is already running changes nothing, and the resulting "I set it
|
|
51
|
+
and nothing happened" is very hard to debug from the outside.
|
|
52
|
+
</Warning>
|
|
53
|
+
|
|
54
|
+
## Loading argument grammar
|
|
55
|
+
|
|
56
|
+
Summaries are enough to choose a tool, not to call one. Load the full parameters for the ones you want:
|
|
57
|
+
|
|
58
|
+
```json
|
|
59
|
+
{ "names": ["reticle_network_mock", "reticle_clock"] }
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
This is the point of the design. Schemas arrive when they are needed, rather than on every turn forever.
|
|
63
|
+
|
|
64
|
+
## Invoking
|
|
65
|
+
|
|
66
|
+
```json
|
|
67
|
+
{ "tool": "reticle_capabilities" }
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Real response from an instrumented app, trimmed:
|
|
71
|
+
|
|
72
|
+
```json
|
|
73
|
+
{
|
|
74
|
+
"testids": [
|
|
75
|
+
"nav-overview",
|
|
76
|
+
"nav-deployments",
|
|
77
|
+
"login-email",
|
|
78
|
+
"login-password",
|
|
79
|
+
"login-submit",
|
|
80
|
+
"deploy-table",
|
|
81
|
+
"new-deploy",
|
|
82
|
+
"deploy-submit",
|
|
83
|
+
"…"
|
|
84
|
+
],
|
|
85
|
+
"signals": [
|
|
86
|
+
"nav:changed",
|
|
87
|
+
"auth:granted",
|
|
88
|
+
"auth:denied",
|
|
89
|
+
"deploy:created",
|
|
90
|
+
"deploy:shipped",
|
|
91
|
+
"modal:opened",
|
|
92
|
+
"toast:shown",
|
|
93
|
+
"…"
|
|
94
|
+
],
|
|
95
|
+
"stores": ["app"],
|
|
96
|
+
"flows": [
|
|
97
|
+
{
|
|
98
|
+
"name": "ship-a-deploy",
|
|
99
|
+
"steps": ["nav-deployments", "new-deploy", "deploy-name", "deploy-submit"]
|
|
100
|
+
},
|
|
101
|
+
{ "name": "generate-a-script", "steps": ["nav-compose", "compose-prompt", "compose-generate"] }
|
|
102
|
+
],
|
|
103
|
+
"source": "live"
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Start here, not with a snapshot
|
|
108
|
+
|
|
109
|
+
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.
|
|
110
|
+
|
|
111
|
+
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.
|
|
112
|
+
|
|
113
|
+
```json
|
|
114
|
+
{
|
|
115
|
+
"tool": "reticle_network_mock",
|
|
116
|
+
"args": { "mocks": [{ "urlContains": "/api/deploys", "status": 500 }] }
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Then drive the flow and see whether your error state actually works. Most do not, which is the point.
|
|
121
|
+
|
|
122
|
+
<Note>
|
|
123
|
+
`reticle_run` returns whatever the invoked tool returns, unchanged. It is a transport, not a
|
|
124
|
+
wrapper. So a tool that produces a verdict still produces one through `run`.
|
|
125
|
+
</Note>
|